I believe the lemon reduce action optimizer needs to compare the codePrefix and codeSuffix. Consider this example:
----8<---- %type malloc {void *} %destructor malloc {free($$)} %type contrived_example {int} bug_report ::= contrived_example. contrived_example(LHS) ::= INT INT INT. { LHS = 0; } contrived_example(LHS) ::= malloc malloc malloc. { LHS = 0; } malloc(LHS) ::= . { LHS = malloc(100); } ----8<---- Since the code (but not the codeSuffix) matches, they will be merged together into this: case 0: /* contrived_example ::= INT INT INT */ case 1: /* contrived_example ::= malloc malloc malloc */ yytestcase(yyruleno==1); #line 8 "bug.lemon" { yymsp[-2].minor.yy4 = 0; } #line 725 "bug.c" break; or this: /********** Begin reduce actions **********************************************/ case 0: /* contrived_example ::= malloc malloc malloc */ case 1: /* contrived_example ::= INT INT INT */ yytestcase(yyruleno==1); { yy_destructor(yypParser,3,&yymsp[-2].minor); #line 8 "bug.lemon" { yymsp[-2].minor.yy4 = 0; } #line 726 "bug.c" yy_destructor(yypParser,3,&yymsp[-1].minor); yy_destructor(yypParser,3,&yymsp[0].minor); } break; depending on which rule is first. patch: diff --git a/lemon.c b/lemon.c index 903fe97..dca5a08 100644 --- a/lemon.c +++ b/lemon.c @@ -4402,7 +4402,11 @@ void ReportTable( writeRuleText(out, rp); fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ + if( + rp2->code==rp->code && + rp2->codePrefix==rp->codePrefix && + rp2->codeSuffix==rp->codeSuffix + ){ fprintf(out," case %d: /* ", rp2->iRule); writeRuleText(out, rp2); fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++; Thanks, Kelvin Sherlock