aparser.cpp

来自「SRI international 发布的OAA框架软件」· C++ 代码 · 共 872 行 · 第 1/2 页

CPP
872
字号
             "<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);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?