> On Apr 29, 2016, at 7:29 AM, Richard Hipp wrote:
>
> On 4/28/16, Kelvin Sherlock wrote:
>> I believe the lemon reduce action optimizer needs to compare the codePrefix
>> and codeSuffix.
>
> Thanks for the bug report. A fix has now been checked in.
>
> --
> D. Richard Hipp
> drh at sqlite.org
Here are a couple more edge cases I noticed:
---
bug_report ::= rule.
%destructor malloc{free($$)}
rule ::= .
rule ::= malloc . /* 1 */
rule ::= malloc malloc . /* 2 */
malloc(X) ::= ID . { X = malloc(100); }
---
1. the rhs[0] destructor will not be called since the lhsalias null check
happens first and the codePrefix is never generated.
The empty lhsalias check can be moved down to compensate:
@@ -3552,30 +3552,30 @@ PRIVATE int translate_code(struct lemon *lemp, struct
rule *rp){
if( rp->code==0 ){
static char newlinestr[2] = { '\n', '\0' };
rp->code = newlinestr;
rp->line = rp->ruleline;
}
- if( rp->lhsalias==0 ){
-/* There is no LHS value symbol. */
-lhsdirect = 1;
- }else if( rp->nrhs==0 ){
+ if( rp->nrhs==0 ){
/* If there are no RHS symbols, then writing directly to the LHS is ok */
lhsdirect = 1;
}else if( rp->rhsalias[0]==0 ){
/* The left-most RHS symbol has not value. LHS direct is ok. But
** we have to call the distructor on the RHS symbol first. */
lhsdirect = 1;
if( has_destructor(rp->rhs[0],lemp) ){
append_str(0,0,0,0);
append_str(" yy_destructor(yypParser,%d,[%d].minor);\n", 0,
rp->rhs[0]->index,1-rp->nrhs);
rp->codePrefix = Strsafe(append_str(0,0,0,0));
}
+ }else if( rp->lhsalias==0 ){
+/* There is no LHS value symbol. */
+lhsdirect = 1;
}else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
/* The LHS symbol and the left-most RHS symbol are the same, so
** direct writing is allowed */
lhsdirect = 1;
lhsused = 1;
used[0] = 1;
2. if there is a codePrefix or codeSuffix but no code, it will be merged into
the default rule and the prefix/suffix will be lost.
@@ -3715,7 +3715,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct
rule *rp){
/* Suffix code generation complete */
cp = append_str(0,0,0,0);
- if( cp ) rp->codeSuffix = Strsafe(cp);
+ if( cp && cp[0] ) rp->codeSuffix = Strsafe(cp);
return rc;
}
@@ -4397,7 +4397,8 @@ void ReportTable(
for(rp=lemp->rule; rp; rp=rp->next){
struct rule *rp2; /* Other rules with the same action */
if( rp->code==0 ) continue;
-if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */
+if( rp->code[0]=='\n' && rp->code[1]==0 && rp->codePrefix==0
+ && rp->codeSuffix==0 ) continue; /* Will be default: */
fprintf(out," case %d: /* ", rp->iRule);
writeRuleText(out, rp);
fprintf(out, " */\n"); lineno++;
@@ -4419,7 +4420,8 @@ void ReportTable(
fprintf(out," default:\n"); lineno++;
for(rp=lemp->rule; rp; rp=rp->next){
if( rp->code==0 ) continue;
-assert( rp->code[0]=='\n' && rp->code[1]==0 );
+assert( rp->code[0]=='\n' && rp->code[1]==0 && rp->codePrefix==0
+ && rp->codeSuffix==0 );
fprintf(out," /* (%d) ", rp->iRule);
writeRuleText(out, rp);
fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++;
Thanks,
Kelvin