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

# Content
1 #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__