P8000/WEGA/contrib/ingres/dbs/src/pqr/rc_parse.c

187 lines
4.2 KiB
C

/*
** --- RC_PARSE.C ------ PARSER FOR YACC OUTPUT -----------------------------
**
** Version: @(#)rc_parse.c 4.0 02/05/89
**
*/
# include "rc.h"
# define ACTION(state) (state & 07777)
# define OPERATION(state) (state >> 12)
/* the OPERATIONS */
# define SHIFT_ON_ERROR 010400
# define ERROR 0
# define SKIP 1
# define SHIFT 2
# define REDUCE 3
# define ACCEPT 4
/* SIZE for state and value stack */
# define MAXDEPTH 150
extern char *yyval; /* defined in the table file */
extern char *yylval; /* defined in the table file */
extern char **yypv; /* defined in the table file */
extern short yygo[]; /* defined in the table file */
extern short yypgo[]; /* defined in the table file */
extern short yyr1[]; /* defined in the table file */
extern short yyr2[]; /* defined in the table file */
extern short yyact[]; /* defined in the table file */
extern short yypact[]; /* defined in the table file */
# ifdef RC_TRACE
int rc_debug = 0; /* TR_PARSE for debugging (rc.h) */
# endif
rc_parse()
{
char *values[MAXDEPTH]; /* value stack */
short states[MAXDEPTH]; /* state stack */
register short *yyps; /* pointer to state stack */
register short *act; /* pointer to performing action */
register int state; /* current parser state */
register int next_state;
register int token; /* current input token number */
register int i;
register int errorflag; /* error recovery flag */
state = 0;
token = -1;
errorflag = 0;
yyps = &states[-1];
yypv = &values[-1];
stack:
*++yyps = state; /* push state into state stack */
*++yypv = yyval; /* push value into value stack */
# ifdef RC_TRACE
if (TR_PARSE)
printf("STATE %d value %d char %d\n", state, yyval, token);
# endif
new_state:
/* set act to point to the parsing actions for the new state */
i = yypact[state + 1];
act = &yyact[i];
next_action: /* get the next action, and perform it */
next_state = ACTION(*act);
switch (OPERATION(*act++)) /* switch on operation */
{
case SKIP:
if (token < 0)
{
/* get next token */
token = rc_lex();
# ifdef RC_TRACE
if (TR_PARSE)
printf( "CHARACTER %d read\n", token);
# endif
}
if (next_state != token)
act++;
goto next_action; /* get next action */
case SHIFT: /* goto next_state */
state = next_state;
yyval = yylval; /* $i = value of last token */
token = -1;
if (errorflag)
errorflag--;
goto stack; /* stack new state and value */
case REDUCE: /* rule next_state */
# ifdef RC_TRACE
if (TR_PARSE)
printf("REDUCE %d\n", next_state);
# endif
yyps -= yyr2[next_state]; /* pop state stack */
yypv -= yyr2[next_state]; /* pop value stack */
yyval = yypv[1]; /* $$ = $1 */
if (Compile && yyactr(next_state))
goto abort;
/* consult goto table to find next state */
i = yyr1[next_state];
i = yypgo[i];
act = &yygo[i];
next_state = *yyps;
for ( ; *act != next_state && *act >= 0; act += 2)
continue;
state = act[1];
goto stack; /* stack new state and value */
case ACCEPT:
return (0);
case ERROR: /* attempt to resume parsing */
switch (errorflag)
{
case 0: /* brand new syntax error */
rc_error(0);
case 1: /* incompletely recovered error, try again */
errorflag = 2;
/* find a state where "error" is a legal SHIFT */
while (yyps >= states)
{
/* search yyps actions */
i = *yyps;
i = yypact[i + 1];
act = &yyact[i];
for ( ; OPERATION(*act) == SKIP; act += 2)
if (*act == SHIFT_ON_ERROR)
goto found;
/* the current yyps has no shift */
/* on "error", pop stack */
# ifdef RC_TRACE
if (TR_PARSE)
{
printf("ERROR recovery poyyps state %d",
yyps[0]);
printf(", uncovers %d\n", yyps[-1]);
}
# endif
yyps--;
yypv--;
}
/* there is no state on the stack */
/* with an error shift ... abort */
abort:
return (1);
found: /* we have a state with a shift on "error", resume parsing */
state = act[1] & 07777;
goto stack;
case 2: /* no shift yet; clobber input char */
# ifdef RC_TRACE
if (TR_PARSE)
printf("err recov discards char %d\n", token);
# endif
/* don't discard EOF; quit */
if (!token)
goto abort;
token = -1;
goto new_state; /* try again in the same state */
}
}
return (1);
}