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

Reply via email to