SBSPSS/Utils/Parser Generator/SOURCE/yyccwork.cpp
2000-12-08 20:40:33 +00:00

286 lines
6.0 KiB
C++

/************************************************************
yyccwork.cpp
This file can be freely modified for the generation of
custom code.
Copyright (c) 1999 Bumble-Bee Software Ltd.
************************************************************/
#include <string.h>
#include "cyacc.h"
// the Visual C++ v1.52 compiler generates an error in NT if this isn't present!
#ifdef _MSC_VER
#if defined(M_I86HM) && defined(NDEBUG)
#pragma function(memcpy)
#endif
#endif
int yycparser::yywork()
{
int errorpop = 0;
while (1) {
yystack_t state = yypeek(); // get top state
int index = yycstateaction[state];
while (1) {
if (yyctokenaction[index].token == YYTK_ALL) {
if (yyctokenaction[index].type == YYAT_DEFAULT) {
state = yyctokenaction[index].sr;
index = yycstateaction[state];
continue;
}
break;
}
if (!yylookahead) {
yychar = yygettoken();
if (yychar < 0) {
yychar = 0;
}
yylookahead = 1;
#ifdef YYDEBUG
yydgettoken(yychar);
#endif
}
if (yyctokenaction[index].token == yychar) {
break;
}
index++;
}
unsigned char type = yyctokenaction[index].type;
short sr = yyctokenaction[index].sr;
// action
switch (type) {
case YYAT_SHIFT:
#ifdef YYDEBUG
yydshift(yychar);
#endif
if (yyskip > 0) {
yysetskip(yyskip - 1);
}
if (!yypush(sr)) {
#ifdef YYDEBUG
yydabort();
#endif
if (yywipeflg) {
yywipe(); // clean up
}
return 1;
}
memcpy(&((char YYFAR*)yyattributestackptr)[yytop * yyattribute_size],
yylvalptr, yyattribute_size);
yylookahead = 0;
continue; // go to top of while loop
case YYAT_REDUCE:
#ifdef YYDEBUG
yydreduce(sr);
#endif
yyretireflg = 0;
if (yyreduction[sr].action != -1) {
// user actions in here
if (yyreduction[sr].length > 0) {
memcpy(yyvalptr, &((char YYFAR*)yyattributestackptr)
[(yytop + 1 - yyreduction[sr].length) * yyattribute_size],
yyattribute_size);
}
yyerrorflg = 0;
yyexitflg = 0;
yyaction(yyreduction[sr].action);
// check for special user requected actions
if (yyexitflg) {
#ifdef YYDEBUG
yydexit(yyexitcode);
#endif
return yyexitcode;
}
if (yyerrorflg) {
errorpop = yyerrorpop;
#ifdef YYDEBUG
yydthrowerror(yyerrorpop);
#endif
yyerrorcount++;
break; // go to error handler
}
}
yypop(yyreduction[sr].length);
{
yystack_t state = yypeek(); // get top state
int nonterm = yyreduction[sr].nonterm;
int index = yycstategoto[state];
while (1) {
if (yycnontermgoto[index].nonterm == -1) {
if (yycnontermgoto[index].next != -1) {
state = yycnontermgoto[index].next;
index = yycstategoto[state];
continue;
}
break;
}
if (yycnontermgoto[index].nonterm == nonterm) {
break;
}
index++;
}
short next = yycnontermgoto[index].next;
yyassert(next != -1);
if (!yypush(next)) {
#ifdef YYDEBUG
yydabort();
#endif
if (yywipeflg) {
yywipe(); // clean up
}
return 1;
}
}
if (yyreduction[sr].action != -1) {
memcpy(&((char YYFAR*)yyattributestackptr)[yytop * yyattribute_size],
yyvalptr, yyattribute_size);
}
if (yyretireflg) {
#ifdef YYDEBUG
yydretire(yyretirecode);
#endif
return yyretirecode;
}
continue; // go to top of while loop
case YYAT_ERROR:
#ifdef YYDEBUG
yydsyntaxerror();
#endif
if (yyskip == 0) {
yyerrorcount++;
yysyntaxerror();
}
break; // go to error handler
default:
yyassert(type == YYAT_ACCEPT);
#ifdef YYDEBUG
yydaccept();
#endif
return 0;
}
// error handler
if (yyskip < 3 || yyerrorpop > 0) {
#ifdef YYDEBUG
yydattemptrecovery();
#endif
yypopflg = 0; // clear flag
while (yytop >= 0) {
state = yypeek(); // get top state
index = yycstateaction[state];
while (1) {
if (yyctokenaction[index].token == YYTK_ALL) {
if (yyctokenaction[index].type == YYAT_DEFAULT) {
state = yyctokenaction[index].sr;
index = yycstateaction[state];
continue;
}
break;
}
if (yyctokenaction[index].token == YYTK_ERROR) {
break;
}
index++;
}
type = yyctokenaction[index].type;
sr = yyctokenaction[index].sr;
if (type == YYAT_SHIFT) {
if (errorpop <= 0) {
#ifdef YYDEBUG
yydshift(YYTK_ERROR);
#endif
if (!yypush(sr)) {
#ifdef YYDEBUG
yydabort();
#endif
if (yywipeflg) {
yywipe(); // clean up
}
return 1;
}
yysetskip(3); // skip 3 erroneous characters
break;
}
errorpop--;
}
yypopflg = 1;
// clean up any symbol attributes
if (yydestructorptr != NULL) {
state = yypeek();
int action = yydestructorptr[state];
if (action != -1) {
// user actions in here
memcpy(yyvalptr, &((char YYFAR*)yyattributestackptr)
[yytop * yyattribute_size], yyattribute_size);
yyaction(action);
memcpy(&((char YYFAR*)yyattributestackptr)
[yytop * yyattribute_size], yyvalptr, yyattribute_size);
}
}
yypop(1);
if (yytop < 0) {
#ifdef YYDEBUG
yydabort();
#endif
if (yywipeflg) {
yywipe(); // clean up
}
return 1;
}
}
}
else {
if (yylookahead) {
if (yychar != 0) {
#ifdef YYDEBUG
yyddiscard(yychar);
#endif
yydiscard(yychar);
// clean up any token attributes
if (yyctokendestptr != NULL) {
const yyctokendest_t YYNEARFAR *tokendestptr = yyctokendestptr;
while (tokendestptr->token != 0) {
if (tokendestptr->token == yychar) {
// user actions in here
memcpy(yyvalptr, yylvalptr, yyattribute_size);
yyaction(tokendestptr->action);
memcpy(yylvalptr, yyvalptr, yyattribute_size);
break;
}
tokendestptr++;
}
}
yylookahead = 0; // skip erroneous character
}
else {
#ifdef YYDEBUG
yydabort();
#endif
if (yywipeflg) {
yywipe(); // clean up
}
return 1;
}
}
}
}
}