#
# define YYFLAG1 -1000
# define YYFLAG2 -2000

/* test me on cases where there are more than one reduction
per state, leading to the necessity to look ahead, and other
arcane flows of control.
*/
# define YYMAXDEPTH 150

/*	parser for yacc output	*/
extern int yyval; /* defined in the table file */
extern int yylval; /* defined in the table file */
extern int *yypv; /* defined in the table file */


int yydebug 0; /* 1 for debugging */
int yyv[YYMAXDEPTH]; /* where the values are stored */
int yychar -1; /* current input token number */
int yynerrs 0;  /* number of errors */
int yyerrflag 0;  /* error recovery flag */


yyparse() {

   extern int yypgo[], yyr1[], yyr2[], yyact[], yypact[];
   extern int yydef[], yychk[];
   extern int yylast, yyerrval;
   int yys[YYMAXDEPTH];
   int yyj;
   register yyn, yystate, *yyps;

   yystate = 0;
   yychar = -1;
   yynerrs = 0;
   yyerrflag = 0;
   yyps= &yys[0]-1;
   yypv= &yyv[0]-1;

 yystack:    /* put a state and value onto the stack */

   if( yydebug  ) printf( "state %d, value %d, char %d\n",yystate,yyval,yychar );
   *++yyps = yystate;
   *++yypv = yyval;

 yynewstate:

   yyn = yypact[yystate];

   if( yyn<= YYFLAG1 ){ /* simple state */
      if( yyn == YYFLAG2 && yychar<0 ) yychar = yylex();
      goto yydefault;
      }

   if( yychar<0 ) yychar = yylex();
   if( (yyn =+ yychar)<0 || yyn >= yylast ) goto yydefault;

   if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */
      yychar = -1;
      yyval = yylval;
      yystate = yyn;
      if( yyerrflag > 0 ) --yyerrflag;
      goto yystack;
      }

 yydefault:
   /* default state action */

   if( (yyn=yydef[yystate]) == -2 ) yyn = yyexcp( yystate );

  if( yyn == -1 ){ /* accept */
      return( 0 );
      }

   if( yyn == 0 ){ /* error */
      /* error ... attempt to resume parsing */

      switch( yyerrflag ){

      case 0:   /* brand new error */

         ++yynerrs;
         yyerror( "syntax error" );

      case 1:
      case 2: /* incompletely recovered error ... try again */

         yyerrflag = 3;

         /* find a state where "error" is a legal shift action */

         while ( yyps >= yys ) {
            yyn = yypact[*yyps] + yyerrval;
            if( yyn>= 0 && yyn < yylast && yychk[yyact[yyn]] == yyerrval ){
               yystate = yyact[yyn];  /* simulate a shift of "error" */
               goto yystack;
               }
            yyn = yypact[*yyps];

            /* the current yyps has no shift onn "error", pop stack */

            if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] );
            --yyps;
            --yypv;
            }

         /* there is no state on the stack with an error shift ... abort */

    abort:
         return(1);


      case 3:  /* no shift yet; clobber input char */

         if( yydebug ) printf( "error recovery discards char %d\n", yychar );

         if( yychar == 0 ) goto abort; /* don't discard EOF, quit */
         yychar = -1;
         goto yynewstate;   /* try again in the same state */

         }

      }

   /* reduction by production yyn */

      if( yydebug ) printf("reduce %d\n",yyn);
      yyps =- yyr2[yyn];
      yypv =- yyr2[yyn];
      yyval=yypv[1];
      yyactr(yyn);
         /* consult goto table to find next state */
      yyn = yyr1[yyn];
      yyj = yypgo[yyn] + *yyps + 1;
      if( yyj>=yylast || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]];
      goto yystack;  /* stack new state and value */

   }
