On 8/16/16, xiaobing <jingxiaob...@gmail.com> wrote:
> 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.

Excellent analysis, Xiaobing.  Thanks.

I have checked in a slightly different fix.  Please confirm that what
I have checked in actually fixes your problem.
https://www.sqlite.org/src/fdiff?dc=20&v1=e3aa9ba3469804d7&v2=e4fb7d888873ac88


>
> 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
>


-- 
D. Richard Hipp
d...@sqlite.org
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to