Index: tool/lemon.c ================================================================== --- tool/lemon.c +++ tool/lemon.c @@ -3295,11 +3295,18 @@ PRIVATE int compute_action(struct lemon *lemp, struct action *ap) { int act; switch( ap->type ){ case SHIFT: act = ap->x.stp->statenum; break; - case SHIFTREDUCE: act = ap->x.rp->iRule + lemp->nstate; break; + case SHIFTREDUCE: { + act = ap->x.rp->iRule + lemp->nstate; + /* Since a SHIFT is inherient after a prior REDUCE, convert any + ** SHIFTREDUCE action with a nonterminal on the LHS into a simple + ** REDUCE action: */ + if( ap->sp->index>=lemp->nterminal ) act += lemp->nrule; + break; + } case REDUCE: act = ap->x.rp->iRule + lemp->nstate+lemp->nrule; break; case ERROR: act = lemp->nstate + lemp->nrule*2; break; case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break; default: act = -1; break; } Index: tool/lempar.c ================================================================== --- tool/lempar.c +++ tool/lempar.c @@ -706,23 +706,27 @@ }; assert( yyrulenoYY_MAX_SHIFT ){ - yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - } + + /* There are no SHIFTREDUCE actions on nonterminals because the table + ** generator has simplified them to pure REDUCE actions. */ + assert( !(yyact>YY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) ); + + /* It is not possible for a REDUCE to be followed by an error */ + assert( yyact!=YY_ERROR_ACTION ); + + if( yyact==YY_ACCEPT_ACTION ){ + yypParser->yytos -= yysize; + yy_accept(yypParser); + }else{ yymsp -= yysize-1; yypParser->yytos = yymsp; yymsp->stateno = (YYACTIONTYPE)yyact; yymsp->major = (YYCODETYPE)yygoto; yyTraceShift(yypParser, yyact); - }else{ - assert( yyact == YY_ACCEPT_ACTION ); - yypParser->yytos -= yysize; - yy_accept(yypParser); } } /* ** The following code executes when the parse fails