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