]>
Commit | Line | Data |
---|---|---|
1 | /* ANTLRParser.h\r | |
2 | *\r | |
3 | * Define the generic ANTLRParser superclass, which is subclassed to\r | |
4 | * define an actual parser.\r | |
5 | *\r | |
6 | * Before entry into this file: ANTLRTokenType must be set.\r | |
7 | *\r | |
8 | * SOFTWARE RIGHTS\r | |
9 | *\r | |
10 | * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r | |
11 | * Set (PCCTS) -- PCCTS is in the public domain. An individual or\r | |
12 | * company may do whatever they wish with source code distributed with\r | |
13 | * PCCTS or the code generated by PCCTS, including the incorporation of\r | |
14 | * PCCTS, or its output, into commerical software.\r | |
15 | *\r | |
16 | * We encourage users to develop software with PCCTS. However, we do ask\r | |
17 | * that credit is given to us for developing PCCTS. By "credit",\r | |
18 | * we mean that if you incorporate our source code into one of your\r | |
19 | * programs (commercial product, research project, or otherwise) that you\r | |
20 | * acknowledge this fact somewhere in the documentation, research report,\r | |
21 | * etc... If you like PCCTS and have developed a nice tool with the\r | |
22 | * output, please mention that you developed it using PCCTS. In\r | |
23 | * addition, we ask that this header remain intact in our source code.\r | |
24 | * As long as these guidelines are kept, we expect to continue enhancing\r | |
25 | * this system and expect to make other tools available as they are\r | |
26 | * completed.\r | |
27 | *\r | |
28 | * ANTLR 1.33\r | |
29 | * Terence Parr\r | |
30 | * Parr Research Corporation\r | |
31 | * with Purdue University and AHPCRC, University of Minnesota\r | |
32 | * 1989-2000\r | |
33 | */\r | |
34 | \r | |
35 | #ifndef APARSER_H_GATE\r | |
36 | #define APARSER_H_GATE\r | |
37 | \r | |
38 | #include "pcctscfg.h"\r | |
39 | \r | |
40 | #include "pccts_stdio.h"\r | |
41 | #include "pccts_setjmp.h"\r | |
42 | \r | |
43 | PCCTS_NAMESPACE_STD\r | |
44 | \r | |
45 | #include ATOKEN_H\r | |
46 | #include ATOKENBUFFER_H\r | |
47 | \r | |
48 | #ifdef ZZCAN_GUESS\r | |
49 | #ifndef ZZINF_LOOK\r | |
50 | #define ZZINF_LOOK\r | |
51 | #endif\r | |
52 | #endif\r | |
53 | \r | |
54 | \r | |
55 | #define NLA (token_type[lap&(LLk-1)])/* --> next LA */\r | |
56 | \r | |
57 | typedef unsigned char SetWordType;\r | |
58 | \r | |
59 | /* Define external bit set stuff (for SetWordType) */\r | |
60 | #define EXT_WORDSIZE (sizeof(char)*8)\r | |
61 | #define EXT_LOGWORDSIZE 3\r | |
62 | \r | |
63 | /* s y n t a c t i c p r e d i c a t e s t u f f */\r | |
64 | \r | |
65 | #ifndef zzUSER_GUESS_HOOK\r | |
66 | #define zzUSER_GUESS_HOOK(seqFrozen,zzrv)\r | |
67 | #endif\r | |
68 | \r | |
69 | #ifndef zzUSER_GUESS_DONE_HOOK\r | |
70 | #define zzUSER_GUESS_DONE_HOOK(seqFrozen)\r | |
71 | #endif\r | |
72 | \r | |
73 | /* MR14 Add zzUSER_GUESS_FAIL_HOOK and related code */\r | |
74 | \r | |
75 | #define zzUSER_GUESS_FAIL_HOOK_INTERNAL zzUSER_GUESS_FAIL_HOOK(SeqFrozen)\r | |
76 | #ifndef zzUSER_GUESS_FAIL_HOOK\r | |
77 | #define zzUSER_GUESS_FAIL_HOOK(zzGuessSeq)\r | |
78 | #endif\r | |
79 | \r | |
80 | \r | |
81 | typedef struct _zzjmp_buf {\r | |
82 | jmp_buf state;\r | |
83 | } zzjmp_buf;\r | |
84 | \r | |
85 | /* these need to be macros not member functions */\r | |
86 | #define zzGUESS_BLOCK ANTLRParserState zzst; int zzrv; int _marker; int zzGuessSeqFrozen;\r | |
87 | #define zzNON_GUESS_MODE if ( !guessing )\r | |
88 | #define zzGUESS_FAIL guess_fail();\r | |
89 | \r | |
90 | /* Note: zzGUESS_DONE does not execute longjmp() */\r | |
91 | \r | |
92 | #define zzGUESS_DONE {zzrv=1; inputTokens->rewind(_marker); guess_done(&zzst);zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) }\r | |
93 | #define zzGUESS saveState(&zzst); \\r | |
94 | guessing = 1; \\r | |
95 | zzGuessSeqFrozen = ++zzGuessSeq; \\r | |
96 | _marker = inputTokens->mark(); \\r | |
97 | zzrv = setjmp(guess_start.state); \\r | |
98 | zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \\r | |
99 | if ( zzrv ) zzGUESS_DONE\r | |
100 | \r | |
101 | #define zzTRACEdata const ANTLRChar *zzTracePrevRuleName = NULL;\r | |
102 | \r | |
103 | #ifndef zzTRACEIN\r | |
104 | #define zzTRACEIN(r) zzTracePrevRuleName=traceCurrentRuleName;tracein(r);\r | |
105 | #endif\r | |
106 | #ifndef zzTRACEOUT\r | |
107 | #define zzTRACEOUT(r) traceout(r);traceCurrentRuleName=zzTracePrevRuleName;\r | |
108 | #endif\r | |
109 | \r | |
110 | /* a n t l r p a r s e r d e f */\r | |
111 | \r | |
112 | struct ANTLRParserState {\r | |
113 | /* class variables */\r | |
114 | zzjmp_buf guess_start;\r | |
115 | int guessing;\r | |
116 | \r | |
117 | int inf_labase;\r | |
118 | int inf_last;\r | |
119 | \r | |
120 | int dirty;\r | |
121 | \r | |
122 | int traceOptionValue; // MR10\r | |
123 | int traceGuessOptionValue; // MR10\r | |
124 | const ANTLRChar *traceCurrentRuleName; // MR10\r | |
125 | int traceDepth; // MR10\r | |
126 | \r | |
127 | };\r | |
128 | \r | |
129 | /* notes:\r | |
130 | *\r | |
131 | * multiple inheritance is a cool way to include what stuff is needed\r | |
132 | * in this structure (like guess stuff). however, i'm not convinced that\r | |
133 | * multiple inheritance works correctly on all platforms. not that\r | |
134 | * much space is used--just include all possibly useful members.\r | |
135 | *\r | |
136 | * the class should also be a template with arguments for the lookahead\r | |
137 | * depth and so on. that way, more than one parser can be defined (as\r | |
138 | * each will probably have different lookahead requirements). however,\r | |
139 | * am i sure that templates work? no, i'm not sure.\r | |
140 | *\r | |
141 | * no attributes are maintained and, hence, the 'asp' variable is not\r | |
142 | * needed. $i can still be referenced, but it refers to the token\r | |
143 | * associated with that rule element. question: where are the token's\r | |
144 | * stored if not on the software stack? in local variables created\r | |
145 | * and assigned to by antlr.\r | |
146 | */\r | |
147 | class ANTLRParser {\r | |
148 | protected:\r | |
149 | /* class variables */\r | |
150 | static SetWordType bitmask[sizeof(SetWordType)*8];\r | |
151 | static char eMsgBuffer[500];\r | |
152 | \r | |
153 | protected:\r | |
154 | int LLk; // number of lookahead symbols (old LL_K)\r | |
155 | int demand_look;\r | |
156 | ANTLRTokenType eofToken; // when do I stop during resynch()s\r | |
157 | int bsetsize; // size of bitsets created by ANTLR in\r | |
158 | // units of SetWordType\r | |
159 | \r | |
160 | ANTLRTokenBuffer *inputTokens; //place to get input tokens\r | |
161 | \r | |
162 | zzjmp_buf guess_start; // where to jump back to upon failure\r | |
163 | int guessing; // if guessing (using (...)? predicate)\r | |
164 | \r | |
165 | // infinite lookahead stuff\r | |
166 | int can_use_inf_look; // set by subclass (generated by ANTLR)\r | |
167 | int inf_lap;\r | |
168 | int inf_labase;\r | |
169 | int inf_last;\r | |
170 | int *_inf_line;\r | |
171 | \r | |
172 | const ANTLRChar **token_tbl; // pointer to table of token type strings MR20 const\r | |
173 | \r | |
174 | int dirty; // used during demand lookahead\r | |
175 | \r | |
176 | ANTLRTokenType *token_type; // fast reference cache of token.getType()\r | |
177 | // ANTLRLightweightToken **token; // the token with all its attributes\r | |
178 | int lap;\r | |
179 | int labase;\r | |
180 | #ifdef ZZDEFER_FETCH\r | |
181 | int stillToFetch; // MR19 V.H. Simonis\r | |
182 | #endif\r | |
183 | \r | |
184 | private:\r | |
185 | void fill_inf_look();\r | |
186 | \r | |
187 | protected:\r | |
188 | virtual void guess_fail() { // MR9 27-Sep-97 make virtual\r | |
189 | traceGuessFail(); // MR10\r | |
190 | longjmp(guess_start.state, 1); } // MR9\r | |
191 | virtual void guess_done(ANTLRParserState *st) { // MR9 27-Sep-97 make virtual\r | |
192 | restoreState(st); } // MR9\r | |
193 | virtual int guess(ANTLRParserState *); // MR9 27-Sep-97 make virtual\r | |
194 | void look(int);\r | |
195 | int _match(ANTLRTokenType, ANTLRChar **, ANTLRTokenType *,\r | |
196 | _ANTLRTokenPtr *, SetWordType **);\r | |
197 | int _setmatch(SetWordType *, ANTLRChar **, ANTLRTokenType *,\r | |
198 | _ANTLRTokenPtr *, SetWordType **,\r | |
199 | SetWordType * tokclassErrset /* MR23 */);\r | |
200 | int _match_wsig(ANTLRTokenType);\r | |
201 | int _setmatch_wsig(SetWordType *);\r | |
202 | virtual void consume();\r | |
203 | virtual void resynch(SetWordType *wd,SetWordType mask); // MR21\r | |
204 | void prime_lookahead();\r | |
205 | virtual void tracein(const ANTLRChar *r); // MR10\r | |
206 | virtual void traceout(const ANTLRChar *r); // MR10\r | |
207 | static unsigned MODWORD(unsigned x) {return x & (EXT_WORDSIZE-1);} // x % EXT_WORDSIZE // MR9\r | |
208 | static unsigned DIVWORD(unsigned x) {return x >> EXT_LOGWORDSIZE;} // x / EXT_WORDSIZE // MR9\r | |
209 | int set_deg(SetWordType *);\r | |
210 | int set_el(ANTLRTokenType, SetWordType *);\r | |
211 | virtual void edecode(SetWordType *); // MR1\r | |
212 | virtual void FAIL(int k, ...); // MR1\r | |
213 | int traceOptionValue; // MR10\r | |
214 | int traceGuessOptionValue; // MR10\r | |
215 | const ANTLRChar *traceCurrentRuleName; // MR10\r | |
216 | int traceDepth; // MR10\r | |
217 | void traceReset(); // MR10\r | |
218 | virtual void traceGuessFail(); // MR10\r | |
219 | virtual void traceGuessDone(const ANTLRParserState *); // MR10\r | |
220 | int zzGuessSeq; // MR10\r | |
221 | \r | |
222 | public:\r | |
223 | ANTLRParser(ANTLRTokenBuffer *,\r | |
224 | int k=1,\r | |
225 | int use_inf_look=0,\r | |
226 | int demand_look=0,\r | |
227 | int bsetsize=1);\r | |
228 | virtual ~ANTLRParser();\r | |
229 | \r | |
230 | virtual void init();\r | |
231 | \r | |
232 | ANTLRTokenType LA(int i)\r | |
233 | {\r | |
234 | //\r | |
235 | // MR14 demand look will always be 0 for C++ mode\r | |
236 | //\r | |
237 | //// return demand_look ? token_type[(labase+(i)-1)&(LLk-1)] :\r | |
238 | //// token_type[(lap+(i)-1)&(LLk-1)];\r | |
239 | \r | |
240 | // MR19 V.H. Simonis Defer fetch feature\r | |
241 | \r | |
242 | #ifdef ZZDEFER_FETCH\r | |
243 | undeferFetch();\r | |
244 | #endif\r | |
245 | return token_type[(lap+(i)-1)&(LLk-1)];\r | |
246 | }\r | |
247 | _ANTLRTokenPtr LT(int i);\r | |
248 | \r | |
249 | void setEofToken(ANTLRTokenType t) { eofToken = t; }\r | |
250 | ANTLRTokenType getEofToken() const { return eofToken; } // MR14\r | |
251 | \r | |
252 | void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); }\r | |
253 | void garbageCollectTokens() { inputTokens->garbageCollectTokens(); }\r | |
254 | \r | |
255 | virtual void syn(_ANTLRTokenPtr tok, ANTLRChar *egroup,\r | |
256 | SetWordType *eset, ANTLRTokenType etok, int k);\r | |
257 | virtual void saveState(ANTLRParserState *); // MR9 27-Sep-97 make virtual\r | |
258 | virtual void restoreState(ANTLRParserState *); // MR9 27-Sep-97 make virtual\r | |
259 | \r | |
260 | virtual void panic(const char *msg); // MR20 const\r | |
261 | \r | |
262 | static char *eMsgd(char *,int);\r | |
263 | static char *eMsg(char *,char *);\r | |
264 | static char *eMsg2(char *,char *,char *);\r | |
265 | \r | |
266 | virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23\r | |
267 | virtual int printMessageV(FILE* pFile, const char* pFormat, va_list arglist); // MR23\r | |
268 | \r | |
269 | void consumeUntil(SetWordType *st);\r | |
270 | void consumeUntilToken(int t);\r | |
271 | \r | |
272 | virtual int _setmatch_wdfltsig(SetWordType *tokensWanted,\r | |
273 | ANTLRTokenType tokenTypeOfSet,\r | |
274 | SetWordType *whatFollows);\r | |
275 | virtual int _match_wdfltsig(ANTLRTokenType tokenWanted,\r | |
276 | SetWordType *whatFollows);\r | |
277 | \r | |
278 | const ANTLRChar * parserTokenName(int tok); // MR1\r | |
279 | \r | |
280 | int traceOptionValueDefault; // MR11\r | |
281 | int traceOption(int delta); // MR11\r | |
282 | int traceGuessOption(int delta); // MR11\r | |
283 | \r | |
284 | // MR8 5-Aug-97 S.Bochnak@microtool.com.pl\r | |
285 | // MR8 Move resynch static local variable\r | |
286 | // MR8 to class instance\r | |
287 | \r | |
288 | int syntaxErrCount; // MR12\r | |
289 | ANTLRTokenStream *getLexer() const { // MR12\r | |
290 | return inputTokens ? inputTokens->getLexer() : 0; } // MR12\r | |
291 | protected: // MR8\r | |
292 | int resynchConsumed; // MR8\r | |
293 | char *zzFAILtext; // workarea required by zzFAIL // MR9\r | |
294 | void undeferFetch(); // MR19 V.H. Simonis\r | |
295 | int isDeferFetchEnabled(); // MR19 V.H. Simonis\r | |
296 | virtual void failedSemanticPredicate(const char* predicate); /* MR23 */\r | |
297 | };\r | |
298 | \r | |
299 | #define zzmatch(_t) \\r | |
300 | if ( !_match((ANTLRTokenType)_t, &zzMissText, &zzMissTok, \\r | |
301 | (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet) ) goto fail;\r | |
302 | \r | |
303 | #define zzmatch_wsig(_t,handler) \\r | |
304 | if ( !_match_wsig((ANTLRTokenType)_t) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}\r | |
305 | \r | |
306 | #define zzsetmatch(_ts,_tokclassErrset) \\r | |
307 | if ( !_setmatch(_ts, &zzMissText, &zzMissTok, \\r | |
308 | (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail;\r | |
309 | \r | |
310 | #define zzsetmatch_wsig(_ts, handler) \\r | |
311 | if ( !_setmatch_wsig(_ts) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}\r | |
312 | \r | |
313 | /* For the dflt signal matchers, a FALSE indicates that an error occurred\r | |
314 | * just like the other matchers, but in this case, the routine has already\r | |
315 | * recovered--we do NOT want to consume another token. However, when\r | |
316 | * the match was successful, we do want to consume hence _signal=0 so that\r | |
317 | * a token is consumed by the "if (!_signal) consume(); _signal=NoSignal;"\r | |
318 | * preamble.\r | |
319 | */\r | |
320 | #define zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) \\r | |
321 | if ( !_setmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) ) \\r | |
322 | _signal = MismatchedToken;\r | |
323 | \r | |
324 | #define zzmatch_wdfltsig(tokenWanted, whatFollows) \\r | |
325 | if ( !_match_wdfltsig(tokenWanted, whatFollows) ) _signal = MismatchedToken;\r | |
326 | \r | |
327 | \r | |
328 | // MR1 10-Apr-97 zzfailed_pred() macro does not backtrack in guess mode.\r | |
329 | // MR1 Identification and correction due to J. Lilley\r | |
330 | //\r | |
331 | // MR23 Call virtual method to report error.\r | |
332 | // MR23 Provide more control over failed predicate action\r | |
333 | // without any need for user to worry about guessing internals.\r | |
334 | \r | |
335 | #ifndef zzfailed_pred\r | |
336 | #define zzfailed_pred(_p,_hasuseraction,_useraction) \\r | |
337 | if (guessing) { \\r | |
338 | zzGUESS_FAIL; \\r | |
339 | } else { \\r | |
340 | zzfailed_pred_action(_p,_hasuseraction,_useraction) \\r | |
341 | }\r | |
342 | #endif\r | |
343 | \r | |
344 | // MR23 Provide more control over failed predicate action\r | |
345 | // without any need for user to worry about guessing internals.\r | |
346 | // _hasuseraction == 0 => no user specified error action\r | |
347 | // _hasuseraction == 1 => user specified error action\r | |
348 | \r | |
349 | #ifndef zzfailed_pred_action\r | |
350 | #define zzfailed_pred_action(_p,_hasuseraction,_useraction) \\r | |
351 | if (_hasuseraction) { _useraction } else { failedSemanticPredicate(_p); }\r | |
352 | #endif\r | |
353 | \r | |
354 | #define zzRULE \\r | |
355 | SetWordType *zzMissSet=NULL; ANTLRTokenType zzMissTok=(ANTLRTokenType)0; \\r | |
356 | _ANTLRTokenPtr zzBadTok=NULL; ANTLRChar *zzBadText=(ANTLRChar *)""; \\r | |
357 | int zzErrk=1,zzpf=0; \\r | |
358 | zzTRACEdata \\r | |
359 | ANTLRChar *zzMissText=(ANTLRChar *)"";\r | |
360 | \r | |
361 | #endif\r | |
362 | \r | |
363 | /* S t a n d a r d E x c e p t i o n S i g n a l s */\r | |
364 | \r | |
365 | #define NoSignal 0\r | |
366 | #define MismatchedToken 1\r | |
367 | #define NoViableAlt 2\r | |
368 | #define NoSemViableAlt 3\r | |
369 | \r | |
370 | /* MR7 Allow more control over signalling */\r | |
371 | /* by adding "Unwind" and "SetSignal" */\r | |
372 | \r | |
373 | #define Unwind 4\r | |
374 | #define setSignal(newValue) *_retsignal=_signal=(newValue)\r | |
375 | #define suppressSignal *_retsignal=_signal=0\r | |
376 | #define exportSignal *_retsignal=_signal\r |