Lemon collapses common destructors and reduce actions into a single case. (CVS 1837)
FossilOrigin-Name: 3c5aa850eeec5c75c5200a3707852cc5fc9e780b
This commit is contained in:
parent
6d08b4d647
commit
0bb132bedc
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\sthe\s'%ifdef'\scapability\sto\slemon.\s\sOther\sminor\schanges.\s(CVS\s1836)
|
C Lemon\scollapses\scommon\sdestructors\sand\sreduce\sactions\sinto\sa\ssingle\scase.\s(CVS\s1837)
|
||||||
D 2004-07-20T12:45:22
|
D 2004-07-20T14:06:52
|
||||||
F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
|
F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@ -47,13 +47,13 @@ F src/os_mac.c 3d31e26be1411acfb7961033098631b4f3486fdf
|
|||||||
F src/os_mac.h 51d2445f47e182ed32d3bd6937f81070c6fd9bd4
|
F src/os_mac.h 51d2445f47e182ed32d3bd6937f81070c6fd9bd4
|
||||||
F src/os_test.c 6bf10100de2ca199a91fe7ac6474561c8a7166ae
|
F src/os_test.c 6bf10100de2ca199a91fe7ac6474561c8a7166ae
|
||||||
F src/os_test.h 6a26a4978492e4bbdbf385554958418ff02db162
|
F src/os_test.h 6a26a4978492e4bbdbf385554958418ff02db162
|
||||||
F src/os_unix.c ee607890d9062b51e27de56e9cb14a7f5a598d8c
|
F src/os_unix.c 02a08065f90ca2737514cdc19d60eb3c4b98fa6b
|
||||||
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
|
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
|
||||||
F src/os_win.c 54181eb73cb4783c4241feca9eaa490768b39008
|
F src/os_win.c 54181eb73cb4783c4241feca9eaa490768b39008
|
||||||
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
|
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
|
||||||
F src/pager.c 53a310a7539c7550dc7cbad8e46c62926a40fb31
|
F src/pager.c 53a310a7539c7550dc7cbad8e46c62926a40fb31
|
||||||
F src/pager.h 269b6cfc114dba0148203446e41dd19f9647dd53
|
F src/pager.h 269b6cfc114dba0148203446e41dd19f9647dd53
|
||||||
F src/parse.y 51c8e696276c409618e66a4ccf316fcff245506e
|
F src/parse.y 1c22ccb2b60237a7263873892a4d580ea5e53536
|
||||||
F src/pragma.c 8326df8c400f573eb43004dfb8e53e5102acb3e4
|
F src/pragma.c 8326df8c400f573eb43004dfb8e53e5102acb3e4
|
||||||
F src/printf.c 36090f6d7b4946539de97c1850675ce55ef66c16
|
F src/printf.c 36090f6d7b4946539de97c1850675ce55ef66c16
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||||
@ -185,7 +185,7 @@ F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
|||||||
F test/view.test ca5c296989d3045f121be9a67588ff88c64874a8
|
F test/view.test ca5c296989d3045f121be9a67588ff88c64874a8
|
||||||
F test/where.test 9c5752b807b78078fab8da6f52e689832579ca20
|
F test/where.test 9c5752b807b78078fab8da6f52e689832579ca20
|
||||||
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||||
F tool/lemon.c b771c5147d0e7eb3240f5be754deb5c87d0aae6a
|
F tool/lemon.c 9ebd2cae1a1b7ab9786e54772413954a4210b2a5
|
||||||
F tool/lempar.c 0b5e7a58634e0d448929b8e85f7981c2aa708d57
|
F tool/lempar.c 0b5e7a58634e0d448929b8e85f7981c2aa708d57
|
||||||
F tool/memleak.awk b744b6109566206c746d826f6ecdba34662216bc
|
F tool/memleak.awk b744b6109566206c746d826f6ecdba34662216bc
|
||||||
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
|
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
|
||||||
@ -237,7 +237,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
|
|||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 826b6797a9f08c69b9378cb403d746e91a54dcde
|
P 522ff721ccc33c4b89072fed4e451f0df82e8140
|
||||||
R 81fe5ff7dba086ebc8b9e46590e3934b
|
R e671edd7c958b648f09895c28b19b648
|
||||||
U drh
|
U drh
|
||||||
Z b94ed056d995c2892f36ab8ddb7dedb9
|
Z 365b5316c2e2676737e040bedd0d4f8a
|
||||||
|
@ -1 +1 @@
|
|||||||
522ff721ccc33c4b89072fed4e451f0df82e8140
|
3c5aa850eeec5c75c5200a3707852cc5fc9e780b
|
@ -61,7 +61,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "os_common.h"
|
#include "os_common.h"
|
||||||
|
|
||||||
#if defined(THREADSAFE) && defined(__linux__)
|
#if defined(THREADSAFE) && THREADSAFE && defined(__linux__)
|
||||||
#define getpid pthread_self
|
#define getpid pthread_self
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.129 2004/06/30 09:49:24 danielk1977 Exp $
|
** @(#) $Id: parse.y,v 1.130 2004/07/20 14:06:52 drh Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
@ -831,11 +831,11 @@ foreach_clause(A) ::= . { A = TK_ROW; }
|
|||||||
foreach_clause(A) ::= FOR EACH ROW. { A = TK_ROW; }
|
foreach_clause(A) ::= FOR EACH ROW. { A = TK_ROW; }
|
||||||
foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }
|
foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }
|
||||||
|
|
||||||
%type when_clause {Expr *}
|
%type when_clause {Expr*}
|
||||||
when_clause(A) ::= . { A = 0; }
|
when_clause(A) ::= . { A = 0; }
|
||||||
when_clause(A) ::= WHEN expr(X). { A = X; }
|
when_clause(A) ::= WHEN expr(X). { A = X; }
|
||||||
|
|
||||||
%type trigger_cmd_list {TriggerStep *}
|
%type trigger_cmd_list {TriggerStep*}
|
||||||
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep($$);}
|
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep($$);}
|
||||||
trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
|
trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
|
||||||
X->pNext = Y;
|
X->pNext = Y;
|
||||||
@ -843,7 +843,7 @@ trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
|
|||||||
}
|
}
|
||||||
trigger_cmd_list(A) ::= . { A = 0; }
|
trigger_cmd_list(A) ::= . { A = 0; }
|
||||||
|
|
||||||
%type trigger_cmd {TriggerStep *}
|
%type trigger_cmd {TriggerStep*}
|
||||||
%destructor trigger_cmd {sqlite3DeleteTriggerStep($$);}
|
%destructor trigger_cmd {sqlite3DeleteTriggerStep($$);}
|
||||||
// UPDATE
|
// UPDATE
|
||||||
trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).
|
trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).
|
||||||
|
190
tool/lemon.c
190
tool/lemon.c
@ -2999,6 +2999,115 @@ struct lemon *lemp;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Append text to a dynamically allocated string. If zText is 0 then
|
||||||
|
** reset the string to be empty again. Always return the complete text
|
||||||
|
** of the string (which is overwritten with each call).
|
||||||
|
*/
|
||||||
|
PRIVATE char *append_str(char *zText, int n, int p1, int p2){
|
||||||
|
static char *z = 0;
|
||||||
|
static int alloced = 0;
|
||||||
|
static int used = 0;
|
||||||
|
int i, c;
|
||||||
|
char zInt[40];
|
||||||
|
|
||||||
|
if( zText==0 ){
|
||||||
|
used = 0;
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
if( n<=0 ) n = strlen(zText);
|
||||||
|
if( n+sizeof(zInt)*2+used >= alloced ){
|
||||||
|
alloced = n + sizeof(zInt)*2 + used + 200;
|
||||||
|
z = realloc(z, alloced);
|
||||||
|
}
|
||||||
|
if( z==0 ) return "";
|
||||||
|
while( n-- > 0 ){
|
||||||
|
c = *(zText++);
|
||||||
|
if( c=='%' && zText[0]=='d' ){
|
||||||
|
sprintf(zInt, "%d", p1);
|
||||||
|
p1 = p2;
|
||||||
|
strcpy(&z[used], zInt);
|
||||||
|
used += strlen(&z[used]);
|
||||||
|
zText++;
|
||||||
|
n--;
|
||||||
|
}else{
|
||||||
|
z[used++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
z[used] = 0;
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** zCode is a string that is the action associated with a rule. Expand
|
||||||
|
** the symbols in this string so that the refer to elements of the parser
|
||||||
|
** stack. Return a new string stored in space obtained from malloc.
|
||||||
|
*/
|
||||||
|
PRIVATE char *translate_code(struct lemon *lemp, struct rule *rp){
|
||||||
|
char *cp, *xp;
|
||||||
|
int i;
|
||||||
|
char lhsused = 0; /* True if the LHS element has been used */
|
||||||
|
char used[MAXRHS]; /* True for each RHS element which is used */
|
||||||
|
|
||||||
|
for(i=0; i<rp->nrhs; i++) used[i] = 0;
|
||||||
|
lhsused = 0;
|
||||||
|
|
||||||
|
append_str(0,0,0,0);
|
||||||
|
for(cp=rp->code; *cp; cp++){
|
||||||
|
if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
|
||||||
|
char saved;
|
||||||
|
for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
|
||||||
|
saved = *xp;
|
||||||
|
*xp = 0;
|
||||||
|
if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
|
||||||
|
append_str("yygotominor.yy%d",-1,rp->lhs->dtnum,0);
|
||||||
|
cp = xp;
|
||||||
|
lhsused = 1;
|
||||||
|
}else{
|
||||||
|
for(i=0; i<rp->nrhs; i++){
|
||||||
|
if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){
|
||||||
|
append_str("yymsp[%d].minor.yy%d",-1,
|
||||||
|
i-rp->nrhs+1,rp->rhs[i]->dtnum);
|
||||||
|
cp = xp;
|
||||||
|
used[i] = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*xp = saved;
|
||||||
|
}
|
||||||
|
append_str(cp, 1, 0, 0);
|
||||||
|
} /* End loop */
|
||||||
|
|
||||||
|
/* Check to make sure the LHS has been used */
|
||||||
|
if( rp->lhsalias && !lhsused ){
|
||||||
|
ErrorMsg(lemp->filename,rp->ruleline,
|
||||||
|
"Label \"%s\" for \"%s(%s)\" is never used.",
|
||||||
|
rp->lhsalias,rp->lhs->name,rp->lhsalias);
|
||||||
|
lemp->errorcnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate destructor code for RHS symbols which are not used in the
|
||||||
|
** reduce code */
|
||||||
|
for(i=0; i<rp->nrhs; i++){
|
||||||
|
if( rp->rhsalias[i] && !used[i] ){
|
||||||
|
ErrorMsg(lemp->filename,rp->ruleline,
|
||||||
|
"Label %s for \"%s(%s)\" is never used.",
|
||||||
|
rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
|
||||||
|
lemp->errorcnt++;
|
||||||
|
}else if( rp->rhsalias[i]==0 ){
|
||||||
|
if( has_destructor(rp->rhs[i],lemp) ){
|
||||||
|
append_str(" yy_destructor(%d,&yymsp[%d].minor);\n", -1,
|
||||||
|
rp->rhs[i]->index,i-rp->nrhs+1);
|
||||||
|
}else{
|
||||||
|
/* No destructor defined for this term */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cp = append_str(0,0,0,0);
|
||||||
|
rp->code = Strsafe(cp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate code which executes when the rule "rp" is reduced. Write
|
** Generate code which executes when the rule "rp" is reduced. Write
|
||||||
** the code to "out". Make sure lineno stays up-to-date.
|
** the code to "out". Make sure lineno stays up-to-date.
|
||||||
@ -3009,74 +3118,20 @@ struct rule *rp;
|
|||||||
struct lemon *lemp;
|
struct lemon *lemp;
|
||||||
int *lineno;
|
int *lineno;
|
||||||
{
|
{
|
||||||
char *cp, *xp;
|
char *cp;
|
||||||
int linecnt = 0;
|
int linecnt = 0;
|
||||||
int i;
|
|
||||||
char lhsused = 0; /* True if the LHS element has been used */
|
|
||||||
char used[MAXRHS]; /* True for each RHS element which is used */
|
|
||||||
|
|
||||||
for(i=0; i<rp->nrhs; i++) used[i] = 0;
|
|
||||||
lhsused = 0;
|
|
||||||
|
|
||||||
/* Generate code to do the reduce action */
|
/* Generate code to do the reduce action */
|
||||||
if( rp->code ){
|
if( rp->code ){
|
||||||
fprintf(out,"#line %d \"%s\"\n{",rp->line,lemp->filename);
|
fprintf(out,"#line %d \"%s\"\n{",rp->line,lemp->filename);
|
||||||
|
fprintf(out,"%s",rp->code);
|
||||||
for(cp=rp->code; *cp; cp++){
|
for(cp=rp->code; *cp; cp++){
|
||||||
if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
|
|
||||||
char saved;
|
|
||||||
for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
|
|
||||||
saved = *xp;
|
|
||||||
*xp = 0;
|
|
||||||
if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
|
|
||||||
fprintf(out,"yygotominor.yy%d",rp->lhs->dtnum);
|
|
||||||
cp = xp;
|
|
||||||
lhsused = 1;
|
|
||||||
}else{
|
|
||||||
for(i=0; i<rp->nrhs; i++){
|
|
||||||
if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){
|
|
||||||
fprintf(out,"yymsp[%d].minor.yy%d",i-rp->nrhs+1,rp->rhs[i]->dtnum);
|
|
||||||
cp = xp;
|
|
||||||
used[i] = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*xp = saved;
|
|
||||||
}
|
|
||||||
if( *cp=='\n' ) linecnt++;
|
if( *cp=='\n' ) linecnt++;
|
||||||
fputc(*cp,out);
|
|
||||||
} /* End loop */
|
} /* End loop */
|
||||||
(*lineno) += 3 + linecnt;
|
(*lineno) += 3 + linecnt;
|
||||||
fprintf(out,"}\n#line %d \"%s\"\n",*lineno,lemp->outname);
|
fprintf(out,"}\n#line %d \"%s\"\n",*lineno,lemp->outname);
|
||||||
} /* End if( rp->code ) */
|
} /* End if( rp->code ) */
|
||||||
|
|
||||||
/* Check to make sure the LHS has been used */
|
|
||||||
if( rp->lhsalias && !lhsused ){
|
|
||||||
ErrorMsg(lemp->filename,rp->ruleline,
|
|
||||||
"Label \"%s\" for \"%s(%s)\" is never used.",
|
|
||||||
rp->lhsalias,rp->lhs->name,rp->lhsalias);
|
|
||||||
lemp->errorcnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate destructor code for RHS symbols which are not used in the
|
|
||||||
** reduce code */
|
|
||||||
for(i=0; i<rp->nrhs; i++){
|
|
||||||
if( rp->rhsalias[i] && !used[i] ){
|
|
||||||
ErrorMsg(lemp->filename,rp->ruleline,
|
|
||||||
"Label %s for \"%s(%s)\" is never used.",
|
|
||||||
rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
|
|
||||||
lemp->errorcnt++;
|
|
||||||
}else if( rp->rhsalias[i]==0 ){
|
|
||||||
if( has_destructor(rp->rhs[i],lemp) ){
|
|
||||||
fprintf(out," yy_destructor(%d,&yymsp[%d].minor);\n",
|
|
||||||
rp->rhs[i]->index,i-rp->nrhs+1); (*lineno)++;
|
|
||||||
}else{
|
|
||||||
fprintf(out," /* No destructor defined for %s */\n",
|
|
||||||
rp->rhs[i]->name);
|
|
||||||
(*lineno)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3569,6 +3624,18 @@ int mhflag; /* Output in makeheaders format if true */
|
|||||||
struct symbol *sp = lemp->symbols[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 ) continue;
|
||||||
fprintf(out," case %d:\n",sp->index); lineno++;
|
fprintf(out," case %d:\n",sp->index); lineno++;
|
||||||
|
|
||||||
|
/* Combine duplicate destructors into a single case */
|
||||||
|
for(j=i+1; j<lemp->nsymbol; j++){
|
||||||
|
struct symbol *sp2 = lemp->symbols[j];
|
||||||
|
if( sp2 && sp2->type!=TERMINAL && sp2->destructor
|
||||||
|
&& sp2->dtnum==sp->dtnum
|
||||||
|
&& strcmp(sp->destructor,sp2->destructor)==0 ){
|
||||||
|
fprintf(out," case %d:\n",sp2->index); lineno++;
|
||||||
|
sp2->destructor = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
|
emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
|
||||||
fprintf(out," break;\n"); lineno++;
|
fprintf(out," break;\n"); lineno++;
|
||||||
}
|
}
|
||||||
@ -3604,7 +3671,18 @@ int mhflag; /* Output in makeheaders format if true */
|
|||||||
|
|
||||||
/* Generate code which execution during each REDUCE action */
|
/* Generate code which execution during each REDUCE action */
|
||||||
for(rp=lemp->rule; rp; rp=rp->next){
|
for(rp=lemp->rule; rp; rp=rp->next){
|
||||||
|
if( rp->code ) translate_code(lemp, rp);
|
||||||
|
}
|
||||||
|
for(rp=lemp->rule; rp; rp=rp->next){
|
||||||
|
struct rule *rp2;
|
||||||
|
if( rp->code==0 ) continue;
|
||||||
fprintf(out," case %d:\n",rp->index); lineno++;
|
fprintf(out," case %d:\n",rp->index); lineno++;
|
||||||
|
for(rp2=rp->next; rp2; rp2=rp2->next){
|
||||||
|
if( rp2->code==rp->code ){
|
||||||
|
fprintf(out," case %d:\n",rp2->index); lineno++;
|
||||||
|
rp2->code = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
emit_code(out,rp,lemp,&lineno);
|
emit_code(out,rp,lemp,&lineno);
|
||||||
fprintf(out," break;\n"); lineno++;
|
fprintf(out," break;\n"); lineno++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user