187 lines
4.2 KiB
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);
|
|
}
|