KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > antlr > Parser


1 package antlr;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/RIGHTS.html
6  *
7  * $Id: //depot/code/org.antlr/main/main/antlr/Parser.java#6 $
8  */

9
10 import antlr.collections.impl.BitSet;
11 import antlr.collections.AST;
12 import antlr.collections.impl.ASTArray;
13
14 /**A generic ANTLR parser (LL(k) for k>=1) containing a bunch of
15  * utility routines useful at any lookahead depth. We distinguish between
16  * the LL(1) and LL(k) parsers because of efficiency. This may not be
17  * necessary in the near future.
18  *
19  * Each parser object contains the state of the parse including a lookahead
20  * cache (the form of which is determined by the subclass), whether or
21  * not the parser is in guess mode, where tokens come from, etc...
22  *
23  * <p>
24  * During <b>guess</b> mode, the current lookahead token(s) and token type(s)
25  * cache must be saved because the token stream may not have been informed
26  * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block.
27  * Guessing is started by:
28  * <ol>
29  * <li>saving the lookahead cache.
30  * <li>marking the current position in the TokenBuffer.
31  * <li>increasing the guessing level.
32  * </ol>
33  *
34  * After guessing, the parser state is restored by:
35  * <ol>
36  * <li>restoring the lookahead cache.
37  * <li>rewinding the TokenBuffer.
38  * <li>decreasing the guessing level.
39  * </ol>
40  *
41  * @see antlr.Token
42  * @see antlr.TokenBuffer
43  * @see antlr.Tokenizer
44  * @see antlr.LL1Parser
45  * @see antlr.LLkParser
46  */

47
48 import java.io.IOException JavaDoc;
49
50 import antlr.debug.MessageListener;
51 import antlr.debug.ParserListener;
52 import antlr.debug.ParserMatchListener;
53 import antlr.debug.ParserTokenListener;
54 import antlr.debug.SemanticPredicateListener;
55 import antlr.debug.SyntacticPredicateListener;
56 import antlr.debug.TraceListener;
57
58 public abstract class Parser {
59     protected ParserSharedInputState inputState;
60
61     /** Nesting level of registered handlers */
62     // protected int exceptionLevel = 0;
63

64     /** Table of token type to token names */
65     protected String JavaDoc[] tokenNames;
66
67     /** AST return value for a rule is squirreled away here */
68     protected AST returnAST;
69
70     /** AST support code; parser and treeparser delegate to this object */
71     protected ASTFactory astFactory = new ASTFactory();
72
73     private boolean ignoreInvalidDebugCalls = false;
74
75     /** Used to keep track of indentdepth for traceIn/Out */
76     protected int traceDepth = 0;
77
78     public Parser() {
79         inputState = new ParserSharedInputState();
80     }
81
82     public Parser(ParserSharedInputState state) {
83         inputState = state;
84     }
85
86     public void addMessageListener(MessageListener l) {
87         if (!ignoreInvalidDebugCalls)
88             throw new IllegalArgumentException JavaDoc("addMessageListener() is only valid if parser built for debugging");
89     }
90
91     public void addParserListener(ParserListener l) {
92         if (!ignoreInvalidDebugCalls)
93             throw new IllegalArgumentException JavaDoc("addParserListener() is only valid if parser built for debugging");
94     }
95
96     public void addParserMatchListener(ParserMatchListener l) {
97         if (!ignoreInvalidDebugCalls)
98             throw new IllegalArgumentException JavaDoc("addParserMatchListener() is only valid if parser built for debugging");
99     }
100
101     public void addParserTokenListener(ParserTokenListener l) {
102         if (!ignoreInvalidDebugCalls)
103             throw new IllegalArgumentException JavaDoc("addParserTokenListener() is only valid if parser built for debugging");
104     }
105
106     public void addSemanticPredicateListener(SemanticPredicateListener l) {
107         if (!ignoreInvalidDebugCalls)
108             throw new IllegalArgumentException JavaDoc("addSemanticPredicateListener() is only valid if parser built for debugging");
109     }
110
111     public void addSyntacticPredicateListener(SyntacticPredicateListener l) {
112         if (!ignoreInvalidDebugCalls)
113             throw new IllegalArgumentException JavaDoc("addSyntacticPredicateListener() is only valid if parser built for debugging");
114     }
115
116     public void addTraceListener(TraceListener l) {
117         if (!ignoreInvalidDebugCalls)
118             throw new IllegalArgumentException JavaDoc("addTraceListener() is only valid if parser built for debugging");
119     }
120
121     /**Get another token object from the token stream */
122     public abstract void consume() throws TokenStreamException;
123
124     /** Consume tokens until one matches the given token */
125     public void consumeUntil(int tokenType) throws TokenStreamException {
126         while (LA(1) != Token.EOF_TYPE && LA(1) != tokenType) {
127             consume();
128         }
129     }
130
131     /** Consume tokens until one matches the given token set */
132     public void consumeUntil(BitSet set) throws TokenStreamException {
133         while (LA(1) != Token.EOF_TYPE && !set.member(LA(1))) {
134             consume();
135         }
136     }
137
138     protected void defaultDebuggingSetup(TokenStream lexer, TokenBuffer tokBuf) {
139         // by default, do nothing -- we're not debugging
140
}
141
142     /** Get the AST return value squirreled away in the parser */
143     public AST getAST() {
144         return returnAST;
145     }
146
147     public ASTFactory getASTFactory() {
148         return astFactory;
149     }
150
151     public String JavaDoc getFilename() {
152         return inputState.filename;
153     }
154
155     public ParserSharedInputState getInputState() {
156         return inputState;
157     }
158
159     public void setInputState(ParserSharedInputState state) {
160         inputState = state;
161     }
162
163     public String JavaDoc getTokenName(int num) {
164         return tokenNames[num];
165     }
166
167     public String JavaDoc[] getTokenNames() {
168         return tokenNames;
169     }
170
171     public boolean isDebugMode() {
172         return false;
173     }
174
175     /** Return the token type of the ith token of lookahead where i=1
176      * is the current token being examined by the parser (i.e., it
177      * has not been matched yet).
178      */

179     public abstract int LA(int i) throws TokenStreamException;
180
181     /**Return the ith token of lookahead */
182     public abstract Token LT(int i) throws TokenStreamException;
183
184     // Forwarded to TokenBuffer
185
public int mark() {
186         return inputState.input.mark();
187     }
188
189     /**Make sure current lookahead symbol matches token type <tt>t</tt>.
190      * Throw an exception upon mismatch, which is catch by either the
191      * error handler or by the syntactic predicate.
192      */

193     public void match(int t) throws MismatchedTokenException, TokenStreamException {
194         if (LA(1) != t)
195             throw new MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
196         else
197         // mark token as consumed -- fetch next token deferred until LA/LT
198
consume();
199     }
200
201     /**Make sure current lookahead symbol matches the given set
202      * Throw an exception upon mismatch, which is catch by either the
203      * error handler or by the syntactic predicate.
204      */

205     public void match(BitSet b) throws MismatchedTokenException, TokenStreamException {
206         if (!b.member(LA(1)))
207             throw new MismatchedTokenException(tokenNames, LT(1), b, false, getFilename());
208         else
209         // mark token as consumed -- fetch next token deferred until LA/LT
210
consume();
211     }
212
213     public void matchNot(int t) throws MismatchedTokenException, TokenStreamException {
214         if (LA(1) == t)
215         // Throws inverted-sense exception
216
throw new MismatchedTokenException(tokenNames, LT(1), t, true, getFilename());
217         else
218         // mark token as consumed -- fetch next token deferred until LA/LT
219
consume();
220     }
221
222     public static void panic() {
223         System.err.println("Parser: panic");
224         System.exit(1);
225     }
226
227     public void removeMessageListener(MessageListener l) {
228         if (!ignoreInvalidDebugCalls)
229             throw new RuntimeException JavaDoc("removeMessageListener() is only valid if parser built for debugging");
230     }
231
232     public void removeParserListener(ParserListener l) {
233         if (!ignoreInvalidDebugCalls)
234             throw new RuntimeException JavaDoc("removeParserListener() is only valid if parser built for debugging");
235     }
236
237     public void removeParserMatchListener(ParserMatchListener l) {
238         if (!ignoreInvalidDebugCalls)
239             throw new RuntimeException JavaDoc("removeParserMatchListener() is only valid if parser built for debugging");
240     }
241
242     public void removeParserTokenListener(ParserTokenListener l) {
243         if (!ignoreInvalidDebugCalls)
244             throw new RuntimeException JavaDoc("removeParserTokenListener() is only valid if parser built for debugging");
245     }
246
247     public void removeSemanticPredicateListener(SemanticPredicateListener l) {
248         if (!ignoreInvalidDebugCalls)
249             throw new IllegalArgumentException JavaDoc("removeSemanticPredicateListener() is only valid if parser built for debugging");
250     }
251
252     public void removeSyntacticPredicateListener(SyntacticPredicateListener l) {
253         if (!ignoreInvalidDebugCalls)
254             throw new IllegalArgumentException JavaDoc("removeSyntacticPredicateListener() is only valid if parser built for debugging");
255     }
256
257     public void removeTraceListener(TraceListener l) {
258         if (!ignoreInvalidDebugCalls)
259             throw new RuntimeException JavaDoc("removeTraceListener() is only valid if parser built for debugging");
260     }
261
262     /** Parser error-reporting function can be overridden in subclass */
263     public void reportError(RecognitionException ex) {
264         System.err.println(ex);
265     }
266
267     /** Parser error-reporting function can be overridden in subclass */
268     public void reportError(String JavaDoc s) {
269         if (getFilename() == null) {
270             System.err.println("error: " + s);
271         }
272         else {
273             System.err.println(getFilename() + ": error: " + s);
274         }
275     }
276
277     /** Parser warning-reporting function can be overridden in subclass */
278     public void reportWarning(String JavaDoc s) {
279         if (getFilename() == null) {
280             System.err.println("warning: " + s);
281         }
282         else {
283             System.err.println(getFilename() + ": warning: " + s);
284         }
285     }
286
287     public void rewind(int pos) {
288         inputState.input.rewind(pos);
289     }
290
291     /** Specify an object with support code (shared by
292      * Parser and TreeParser. Normally, the programmer
293      * does not play with this, using setASTNodeType instead.
294      */

295     public void setASTFactory(ASTFactory f) {
296         astFactory = f;
297     }
298
299     public void setASTNodeClass(String JavaDoc cl) {
300         astFactory.setASTNodeType(cl);
301     }
302
303     /** Specify the type of node to create during tree building; use setASTNodeClass now
304      * to be consistent with Token Object Type accessor.
305      */

306     public void setASTNodeType(String JavaDoc nodeType) {
307         setASTNodeClass(nodeType);
308     }
309
310     public void setDebugMode(boolean debugMode) {
311         if (!ignoreInvalidDebugCalls)
312             throw new RuntimeException JavaDoc("setDebugMode() only valid if parser built for debugging");
313     }
314
315     public void setFilename(String JavaDoc f) {
316         inputState.filename = f;
317     }
318
319     public void setIgnoreInvalidDebugCalls(boolean value) {
320         ignoreInvalidDebugCalls = value;
321     }
322
323     /** Set or change the input token buffer */
324     public void setTokenBuffer(TokenBuffer t) {
325         inputState.input = t;
326     }
327
328     public void traceIndent() {
329         for (int i = 0; i < traceDepth; i++)
330             System.out.print(" ");
331     }
332
333     public void traceIn(String JavaDoc rname) throws TokenStreamException {
334         traceDepth += 1;
335         traceIndent();
336         System.out.println("> " + rname + "; LA(1)==" + LT(1).getText() +
337                            ((inputState.guessing > 0)?" [guessing]":""));
338     }
339
340     public void traceOut(String JavaDoc rname) throws TokenStreamException {
341         traceIndent();
342         System.out.println("< " + rname + "; LA(1)==" + LT(1).getText() +
343                            ((inputState.guessing > 0)?" [guessing]":""));
344         traceDepth -= 1;
345     }
346 }
347
Popular Tags