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