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