mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-20 15:48:18 +01:00
7c0aa811ec
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
872 lines
24 KiB
C++
872 lines
24 KiB
C++
/* ANTLRParser.C
|
|
*
|
|
* SOFTWARE RIGHTS
|
|
*
|
|
* We reserve no LEGAL rights to the Purdue Compiler Construction Tool
|
|
* Set (PCCTS) -- PCCTS is in the public domain. An individual or
|
|
* company may do whatever they wish with source code distributed with
|
|
* PCCTS or the code generated by PCCTS, including the incorporation of
|
|
* PCCTS, or its output, into commerical software.
|
|
*
|
|
* We encourage users to develop software with PCCTS. However, we do ask
|
|
* that credit is given to us for developing PCCTS. By "credit",
|
|
* we mean that if you incorporate our source code into one of your
|
|
* programs (commercial product, research project, or otherwise) that you
|
|
* acknowledge this fact somewhere in the documentation, research report,
|
|
* etc... If you like PCCTS and have developed a nice tool with the
|
|
* output, please mention that you developed it using PCCTS. In
|
|
* addition, we ask that this header remain intact in our source code.
|
|
* As long as these guidelines are kept, we expect to continue enhancing
|
|
* this system and expect to make other tools available as they are
|
|
* completed.
|
|
*
|
|
* ANTLR 1.33
|
|
* Terence Parr
|
|
* Parr Research Corporation
|
|
* with Purdue University and AHPCRC, University of Minnesota
|
|
* 1989-2000
|
|
*/
|
|
|
|
#include "pcctscfg.h"
|
|
|
|
#include "pccts_stdlib.h"
|
|
#include "pccts_stdarg.h"
|
|
#include "pccts_string.h"
|
|
#include "pccts_stdio.h"
|
|
|
|
PCCTS_NAMESPACE_STD
|
|
|
|
/* I have to put this here due to C++ limitation
|
|
* that you can't have a 'forward' decl for enums.
|
|
* I hate C++!!!!!!!!!!!!!!!
|
|
* Of course, if I could use real templates, this would go away.
|
|
*/
|
|
// MR1
|
|
// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the
|
|
// MR1 ANTLRTokenType enum
|
|
// MR1
|
|
|
|
enum ANTLRTokenType { TER_HATES_CPP=0, ITS_TOO_COMPLICATED=9999}; // MR1
|
|
|
|
#define ANTLR_SUPPORT_CODE
|
|
|
|
#include ATOKEN_H
|
|
#include ATOKENBUFFER_H
|
|
#include APARSER_H
|
|
|
|
static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000; /* MR14 */
|
|
static const int zzINF_BUFFER_TOKEN_CHUNK_SIZE = 1000; /* MR14 */
|
|
|
|
/* L o o k a h e a d M a c r o s */
|
|
|
|
/* maximum of 32 bits/unsigned int and must be 8 bits/byte;
|
|
* we only use 8 bits of it.
|
|
*/
|
|
SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = {
|
|
0x00000001, 0x00000002, 0x00000004, 0x00000008,
|
|
0x00000010, 0x00000020, 0x00000040, 0x00000080
|
|
};
|
|
|
|
char ANTLRParser::eMsgBuffer[500] = "";
|
|
|
|
ANTLRParser::
|
|
~ANTLRParser()
|
|
{
|
|
delete [] token_type;
|
|
delete [] zzFAILtext; // MR16 Manfred Kogler
|
|
}
|
|
|
|
ANTLRParser::
|
|
ANTLRParser(ANTLRTokenBuffer *_inputTokens,
|
|
int k,
|
|
int use_inf_look,
|
|
int dlook,
|
|
int ssize)
|
|
{
|
|
LLk = k;
|
|
can_use_inf_look = use_inf_look;
|
|
/* MR14 */ if (dlook != 0) {
|
|
/* MR14 */ panic("ANTLRParser::ANTLRParser - Demand lookahead not supported in C++ mode");
|
|
/* MR14 */
|
|
/* MR14 */ };
|
|
demand_look = 0; /* demand_look = dlook; */
|
|
bsetsize = ssize;
|
|
guessing = 0;
|
|
token_tbl = NULL;
|
|
eofToken = (ANTLRTokenType)1;
|
|
|
|
// allocate lookahead buffer
|
|
token_type = new ANTLRTokenType[LLk];
|
|
lap = 0;
|
|
labase = 0;
|
|
#ifdef ZZDEFER_FETCH
|
|
stillToFetch = 0; // MR19
|
|
#endif
|
|
dirty = 0;
|
|
inf_labase = 0; // MR7
|
|
inf_last = 0; // MR7
|
|
/* prime lookahead buffer, point to inputTokens */
|
|
this->inputTokens = _inputTokens;
|
|
this->inputTokens->setMinTokens(k);
|
|
_inputTokens->setParser(this); // MR1
|
|
resynchConsumed=1; // MR8
|
|
zzFAILtext=NULL; // MR9
|
|
traceOptionValueDefault=0; // MR10
|
|
traceReset(); // MR10
|
|
zzGuessSeq=0; // MR10
|
|
syntaxErrCount=0; // MR11
|
|
}
|
|
|
|
void ANTLRParser::init()
|
|
{
|
|
prime_lookahead();
|
|
resynchConsumed=1; // MR8
|
|
traceReset(); // MR10
|
|
}
|
|
|
|
void ANTLRParser::traceReset()
|
|
{
|
|
traceOptionValue=traceOptionValueDefault;
|
|
traceGuessOptionValue=1;
|
|
traceCurrentRuleName=NULL;
|
|
traceDepth=0;
|
|
}
|
|
|
|
|
|
#ifdef _MSC_VER // MR23
|
|
//Turn off warning:
|
|
//interaction between '_setjmp' and C++ object destruction is non-portable
|
|
#pragma warning(disable : 4611)
|
|
#endif
|
|
int ANTLRParser::
|
|
guess(ANTLRParserState *st)
|
|
{
|
|
saveState(st);
|
|
guessing = 1;
|
|
return setjmp(guess_start.state);
|
|
}
|
|
#ifdef _MSC_VER // MR23
|
|
#pragma warning(default: 4611)
|
|
#endif
|
|
|
|
void ANTLRParser::
|
|
saveState(ANTLRParserState *buf)
|
|
{
|
|
buf->guess_start = guess_start;
|
|
buf->guessing = guessing;
|
|
buf->inf_labase = inf_labase;
|
|
buf->inf_last = inf_last;
|
|
buf->dirty = dirty;
|
|
buf->traceOptionValue=traceOptionValue; /* MR10 */
|
|
buf->traceGuessOptionValue=traceGuessOptionValue; /* MR10 */
|
|
buf->traceCurrentRuleName=traceCurrentRuleName; /* MR10 */
|
|
buf->traceDepth=traceDepth; /* MR10 */
|
|
}
|
|
|
|
void ANTLRParser::
|
|
restoreState(ANTLRParserState *buf)
|
|
{
|
|
int i;
|
|
int prevTraceOptionValue;
|
|
|
|
guess_start = buf->guess_start;
|
|
guessing = buf->guessing;
|
|
inf_labase = buf->inf_labase;
|
|
inf_last = buf->inf_last;
|
|
dirty = buf->dirty;
|
|
|
|
// restore lookahead buffer from k tokens before restored TokenBuffer position
|
|
// if demand_look, then I guess we don't look backwards for these tokens.
|
|
for (i=1; i<=LLk; i++) token_type[i-1] =
|
|
inputTokens->bufferedToken(i-LLk)->getType();
|
|
lap = 0;
|
|
labase = 0;
|
|
|
|
/* MR10 */
|
|
|
|
prevTraceOptionValue=traceOptionValue;
|
|
traceOptionValue=buf->traceOptionValue;
|
|
if ( (prevTraceOptionValue > 0) !=
|
|
(traceOptionValue > 0)) {
|
|
if (traceCurrentRuleName != NULL) { /* MR21 */
|
|
if (traceOptionValue > 0) {
|
|
/* MR23 */ printMessage(stderr,
|
|
"trace enable restored in rule %s depth %d\n",
|
|
traceCurrentRuleName,
|
|
traceDepth);
|
|
};
|
|
if (traceOptionValue <= 0) {
|
|
/* MR23 */ printMessage(stderr,
|
|
"trace disable restored in rule %s depth %d\n",
|
|
traceCurrentRuleName, /* MR21 */
|
|
traceDepth);
|
|
};
|
|
}
|
|
};
|
|
traceGuessOptionValue=buf->traceGuessOptionValue;
|
|
traceCurrentRuleName=buf->traceCurrentRuleName;
|
|
traceDepth=buf->traceDepth;
|
|
traceGuessDone(buf);
|
|
}
|
|
|
|
/* Get the next symbol from the input stream; put it into lookahead buffer;
|
|
* fill token_type[] fast reference cache also. NLA is the next place where
|
|
* a lookahead ANTLRAbstractToken should go.
|
|
*/
|
|
void ANTLRParser::
|
|
consume()
|
|
{
|
|
|
|
#ifdef ZZDEBUG_CONSUME_ACTION
|
|
zzdebug_consume_action();
|
|
#endif
|
|
|
|
// MR19 V.H. Simonis
|
|
// Defer Fetch feature
|
|
// Moves action of consume() into LA() function
|
|
|
|
#ifdef ZZDEFER_FETCH
|
|
stillToFetch++;
|
|
#else
|
|
NLA = inputTokens->getToken()->getType();
|
|
dirty--;
|
|
lap = (lap+1)&(LLk-1);
|
|
#endif
|
|
|
|
}
|
|
|
|
_ANTLRTokenPtr ANTLRParser::
|
|
LT(int i)
|
|
{
|
|
|
|
// MR19 V.H. Simonis
|
|
// Defer Fetch feature
|
|
// Moves action of consume() into LA() function
|
|
|
|
#ifdef ZZDEFER_FETCH
|
|
undeferFetch();
|
|
#endif
|
|
|
|
#ifdef DEBUG_TOKENBUFFER
|
|
if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */
|
|
{
|
|
char buf[2000]; /* MR20 Was "static" */
|
|
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);
|
|
panic(buf);
|
|
}
|
|
#endif
|
|
return inputTokens->bufferedToken(i-LLk);
|
|
}
|
|
|
|
void
|
|
ANTLRParser::
|
|
look(int k)
|
|
{
|
|
int i, c = k - (LLk-dirty);
|
|
for (i=1; i<=c; i++) consume();
|
|
}
|
|
|
|
/* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK);
|
|
*/
|
|
void
|
|
ANTLRParser::
|
|
prime_lookahead()
|
|
{
|
|
int i;
|
|
for(i=1;i<=LLk; i++) consume();
|
|
dirty=0;
|
|
// lap = 0; // MR14 Sinan Karasu (sinan.karasu@boeing.com)
|
|
// labase = 0; // MR14
|
|
labase=lap; // MR14
|
|
}
|
|
|
|
/* check to see if the current input symbol matches '_t'.
|
|
* During NON demand lookahead mode, dirty will always be 0 and
|
|
* hence the extra code for consuming tokens in _match is never
|
|
* executed; the same routine can be used for both modes.
|
|
*/
|
|
int ANTLRParser::
|
|
_match(ANTLRTokenType _t, ANTLRChar **MissText,
|
|
ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
|
|
SetWordType **MissSet)
|
|
{
|
|
if ( dirty==LLk ) {
|
|
consume();
|
|
}
|
|
if ( LA(1)!=_t ) {
|
|
*MissText=NULL;
|
|
*MissTok= _t;
|
|
*BadTok = LT(1);
|
|
*MissSet=NULL;
|
|
return 0;
|
|
}
|
|
dirty++;
|
|
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
|
|
return 1;
|
|
}
|
|
|
|
/* check to see if the current input symbol matches '_t'.
|
|
* Used during exception handling.
|
|
*/
|
|
int ANTLRParser::
|
|
_match_wsig(ANTLRTokenType _t)
|
|
{
|
|
if ( dirty==LLk ) {
|
|
consume();
|
|
}
|
|
if ( LA(1)!=_t ) return 0;
|
|
dirty++;
|
|
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
|
|
return 1;
|
|
}
|
|
|
|
/* check to see if the current input symbol matches any token in a set.
|
|
* During NON demand lookahead mode, dirty will always be 0 and
|
|
* hence the extra code for consuming tokens in _match is never
|
|
* executed; the same routine can be used for both modes.
|
|
*/
|
|
int ANTLRParser::
|
|
_setmatch(SetWordType *tset, ANTLRChar **MissText,
|
|
ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
|
|
SetWordType **MissSet, SetWordType *tokclassErrset)
|
|
{
|
|
if ( dirty==LLk ) {
|
|
consume();
|
|
}
|
|
if ( !set_el(LA(1), tset) ) {
|
|
*MissText=NULL; /* MR23 */
|
|
*MissTok=(ANTLRTokenType) 0; /* MR23 */
|
|
*BadTok=LT(1); /* MR23 */
|
|
*MissSet=tokclassErrset; /* MR23 */
|
|
return 0;
|
|
}
|
|
dirty++;
|
|
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
|
|
return 1;
|
|
}
|
|
|
|
int ANTLRParser::
|
|
_setmatch_wsig(SetWordType *tset)
|
|
{
|
|
if ( dirty==LLk ) {
|
|
consume();
|
|
}
|
|
if ( !set_el(LA(1), tset) ) return 0;
|
|
dirty++;
|
|
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
|
|
return 1;
|
|
}
|
|
|
|
/* Exception handling routines */
|
|
//
|
|
// 7-Apr-97 133MR1
|
|
// Change suggested by Eli Sternheim (eli@interhdl.com)
|
|
//
|
|
void ANTLRParser::
|
|
consumeUntil(SetWordType *st)
|
|
{
|
|
ANTLRTokenType tmp; // MR1
|
|
const int Eof=1; // MR1
|
|
while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); } // MR1
|
|
}
|
|
|
|
//
|
|
// 7-Apr-97 133MR1
|
|
// Change suggested by Eli Sternheim (eli@interhdl.com)
|
|
//
|
|
void ANTLRParser::
|
|
consumeUntilToken(int t)
|
|
{
|
|
int tmp; // MR1
|
|
const int Eof=1; // MR1
|
|
while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); } // MR1
|
|
}
|
|
|
|
|
|
/* Old error stuff */
|
|
|
|
void ANTLRParser::
|
|
resynch(SetWordType *wd,SetWordType mask)
|
|
{
|
|
|
|
/* MR8 S.Bochnak@microtool.com.pl */
|
|
/* MR8 Change file scope static "consumed" to instance var */
|
|
|
|
/* if you enter here without having consumed a token from last resynch
|
|
* force a token consumption.
|
|
*/
|
|
/* MR8 */ if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;}
|
|
|
|
/* if current token is in resynch set, we've got what we wanted */
|
|
|
|
/* MR8 */ if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;}
|
|
|
|
/* scan until we find something in the resynch set */
|
|
|
|
while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();}
|
|
|
|
/* MR8 */ resynchConsumed=1;
|
|
}
|
|
|
|
/* standard error reporting function that assumes DLG-based scanners;
|
|
* you should redefine in subclass to change it or if you use your
|
|
* own scanner.
|
|
*/
|
|
|
|
/* MR23 THM There appears to be a parameter "badText" passed to syn()
|
|
which is not present in the parameter list. This may be
|
|
because in C mode there is no attribute function which
|
|
returns the text, so the text representation of the token
|
|
must be passed explicitly. I think.
|
|
*/
|
|
|
|
void ANTLRParser::
|
|
syn(_ANTLRTokenPtr /*tok MR23*/, ANTLRChar *egroup, SetWordType *eset,
|
|
ANTLRTokenType etok, int k)
|
|
{
|
|
int line;
|
|
|
|
line = LT(1)->getLine();
|
|
|
|
syntaxErrCount++; /* MR11 */
|
|
|
|
/* MR23 If the token is not an EOF token, then use the ->getText() value.
|
|
|
|
If the token is the EOF token the text returned by ->getText()
|
|
may be garbage. If the text from the token table is "@" use
|
|
"<eof>" instead, because end-users don't know what "@" means.
|
|
If the text is not "@" then use that text, which must have been
|
|
supplied by the grammar writer.
|
|
*/
|
|
const char * errorAt = LT(1)->getText();
|
|
if (LA(1) == eofToken) {
|
|
errorAt = parserTokenName(LA(1));
|
|
if (errorAt[0] == '@') errorAt = "<eof>";
|
|
}
|
|
/* MR23 */ printMessage(stderr, "line %d: syntax error at \"%s\"",
|
|
line, errorAt);
|
|
if ( !etok && !eset ) {/* MR23 */ printMessage(stderr, "\n"); return;}
|
|
if ( k==1 ) /* MR23 */ printMessage(stderr, " missing");
|
|
else
|
|
{
|
|
/* MR23 */ printMessage(stderr, "; \"%s\" not", LT(k)->getText()); // MR23 use LT(k) since k>1
|
|
if ( set_deg(eset)>1 ) /* MR23 */ printMessage(stderr, " in");
|
|
}
|
|
if ( set_deg(eset)>0 ) edecode(eset);
|
|
else /* MR23 */ printMessage(stderr, " %s", token_tbl[etok]);
|
|
if ( strlen(egroup) > 0 ) /* MR23 */ printMessage(stderr, " in %s", egroup);
|
|
/* MR23 */ printMessage(stderr, "\n");
|
|
}
|
|
|
|
/* is b an element of set p? */
|
|
int ANTLRParser::
|
|
set_el(ANTLRTokenType b, SetWordType *p)
|
|
{
|
|
return( p[DIVWORD(b)] & bitmask[MODWORD(b)] );
|
|
}
|
|
|
|
int ANTLRParser::
|
|
set_deg(SetWordType *a)
|
|
{
|
|
/* Fast compute degree of a set... the number
|
|
of elements present in the set. Assumes
|
|
that all word bits are used in the set
|
|
*/
|
|
register SetWordType *p = a;
|
|
register SetWordType *endp = &(a[bsetsize]);
|
|
register int degree = 0;
|
|
|
|
if ( a == NULL ) return 0;
|
|
while ( p < endp )
|
|
{
|
|
register SetWordType t = *p;
|
|
register SetWordType *b = &(bitmask[0]);
|
|
do {
|
|
if (t & *b) ++degree;
|
|
} while (++b < &(bitmask[sizeof(SetWordType)*8]));
|
|
p++;
|
|
}
|
|
|
|
return(degree);
|
|
}
|
|
|
|
void ANTLRParser::
|
|
edecode(SetWordType *a)
|
|
{
|
|
register SetWordType *p = a;
|
|
register SetWordType *endp = &(p[bsetsize]);
|
|
register unsigned e = 0;
|
|
|
|
if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " {");
|
|
do {
|
|
register SetWordType t = *p;
|
|
register SetWordType *b = &(bitmask[0]);
|
|
do {
|
|
if ( t & *b ) /* MR23 */ printMessage(stderr, " %s", token_tbl[e]);
|
|
e++;
|
|
} while (++b < &(bitmask[sizeof(SetWordType)*8]));
|
|
} while (++p < endp);
|
|
if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " }");
|
|
}
|
|
|
|
/* input looks like:
|
|
* zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk)
|
|
* where the zzMiss stuff is set here to the token that did not match
|
|
* (and which set wasn't it a member of).
|
|
*/
|
|
|
|
// MR9 29-Sep-97 Stan Bochnak (S.Bochnak@microTool.com.pl)
|
|
// MR9 Original fix to static allocated text didn't
|
|
// MR9 work because a pointer to it was passed back
|
|
// MR9 to caller. Replace with instance variable.
|
|
|
|
const int SETWORDCOUNT=20;
|
|
|
|
void
|
|
ANTLRParser::FAIL(int k, ...)
|
|
{
|
|
//
|
|
// MR1 10-Apr-97
|
|
//
|
|
|
|
if (zzFAILtext == NULL) zzFAILtext=new char [1000]; // MR9
|
|
SetWordType **f=new SetWordType *[SETWORDCOUNT]; // MR1 // MR9
|
|
SetWordType **miss_set;
|
|
ANTLRChar **miss_text;
|
|
_ANTLRTokenPtr *bad_tok;
|
|
ANTLRChar **bad_text;
|
|
//
|
|
// 7-Apr-97 133MR1
|
|
// err_k is passed as a "int *", not "unsigned *"
|
|
//
|
|
int *err_k; // MR1
|
|
int i;
|
|
va_list ap;
|
|
|
|
va_start(ap, k);
|
|
|
|
zzFAILtext[0] = '\0';
|
|
if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer");
|
|
for (i=1; i<=k; i++) /* collect all lookahead sets */
|
|
{
|
|
f[i-1] = va_arg(ap, SetWordType *);
|
|
}
|
|
for (i=1; i<=k; i++) /* look for offending token */
|
|
{
|
|
if ( i>1 ) strcat(zzFAILtext, " ");
|
|
strcat(zzFAILtext, LT(i)->getText());
|
|
if ( !set_el(LA(i), f[i-1]) ) break;
|
|
}
|
|
miss_set = va_arg(ap, SetWordType **);
|
|
miss_text = va_arg(ap, ANTLRChar **);
|
|
bad_tok = va_arg(ap, _ANTLRTokenPtr *);
|
|
bad_text = va_arg(ap, ANTLRChar **);
|
|
err_k = va_arg(ap, int *); // MR1
|
|
if ( i>k )
|
|
{
|
|
/* bad; lookahead is permutation that cannot be matched,
|
|
* but, the ith token of lookahead is valid at the ith position
|
|
* (The old LL sub 1 (k) versus LL(k) parsing technique)
|
|
*/
|
|
*miss_set = NULL;
|
|
*miss_text = LT(1)->getText();
|
|
*bad_tok = LT(1);
|
|
*bad_text = (*bad_tok)->getText();
|
|
*err_k = k;
|
|
//
|
|
// MR4 20-May-97 erroneously deleted contents of f[]
|
|
// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)
|
|
// MR1 10-Apr-97 release temporary storage
|
|
//
|
|
delete [] f; // MR1
|
|
return; // MR1
|
|
}
|
|
/* MR23 printMessage(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/
|
|
*miss_set = f[i-1];
|
|
*miss_text = zzFAILtext;
|
|
*bad_tok = LT(i);
|
|
*bad_text = (*bad_tok)->getText();
|
|
if ( i==1 ) *err_k = 1;
|
|
else *err_k = k;
|
|
//
|
|
// MR4 20-May-97 erroneously deleted contents of f[]
|
|
// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)
|
|
// MR1 10-Apr-97 release temporary storage
|
|
//
|
|
delete [] f; // MR1
|
|
return; // MR1
|
|
}
|
|
|
|
int ANTLRParser::
|
|
_match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows)
|
|
{
|
|
if ( dirty==LLk ) consume();
|
|
|
|
if ( LA(1)!=tokenWanted )
|
|
{
|
|
syntaxErrCount++; /* MR11 */
|
|
/* MR23 */ printMessage(stderr,
|
|
"line %d: syntax error at \"%s\" missing %s\n",
|
|
LT(1)->getLine(),
|
|
(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
|
|
token_tbl[tokenWanted]);
|
|
consumeUntil( whatFollows );
|
|
return 0;
|
|
}
|
|
else {
|
|
dirty++;
|
|
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
|
|
/* if ( !demand_look ) consume(); */
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
int ANTLRParser::
|
|
_setmatch_wdfltsig(SetWordType *tokensWanted,
|
|
ANTLRTokenType tokenTypeOfSet,
|
|
SetWordType *whatFollows)
|
|
{
|
|
if ( dirty==LLk ) consume();
|
|
if ( !set_el(LA(1), tokensWanted) )
|
|
{
|
|
syntaxErrCount++; /* MR11 */
|
|
/* MR23 */ printMessage(stderr,
|
|
"line %d: syntax error at \"%s\" missing %s\n",
|
|
LT(1)->getLine(),
|
|
(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
|
|
token_tbl[tokenTypeOfSet]);
|
|
consumeUntil( whatFollows );
|
|
return 0;
|
|
}
|
|
else {
|
|
dirty++;
|
|
labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
|
|
/* if ( !demand_look ) consume(); */
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
char *ANTLRParser::
|
|
eMsgd(char *err,int d)
|
|
{
|
|
sprintf(eMsgBuffer, err, d); // dangerous, but I don't care
|
|
return eMsgBuffer;
|
|
}
|
|
|
|
char *ANTLRParser::
|
|
eMsg(char *err, char *s)
|
|
{
|
|
sprintf(eMsgBuffer, err, s);
|
|
return eMsgBuffer;
|
|
}
|
|
|
|
char *ANTLRParser::
|
|
eMsg2(char *err,char *s, char *t)
|
|
{
|
|
sprintf(eMsgBuffer, err, s, t);
|
|
return eMsgBuffer;
|
|
}
|
|
|
|
void ANTLRParser::
|
|
panic(const char *msg) // MR20 const
|
|
{
|
|
/* MR23 */ printMessage(stderr, "ANTLR panic: %s\n", msg);
|
|
exit(PCCTS_EXIT_FAILURE); // MR1
|
|
}
|
|
|
|
const ANTLRChar *ANTLRParser:: // MR1
|
|
parserTokenName(int tok) { // MR1
|
|
return token_tbl[tok]; // MR1
|
|
} // MR1
|
|
|
|
void ANTLRParser::traceGuessDone(const ANTLRParserState *state) {
|
|
|
|
int doIt=0;
|
|
|
|
if (traceCurrentRuleName == NULL) return;
|
|
|
|
if (traceOptionValue <= 0) {
|
|
doIt=0;
|
|
} else if (traceGuessOptionValue <= 0) {
|
|
doIt=0;
|
|
} else {
|
|
doIt=1;
|
|
};
|
|
|
|
if (doIt) {
|
|
/* MR23 */ printMessage(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",
|
|
state->traceCurrentRuleName,
|
|
LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
|
|
state->traceDepth);
|
|
if (state->guessing != 0) {
|
|
/* MR23 */ printMessage(stderr," (guess mode continues - an enclosing guess is still active)");
|
|
} else {
|
|
/* MR23 */ printMessage(stderr," (guess mode ends)");
|
|
};
|
|
/* MR23 */ printMessage(stderr,"\n");
|
|
};
|
|
}
|
|
|
|
void ANTLRParser::traceGuessFail() {
|
|
|
|
int doIt=0;
|
|
|
|
if (traceCurrentRuleName == NULL) return; /* MR21 */
|
|
|
|
if (traceOptionValue <= 0) {
|
|
doIt=0;
|
|
} else if (guessing && traceGuessOptionValue <= 0) {
|
|
doIt=0;
|
|
} else {
|
|
doIt=1;
|
|
};
|
|
|
|
if (doIt) {
|
|
/* MR23 */ printMessage(stderr,"guess failed in %s\n",traceCurrentRuleName);
|
|
};
|
|
}
|
|
|
|
/* traceOption:
|
|
zero value turns off trace
|
|
*/
|
|
|
|
void ANTLRParser::tracein(const ANTLRChar * rule) {
|
|
|
|
int doIt=0;
|
|
|
|
traceDepth++;
|
|
traceCurrentRuleName=rule;
|
|
|
|
if (traceOptionValue <= 0) {
|
|
doIt=0;
|
|
} else if (guessing && traceGuessOptionValue <= 0) {
|
|
doIt=0;
|
|
} else {
|
|
doIt=1;
|
|
};
|
|
|
|
if (doIt) {
|
|
/* MR23 */ printMessage(stderr,"enter rule %s {\"%s\"} depth %d",
|
|
rule,
|
|
LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
|
|
traceDepth);
|
|
if (guessing) /* MR23 */ printMessage(stderr," guessing");
|
|
/* MR23 */ printMessage(stderr,"\n");
|
|
};
|
|
return;
|
|
}
|
|
|
|
void ANTLRParser::traceout(const ANTLRChar * rule) {
|
|
|
|
int doIt=0;
|
|
|
|
traceDepth--;
|
|
|
|
if (traceOptionValue <= 0) {
|
|
doIt=0;
|
|
} else if (guessing && traceGuessOptionValue <= 0) {
|
|
doIt=0;
|
|
} else {
|
|
doIt=1;
|
|
};
|
|
|
|
if (doIt) {
|
|
/* MR23 */ printMessage(stderr,"exit rule %s {\"%s\"} depth %d",
|
|
rule,
|
|
LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
|
|
traceDepth+1);
|
|
if (guessing) /* MR23 */ printMessage(stderr," guessing");
|
|
/* MR23 */ printMessage(stderr,"\n");
|
|
};
|
|
}
|
|
|
|
int ANTLRParser::traceOption(int delta) {
|
|
|
|
int prevValue=traceOptionValue;
|
|
|
|
traceOptionValue=traceOptionValue+delta;
|
|
|
|
if (traceCurrentRuleName != NULL) {
|
|
if (prevValue <= 0 && traceOptionValue > 0) {
|
|
/* MR23 */ printMessage(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
|
|
};
|
|
if (prevValue > 0 && traceOptionValue <= 0) {
|
|
/* MR23 */ printMessage(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
|
|
};
|
|
};
|
|
|
|
return prevValue;
|
|
}
|
|
|
|
int ANTLRParser::traceGuessOption(int delta) {
|
|
|
|
int prevValue=traceGuessOptionValue;
|
|
|
|
traceGuessOptionValue=traceGuessOptionValue+delta;
|
|
|
|
if (traceCurrentRuleName != NULL) {
|
|
if (prevValue <= 0 && traceGuessOptionValue > 0) {
|
|
/* MR23 */ printMessage(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
|
|
};
|
|
if (prevValue > 0 && traceGuessOptionValue <= 0) {
|
|
/* MR23 */ printMessage(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
|
|
};
|
|
};
|
|
return prevValue;
|
|
}
|
|
|
|
// MR19 V.H. Simonis Defer Fetch feature
|
|
|
|
void ANTLRParser::undeferFetch()
|
|
{
|
|
|
|
#ifdef ZZDEFER_FETCH
|
|
if (stillToFetch) {
|
|
for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) {
|
|
NLA = inputTokens->getToken()->getType();
|
|
dirty--;
|
|
lap = (lap+1)&(LLk-1);
|
|
}
|
|
stillToFetch = 0;
|
|
}
|
|
#else
|
|
return;
|
|
#endif
|
|
|
|
}
|
|
|
|
int ANTLRParser::isDeferFetchEnabled()
|
|
{
|
|
#ifdef ZZDEFER_FETCH
|
|
return 1;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
//MR23
|
|
int ANTLRParser::printMessage(FILE* pFile, const char* pFormat, ...)
|
|
{
|
|
va_list marker;
|
|
va_start( marker, pFormat );
|
|
int iRet = printMessageV(pFile, pFormat, marker);
|
|
va_end( marker );
|
|
return iRet;
|
|
}
|
|
|
|
int ANTLRParser::printMessageV(FILE* pFile, const char* pFormat, va_list arglist) // MR23
|
|
{
|
|
return vfprintf(pFile, pFormat, arglist);
|
|
}
|
|
|
|
// MR23 Move semantic predicate error handling from macro to virtual function
|
|
//
|
|
// Called by the zzfailed_pred
|
|
|
|
void ANTLRParser::failedSemanticPredicate(const char* predicate)
|
|
{
|
|
printMessage(stdout,"line %d: semantic error; failed predicate: '%s'\n",
|
|
LT(1)->getLine(), predicate);
|
|
}
|