ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/antlr/Parser.hpp
Revision: 2469
Committed: Fri Dec 2 15:38:03 2005 UTC (18 years, 7 months ago) by tim
File size: 8848 byte(s)
Log Message:
End of the Link --> List
Return of the Oject-Oriented
replace yacc/lex parser with antlr parser

File Contents

# User Rev Content
1 tim 2469 #ifndef INC_Parser_hpp__
2     #define INC_Parser_hpp__
3    
4     /* ANTLR Translator Generator
5     * Project led by Terence Parr at http://www.jGuru.com
6     * Software rights: http://www.antlr.org/license.html
7     *
8     * $Id: Parser.hpp,v 1.1 2005-12-02 15:38:02 tim Exp $
9     */
10    
11     #include <iostream>
12     #include <exception>
13    
14     #include <antlr/config.hpp>
15     #include <antlr/BitSet.hpp>
16     #include <antlr/TokenBuffer.hpp>
17     #include <antlr/RecognitionException.hpp>
18     #include <antlr/MismatchedTokenException.hpp>
19     #include <antlr/ASTFactory.hpp>
20     #include <antlr/ParserSharedInputState.hpp>
21    
22     #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
23     namespace antlr {
24     #endif
25    
26     extern bool DEBUG_PARSER;
27    
28     /** A generic ANTLR parser (LL(k) for k>=1) containing a bunch of
29     * utility routines useful at any lookahead depth. We distinguish between
30     * the LL(1) and LL(k) parsers because of efficiency. This may not be
31     * necessary in the near future.
32     *
33     * Each parser object contains the state of the parse including a lookahead
34     * cache (the form of which is determined by the subclass), whether or
35     * not the parser is in guess mode, where tokens come from, etc...
36     *
37     * <p>
38     * During <b>guess</b> mode, the current lookahead token(s) and token type(s)
39     * cache must be saved because the token stream may not have been informed
40     * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block.
41     * Guessing is started by:
42     * <ol>
43     * <li>saving the lookahead cache.
44     * <li>marking the current position in the TokenBuffer.
45     * <li>increasing the guessing level.
46     * </ol>
47     *
48     * After guessing, the parser state is restored by:
49     * <ol>
50     * <li>restoring the lookahead cache.
51     * <li>rewinding the TokenBuffer.
52     * <li>decreasing the guessing level.
53     * </ol>
54     *
55     * @see antlr.Token
56     * @see antlr.TokenBuffer
57     * @see antlr.TokenStream
58     * @see antlr.LL1Parser
59     * @see antlr.LLkParser
60     *
61     * @todo add constructors with ASTFactory.
62     */
63     class ANTLR_API Parser {
64     protected:
65     Parser(TokenBuffer& input)
66     : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0)
67     {
68     }
69     Parser(TokenBuffer* input)
70     : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0)
71     {
72     }
73     Parser(const ParserSharedInputState& state)
74     : inputState(state), astFactory(0), traceDepth(0)
75     {
76     }
77     public:
78     virtual ~Parser()
79     {
80     }
81    
82     /** Return the token type of the ith token of lookahead where i=1
83     * is the current token being examined by the parser (i.e., it
84     * has not been matched yet).
85     */
86     virtual int LA(unsigned int i)=0;
87    
88     /// Return the i-th token of lookahead
89     virtual RefToken LT(unsigned int i)=0;
90    
91     /** DEPRECATED! Specify the factory to be used during tree building. (Compulsory)
92     * Setting the factory is nowadays compulsory.
93     * @see setASTFactory
94     */
95     virtual void setASTNodeFactory( ASTFactory *factory )
96     {
97     astFactory = factory;
98     }
99     /** Specify the factory to be used during tree building. (Compulsory)
100     * Setting the factory is nowadays compulsory.
101     */
102     virtual void setASTFactory( ASTFactory *factory )
103     {
104     astFactory = factory;
105     }
106     /** Return a pointer to the ASTFactory used.
107     * So you might use it in subsequent treewalkers or to reload AST's
108     * from disk.
109     */
110     virtual ASTFactory* getASTFactory()
111     {
112     return astFactory;
113     }
114     /** Get the root AST node of the generated AST. When using a custom AST type
115     * or heterogenous AST's, you'll have to convert it to the right type
116     * yourself.
117     */
118     virtual RefAST getAST() = 0;
119    
120     /// Return the filename of the input file.
121     virtual inline ANTLR_USE_NAMESPACE(std)string getFilename() const
122     {
123     return inputState->filename;
124     }
125     /// Set the filename of the input file (used for error reporting).
126     virtual void setFilename(const ANTLR_USE_NAMESPACE(std)string& f)
127     {
128     inputState->filename = f;
129     }
130    
131     virtual void setInputState(ParserSharedInputState state)
132     {
133     inputState = state;
134     }
135     virtual inline ParserSharedInputState getInputState() const
136     {
137     return inputState;
138     }
139    
140     /// Get another token object from the token stream
141     virtual void consume()=0;
142     /// Consume tokens until one matches the given token
143     virtual void consumeUntil(int tokenType)
144     {
145     while (LA(1) != Token::EOF_TYPE && LA(1) != tokenType)
146     consume();
147     }
148    
149     /// Consume tokens until one matches the given token set
150     virtual void consumeUntil(const BitSet& set)
151     {
152     while (LA(1) != Token::EOF_TYPE && !set.member(LA(1)))
153     consume();
154     }
155    
156     /** Make sure current lookahead symbol matches token type <tt>t</tt>.
157     * Throw an exception upon mismatch, which is catch by either the
158     * error handler or by the syntactic predicate.
159     */
160     virtual void match(int t)
161     {
162     if ( DEBUG_PARSER )
163     {
164     traceIndent();
165     ANTLR_USE_NAMESPACE(std)cout << "enter match(" << t << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl;
166     }
167     if ( LA(1) != t )
168     {
169     if ( DEBUG_PARSER )
170     {
171     traceIndent();
172     ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << "!=" << t << ANTLR_USE_NAMESPACE(std)endl;
173     }
174     throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, false, getFilename());
175     }
176     else
177     {
178     // mark token as consumed -- fetch next token deferred until LA/LT
179     consume();
180     }
181     }
182    
183     virtual void matchNot(int t)
184     {
185     if ( LA(1)==t )
186     {
187     // Throws inverted-sense exception
188     throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, true, getFilename());
189     }
190     else
191     {
192     // mark token as consumed -- fetch next token deferred until LA/LT
193     consume();
194     }
195     }
196    
197     /** Make sure current lookahead symbol matches the given set
198     * Throw an exception upon mismatch, which is catch by either the
199     * error handler or by the syntactic predicate.
200     */
201     virtual void match(const BitSet& b)
202     {
203     if ( DEBUG_PARSER )
204     {
205     traceIndent();
206     ANTLR_USE_NAMESPACE(std)cout << "enter match(" << "bitset" /*b.toString()*/
207     << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl;
208     }
209     if ( !b.member(LA(1)) )
210     {
211     if ( DEBUG_PARSER )
212     {
213     traceIndent();
214     ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << " not member of "
215     << "bitset" /*b.toString()*/ << ANTLR_USE_NAMESPACE(std)endl;
216     }
217     throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), b, false, getFilename());
218     }
219     else
220     {
221     // mark token as consumed -- fetch next token deferred until LA/LT
222     consume();
223     }
224     }
225    
226     /** Mark a spot in the input and return the position.
227     * Forwarded to TokenBuffer.
228     */
229     virtual inline unsigned int mark()
230     {
231     return inputState->getInput().mark();
232     }
233     /// rewind to a previously marked position
234     virtual inline void rewind(unsigned int pos)
235     {
236     inputState->getInput().rewind(pos);
237     }
238     /** called by the generated parser to do error recovery, override to
239     * customize the behaviour.
240     */
241     virtual void recover(const RecognitionException& ex, const BitSet& tokenSet)
242     {
243     consume();
244     consumeUntil(tokenSet);
245     }
246    
247     /// Parser error-reporting function can be overridden in subclass
248     virtual void reportError(const RecognitionException& ex);
249     /// Parser error-reporting function can be overridden in subclass
250     virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s);
251     /// Parser warning-reporting function can be overridden in subclass
252     virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s);
253    
254     /// get the token name for the token number 'num'
255     virtual const char* getTokenName(int num) const = 0;
256     /// get a vector with all token names
257     virtual const char* const* getTokenNames() const = 0;
258     /** Get the number of tokens defined.
259     * This one should be overridden in subclasses.
260     */
261     virtual int getNumTokens(void) const = 0;
262    
263     /** Set or change the input token buffer */
264     // void setTokenBuffer(TokenBuffer<Token>* t);
265    
266     virtual void traceIndent();
267     virtual void traceIn(const char* rname);
268     virtual void traceOut(const char* rname);
269     protected:
270     // void setTokenNames(const char** tokenNames_);
271    
272     ParserSharedInputState inputState;
273    
274     // /// AST return value for a rule is squirreled away here
275     // RefAST returnAST;
276    
277     /// AST support code; parser and treeparser delegate to this object
278     ASTFactory *astFactory;
279    
280     // used to keep track of the indentation for the trace
281     int traceDepth;
282    
283     /** Utility class which allows tracing to work even when exceptions are
284     * thrown.
285     */
286     class Tracer { /*{{{*/
287     private:
288     Parser* parser;
289     const char* text;
290     public:
291     Tracer(Parser* p,const char * t)
292     : parser(p), text(t)
293     {
294     parser->traceIn(text);
295     }
296     ~Tracer()
297     {
298     #ifdef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION
299     // Only give trace if there's no uncaught exception..
300     if(!ANTLR_USE_NAMESPACE(std)uncaught_exception())
301     #endif
302     parser->traceOut(text);
303     }
304     private:
305     Tracer(const Tracer&); // undefined
306     const Tracer& operator=(const Tracer&); // undefined
307     /*}}}*/
308     };
309     private:
310     Parser(const Parser&); // undefined
311     const Parser& operator=(const Parser&); // undefined
312     };
313    
314     #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
315     }
316     #endif
317    
318     #endif //INC_Parser_hpp__