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
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users