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-1998
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
37PCCTS_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
49enum 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
57static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000;    /* MR14 */
58static 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 */
65SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = {
66	0x00000001, 0x00000002, 0x00000004, 0x00000008,
67	0x00000010, 0x00000020, 0x00000040, 0x00000080
68};
69
70char ANTLRParser::eMsgBuffer[500] = "";
71
72ANTLRParser::
73~ANTLRParser()
74{
75	delete [] token_type;
76    delete [] zzFAILtext;       // MR16 Manfred Kogler
77}
78
79ANTLRParser::
80ANTLRParser(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
120void ANTLRParser::init()
121{
122   prime_lookahead();
123   resynchConsumed=1;                                                   // MR8
124   traceReset();                                                        // MR10
125}
126
127void ANTLRParser::traceReset()
128{
129   traceOptionValue=traceOptionValueDefault;
130   traceGuessOptionValue=1;
131   traceCurrentRuleName=NULL;
132   traceDepth=0;
133}
134
135int ANTLRParser::
136guess(ANTLRParserState *st)
137{
138	saveState(st);
139	guessing = 1;
140	return setjmp(guess_start.state);
141}
142
143void ANTLRParser::
144saveState(ANTLRParserState *buf)
145{
146	buf->guess_start = guess_start;
147	buf->guessing = guessing;
148	buf->inf_labase = inf_labase;
149	buf->inf_last = inf_last;
150	buf->dirty = dirty;
151    buf->traceOptionValue=traceOptionValue;            /* MR10 */
152    buf->traceGuessOptionValue=traceGuessOptionValue;  /* MR10 */
153    buf->traceCurrentRuleName=traceCurrentRuleName;    /* MR10 */
154    buf->traceDepth=traceDepth;                        /* MR10 */
155}
156
157void ANTLRParser::
158restoreState(ANTLRParserState *buf)
159{
160	int     i;
161    int     prevTraceOptionValue;
162
163	guess_start = buf->guess_start;
164	guessing = buf->guessing;
165	inf_labase = buf->inf_labase;
166	inf_last = buf->inf_last;
167	dirty = buf->dirty;
168
169	// restore lookahead buffer from k tokens before restored TokenBuffer position
170	// if demand_look, then I guess we don't look backwards for these tokens.
171	for (i=1; i<=LLk; i++) token_type[i-1] =
172		inputTokens->bufferedToken(i-LLk)->getType();
173	lap = 0;
174	labase = 0;
175
176    /* MR10 */
177
178    prevTraceOptionValue=traceOptionValue;
179    traceOptionValue=buf->traceOptionValue;
180    if ( (prevTraceOptionValue > 0) !=
181             (traceOptionValue > 0)) {
182      if (traceCurrentRuleName != NULL) {  /* MR21 */
183          if (traceOptionValue > 0) {
184            fprintf(stderr,
185                   "trace enable restored in rule %s depth %d\n",
186                   traceCurrentRuleName,
187                   traceDepth);
188          };
189          if (traceOptionValue <= 0) {
190            fprintf(stderr,
191            "trace disable restored in rule %s depth %d\n",
192            traceCurrentRuleName, /* MR21 */
193            traceDepth);
194          };
195       }
196    };
197    traceGuessOptionValue=buf->traceGuessOptionValue;
198    traceCurrentRuleName=buf->traceCurrentRuleName;
199    traceDepth=buf->traceDepth;
200    traceGuessDone(buf);
201}
202
203/* Get the next symbol from the input stream; put it into lookahead buffer;
204 * fill token_type[] fast reference cache also.  NLA is the next place where
205 * a lookahead ANTLRAbstractToken should go.
206 */
207void ANTLRParser::
208consume()
209{
210
211#ifdef ZZDEBUG_CONSUME_ACTION
212    zzdebug_consume_action();
213#endif
214
215// MR19 V.H. Simonis
216//      Defer Fetch feature
217//      Moves action of consume() into LA() function
218
219#ifdef ZZDEFER_FETCH
220      stillToFetch++;
221#else
222      NLA = inputTokens->getToken()->getType();
223      dirty--;
224      lap = (lap+1)&(LLk-1);
225#endif
226
227}
228
229_ANTLRTokenPtr ANTLRParser::
230LT(int i)
231{
232
233// MR19 V.H. Simonis
234//      Defer Fetch feature
235//      Moves action of consume() into LA() function
236
237#ifdef ZZDEFER_FETCH
238    undeferFetch();
239#endif
240
241#ifdef DEBUG_TOKENBUFFER
242	if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk )     /* MR20 Was "<=" */
243	{
244		char buf[2000];                 /* MR20 Was "static" */
245        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);
246		panic(buf);
247	}
248#endif
249	return inputTokens->bufferedToken(i-LLk);
250}
251
252void
253ANTLRParser::
254look(int k)
255{
256	int i, c = k - (LLk-dirty);
257	for (i=1; i<=c; i++) consume();
258}
259
260/* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK);
261 */
262void
263ANTLRParser::
264prime_lookahead()
265{
266	int i;
267	for(i=1;i<=LLk; i++) consume();
268	dirty=0;
269	// lap = 0;     // MR14 Sinan Karasu (sinan.karasu@boeing.com)
270	// labase = 0;  // MR14
271    labase=lap;     // MR14
272}
273
274/* check to see if the current input symbol matches '_t'.
275 * During NON demand lookahead mode, dirty will always be 0 and
276 * hence the extra code for consuming tokens in _match is never
277 * executed; the same routine can be used for both modes.
278 */
279int ANTLRParser::
280_match(ANTLRTokenType _t, ANTLRChar **MissText,
281	   ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
282	   SetWordType **MissSet)
283{
284	if ( dirty==LLk ) {
285		consume();
286	}
287	if ( LA(1)!=_t ) {
288		*MissText=NULL;
289		*MissTok= _t; *BadTok = LT(1);
290		*MissSet=NULL;
291		return 0;
292	}
293	dirty++;
294	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look
295	return 1;
296}
297
298/* check to see if the current input symbol matches '_t'.
299 * Used during exception handling.
300 */
301int ANTLRParser::
302_match_wsig(ANTLRTokenType _t)
303{
304	if ( dirty==LLk ) {
305		consume();
306	}
307	if ( LA(1)!=_t ) return 0;
308	dirty++;
309	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look
310	return 1;
311}
312
313/* check to see if the current input symbol matches any token in a set.
314 * During NON demand lookahead mode, dirty will always be 0 and
315 * hence the extra code for consuming tokens in _match is never
316 * executed; the same routine can be used for both modes.
317 */
318int ANTLRParser::
319_setmatch(SetWordType *tset, ANTLRChar **MissText,
320	   ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
321	   SetWordType **MissSet)
322{
323	if ( dirty==LLk ) {
324		consume();
325	}
326	if ( !set_el(LA(1), tset) ) {
327		*MissText=NULL;
328		*MissTok= (ANTLRTokenType)0; *BadTok=LT(1);
329		*MissSet=tset;
330		return 0;
331	}
332	dirty++;
333	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look
334	return 1;
335}
336
337int ANTLRParser::
338_setmatch_wsig(SetWordType *tset)
339{
340	if ( dirty==LLk ) {
341		consume();
342	}
343	if ( !set_el(LA(1), tset) ) return 0;
344	dirty++;
345	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look
346	return 1;
347}
348
349                   /* Exception handling routines */
350//
351//  7-Apr-97 133MR1
352//   	     Change suggested by Eli Sternheim (eli@interhdl.com)
353//
354void ANTLRParser::
355consumeUntil(SetWordType *st)
356{
357	ANTLRTokenType		tmp;	                        				// MR1
358	const			int Eof=1;                                          // MR1
359	while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); }       // MR1
360}
361
362//
363//  7-Apr-97 133MR1
364//   	     Change suggested by Eli Sternheim (eli@interhdl.com)
365//
366void ANTLRParser::
367consumeUntilToken(int t)
368{
369	int	tmp;                                                            // MR1
370	const	int Eof=1;                                                  // MR1
371	while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); }                 // MR1
372}
373
374
375                        /* Old error stuff */
376
377void ANTLRParser::
378resynch(SetWordType *wd,SetWordType mask)
379{
380
381/* MR8              S.Bochnak@microtool.com.pl                          */
382/* MR8              Change file scope static "consumed" to instance var */
383
384	/* if you enter here without having consumed a token from last resynch
385	 * force a token consumption.
386	 */
387/* MR8 */  	if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;}
388
389   	/* if current token is in resynch set, we've got what we wanted */
390
391/* MR8 */  	if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;}
392
393   	/* scan until we find something in the resynch set */
394
395        	while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();}
396
397/* MR8 */	resynchConsumed=1;
398}
399
400/* standard error reporting function that assumes DLG-based scanners;
401 * you should redefine in subclass to change it or if you use your
402 * own scanner.
403 */
404void ANTLRParser::
405syn(_ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
406	ANTLRTokenType etok, int k)
407{
408	int line;
409
410	line = LT(1)->getLine();
411
412    syntaxErrCount++;                                   /* MR11 */
413	fprintf(stderr, "line %d: syntax error at \"%s\"",
414					line,
415    				(LA(1)==eofToken && LT(1)->getText()[0] == '@')?
416                                        "<eof>":LT(1)->getText() /* MR21a */);
417	if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
418	if ( k==1 ) fprintf(stderr, " missing");
419	else
420	{
421		fprintf(stderr, "; \"%s\" not", LT(1)->getText());
422		if ( set_deg(eset)>1 ) fprintf(stderr, " in");
423	}
424	if ( set_deg(eset)>0 ) edecode(eset);
425	else fprintf(stderr, " %s", token_tbl[etok]);
426	if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup);
427	fprintf(stderr, "\n");
428}
429
430/* is b an element of set p? */
431int ANTLRParser::
432set_el(ANTLRTokenType b, SetWordType *p)
433{
434	return( p[DIVWORD(b)] & bitmask[MODWORD(b)] );
435}
436
437int ANTLRParser::
438set_deg(SetWordType *a)
439{
440	/* Fast compute degree of a set... the number
441	   of elements present in the set.  Assumes
442	   that all word bits are used in the set
443	*/
444	register SetWordType *p = a;
445	register SetWordType *endp = &(a[bsetsize]);
446	register int degree = 0;
447
448	if ( a == NULL ) return 0;
449	while ( p < endp )
450	{
451		register SetWordType t = *p;
452		register SetWordType *b = &(bitmask[0]);
453		do {
454			if (t & *b) ++degree;
455		} while (++b < &(bitmask[sizeof(SetWordType)*8]));
456		p++;
457	}
458
459	return(degree);
460}
461
462void ANTLRParser::
463edecode(SetWordType *a)
464{
465	register SetWordType *p = a;
466	register SetWordType *endp = &(p[bsetsize]);
467	register unsigned e = 0;
468
469	if ( set_deg(a)>1 ) fprintf(stderr, " {");
470	do {
471		register SetWordType t = *p;
472		register SetWordType *b = &(bitmask[0]);
473		do {
474			if ( t & *b ) fprintf(stderr, " %s", token_tbl[e]);
475			e++;
476		} while (++b < &(bitmask[sizeof(SetWordType)*8]));
477	} while (++p < endp);
478	if ( set_deg(a)>1 ) fprintf(stderr, " }");
479}
480
481/* input looks like:
482 *      zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk)
483 * where the zzMiss stuff is set here to the token that did not match
484 * (and which set wasn't it a member of).
485 */
486
487// MR9 29-Sep-97    Stan Bochnak (S.Bochnak@microTool.com.pl)
488// MR9              Original fix to static allocated text didn't
489// MR9                work because a pointer to it was passed back
490// MR9                to caller.  Replace with instance variable.
491
492const int   SETWORDCOUNT=20;
493
494void
495ANTLRParser::FAIL(int k, ...)
496{
497//
498//  MR1 10-Apr-97
499//
500
501    if (zzFAILtext == NULL) zzFAILtext=new char [1000];          // MR9
502    SetWordType **f=new SetWordType *[SETWORDCOUNT];             // MR1 // MR9
503    SetWordType **miss_set;
504    ANTLRChar **miss_text;
505    _ANTLRTokenPtr *bad_tok;
506    ANTLRChar **bad_text;
507//
508//  7-Apr-97 133MR1
509//  		err_k is passed as a "int *", not "unsigned *"
510//
511    int	*err_k;                                                         // MR1
512    int i;
513    va_list ap;
514
515    va_start(ap, k);
516
517    zzFAILtext[0] = '\0';
518	if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer");
519    for (i=1; i<=k; i++)    /* collect all lookahead sets */
520    {
521        f[i-1] = va_arg(ap, SetWordType *);
522    }
523    for (i=1; i<=k; i++)    /* look for offending token */
524    {
525        if ( i>1 ) strcat(zzFAILtext, " ");
526        strcat(zzFAILtext, LT(i)->getText());
527        if ( !set_el(LA(i), f[i-1]) ) break;
528    }
529    miss_set = va_arg(ap, SetWordType **);
530    miss_text = va_arg(ap, ANTLRChar **);
531    bad_tok = va_arg(ap, _ANTLRTokenPtr *);
532    bad_text = va_arg(ap, ANTLRChar **);
533    err_k = va_arg(ap, int *);                      					// MR1
534    if ( i>k )
535    {
536        /* bad; lookahead is permutation that cannot be matched,
537         * but, the ith token of lookahead is valid at the ith position
538         * (The old LL sub 1 (k) versus LL(k) parsing technique)
539         */
540        *miss_set = NULL;
541        *miss_text = LT(1)->getText();
542        *bad_tok = LT(1);
543        *bad_text = (*bad_tok)->getText();
544        *err_k = k;
545//
546//  MR4 20-May-97	erroneously deleted contents of f[]
547//  MR4			        reported by Bruce Guenter (bruceg@qcc.sk.ca)
548//  MR1 10-Apr-97	release temporary storage
549//
550      delete [] f;                                                      // MR1
551      return;                                                           // MR1
552    }
553/*  fprintf(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/
554    *miss_set = f[i-1];
555    *miss_text = zzFAILtext;
556    *bad_tok = LT(i);
557    *bad_text = (*bad_tok)->getText();
558    if ( i==1 ) *err_k = 1;
559    else *err_k = k;
560//
561//  MR4 20-May-97	erroneously deleted contents of f[]
562//  MR4			      reported by Bruce Guenter (bruceg@qcc.sk.ca)
563//  MR1 10-Apr-97	release temporary storage
564//
565    delete [] f;                                                        // MR1
566    return;                                                             // MR1
567}
568
569int ANTLRParser::
570_match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows)
571{
572	if ( dirty==LLk ) consume();
573
574	if ( LA(1)!=tokenWanted )
575	{
576        syntaxErrCount++;                                   /* MR11 */
577		fprintf(stderr,
578				"line %d: syntax error at \"%s\" missing %s\n",
579				LT(1)->getLine(),
580				(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
581				token_tbl[tokenWanted]);
582		consumeUntil( whatFollows );
583		return 0;
584	}
585	else {
586		dirty++;
587		labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
588/*		if ( !demand_look ) consume(); */
589		return 1;
590	}
591}
592
593
594int ANTLRParser::
595_setmatch_wdfltsig(SetWordType *tokensWanted,
596					ANTLRTokenType tokenTypeOfSet,
597					SetWordType *whatFollows)
598{
599	if ( dirty==LLk ) consume();
600	if ( !set_el(LA(1), tokensWanted) )
601	{
602        syntaxErrCount++;                                   /* MR11 */
603		fprintf(stderr,
604				"line %d: syntax error at \"%s\" missing %s\n",
605				LT(1)->getLine(),
606				(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
607				token_tbl[tokenTypeOfSet]);
608		consumeUntil( whatFollows );
609		return 0;
610	}
611	else {
612		dirty++;
613		labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
614/*		if ( !demand_look ) consume(); */
615		return 1;
616	}
617}
618
619char *ANTLRParser::
620eMsgd(char *err,int d)
621{
622	sprintf(eMsgBuffer, err, d);	// dangerous, but I don't care
623	return eMsgBuffer;
624}
625
626char *ANTLRParser::
627eMsg(char *err, char *s)
628{
629	sprintf(eMsgBuffer, err, s);
630	return eMsgBuffer;
631}
632
633char *ANTLRParser::
634eMsg2(char *err,char *s, char *t)
635{
636	sprintf(eMsgBuffer, err, s, t);
637	return eMsgBuffer;
638}
639
640void ANTLRParser::
641panic(const char *msg)  // MR20 const
642{
643	fprintf(stderr, "ANTLR panic: %s\n", msg);
644	exit(PCCTS_EXIT_FAILURE);           // MR1
645}
646
647const ANTLRChar *ANTLRParser::          // MR1
648parserTokenName(int tok) {              // MR1
649	return token_tbl[tok];              // MR1
650}                                       // MR1
651
652void ANTLRParser::traceGuessDone(const ANTLRParserState *state) {
653
654  int   doIt=0;
655
656  if (traceCurrentRuleName == NULL) return;
657
658  if (traceOptionValue <= 0) {
659    doIt=0;
660  } else if (traceGuessOptionValue <= 0) {
661    doIt=0;
662  } else {
663    doIt=1;
664  };
665
666  if (doIt) {
667    fprintf(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",
668        state->traceCurrentRuleName,
669        LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
670        state->traceDepth);
671    if (state->guessing != 0) {
672      fprintf(stderr," (guess mode continues - an enclosing guess is still active)");
673    } else {
674      fprintf(stderr," (guess mode ends)");
675    };
676    fprintf(stderr,"\n");
677  };
678}
679
680void ANTLRParser::traceGuessFail() {
681
682  int   doIt=0;
683
684  if (traceCurrentRuleName == NULL) return;     /* MR21 */
685
686  if (traceOptionValue <= 0) {
687    doIt=0;
688  } else if (guessing && traceGuessOptionValue <= 0) {
689    doIt=0;
690  } else {
691    doIt=1;
692  };
693
694  if (doIt) {
695    fprintf(stderr,"guess failed\n");
696  };
697}
698
699/* traceOption:
700     zero value turns off trace
701*/
702
703void ANTLRParser::tracein(const ANTLRChar * rule) {
704
705  int       doIt=0;
706
707  traceDepth++;
708  traceCurrentRuleName=rule;
709
710  if (traceOptionValue <= 0) {
711    doIt=0;
712  } else if (guessing && traceGuessOptionValue <= 0) {
713    doIt=0;
714  } else {
715    doIt=1;
716  };
717
718  if (doIt) {
719    fprintf(stderr,"enter rule %s {\"%s\"} depth %d",
720            rule,
721            LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
722            traceDepth);
723    if (guessing) fprintf(stderr," guessing");
724    fprintf(stderr,"\n");
725  };
726  return;
727}
728
729void ANTLRParser::traceout(const ANTLRChar * rule) {
730
731  int       doIt=0;
732
733  traceDepth--;
734
735  if (traceOptionValue <= 0) {
736    doIt=0;
737  } else if (guessing && traceGuessOptionValue <= 0) {
738    doIt=0;
739  } else {
740    doIt=1;
741  };
742
743  if (doIt) {
744    fprintf(stderr,"exit rule %s {\"%s\"} depth %d",
745            rule,
746            LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
747            traceDepth+1);
748    if (guessing) fprintf(stderr," guessing");
749    fprintf(stderr,"\n");
750  };
751}
752
753int ANTLRParser::traceOption(int delta) {
754
755    int     prevValue=traceOptionValue;
756
757    traceOptionValue=traceOptionValue+delta;
758
759    if (traceCurrentRuleName != NULL) {
760      if (prevValue <= 0 && traceOptionValue > 0) {
761        fprintf(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
762      };
763      if (prevValue > 0 && traceOptionValue <= 0) {
764        fprintf(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
765      };
766    };
767
768    return  prevValue;
769}
770
771int ANTLRParser::traceGuessOption(int delta) {
772
773    int     prevValue=traceGuessOptionValue;
774
775    traceGuessOptionValue=traceGuessOptionValue+delta;
776
777    if (traceCurrentRuleName != NULL) {
778      if (prevValue <= 0 && traceGuessOptionValue > 0) {
779        fprintf(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
780      };
781      if (prevValue > 0 && traceGuessOptionValue <= 0) {
782        fprintf(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
783      };
784    };
785    return prevValue;
786}
787
788// MR19 V.H. Simonis Defer Fetch feature
789
790void ANTLRParser::undeferFetch()
791{
792
793#ifdef ZZDEFER_FETCH
794    if (stillToFetch) {
795        for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) {
796    		NLA = inputTokens->getToken()->getType();
797    		dirty--;
798    		lap = (lap+1)&(LLk-1);
799        }
800        stillToFetch = 0;
801    }
802#else
803    return;
804#endif
805
806}
807
808int ANTLRParser::isDeferFetchEnabled()
809{
810#ifdef ZZDEFER_FETCH
811    return 1;
812#else
813    return 0;
814#endif
815}
816