In lemon.c:ReportTable() , when " Combine duplicate destructors into a
single case ", sp2->destructor is set to 0, but later it is used in
tranlate_code to generate destructor.
so if you have grammar like this:
    %destructor expr_a { expr_free($$); }
    %destructor expr_b { expr_free($$); }  // this one will be lost, unless
you insert some comment so strcmp return nonzero
    expr ::= expr_a expr_b.
the generated code will include destructor of expr_a, however, destructor
of expr_b will be lost.

Here is my patch to lemon.c:

--- old/lemon.c 2016-05-18 18:07:00.000000000 +0800
+++ new/lemon.c       2016-08-16 20:57:36.799178091 +0800
@@ -263,6 +263,7 @@
   int useCnt;              /* Number of times used */
   char *destructor;        /* Code which executes whenever this symbol is
                            ** popped from the stack during error
processing */
+  int destructor_emitted;  /* Is the destructor code emitted */
   int destLineno;          /* Line number for start of destructor */
   char *datatype;          /* The data type of information held by this
                            ** object. Only used if type==NONTERMINAL */
@@ -4351,8 +4352,9 @@
   }
   for(i=0; i<lemp->nsymbol; i++){
     struct symbol *sp = lemp->symbols[i];
-    if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
+    if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ||
sp->destructor_emitted) continue;
     fprintf(out,"    case %d: /* %s */\n", sp->index, sp->name); lineno++;
+    sp->destructor_emitted = 1;

     /* Combine duplicate destructors into a single case */
     for(j=i+1; j<lemp->nsymbol; j++){
@@ -4362,7 +4364,7 @@
           && strcmp(sp->destructor,sp2->destructor)==0 ){
          fprintf(out,"    case %d: /* %s */\n",
                  sp2->index, sp2->name); lineno++;
-         sp2->destructor = 0;
+         sp2->destructor_emitted = 1;
       }
     }

@@ -4876,6 +4878,7 @@
     sp->firstset = 0;
     sp->lambda = LEMON_FALSE;
     sp->destructor = 0;
+    sp->destructor_emitted = 0;
     sp->destLineno = 0;
     sp->datatype = 0;
     sp->useCnt = 0;
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to