/* yaccpar	19-Dec-86	Parser to interpret yacc output tables */
/* 14-May-88 */

#ifndef YYDEBUG
#define YYDEBUG		1	/* debugging is available, but not on yet */
#endif

#ifndef YYFULLERR
#define YYFULLERR 	0	/* full error messages are not available */
#endif

#ifndef YYUNION
#define YYUNION 	0	/* 0 == C compiler supports union assignment */
#endif

#if YYDEBUG
#define YYDESC	1
#else
#if YYFULLERR
#define YYDESC	1
#endif /* YYFULLERR */
#endif /* YYDEBUG */

#if YYDEBUG
static int yyyylex();	/* !!! */
#else
#define yyyylex()	yylex()
#endif

static void yygetchar();

#if YYDESC
static char *yydesc();
#endif

#if YYFULLERR
static void yyterror();
#endif

#if YYUNION
#define _yyassign(to,from)	yyunion(&to,&from)
#else
#define	_yyassign(to,from)	(to=from)
#endif

#define YYFLAG		(-1000)
#define YYERROR		goto yyerrlab
#define YYACCEPT	return(0)
#define YYABORT		return(1)

#if YYDEBUG
int	yydebug=0;		/* set to 1 to turn on debugging */
#endif

YYSTYPE yyvalue[YYMAXDEPTH];	/* parser value stack */
int yystack[YYMAXDEPTH];	/* parser state stack */
int yychar=(-1);		/* current input token (-1 == none) */
int yynerrs=0;			/* number of errors */
int yyerrflag=0;		/* error recovery in progress */

yyparse()
{
    int yystate;
    int *yypstack;
    YYSTYPE *yypvalue;
    int yyindex;
    int *yyxi;
    int yypush;

    yystate=0;
    yychar=(-1);
    yynerrs=0;
    yyerrflag=0;
    yypstack= &yystack[-1];	/* beware of old assignment operators !!! */
    yypvalue= &yyvalue[-1];
    yypush=1;

    for (;;) {
	if (yypush) {		/* put a state and value onto the stack */
#if YYDEBUG
	    if (yydebug)
		printf("[yydebug] state %d, token %s\n",
		    yystate,yydesc(yychar,yytoks));
#endif
	    if (++yypstack > &yystack[YYMAXDEPTH]) {
		yyerror("yacc stack overflow");
		YYABORT;
	    }
	    *yypstack=yystate;
	    ++yypvalue;
	    _yyassign(*yypvalue,yyval);
	}

	yyindex=yypact[yystate];
	if (yyindex>YYFLAG
	  && (yygetchar(),
	       (yyindex+= yychar) >= 0 && yyindex < YYLAST
               && yychk[ yyindex=yyact[ yyindex ] ] == yychar
	     )
          ) {			/* valid shift */
	    yychar=(-1);
	    _yyassign(yyval,yylval);
	    yystate=yyindex;
	    if (yyerrflag > 0) --yyerrflag;
	    yypush=1;
	}
	else {			/* default state action */
	    if ( (yyindex=yydef[yystate]) == -2 ) {
		yygetchar();
		/* look through exception table */
#if YYDEBUG
		if (yydebug)
		    printf("[yydebug] on lookahead %s\n",
			yydesc(yychar,yytoks));
#endif
		for (yyxi=yyexca; (*yyxi!=(-1))||(yyxi[1]!=yystate); yyxi+=2);
		for (yyxi+=2; *yyxi >= 0 && *yyxi != yychar; yyxi+=2);
		if ((yyindex=yyxi[1]) < 0) {
#if YYDEBUG
		    if (yydebug) printf("[yydebug] accept\n");
#endif
		    YYACCEPT;
		}
	    }

	    if (yyindex == 0) {	/* error ... attempt to resume parsing */
		switch(yyerrflag) {
		    case 0:	/* brand new error */
#if YYFULLERR
			yyindex=yypact[yystate];
			if (yyindex>YYFLAG && yyindex<YYLAST) {
			    int token,index;
			    for (index=(yyindex>0)?yyindex:0;
			      index<YYLAST; ++index) {
				token=index-yyindex;
				if (yychk[yyact[index]] == token
				  && token != YYERRCODE) {
				    yyterror(yydesc(token,yytoks));
				}
			    }
			}
			yyterror(NULL);
#else
			yyerror("syntax error");
#endif
yyerrlab:
			++yynerrs;
		    case 1:
		    case 2:	/* incompletely recovered error */
			yyerrflag=3;
	/* find a state where "error" is a legal shift action */
			yypush=0;	/* use as local flag */
			while(yypstack >= yystack) {
			    yyindex=yypact[*yypstack] +YYERRCODE;
			    if ( yyindex>=0 && yyindex<YYLAST
			      && yychk[yyact[yyindex]] == YYERRCODE) {
				yystate=yyact[yyindex];	/* shift error */
				yypush=1;
				break;			/* ... out of loop */
			    }
			    else {		/* no shift on error */
#if YYDEBUG
				if (yydebug) printf(
		"[yydebug] error recovery pops state %d, uncovers %d\n",
					*yypstack,yypstack[-1]);
#endif
				--yypstack;		/* pop stack */
				--yypvalue;
			    }
			}
			if (!yypush)	/* no error shift state on stack */
			    YYABORT;

			break;		/* else stack error state */

		    case 3:		/* no shift yet; discard input char */
#if YYDEBUG
			if (yydebug)
			    printf("[yydebug] error recovery discards %s\n",
				yydesc(yychar,yytoks));
#endif
			if (yychar == 0) YYABORT;	/* don't discard EOF */
			yychar=(-1);
			yypush=0;	/* try again in SAME state */
		}
	    }
	    else {		/* reduction by production yyindex */
		YYSTYPE *yypvt;
		int yynont;
		int yyrule;

		yyrule=yyindex;
#if YYDEBUG
		if (yydebug)
		    printf("[yydebug] reduce by (%d) \"%s\"\n",
			yyrule,yyreds[yyrule]);
#endif
		yypstack -= yyr2[yyrule];
		yypvt=yypvalue;
		yypvalue -= yyr2[yyrule];
		_yyassign(yyval,yypvalue[1]);
		/* consult goto table to find next state */
		yynont=yyr1[yyrule];
		yyindex=yypgo[yynont] + *yypstack + 1;
		if (yyindex>=YYLAST
		  || yychk[yystate=yyact[yyindex]] != -yynont)
		    yystate=yyact[yypgo[yynont]];
		switch(yyrule) {
		    $A
		}
		yypush=1;	/* stack new state and value */
	    }
	}
    }
}


static void
yygetchar()
{
    if (yychar < 0) if ((yychar=yyyylex()) < 0) yychar=0;
}

#if YYDEBUG

static int
yyyylex()
{
    int ch;

    ch=yylex();
    if (yydebug)
	printf("[yydebug] received token %s\n",yydesc(ch,yytoks));
    return ch;
}

#endif /* YYDEBUG */

#if YYDESC

static char *
yydesc(ch,table)
int ch;
yytoktype *table;
{
    register yytoktype *p;
    char *s;

    if (ch == 0)
	s="end-of-file";
    else if (ch < 0)
	s="-none-";
    else {
	for (p=table; p->t_val != ch && p->t_val >= 0; ++p);
	s=p->t_name;
    }
    return s;
}

#endif /* YYDESC */


