]>
Commit | Line | Data |
---|---|---|
30fdf114 LG |
1 | /* ANTLRParser.C\r |
2 | *\r | |
3 | * SOFTWARE RIGHTS\r | |
4 | *\r | |
5 | * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r | |
6 | * Set (PCCTS) -- PCCTS is in the public domain. An individual or\r | |
7 | * company may do whatever they wish with source code distributed with\r | |
8 | * PCCTS or the code generated by PCCTS, including the incorporation of\r | |
9 | * PCCTS, or its output, into commerical software.\r | |
10 | *\r | |
11 | * We encourage users to develop software with PCCTS. However, we do ask\r | |
12 | * that credit is given to us for developing PCCTS. By "credit",\r | |
13 | * we mean that if you incorporate our source code into one of your\r | |
14 | * programs (commercial product, research project, or otherwise) that you\r | |
15 | * acknowledge this fact somewhere in the documentation, research report,\r | |
16 | * etc... If you like PCCTS and have developed a nice tool with the\r | |
17 | * output, please mention that you developed it using PCCTS. In\r | |
18 | * addition, we ask that this header remain intact in our source code.\r | |
19 | * As long as these guidelines are kept, we expect to continue enhancing\r | |
20 | * this system and expect to make other tools available as they are\r | |
21 | * completed.\r | |
22 | *\r | |
23 | * ANTLR 1.33\r | |
24 | * Terence Parr\r | |
25 | * Parr Research Corporation\r | |
26 | * with Purdue University and AHPCRC, University of Minnesota\r | |
27 | * 1989-2000\r | |
28 | */\r | |
29 | \r | |
30 | #include "pcctscfg.h"\r | |
31 | \r | |
32 | #include "pccts_stdlib.h"\r | |
33 | #include "pccts_stdarg.h"\r | |
34 | #include "pccts_string.h"\r | |
35 | #include "pccts_stdio.h"\r | |
36 | \r | |
37 | PCCTS_NAMESPACE_STD\r | |
38 | \r | |
39 | /* I have to put this here due to C++ limitation\r | |
40 | * that you can't have a 'forward' decl for enums.\r | |
41 | * I hate C++!!!!!!!!!!!!!!!\r | |
42 | * Of course, if I could use real templates, this would go away.\r | |
43 | */\r | |
44 | // MR1\r | |
45 | // MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the\r | |
46 | // MR1 ANTLRTokenType enum\r | |
47 | // MR1\r | |
48 | \r | |
49 | enum ANTLRTokenType { TER_HATES_CPP=0, ITS_TOO_COMPLICATED=9999}; // MR1\r | |
50 | \r | |
51 | #define ANTLR_SUPPORT_CODE\r | |
52 | \r | |
53 | #include ATOKEN_H\r | |
54 | #include ATOKENBUFFER_H\r | |
55 | #include APARSER_H\r | |
56 | \r | |
57 | static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000; /* MR14 */\r | |
58 | static const int zzINF_BUFFER_TOKEN_CHUNK_SIZE = 1000; /* MR14 */\r | |
59 | \r | |
60 | /* L o o k a h e a d M a c r o s */\r | |
61 | \r | |
62 | /* maximum of 32 bits/unsigned int and must be 8 bits/byte;\r | |
63 | * we only use 8 bits of it.\r | |
64 | */\r | |
65 | SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = {\r | |
66 | 0x00000001, 0x00000002, 0x00000004, 0x00000008,\r | |
67 | 0x00000010, 0x00000020, 0x00000040, 0x00000080\r | |
68 | };\r | |
69 | \r | |
70 | char ANTLRParser::eMsgBuffer[500] = "";\r | |
71 | \r | |
72 | ANTLRParser::\r | |
73 | ~ANTLRParser()\r | |
74 | {\r | |
75 | delete [] token_type;\r | |
76 | delete [] zzFAILtext; // MR16 Manfred Kogler\r | |
77 | }\r | |
78 | \r | |
79 | ANTLRParser::\r | |
80 | ANTLRParser(ANTLRTokenBuffer *_inputTokens,\r | |
81 | int k,\r | |
82 | int use_inf_look,\r | |
83 | int dlook,\r | |
84 | int ssize)\r | |
85 | {\r | |
86 | LLk = k;\r | |
87 | can_use_inf_look = use_inf_look;\r | |
88 | /* MR14 */ if (dlook != 0) {\r | |
89 | /* MR14 */ panic("ANTLRParser::ANTLRParser - Demand lookahead not supported in C++ mode");\r | |
90 | /* MR14 */\r | |
91 | /* MR14 */ };\r | |
92 | demand_look = 0; /* demand_look = dlook; */\r | |
93 | bsetsize = ssize;\r | |
94 | guessing = 0;\r | |
95 | token_tbl = NULL;\r | |
96 | eofToken = (ANTLRTokenType)1;\r | |
97 | \r | |
98 | // allocate lookahead buffer\r | |
99 | token_type = new ANTLRTokenType[LLk];\r | |
100 | lap = 0;\r | |
101 | labase = 0;\r | |
102 | #ifdef ZZDEFER_FETCH\r | |
103 | stillToFetch = 0; // MR19\r | |
104 | #endif\r | |
105 | dirty = 0;\r | |
106 | inf_labase = 0; // MR7\r | |
107 | inf_last = 0; // MR7\r | |
108 | /* prime lookahead buffer, point to inputTokens */\r | |
109 | this->inputTokens = _inputTokens;\r | |
110 | this->inputTokens->setMinTokens(k);\r | |
111 | _inputTokens->setParser(this); // MR1\r | |
112 | resynchConsumed=1; // MR8\r | |
113 | zzFAILtext=NULL; // MR9\r | |
114 | traceOptionValueDefault=0; // MR10\r | |
115 | traceReset(); // MR10\r | |
116 | zzGuessSeq=0; // MR10\r | |
117 | syntaxErrCount=0; // MR11\r | |
118 | }\r | |
119 | \r | |
120 | void ANTLRParser::init()\r | |
121 | {\r | |
122 | prime_lookahead();\r | |
123 | resynchConsumed=1; // MR8\r | |
124 | traceReset(); // MR10\r | |
125 | }\r | |
126 | \r | |
127 | void ANTLRParser::traceReset()\r | |
128 | {\r | |
129 | traceOptionValue=traceOptionValueDefault;\r | |
130 | traceGuessOptionValue=1;\r | |
131 | traceCurrentRuleName=NULL;\r | |
132 | traceDepth=0;\r | |
133 | }\r | |
134 | \r | |
135 | \r | |
136 | #ifdef _MSC_VER // MR23\r | |
137 | //Turn off warning:\r | |
138 | //interaction between '_setjmp' and C++ object destruction is non-portable\r | |
139 | #pragma warning(disable : 4611)\r | |
140 | #endif\r | |
141 | int ANTLRParser::\r | |
142 | guess(ANTLRParserState *st)\r | |
143 | {\r | |
144 | saveState(st);\r | |
145 | guessing = 1;\r | |
146 | return setjmp(guess_start.state);\r | |
147 | }\r | |
148 | #ifdef _MSC_VER // MR23\r | |
149 | #pragma warning(default: 4611)\r | |
150 | #endif\r | |
151 | \r | |
152 | void ANTLRParser::\r | |
153 | saveState(ANTLRParserState *buf)\r | |
154 | {\r | |
155 | buf->guess_start = guess_start;\r | |
156 | buf->guessing = guessing;\r | |
157 | buf->inf_labase = inf_labase;\r | |
158 | buf->inf_last = inf_last;\r | |
159 | buf->dirty = dirty;\r | |
160 | buf->traceOptionValue=traceOptionValue; /* MR10 */\r | |
161 | buf->traceGuessOptionValue=traceGuessOptionValue; /* MR10 */\r | |
162 | buf->traceCurrentRuleName=traceCurrentRuleName; /* MR10 */\r | |
163 | buf->traceDepth=traceDepth; /* MR10 */\r | |
164 | }\r | |
165 | \r | |
166 | void ANTLRParser::\r | |
167 | restoreState(ANTLRParserState *buf)\r | |
168 | {\r | |
169 | int i;\r | |
170 | int prevTraceOptionValue;\r | |
171 | \r | |
172 | guess_start = buf->guess_start;\r | |
173 | guessing = buf->guessing;\r | |
174 | inf_labase = buf->inf_labase;\r | |
175 | inf_last = buf->inf_last;\r | |
176 | dirty = buf->dirty;\r | |
177 | \r | |
178 | // restore lookahead buffer from k tokens before restored TokenBuffer position\r | |
179 | // if demand_look, then I guess we don't look backwards for these tokens.\r | |
180 | for (i=1; i<=LLk; i++) token_type[i-1] =\r | |
181 | inputTokens->bufferedToken(i-LLk)->getType();\r | |
182 | lap = 0;\r | |
183 | labase = 0;\r | |
184 | \r | |
185 | /* MR10 */\r | |
186 | \r | |
187 | prevTraceOptionValue=traceOptionValue;\r | |
188 | traceOptionValue=buf->traceOptionValue;\r | |
189 | if ( (prevTraceOptionValue > 0) !=\r | |
190 | (traceOptionValue > 0)) {\r | |
191 | if (traceCurrentRuleName != NULL) { /* MR21 */\r | |
192 | if (traceOptionValue > 0) {\r | |
193 | /* MR23 */ printMessage(stderr,\r | |
194 | "trace enable restored in rule %s depth %d\n",\r | |
195 | traceCurrentRuleName,\r | |
196 | traceDepth);\r | |
197 | };\r | |
198 | if (traceOptionValue <= 0) {\r | |
199 | /* MR23 */ printMessage(stderr,\r | |
200 | "trace disable restored in rule %s depth %d\n",\r | |
201 | traceCurrentRuleName, /* MR21 */\r | |
202 | traceDepth);\r | |
203 | };\r | |
204 | }\r | |
205 | };\r | |
206 | traceGuessOptionValue=buf->traceGuessOptionValue;\r | |
207 | traceCurrentRuleName=buf->traceCurrentRuleName;\r | |
208 | traceDepth=buf->traceDepth;\r | |
209 | traceGuessDone(buf);\r | |
210 | }\r | |
211 | \r | |
212 | /* Get the next symbol from the input stream; put it into lookahead buffer;\r | |
213 | * fill token_type[] fast reference cache also. NLA is the next place where\r | |
214 | * a lookahead ANTLRAbstractToken should go.\r | |
215 | */\r | |
216 | void ANTLRParser::\r | |
217 | consume()\r | |
218 | {\r | |
219 | \r | |
220 | #ifdef ZZDEBUG_CONSUME_ACTION\r | |
221 | zzdebug_consume_action();\r | |
222 | #endif\r | |
223 | \r | |
224 | // MR19 V.H. Simonis\r | |
225 | // Defer Fetch feature\r | |
226 | // Moves action of consume() into LA() function\r | |
227 | \r | |
228 | #ifdef ZZDEFER_FETCH\r | |
229 | stillToFetch++;\r | |
230 | #else\r | |
231 | NLA = inputTokens->getToken()->getType();\r | |
232 | dirty--;\r | |
233 | lap = (lap+1)&(LLk-1);\r | |
234 | #endif\r | |
235 | \r | |
236 | }\r | |
237 | \r | |
238 | _ANTLRTokenPtr ANTLRParser::\r | |
239 | LT(int i)\r | |
240 | {\r | |
241 | \r | |
242 | // MR19 V.H. Simonis\r | |
243 | // Defer Fetch feature\r | |
244 | // Moves action of consume() into LA() function\r | |
245 | \r | |
246 | #ifdef ZZDEFER_FETCH\r | |
247 | undeferFetch();\r | |
248 | #endif\r | |
249 | \r | |
250 | #ifdef DEBUG_TOKENBUFFER\r | |
251 | if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */\r | |
252 | {\r | |
253 | char buf[2000]; /* MR20 Was "static" */\r | |
254 | sprintf(buf, "The minimum number of tokens you requested that the\nANTLRTokenBuffer buffer is not enough to satisfy your\nLT(%d) request; increase 'k' argument to constructor for ANTLRTokenBuffer\n", i);\r | |
255 | panic(buf);\r | |
256 | }\r | |
257 | #endif\r | |
258 | return inputTokens->bufferedToken(i-LLk);\r | |
259 | }\r | |
260 | \r | |
261 | void\r | |
262 | ANTLRParser::\r | |
263 | look(int k)\r | |
264 | {\r | |
265 | int i, c = k - (LLk-dirty);\r | |
266 | for (i=1; i<=c; i++) consume();\r | |
267 | }\r | |
268 | \r | |
269 | /* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK);\r | |
270 | */\r | |
271 | void\r | |
272 | ANTLRParser::\r | |
273 | prime_lookahead()\r | |
274 | {\r | |
275 | int i;\r | |
276 | for(i=1;i<=LLk; i++) consume();\r | |
277 | dirty=0;\r | |
278 | // lap = 0; // MR14 Sinan Karasu (sinan.karasu@boeing.com)\r | |
279 | // labase = 0; // MR14\r | |
280 | labase=lap; // MR14\r | |
281 | }\r | |
282 | \r | |
283 | /* check to see if the current input symbol matches '_t'.\r | |
284 | * During NON demand lookahead mode, dirty will always be 0 and\r | |
285 | * hence the extra code for consuming tokens in _match is never\r | |
286 | * executed; the same routine can be used for both modes.\r | |
287 | */\r | |
288 | int ANTLRParser::\r | |
289 | _match(ANTLRTokenType _t, ANTLRChar **MissText,\r | |
290 | ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,\r | |
291 | SetWordType **MissSet)\r | |
292 | {\r | |
293 | if ( dirty==LLk ) {\r | |
294 | consume();\r | |
295 | }\r | |
296 | if ( LA(1)!=_t ) {\r | |
297 | *MissText=NULL;\r | |
298 | *MissTok= _t;\r | |
299 | *BadTok = LT(1);\r | |
300 | *MissSet=NULL;\r | |
301 | return 0;\r | |
302 | }\r | |
303 | dirty++;\r | |
304 | labase = (labase+1)&(LLk-1); // labase maintained even if !demand look\r | |
305 | return 1;\r | |
306 | }\r | |
307 | \r | |
308 | /* check to see if the current input symbol matches '_t'.\r | |
309 | * Used during exception handling.\r | |
310 | */\r | |
311 | int ANTLRParser::\r | |
312 | _match_wsig(ANTLRTokenType _t)\r | |
313 | {\r | |
314 | if ( dirty==LLk ) {\r | |
315 | consume();\r | |
316 | }\r | |
317 | if ( LA(1)!=_t ) return 0;\r | |
318 | dirty++;\r | |
319 | labase = (labase+1)&(LLk-1); // labase maintained even if !demand look\r | |
320 | return 1;\r | |
321 | }\r | |
322 | \r | |
323 | /* check to see if the current input symbol matches any token in a set.\r | |
324 | * During NON demand lookahead mode, dirty will always be 0 and\r | |
325 | * hence the extra code for consuming tokens in _match is never\r | |
326 | * executed; the same routine can be used for both modes.\r | |
327 | */\r | |
328 | int ANTLRParser::\r | |
329 | _setmatch(SetWordType *tset, ANTLRChar **MissText,\r | |
330 | ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,\r | |
331 | SetWordType **MissSet, SetWordType *tokclassErrset)\r | |
332 | {\r | |
333 | if ( dirty==LLk ) {\r | |
334 | consume();\r | |
335 | }\r | |
336 | if ( !set_el(LA(1), tset) ) {\r | |
337 | *MissText=NULL; /* MR23 */\r | |
338 | *MissTok=(ANTLRTokenType) 0; /* MR23 */\r | |
339 | *BadTok=LT(1); /* MR23 */\r | |
340 | *MissSet=tokclassErrset; /* MR23 */\r | |
341 | return 0;\r | |
342 | }\r | |
343 | dirty++;\r | |
344 | labase = (labase+1)&(LLk-1); // labase maintained even if !demand look\r | |
345 | return 1;\r | |
346 | }\r | |
347 | \r | |
348 | int ANTLRParser::\r | |
349 | _setmatch_wsig(SetWordType *tset)\r | |
350 | {\r | |
351 | if ( dirty==LLk ) {\r | |
352 | consume();\r | |
353 | }\r | |
354 | if ( !set_el(LA(1), tset) ) return 0;\r | |
355 | dirty++;\r | |
356 | labase = (labase+1)&(LLk-1); // labase maintained even if !demand look\r | |
357 | return 1;\r | |
358 | }\r | |
359 | \r | |
360 | /* Exception handling routines */\r | |
361 | //\r | |
362 | // 7-Apr-97 133MR1\r | |
363 | // Change suggested by Eli Sternheim (eli@interhdl.com)\r | |
364 | //\r | |
365 | void ANTLRParser::\r | |
366 | consumeUntil(SetWordType *st)\r | |
367 | {\r | |
368 | ANTLRTokenType tmp; // MR1\r | |
369 | const int Eof=1; // MR1\r | |
370 | while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); } // MR1\r | |
371 | }\r | |
372 | \r | |
373 | //\r | |
374 | // 7-Apr-97 133MR1\r | |
375 | // Change suggested by Eli Sternheim (eli@interhdl.com)\r | |
376 | //\r | |
377 | void ANTLRParser::\r | |
378 | consumeUntilToken(int t)\r | |
379 | {\r | |
380 | int tmp; // MR1\r | |
381 | const int Eof=1; // MR1\r | |
382 | while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); } // MR1\r | |
383 | }\r | |
384 | \r | |
385 | \r | |
386 | /* Old error stuff */\r | |
387 | \r | |
388 | void ANTLRParser::\r | |
389 | resynch(SetWordType *wd,SetWordType mask)\r | |
390 | {\r | |
391 | \r | |
392 | /* MR8 S.Bochnak@microtool.com.pl */\r | |
393 | /* MR8 Change file scope static "consumed" to instance var */\r | |
394 | \r | |
395 | /* if you enter here without having consumed a token from last resynch\r | |
396 | * force a token consumption.\r | |
397 | */\r | |
398 | /* MR8 */ if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;}\r | |
399 | \r | |
400 | /* if current token is in resynch set, we've got what we wanted */\r | |
401 | \r | |
402 | /* MR8 */ if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;}\r | |
403 | \r | |
404 | /* scan until we find something in the resynch set */\r | |
405 | \r | |
406 | while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();}\r | |
407 | \r | |
408 | /* MR8 */ resynchConsumed=1;\r | |
409 | }\r | |
410 | \r | |
411 | /* standard error reporting function that assumes DLG-based scanners;\r | |
412 | * you should redefine in subclass to change it or if you use your\r | |
413 | * own scanner.\r | |
414 | */\r | |
415 | \r | |
416 | /* MR23 THM There appears to be a parameter "badText" passed to syn()\r | |
417 | which is not present in the parameter list. This may be\r | |
418 | because in C mode there is no attribute function which\r | |
419 | returns the text, so the text representation of the token\r | |
420 | must be passed explicitly. I think.\r | |
421 | */\r | |
422 | \r | |
423 | void ANTLRParser::\r | |
424 | syn(_ANTLRTokenPtr /*tok MR23*/, ANTLRChar *egroup, SetWordType *eset,\r | |
425 | ANTLRTokenType etok, int k)\r | |
426 | {\r | |
427 | int line;\r | |
428 | \r | |
429 | line = LT(1)->getLine();\r | |
430 | \r | |
431 | syntaxErrCount++; /* MR11 */\r | |
432 | \r | |
433 | /* MR23 If the token is not an EOF token, then use the ->getText() value.\r | |
434 | \r | |
435 | If the token is the EOF token the text returned by ->getText() \r | |
436 | may be garbage. If the text from the token table is "@" use\r | |
437 | "<eof>" instead, because end-users don't know what "@" means.\r | |
438 | If the text is not "@" then use that text, which must have been\r | |
439 | supplied by the grammar writer.\r | |
440 | */\r | |
441 | const char * errorAt = LT(1)->getText();\r | |
442 | if (LA(1) == eofToken) {\r | |
443 | errorAt = parserTokenName(LA(1));\r | |
444 | if (errorAt[0] == '@') errorAt = "<eof>";\r | |
445 | }\r | |
446 | /* MR23 */ printMessage(stderr, "line %d: syntax error at \"%s\"",\r | |
447 | line, errorAt);\r | |
448 | if ( !etok && !eset ) {/* MR23 */ printMessage(stderr, "\n"); return;}\r | |
449 | if ( k==1 ) /* MR23 */ printMessage(stderr, " missing");\r | |
450 | else\r | |
451 | {\r | |
452 | /* MR23 */ printMessage(stderr, "; \"%s\" not", LT(k)->getText()); // MR23 use LT(k) since k>1\r | |
453 | if ( set_deg(eset)>1 ) /* MR23 */ printMessage(stderr, " in");\r | |
454 | }\r | |
455 | if ( set_deg(eset)>0 ) edecode(eset);\r | |
456 | else /* MR23 */ printMessage(stderr, " %s", token_tbl[etok]);\r | |
457 | if ( strlen(egroup) > 0 ) /* MR23 */ printMessage(stderr, " in %s", egroup);\r | |
458 | /* MR23 */ printMessage(stderr, "\n");\r | |
459 | }\r | |
460 | \r | |
461 | /* is b an element of set p? */\r | |
462 | int ANTLRParser::\r | |
463 | set_el(ANTLRTokenType b, SetWordType *p)\r | |
464 | {\r | |
465 | return( p[DIVWORD(b)] & bitmask[MODWORD(b)] );\r | |
466 | }\r | |
467 | \r | |
468 | int ANTLRParser::\r | |
469 | set_deg(SetWordType *a)\r | |
470 | {\r | |
471 | /* Fast compute degree of a set... the number\r | |
472 | of elements present in the set. Assumes\r | |
473 | that all word bits are used in the set\r | |
474 | */\r | |
475 | register SetWordType *p = a;\r | |
476 | register SetWordType *endp = &(a[bsetsize]);\r | |
477 | register int degree = 0;\r | |
478 | \r | |
479 | if ( a == NULL ) return 0;\r | |
480 | while ( p < endp )\r | |
481 | {\r | |
482 | register SetWordType t = *p;\r | |
483 | register SetWordType *b = &(bitmask[0]);\r | |
484 | do {\r | |
485 | if (t & *b) ++degree;\r | |
486 | } while (++b < &(bitmask[sizeof(SetWordType)*8]));\r | |
487 | p++;\r | |
488 | }\r | |
489 | \r | |
490 | return(degree);\r | |
491 | }\r | |
492 | \r | |
493 | void ANTLRParser::\r | |
494 | edecode(SetWordType *a)\r | |
495 | {\r | |
496 | register SetWordType *p = a;\r | |
497 | register SetWordType *endp = &(p[bsetsize]);\r | |
498 | register unsigned e = 0;\r | |
499 | \r | |
500 | if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " {");\r | |
501 | do {\r | |
502 | register SetWordType t = *p;\r | |
503 | register SetWordType *b = &(bitmask[0]);\r | |
504 | do {\r | |
505 | if ( t & *b ) /* MR23 */ printMessage(stderr, " %s", token_tbl[e]);\r | |
506 | e++;\r | |
507 | } while (++b < &(bitmask[sizeof(SetWordType)*8]));\r | |
508 | } while (++p < endp);\r | |
509 | if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " }");\r | |
510 | }\r | |
511 | \r | |
512 | /* input looks like:\r | |
513 | * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk)\r | |
514 | * where the zzMiss stuff is set here to the token that did not match\r | |
515 | * (and which set wasn't it a member of).\r | |
516 | */\r | |
517 | \r | |
518 | // MR9 29-Sep-97 Stan Bochnak (S.Bochnak@microTool.com.pl)\r | |
519 | // MR9 Original fix to static allocated text didn't\r | |
520 | // MR9 work because a pointer to it was passed back\r | |
521 | // MR9 to caller. Replace with instance variable.\r | |
522 | \r | |
523 | const int SETWORDCOUNT=20;\r | |
524 | \r | |
525 | void\r | |
526 | ANTLRParser::FAIL(int k, ...)\r | |
527 | {\r | |
528 | //\r | |
529 | // MR1 10-Apr-97 \r | |
530 | //\r | |
531 | \r | |
532 | if (zzFAILtext == NULL) zzFAILtext=new char [1000]; // MR9\r | |
533 | SetWordType **f=new SetWordType *[SETWORDCOUNT]; // MR1 // MR9\r | |
534 | SetWordType **miss_set;\r | |
535 | ANTLRChar **miss_text;\r | |
536 | _ANTLRTokenPtr *bad_tok;\r | |
537 | ANTLRChar **bad_text;\r | |
538 | //\r | |
539 | // 7-Apr-97 133MR1\r | |
540 | // err_k is passed as a "int *", not "unsigned *"\r | |
541 | //\r | |
542 | int *err_k; // MR1\r | |
543 | int i;\r | |
544 | va_list ap;\r | |
545 | \r | |
546 | va_start(ap, k);\r | |
547 | \r | |
548 | zzFAILtext[0] = '\0';\r | |
549 | if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer");\r | |
550 | for (i=1; i<=k; i++) /* collect all lookahead sets */\r | |
551 | {\r | |
552 | f[i-1] = va_arg(ap, SetWordType *);\r | |
553 | }\r | |
554 | for (i=1; i<=k; i++) /* look for offending token */\r | |
555 | {\r | |
556 | if ( i>1 ) strcat(zzFAILtext, " ");\r | |
557 | strcat(zzFAILtext, LT(i)->getText());\r | |
558 | if ( !set_el(LA(i), f[i-1]) ) break;\r | |
559 | }\r | |
560 | miss_set = va_arg(ap, SetWordType **);\r | |
561 | miss_text = va_arg(ap, ANTLRChar **);\r | |
562 | bad_tok = va_arg(ap, _ANTLRTokenPtr *);\r | |
563 | bad_text = va_arg(ap, ANTLRChar **);\r | |
564 | err_k = va_arg(ap, int *); // MR1\r | |
565 | if ( i>k )\r | |
566 | {\r | |
567 | /* bad; lookahead is permutation that cannot be matched,\r | |
568 | * but, the ith token of lookahead is valid at the ith position\r | |
569 | * (The old LL sub 1 (k) versus LL(k) parsing technique)\r | |
570 | */\r | |
571 | *miss_set = NULL;\r | |
572 | *miss_text = LT(1)->getText();\r | |
573 | *bad_tok = LT(1);\r | |
574 | *bad_text = (*bad_tok)->getText();\r | |
575 | *err_k = k;\r | |
576 | //\r | |
577 | // MR4 20-May-97 erroneously deleted contents of f[]\r | |
578 | // MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)\r | |
579 | // MR1 10-Apr-97 release temporary storage\r | |
580 | //\r | |
581 | delete [] f; // MR1\r | |
582 | return; // MR1\r | |
583 | }\r | |
584 | /* MR23 printMessage(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/\r | |
585 | *miss_set = f[i-1];\r | |
586 | *miss_text = zzFAILtext;\r | |
587 | *bad_tok = LT(i);\r | |
588 | *bad_text = (*bad_tok)->getText();\r | |
589 | if ( i==1 ) *err_k = 1;\r | |
590 | else *err_k = k;\r | |
591 | //\r | |
592 | // MR4 20-May-97 erroneously deleted contents of f[]\r | |
593 | // MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)\r | |
594 | // MR1 10-Apr-97 release temporary storage\r | |
595 | //\r | |
596 | delete [] f; // MR1\r | |
597 | return; // MR1\r | |
598 | }\r | |
599 | \r | |
600 | int ANTLRParser::\r | |
601 | _match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows)\r | |
602 | {\r | |
603 | if ( dirty==LLk ) consume();\r | |
604 | \r | |
605 | if ( LA(1)!=tokenWanted )\r | |
606 | {\r | |
607 | syntaxErrCount++; /* MR11 */\r | |
608 | /* MR23 */ printMessage(stderr,\r | |
609 | "line %d: syntax error at \"%s\" missing %s\n",\r | |
610 | LT(1)->getLine(),\r | |
611 | (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */\r | |
612 | token_tbl[tokenWanted]);\r | |
613 | consumeUntil( whatFollows );\r | |
614 | return 0;\r | |
615 | }\r | |
616 | else {\r | |
617 | dirty++;\r | |
618 | labase = (labase+1)&(LLk-1); // labase maintained even if !demand look\r | |
619 | /* if ( !demand_look ) consume(); */\r | |
620 | return 1;\r | |
621 | }\r | |
622 | }\r | |
623 | \r | |
624 | \r | |
625 | int ANTLRParser::\r | |
626 | _setmatch_wdfltsig(SetWordType *tokensWanted,\r | |
627 | ANTLRTokenType tokenTypeOfSet,\r | |
628 | SetWordType *whatFollows)\r | |
629 | {\r | |
630 | if ( dirty==LLk ) consume();\r | |
631 | if ( !set_el(LA(1), tokensWanted) )\r | |
632 | {\r | |
633 | syntaxErrCount++; /* MR11 */\r | |
634 | /* MR23 */ printMessage(stderr,\r | |
635 | "line %d: syntax error at \"%s\" missing %s\n",\r | |
636 | LT(1)->getLine(),\r | |
637 | (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */\r | |
638 | token_tbl[tokenTypeOfSet]);\r | |
639 | consumeUntil( whatFollows );\r | |
640 | return 0;\r | |
641 | }\r | |
642 | else {\r | |
643 | dirty++;\r | |
644 | labase = (labase+1)&(LLk-1); // labase maintained even if !demand look\r | |
645 | /* if ( !demand_look ) consume(); */\r | |
646 | return 1;\r | |
647 | }\r | |
648 | }\r | |
649 | \r | |
650 | char *ANTLRParser::\r | |
651 | eMsgd(char *err,int d)\r | |
652 | {\r | |
653 | sprintf(eMsgBuffer, err, d); // dangerous, but I don't care\r | |
654 | return eMsgBuffer;\r | |
655 | }\r | |
656 | \r | |
657 | char *ANTLRParser::\r | |
658 | eMsg(char *err, char *s)\r | |
659 | {\r | |
660 | sprintf(eMsgBuffer, err, s);\r | |
661 | return eMsgBuffer;\r | |
662 | }\r | |
663 | \r | |
664 | char *ANTLRParser::\r | |
665 | eMsg2(char *err,char *s, char *t)\r | |
666 | {\r | |
667 | sprintf(eMsgBuffer, err, s, t);\r | |
668 | return eMsgBuffer;\r | |
669 | }\r | |
670 | \r | |
671 | void ANTLRParser::\r | |
672 | panic(const char *msg) // MR20 const\r | |
673 | {\r | |
674 | /* MR23 */ printMessage(stderr, "ANTLR panic: %s\n", msg);\r | |
675 | exit(PCCTS_EXIT_FAILURE); // MR1\r | |
676 | }\r | |
677 | \r | |
678 | const ANTLRChar *ANTLRParser:: // MR1\r | |
679 | parserTokenName(int tok) { // MR1\r | |
680 | return token_tbl[tok]; // MR1\r | |
681 | } // MR1\r | |
682 | \r | |
683 | void ANTLRParser::traceGuessDone(const ANTLRParserState *state) {\r | |
684 | \r | |
685 | int doIt=0;\r | |
686 | \r | |
687 | if (traceCurrentRuleName == NULL) return;\r | |
688 | \r | |
689 | if (traceOptionValue <= 0) {\r | |
690 | doIt=0;\r | |
691 | } else if (traceGuessOptionValue <= 0) {\r | |
692 | doIt=0;\r | |
693 | } else {\r | |
694 | doIt=1;\r | |
695 | };\r | |
696 | \r | |
697 | if (doIt) {\r | |
698 | /* MR23 */ printMessage(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",\r | |
699 | state->traceCurrentRuleName,\r | |
700 | LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),\r | |
701 | state->traceDepth);\r | |
702 | if (state->guessing != 0) {\r | |
703 | /* MR23 */ printMessage(stderr," (guess mode continues - an enclosing guess is still active)");\r | |
704 | } else {\r | |
705 | /* MR23 */ printMessage(stderr," (guess mode ends)");\r | |
706 | };\r | |
707 | /* MR23 */ printMessage(stderr,"\n");\r | |
708 | };\r | |
709 | }\r | |
710 | \r | |
711 | void ANTLRParser::traceGuessFail() {\r | |
712 | \r | |
713 | int doIt=0;\r | |
714 | \r | |
715 | if (traceCurrentRuleName == NULL) return; /* MR21 */\r | |
716 | \r | |
717 | if (traceOptionValue <= 0) {\r | |
718 | doIt=0;\r | |
719 | } else if (guessing && traceGuessOptionValue <= 0) {\r | |
720 | doIt=0;\r | |
721 | } else {\r | |
722 | doIt=1;\r | |
723 | };\r | |
724 | \r | |
725 | if (doIt) {\r | |
726 | /* MR23 */ printMessage(stderr,"guess failed in %s\n",traceCurrentRuleName);\r | |
727 | };\r | |
728 | }\r | |
729 | \r | |
730 | /* traceOption:\r | |
731 | zero value turns off trace\r | |
732 | */\r | |
733 | \r | |
734 | void ANTLRParser::tracein(const ANTLRChar * rule) {\r | |
735 | \r | |
736 | int doIt=0;\r | |
737 | \r | |
738 | traceDepth++;\r | |
739 | traceCurrentRuleName=rule;\r | |
740 | \r | |
741 | if (traceOptionValue <= 0) {\r | |
742 | doIt=0;\r | |
743 | } else if (guessing && traceGuessOptionValue <= 0) {\r | |
744 | doIt=0;\r | |
745 | } else {\r | |
746 | doIt=1;\r | |
747 | };\r | |
748 | \r | |
749 | if (doIt) {\r | |
750 | /* MR23 */ printMessage(stderr,"enter rule %s {\"%s\"} depth %d",\r | |
751 | rule,\r | |
752 | LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),\r | |
753 | traceDepth);\r | |
754 | if (guessing) /* MR23 */ printMessage(stderr," guessing");\r | |
755 | /* MR23 */ printMessage(stderr,"\n");\r | |
756 | };\r | |
757 | return;\r | |
758 | }\r | |
759 | \r | |
760 | void ANTLRParser::traceout(const ANTLRChar * rule) {\r | |
761 | \r | |
762 | int doIt=0;\r | |
763 | \r | |
764 | traceDepth--;\r | |
765 | \r | |
766 | if (traceOptionValue <= 0) {\r | |
767 | doIt=0;\r | |
768 | } else if (guessing && traceGuessOptionValue <= 0) {\r | |
769 | doIt=0;\r | |
770 | } else {\r | |
771 | doIt=1;\r | |
772 | };\r | |
773 | \r | |
774 | if (doIt) {\r | |
775 | /* MR23 */ printMessage(stderr,"exit rule %s {\"%s\"} depth %d",\r | |
776 | rule,\r | |
777 | LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),\r | |
778 | traceDepth+1);\r | |
779 | if (guessing) /* MR23 */ printMessage(stderr," guessing");\r | |
780 | /* MR23 */ printMessage(stderr,"\n");\r | |
781 | };\r | |
782 | }\r | |
783 | \r | |
784 | int ANTLRParser::traceOption(int delta) {\r | |
785 | \r | |
786 | int prevValue=traceOptionValue;\r | |
787 | \r | |
788 | traceOptionValue=traceOptionValue+delta;\r | |
789 | \r | |
790 | if (traceCurrentRuleName != NULL) {\r | |
791 | if (prevValue <= 0 && traceOptionValue > 0) {\r | |
792 | /* MR23 */ printMessage(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);\r | |
793 | };\r | |
794 | if (prevValue > 0 && traceOptionValue <= 0) {\r | |
795 | /* MR23 */ printMessage(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);\r | |
796 | };\r | |
797 | };\r | |
798 | \r | |
799 | return prevValue;\r | |
800 | }\r | |
801 | \r | |
802 | int ANTLRParser::traceGuessOption(int delta) {\r | |
803 | \r | |
804 | int prevValue=traceGuessOptionValue;\r | |
805 | \r | |
806 | traceGuessOptionValue=traceGuessOptionValue+delta;\r | |
807 | \r | |
808 | if (traceCurrentRuleName != NULL) {\r | |
809 | if (prevValue <= 0 && traceGuessOptionValue > 0) {\r | |
810 | /* MR23 */ printMessage(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);\r | |
811 | };\r | |
812 | if (prevValue > 0 && traceGuessOptionValue <= 0) {\r | |
813 | /* MR23 */ printMessage(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);\r | |
814 | };\r | |
815 | };\r | |
816 | return prevValue;\r | |
817 | }\r | |
818 | \r | |
819 | // MR19 V.H. Simonis Defer Fetch feature\r | |
820 | \r | |
821 | void ANTLRParser::undeferFetch()\r | |
822 | {\r | |
823 | \r | |
824 | #ifdef ZZDEFER_FETCH\r | |
825 | if (stillToFetch) {\r | |
826 | for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) {\r | |
827 | NLA = inputTokens->getToken()->getType();\r | |
828 | dirty--;\r | |
829 | lap = (lap+1)&(LLk-1);\r | |
830 | }\r | |
831 | stillToFetch = 0;\r | |
832 | }\r | |
833 | #else\r | |
834 | return;\r | |
835 | #endif\r | |
836 | \r | |
837 | }\r | |
838 | \r | |
839 | int ANTLRParser::isDeferFetchEnabled()\r | |
840 | {\r | |
841 | #ifdef ZZDEFER_FETCH\r | |
842 | return 1;\r | |
843 | #else\r | |
844 | return 0;\r | |
845 | #endif\r | |
846 | }\r | |
847 | \r | |
848 | //MR23\r | |
849 | int ANTLRParser::printMessage(FILE* pFile, const char* pFormat, ...)\r | |
850 | {\r | |
851 | va_list marker;\r | |
852 | va_start( marker, pFormat );\r | |
853 | int iRet = printMessageV(pFile, pFormat, marker);\r | |
854 | va_end( marker );\r | |
855 | return iRet;\r | |
856 | }\r | |
857 | \r | |
858 | int ANTLRParser::printMessageV(FILE* pFile, const char* pFormat, va_list arglist) // MR23\r | |
859 | {\r | |
860 | return vfprintf(pFile, pFormat, arglist);\r | |
861 | }\r | |
862 | \r | |
863 | // MR23 Move semantic predicate error handling from macro to virtual function\r | |
864 | //\r | |
865 | // Called by the zzfailed_pred\r | |
866 | \r | |
867 | void ANTLRParser::failedSemanticPredicate(const char* predicate)\r | |
868 | {\r | |
869 | printMessage(stdout,"line %d: semantic error; failed predicate: '%s'\n",\r | |
870 | LT(1)->getLine(), predicate);\r | |
871 | }\r |