001: package persistence.antlr.debug;
002:
003: import persistence.antlr.ParserSharedInputState;
004: import persistence.antlr.TokenStreamException;
005: import persistence.antlr.LLkParser;
006: import persistence.antlr.TokenBuffer;
007: import persistence.antlr.TokenStream;
008: import persistence.antlr.MismatchedTokenException;
009: import persistence.antlr.RecognitionException;
010: import persistence.antlr.collections.impl.BitSet;
011: import java.io.IOException;
012: import persistence.antlr.TokenStreamException;
013:
014: import persistence.antlr.debug.ParserEventSupport;
015:
016: import java.lang.reflect.Constructor;
017:
018: public class LLkDebuggingParser extends LLkParser implements
019: DebuggingParser {
020: protected ParserEventSupport parserEventSupport = new ParserEventSupport(
021: this );
022:
023: private boolean _notDebugMode = false;
024: protected String ruleNames[];
025: protected String semPredNames[];
026:
027: public LLkDebuggingParser(int k_) {
028: super (k_);
029: }
030:
031: public LLkDebuggingParser(ParserSharedInputState state, int k_) {
032: super (state, k_);
033: }
034:
035: public LLkDebuggingParser(TokenBuffer tokenBuf, int k_) {
036: super (tokenBuf, k_);
037: }
038:
039: public LLkDebuggingParser(TokenStream lexer, int k_) {
040: super (lexer, k_);
041: }
042:
043: public void addMessageListener(MessageListener l) {
044: parserEventSupport.addMessageListener(l);
045: }
046:
047: public void addParserListener(ParserListener l) {
048: parserEventSupport.addParserListener(l);
049: }
050:
051: public void addParserMatchListener(ParserMatchListener l) {
052: parserEventSupport.addParserMatchListener(l);
053: }
054:
055: public void addParserTokenListener(ParserTokenListener l) {
056: parserEventSupport.addParserTokenListener(l);
057: }
058:
059: public void addSemanticPredicateListener(SemanticPredicateListener l) {
060: parserEventSupport.addSemanticPredicateListener(l);
061: }
062:
063: public void addSyntacticPredicateListener(
064: SyntacticPredicateListener l) {
065: parserEventSupport.addSyntacticPredicateListener(l);
066: }
067:
068: public void addTraceListener(TraceListener l) {
069: parserEventSupport.addTraceListener(l);
070: }
071:
072: /**Get another token object from the token stream */
073: public void consume() {
074: int la_1 = -99;
075: try {
076: la_1 = LA(1);
077: } catch (TokenStreamException ignoreAnException) {
078: }
079: super .consume();
080: parserEventSupport.fireConsume(la_1);
081: }
082:
083: protected void fireEnterRule(int num, int data) {
084: if (isDebugMode())
085: parserEventSupport.fireEnterRule(num, inputState.guessing,
086: data);
087: }
088:
089: protected void fireExitRule(int num, int data) {
090: if (isDebugMode())
091: parserEventSupport.fireExitRule(num, inputState.guessing,
092: data);
093: }
094:
095: protected boolean fireSemanticPredicateEvaluated(int type, int num,
096: boolean condition) {
097: if (isDebugMode())
098: return parserEventSupport.fireSemanticPredicateEvaluated(
099: type, num, condition, inputState.guessing);
100: else
101: return condition;
102: }
103:
104: protected void fireSyntacticPredicateFailed() {
105: if (isDebugMode())
106: parserEventSupport
107: .fireSyntacticPredicateFailed(inputState.guessing);
108: }
109:
110: protected void fireSyntacticPredicateStarted() {
111: if (isDebugMode())
112: parserEventSupport
113: .fireSyntacticPredicateStarted(inputState.guessing);
114: }
115:
116: protected void fireSyntacticPredicateSucceeded() {
117: if (isDebugMode())
118: parserEventSupport
119: .fireSyntacticPredicateSucceeded(inputState.guessing);
120: }
121:
122: public String getRuleName(int num) {
123: return ruleNames[num];
124: }
125:
126: public String getSemPredName(int num) {
127: return semPredNames[num];
128: }
129:
130: public synchronized void goToSleep() {
131: try {
132: wait();
133: } catch (InterruptedException e) {
134: }
135: }
136:
137: public boolean isDebugMode() {
138: return !_notDebugMode;
139: }
140:
141: public boolean isGuessing() {
142: return inputState.guessing > 0;
143: }
144:
145: /** Return the token type of the ith token of lookahead where i=1
146: * is the current token being examined by the parser (i.e., it
147: * has not been matched yet).
148: */
149: public int LA(int i) throws TokenStreamException {
150: int la = super .LA(i);
151: parserEventSupport.fireLA(i, la);
152: return la;
153: }
154:
155: /**Make sure current lookahead symbol matches token type <tt>t</tt>.
156: * Throw an exception upon mismatch, which is catch by either the
157: * error handler or by the syntactic predicate.
158: */
159: public void match(int t) throws MismatchedTokenException,
160: TokenStreamException {
161: String text = LT(1).getText();
162: int la_1 = LA(1);
163: try {
164: super .match(t);
165: parserEventSupport.fireMatch(t, text, inputState.guessing);
166: } catch (MismatchedTokenException e) {
167: if (inputState.guessing == 0)
168: parserEventSupport.fireMismatch(la_1, t, text,
169: inputState.guessing);
170: throw e;
171: }
172: }
173:
174: /**Make sure current lookahead symbol matches the given set
175: * Throw an exception upon mismatch, which is catch by either the
176: * error handler or by the syntactic predicate.
177: */
178: public void match(BitSet b) throws MismatchedTokenException,
179: TokenStreamException {
180: String text = LT(1).getText();
181: int la_1 = LA(1);
182: try {
183: super .match(b);
184: parserEventSupport.fireMatch(la_1, b, text,
185: inputState.guessing);
186: } catch (MismatchedTokenException e) {
187: if (inputState.guessing == 0)
188: parserEventSupport.fireMismatch(la_1, b, text,
189: inputState.guessing);
190: throw e;
191: }
192: }
193:
194: public void matchNot(int t) throws MismatchedTokenException,
195: TokenStreamException {
196: String text = LT(1).getText();
197: int la_1 = LA(1);
198: try {
199: super .matchNot(t);
200: parserEventSupport.fireMatchNot(la_1, t, text,
201: inputState.guessing);
202: } catch (MismatchedTokenException e) {
203: if (inputState.guessing == 0)
204: parserEventSupport.fireMismatchNot(la_1, t, text,
205: inputState.guessing);
206: throw e;
207: }
208: }
209:
210: public void removeMessageListener(MessageListener l) {
211: parserEventSupport.removeMessageListener(l);
212: }
213:
214: public void removeParserListener(ParserListener l) {
215: parserEventSupport.removeParserListener(l);
216: }
217:
218: public void removeParserMatchListener(ParserMatchListener l) {
219: parserEventSupport.removeParserMatchListener(l);
220: }
221:
222: public void removeParserTokenListener(ParserTokenListener l) {
223: parserEventSupport.removeParserTokenListener(l);
224: }
225:
226: public void removeSemanticPredicateListener(
227: SemanticPredicateListener l) {
228: parserEventSupport.removeSemanticPredicateListener(l);
229: }
230:
231: public void removeSyntacticPredicateListener(
232: SyntacticPredicateListener l) {
233: parserEventSupport.removeSyntacticPredicateListener(l);
234: }
235:
236: public void removeTraceListener(TraceListener l) {
237: parserEventSupport.removeTraceListener(l);
238: }
239:
240: /** Parser error-reporting function can be overridden in subclass */
241: public void reportError(RecognitionException ex) {
242: parserEventSupport.fireReportError(ex);
243: super .reportError(ex);
244: }
245:
246: /** Parser error-reporting function can be overridden in subclass */
247: public void reportError(String s) {
248: parserEventSupport.fireReportError(s);
249: super .reportError(s);
250: }
251:
252: /** Parser warning-reporting function can be overridden in subclass */
253: public void reportWarning(String s) {
254: parserEventSupport.fireReportWarning(s);
255: super .reportWarning(s);
256: }
257:
258: public void setDebugMode(boolean value) {
259: _notDebugMode = !value;
260: }
261:
262: public void setupDebugging(TokenBuffer tokenBuf) {
263: setupDebugging(null, tokenBuf);
264: }
265:
266: public void setupDebugging(TokenStream lexer) {
267: setupDebugging(lexer, null);
268: }
269:
270: /** User can override to do their own debugging */
271: protected void setupDebugging(TokenStream lexer,
272: TokenBuffer tokenBuf) {
273: setDebugMode(true);
274: // default parser debug setup is ParseView
275: try {
276: try {
277: Class.forName("javax.swing.JButton");
278: } catch (ClassNotFoundException e) {
279: System.err
280: .println("Swing is required to use ParseView, but is not present in your CLASSPATH");
281: System.exit(1);
282: }
283: Class c = Class.forName("antlr.parseview.ParseView");
284: Constructor constructor = c.getConstructor(new Class[] {
285: LLkDebuggingParser.class, TokenStream.class,
286: TokenBuffer.class });
287: constructor.newInstance(new Object[] { this , lexer,
288: tokenBuf });
289: } catch (Exception e) {
290: System.err.println("Error initializing ParseView: " + e);
291: System.err
292: .println("Please report this to Scott Stanchfield, thetick@magelang.com");
293: System.exit(1);
294: }
295: }
296:
297: public synchronized void wakeUp() {
298: notify();
299: }
300: }
|