Home | History | Annotate | Download | only in h
      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