KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > persistence > antlr > Parser


1 package persistence.antlr;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/license.html
6  *
7  */

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

46
47 import java.io.IOException JavaDoc;
48 import java.util.Hashtable JavaDoc;
49
50 import persistence.antlr.debug.MessageListener;
51 import persistence.antlr.debug.ParserListener;
52 import persistence.antlr.debug.ParserMatchListener;
53 import persistence.antlr.debug.ParserTokenListener;
54 import persistence.antlr.debug.SemanticPredicateListener;
55 import persistence.antlr.debug.SyntacticPredicateListener;
56 import persistence.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 delegates to this object.
71      * This is set during parser construction by default
72      * to either "new ASTFactory()" or a ctor that
73      * has a token type to class map for hetero nodes.
74      */

75     protected ASTFactory astFactory = null;
76
77     /** Constructed if any AST types specified in tokens{..}.
78      * Maps an Integer->Class object.
79      */

80     protected Hashtable JavaDoc tokenTypeToASTClassMap = null;
81
82     private boolean ignoreInvalidDebugCalls = false;
83
84     /** Used to keep track of indentdepth for traceIn/Out */
85     protected int traceDepth = 0;
86
87     public Parser() {
88         this(new ParserSharedInputState());
89     }
90
91     public Parser(ParserSharedInputState state) {
92         inputState = state;
93     }
94
95     /** If the user specifies a tokens{} section with heterogeneous
96      * AST node types, then ANTLR generates code to fill
97      * this mapping.
98      */

99     public Hashtable JavaDoc getTokenTypeToASTClassMap() {
100         return tokenTypeToASTClassMap;
101     }
102
103     public void addMessageListener(MessageListener l) {
104         if (!ignoreInvalidDebugCalls)
105             throw new IllegalArgumentException JavaDoc("addMessageListener() is only valid if parser built for debugging");
106     }
107
108     public void addParserListener(ParserListener l) {
109         if (!ignoreInvalidDebugCalls)
110             throw new IllegalArgumentException JavaDoc("addParserListener() is only valid if parser built for debugging");
111     }
112
113     public void addParserMatchListener(ParserMatchListener l) {
114         if (!ignoreInvalidDebugCalls)
115             throw new IllegalArgumentException JavaDoc("addParserMatchListener() is only valid if parser built for debugging");
116     }
117
118     public void addParserTokenListener(ParserTokenListener l) {
119         if (!ignoreInvalidDebugCalls)
120             throw new IllegalArgumentException JavaDoc("addParserTokenListener() is only valid if parser built for debugging");
121     }
122
123     public void addSemanticPredicateListener(SemanticPredicateListener l) {
124         if (!ignoreInvalidDebugCalls)
125             throw new IllegalArgumentException JavaDoc("addSemanticPredicateListener() is only valid if parser built for debugging");
126     }
127
128     public void addSyntacticPredicateListener(SyntacticPredicateListener l) {
129         if (!ignoreInvalidDebugCalls)
130             throw new IllegalArgumentException JavaDoc("addSyntacticPredicateListener() is only valid if parser built for debugging");
131     }
132
133     public void addTraceListener(TraceListener l) {
134         if (!ignoreInvalidDebugCalls)
135             throw new IllegalArgumentException JavaDoc("addTraceListener() is only valid if parser built for debugging");
136     }
137
138     /**Get another token object from the token stream */
139     public abstract void consume() throws TokenStreamException;
140
141     /** Consume tokens until one matches the given token */
142     public void consumeUntil(int tokenType) throws TokenStreamException {
143         while (LA(1) != Token.EOF_TYPE && LA(1) != tokenType) {
144             consume();
145         }
146     }
147
148     /** Consume tokens until one matches the given token set */
149     public void consumeUntil(BitSet set) throws TokenStreamException {
150         while (LA(1) != Token.EOF_TYPE && !set.member(LA(1))) {
151             consume();
152         }
153     }
154
155     protected void defaultDebuggingSetup(TokenStream lexer, TokenBuffer tokBuf) {
156         // by default, do nothing -- we're not debugging
157
}
158
159     /** Get the AST return value squirreled away in the parser */
160     public AST getAST() {
161         return returnAST;
162     }
163
164     public ASTFactory getASTFactory() {
165         return astFactory;
166     }
167
168     public String JavaDoc getFilename() {
169         return inputState.filename;
170     }
171
172     public ParserSharedInputState getInputState() {
173         return inputState;
174     }
175
176     public void setInputState(ParserSharedInputState state) {
177         inputState = state;
178     }
179
180     public String JavaDoc getTokenName(int num) {
181         return tokenNames[num];
182     }
183
184     public String JavaDoc[] getTokenNames() {
185         return tokenNames;
186     }
187
188     public boolean isDebugMode() {
189         return false;
190     }
191
192     /** Return the token type of the ith token of lookahead where i=1
193      * is the current token being examined by the parser (i.e., it
194      * has not been matched yet).
195      */

196     public abstract int LA(int i) throws TokenStreamException;
197
198     /**Return the ith token of lookahead */
199     public abstract Token LT(int i) throws TokenStreamException;
200
201     // Forwarded to TokenBuffer
202
public int mark() {
203         return inputState.input.mark();
204     }
205
206     /**Make sure current lookahead symbol matches token type <tt>t</tt>.
207      * Throw an exception upon mismatch, which is catch by either the
208      * error handler or by the syntactic predicate.
209      */

210     public void match(int t) throws MismatchedTokenException, TokenStreamException {
211         if (LA(1) != t)
212             throw new MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
213         else
214         // mark token as consumed -- fetch next token deferred until LA/LT
215
consume();
216     }
217
218     /**Make sure current lookahead symbol matches the given set
219      * Throw an exception upon mismatch, which is catch by either the
220      * error handler or by the syntactic predicate.
221      */

222     public void match(BitSet b) throws MismatchedTokenException, TokenStreamException {
223         if (!b.member(LA(1)))
224             throw new MismatchedTokenException(tokenNames, LT(1), b, false, getFilename());
225         else
226         // mark token as consumed -- fetch next token deferred until LA/LT
227
consume();
228     }
229
230     public void matchNot(int t) throws MismatchedTokenException, TokenStreamException {
231         if (LA(1) == t)
232         // Throws inverted-sense exception
233
throw new MismatchedTokenException(tokenNames, LT(1), t, true, getFilename());
234         else
235         // mark token as consumed -- fetch next token deferred until LA/LT
236
consume();
237     }
238
239     /** @deprecated as of 2.7.2. This method calls System.exit() and writes
240      * directly to stderr, which is usually not appropriate when
241      * a parser is embedded into a larger application. Since the method is
242      * <code>static</code>, it cannot be overridden to avoid these problems.
243      * ANTLR no longer uses this method internally or in generated code.
244      */

245     public static void panic() {
246         System.err.println("Parser: panic");
247         System.exit(1);
248     }
249
250     public void removeMessageListener(MessageListener l) {
251         if (!ignoreInvalidDebugCalls)
252             throw new RuntimeException JavaDoc("removeMessageListener() is only valid if parser built for debugging");
253     }
254
255     public void removeParserListener(ParserListener l) {
256         if (!ignoreInvalidDebugCalls)
257             throw new RuntimeException JavaDoc("removeParserListener() is only valid if parser built for debugging");
258     }
259
260     public void removeParserMatchListener(ParserMatchListener l) {
261         if (!ignoreInvalidDebugCalls)
262             throw new RuntimeException JavaDoc("removeParserMatchListener() is only valid if parser built for debugging");
263     }
264
265     public void removeParserTokenListener(ParserTokenListener l) {
266         if (!ignoreInvalidDebugCalls)
267             throw new RuntimeException JavaDoc("removeParserTokenListener() is only valid if parser built for debugging");
268     }
269
270     public void removeSemanticPredicateListener(SemanticPredicateListener l) {
271         if (!ignoreInvalidDebugCalls)
272             throw new IllegalArgumentException JavaDoc("removeSemanticPredicateListener() is only valid if parser built for debugging");
273     }
274
275     public void removeSyntacticPredicateListener(SyntacticPredicateListener l) {
276         if (!ignoreInvalidDebugCalls)
277             throw new IllegalArgumentException JavaDoc("removeSyntacticPredicateListener() is only valid if parser built for debugging");
278     }
279
280     public void removeTraceListener(TraceListener l) {
281         if (!ignoreInvalidDebugCalls)
282             throw new RuntimeException JavaDoc("removeTraceListener() is only valid if parser built for debugging");
283     }
284
285     /** Parser error-reporting function can be overridden in subclass */
286     public void reportError(RecognitionException ex) {
287         System.err.println(ex);
288     }
289
290     /** Parser error-reporting function can be overridden in subclass */
291     public void reportError(String JavaDoc s) {
292         if (getFilename() == null) {
293             System.err.println("error: " + s);
294         }
295         else {
296             System.err.println(getFilename() + ": error: " + s);
297         }
298     }
299
300     /** Parser warning-reporting function can be overridden in subclass */
301     public void reportWarning(String JavaDoc s) {
302         if (getFilename() == null) {
303             System.err.println("warning: " + s);
304         }
305         else {
306             System.err.println(getFilename() + ": warning: " + s);
307         }
308     }
309
310     public void rewind(int pos) {
311         inputState.input.rewind(pos);
312     }
313
314     /** Specify an object with support code (shared by
315      * Parser and TreeParser. Normally, the programmer
316      * does not play with this, using setASTNodeType instead.
317      */

318     public void setASTFactory(ASTFactory f) {
319         astFactory = f;
320     }
321
322     public void setASTNodeClass(String JavaDoc cl) {
323         astFactory.setASTNodeType(cl);
324     }
325
326     /** Specify the type of node to create during tree building; use setASTNodeClass now
327      * to be consistent with Token Object Type accessor.
328      * @deprecated since 2.7.1
329      */

330     public void setASTNodeType(String JavaDoc nodeType) {
331         setASTNodeClass(nodeType);
332     }
333
334     public void setDebugMode(boolean debugMode) {
335         if (!ignoreInvalidDebugCalls)
336             throw new RuntimeException JavaDoc("setDebugMode() only valid if parser built for debugging");
337     }
338
339     public void setFilename(String JavaDoc f) {
340         inputState.filename = f;
341     }
342
343     public void setIgnoreInvalidDebugCalls(boolean value) {
344         ignoreInvalidDebugCalls = value;
345     }
346
347     /** Set or change the input token buffer */
348     public void setTokenBuffer(TokenBuffer t) {
349         inputState.input = t;
350     }
351
352     public void traceIndent() {
353         for (int i = 0; i < traceDepth; i++)
354             System.out.print(" ");
355     }
356
357     public void traceIn(String JavaDoc rname) throws TokenStreamException {
358         traceDepth += 1;
359         traceIndent();
360         System.out.println("> " + rname + "; LA(1)==" + LT(1).getText() +
361                            ((inputState.guessing > 0)?" [guessing]":""));
362     }
363
364     public void traceOut(String JavaDoc rname) throws TokenStreamException {
365         traceIndent();
366         System.out.println("< " + rname + "; LA(1)==" + LT(1).getText() +
367                            ((inputState.guessing > 0)?" [guessing]":""));
368         traceDepth -= 1;
369     }
370 }
371
Popular Tags