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 */ 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 = lex(); 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 */ yyps -= yyr2[next_state]; /* pop state stack */ yypv -= yyr2[next_state]; /* pop value stack */ yyval = yypv[1]; /* $$ = $1 */ if (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 */ amxerror(88); 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 */ 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 = ACTION(act[1]); goto stack; case 2: /* no shift yet; clobber input char */ /* don't discard EOF; quit */ if (!token) goto abort; token = -1; goto new_state; /* try again in the same state */ } } /*NOTREACHED*/ }
/* * This routine parses the input stream, and * returns if it accepts, or if an unrecoverable syntax * error is encountered. */ yyparse() { register int *ps, n, *p; int paniced, *panicps, idfail; yystate = 0; yychar = yylex(); OY.Yychar = -1; yyshifts = 3; paniced = 0; ps = &yys[0]-1; yypv = &yyv[0]-1; #ifdef PXP yypw = &yyw[0]-1; #endif stack: /* * Push new state and value. */ if (yypv >= &yyv[MAXDEPTH-1]) { yerror("Parse stack overflow"); pexit(DIED); } *++ps = yystate; *++yypv = yyval; #ifdef PXP yypw++; #endif newstate: /* * Locate parsing actions for the * new parser state. */ p = &yyact[ yypact[yystate+1] ]; actn: /* * Search the parse actions table * for something useful to do. * While n is non-positive, it is the negation * of the token we are testing for. */ #ifdef PI if ((n = *p++) <= 0) { if (yychar < 0) yychar = yylex(); do if ((n += yychar) != 0) p++; while ((n = *p++) <= 0); } #else while ((n = *p++) <= 0) if ((n += yychar) != 0) p++; #endif switch (n >> 12) { /* * Shift. */ case 2: #ifdef PXP yypw[1].Wseqid = yyseqid; yypw[1].Wcol = yycol; #endif OYcopy(); yystate = n & 07777; yyval = yylval; #ifdef PI yychar = -1; #else yychar = yylex(); #endif yyshifts++; yytshifts++; goto stack; /* * Reduce. */ case 3: n &= 07777; N = yyr2[n]; if (N == 1 && OY.Yychar == YID && !yyEactr(n, yypv[0])) { idfail = 1; goto errin; } OY.Yychar = -1; ps -= N; yypv -= N; #ifdef PXP yypw -= N; #endif yyval = yypv[1]; yyactr(n); /* * Use goto table to find next state. */ p = &yygo[yypgo[yyr1[n]]]; while (*p != *ps && *p >= 0) p += 2; yystate = p[1]; goto stack; /* * Accept. */ case 4: return; /* * Error. */ case 1: idfail = 0; errin: if ((paniced || yyshifts != 0) && yyrecover(ps, idfail)) { paniced = 0; ps = Ps; yystate = *ps; goto newstate; } /* * Find a state where 'error' is a * legal shift action. */ if (paniced && yyshifts <= 0 && ps >= panicps) { yypv -= (ps - panicps) + 1; #ifdef PXP yypw -= (ps - panicps) + 1; #endif ps = panicps - 1; } while (ps >= yys) { for (p = &yyact[ yypact[*ps+1] ] ; *p <= 0; p += 2) if (*p == -256) { panicps = ps; yystate= p[1] & 07777; yyOshifts = yyshifts; yyshifts = 0; paniced = 1; goto stack; } --ps; --yypv; #ifdef PXP --yypw; #endif #ifdef PI if (OY.Yychar != YID) syneflg = TRUE; #endif OY.Yychar = -1; } if (yychar == YEOF) yyunexeof(); if (yystate == 1) yyexeof(); yerror("Unrecoverable syntax error - QUIT"); return; } panic("yyparse"); }
yyparse() { extern int yygo[], yypgo[], yyr1[], yyr2[], yyact[], yypact[]; auto int *ps, s[_maxdepth]; auto int ac, n, *p; yystate = 0; yychar = -1; yynerrs = 0; yyerrflag = 0; ps= &s[0]-1; yypv= &yyv[0]-1; stack: /* put a state and value onto the stack */ if( yydebug ) printf( "state %d, value %d, char %d\n",yystate,yyval,yychar ); *++ps = yystate; *++yypv = yyval; newstate: /* set ap to point to the parsing actions for the new state */ p = &yyact[ yypact[yystate+1] ]; actn: /* get the next action, and perform it */ n = ( ac = *p++ ) & 07777; /* n is the "address" of the action */ switch( ac>>12 ) { /* switch on operation */ case 1: /* skip on test */ if( yydebug && (yychar<0) ){ yychar = yylex(); printf( "character %d read\n", yychar ); } if( n != ( (yychar<0) ? ( yychar=yylex() ) : yychar ) ) ++p; goto actn; /* get next action */ case 2: /* shift */ yystate=n; yyval=yylval; yychar= -1; if( yyerrflag ) --yyerrflag; goto stack; /* stack new state */ case 3: /* reduce */ if( yydebug ) printf("reduce %d\n",n); ps =- yyr2[n]; yypv =- yyr2[n]; yyval=yypv[1]; yyactr(n); /* consult goto table to find next state */ for( p= &yygo[yypgo[yyr1[n]]]; *p != *ps && *p >= 0 ; p =+ 2 ) ; yystate = p[1]; goto stack; /* stack new state and value */ case 4: /* accept */ return(0); case 0: /* 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 ( ps >= s ) { for( p= &yyact[ yypact[*ps+1] ] ; (*p>>12) == 1 ; p =+ 2 ) /* search ps actions */ if( *p == 4352 ) goto found; /* the current ps has no shift onn "error", pop stack */ if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *ps, ps[-1] ); --ps; --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 */ yystate = p[1] & 07777; goto stack; 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 newstate; /* try again in the same state */ } } }