Enhance Lemon so that if reduce code contains a comment of the form
"/*A-overwrites-X*/" then a LHS label A is allowed to overwrite the RHS label X. FossilOrigin-Name: 5cfe9545d478a2c500083613dd20e14b2ffce645
This commit is contained in:
parent
dabd04c656
commit
cf82f0d3d2
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Further\simprovements\sto\sthe\sLemon-generated\scode\sfor\syy_reduce().
|
||||
D 2016-02-17T01:46:19.413
|
||||
C Enhance\sLemon\sso\sthat\sif\sreduce\scode\scontains\sa\scomment\sof\sthe\sform\n"/*A-overwrites-X*/"\sthen\sa\sLHS\slabel\sA\sis\sallowed\sto\soverwrite\sthe\nRHS\slabel\sX.
|
||||
D 2016-02-17T04:33:10.506
|
||||
F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 30f075dc4f27a07abb76088946b2944178d85347
|
||||
@ -337,7 +337,7 @@ F src/os_win.c f0d7aa603eb6262143d7169a222aea07c4fca91d
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 6812f3803951774b56abded396171e1c12b0b003
|
||||
F src/pager.h f3eb324a3ff2408b28bab7e81c1c55c13720f865
|
||||
F src/parse.y b845cfc4ba7d96b843856007a3c09c5b7ca2878f
|
||||
F src/parse.y 8c2f7e7e12cb03ddeaa204463198978aab2dcde9
|
||||
F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
|
||||
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
|
||||
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
|
||||
@ -1378,7 +1378,7 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/lemon.c 61844c3d01865473bce2dc8134e17346cda07000
|
||||
F tool/lemon.c 31a7325a4407fa35af7e5913b67517debae8181b
|
||||
F tool/lempar.c c7dde8fae568759a1a136b1acf35c4084864d035
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||
@ -1427,7 +1427,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh a98af506df552f3b3c0d904f94e4cdc4e1a6d598
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 4bb94c7c4c3cb3ccad72c2451d88684130dde845
|
||||
R 8570435db7ea690b60e76be3d8d02f8b
|
||||
P ef95a7d6490e33a9af4bc7b4b622de7328742ca7
|
||||
R f9d92e1ecf92fd9298e3c4ee80590b18
|
||||
U drh
|
||||
Z bc476c236d739b2c3e79f3d57d12535c
|
||||
Z 42e27a9e216e6c463abe3b883471bdc4
|
||||
|
@ -1 +1 @@
|
||||
ef95a7d6490e33a9af4bc7b4b622de7328742ca7
|
||||
5cfe9545d478a2c500083613dd20e14b2ffce645
|
70
src/parse.y
70
src/parse.y
@ -138,9 +138,9 @@ trans_opt ::= TRANSACTION.
|
||||
trans_opt ::= TRANSACTION nm.
|
||||
%type transtype {int}
|
||||
transtype(A) ::= . {A = TK_DEFERRED;}
|
||||
transtype(A) ::= DEFERRED(X). {A = @X;}
|
||||
transtype(A) ::= IMMEDIATE(X). {A = @X;}
|
||||
transtype(A) ::= EXCLUSIVE(X). {A = @X;}
|
||||
transtype(A) ::= DEFERRED(X). {A = @X; /*A-overwrites-X*/}
|
||||
transtype(A) ::= IMMEDIATE(X). {A = @X; /*A-overwrites-X*/}
|
||||
transtype(A) ::= EXCLUSIVE(X). {A = @X; /*A-overwrites-X*/}
|
||||
cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);}
|
||||
cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);}
|
||||
cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);}
|
||||
@ -456,7 +456,7 @@ select(A) ::= with(W) selectnowith(X). {
|
||||
}else{
|
||||
sqlite3WithDelete(pParse->db, W);
|
||||
}
|
||||
A = p;
|
||||
A = p; /*A-overwrites-W*/
|
||||
}
|
||||
|
||||
selectnowith(A) ::= oneselect(A).
|
||||
@ -484,9 +484,9 @@ selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). {
|
||||
A = pRhs;
|
||||
}
|
||||
%type multiselect_op {int}
|
||||
multiselect_op(A) ::= UNION(OP). {A = @OP;}
|
||||
multiselect_op(A) ::= UNION(OP). {A = @OP; /*A-overwrites-OP*/}
|
||||
multiselect_op(A) ::= UNION ALL. {A = TK_ALL;}
|
||||
multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;}
|
||||
multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP; /*A-overwrites-OP*/}
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
|
||||
groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
|
||||
@ -648,14 +648,17 @@ dbnm(A) ::= DOT nm(X). {A = X;}
|
||||
|
||||
%type fullname {SrcList*}
|
||||
%destructor fullname {sqlite3SrcListDelete(pParse->db, $$);}
|
||||
fullname(A) ::= nm(X) dbnm(Y). {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y);}
|
||||
fullname(A) ::= nm(X) dbnm(Y).
|
||||
{A = sqlite3SrcListAppend(pParse->db,0,&X,&Y); /*A-overwrites-X*/}
|
||||
|
||||
%type joinop {int}
|
||||
joinop(X) ::= COMMA|JOIN. { X = JT_INNER; }
|
||||
joinop(X) ::= JOIN_KW(A) JOIN. { X = sqlite3JoinType(pParse,&A,0,0); }
|
||||
joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqlite3JoinType(pParse,&A,&B,0); }
|
||||
joinop(X) ::= JOIN_KW(A) JOIN.
|
||||
{X = sqlite3JoinType(pParse,&A,0,0); /*X-overwrites-A*/}
|
||||
joinop(X) ::= JOIN_KW(A) nm(B) JOIN.
|
||||
{X = sqlite3JoinType(pParse,&A,&B,0); /*X-overwrites-A*/}
|
||||
joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
|
||||
{ X = sqlite3JoinType(pParse,&A,&B,&C); }
|
||||
{X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/}
|
||||
|
||||
%type on_opt {Expr*}
|
||||
%destructor on_opt {sqlite3ExprDelete(pParse->db, $$);}
|
||||
@ -700,7 +703,7 @@ sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). {
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
}
|
||||
sortlist(A) ::= expr(Y) sortorder(Z). {
|
||||
A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
|
||||
A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
}
|
||||
|
||||
@ -825,7 +828,7 @@ idlist_opt(A) ::= LP idlist(X) RP. {A = X;}
|
||||
idlist(A) ::= idlist(A) COMMA nm(Y).
|
||||
{A = sqlite3IdListAppend(pParse->db,A,&Y);}
|
||||
idlist(A) ::= nm(Y).
|
||||
{A = sqlite3IdListAppend(pParse->db,0,&Y);}
|
||||
{A = sqlite3IdListAppend(pParse->db,0,&Y); /*A-overwrites-Y*/}
|
||||
|
||||
/////////////////////////// Expression Processing /////////////////////////////
|
||||
//
|
||||
@ -864,16 +867,16 @@ expr(A) ::= JOIN_KW(X). {spanExpr(&A, pParse, TK_ID, &X);}
|
||||
expr(A) ::= nm(X) DOT nm(Y). {
|
||||
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
|
||||
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y);
|
||||
spanSet(&A,&X,&Y); /*A-overwrites-X*/
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
|
||||
spanSet(&A,&X,&Y);
|
||||
}
|
||||
expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
|
||||
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
|
||||
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y);
|
||||
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Z);
|
||||
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
|
||||
spanSet(&A,&X,&Z); /*A-overwrites-X*/
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
|
||||
spanSet(&A,&X,&Z);
|
||||
}
|
||||
term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A, pParse, @X, &X);}
|
||||
term(A) ::= STRING(X). {spanExpr(&A, pParse, @X, &X);}
|
||||
@ -961,7 +964,7 @@ expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
|
||||
{spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
%type likeop {struct LikeOp}
|
||||
likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;}
|
||||
likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;/*A-overwrites-X*/}
|
||||
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 1;}
|
||||
expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
|
||||
ExprList *pList;
|
||||
@ -1203,7 +1206,7 @@ case_else(A) ::= ELSE expr(X). {A = X.pExpr;}
|
||||
case_else(A) ::= . {A = 0;}
|
||||
%type case_operand {Expr*}
|
||||
%destructor case_operand {sqlite3ExprDelete(pParse->db, $$);}
|
||||
case_operand(A) ::= expr(X). {A = X.pExpr;}
|
||||
case_operand(A) ::= expr(X). {A = X.pExpr; /*A-overwrites-X*/}
|
||||
case_operand(A) ::= . {A = 0;}
|
||||
|
||||
%type exprlist {ExprList*}
|
||||
@ -1216,7 +1219,7 @@ exprlist(A) ::= . {A = 0;}
|
||||
nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
|
||||
{A = sqlite3ExprListAppend(pParse,A,Y.pExpr);}
|
||||
nexprlist(A) ::= expr(Y).
|
||||
{A = sqlite3ExprListAppend(pParse,0,Y.pExpr);}
|
||||
{A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}
|
||||
|
||||
|
||||
///////////////////////////// The CREATE INDEX command ///////////////////////
|
||||
@ -1284,7 +1287,7 @@ eidlist(A) ::= eidlist(A) COMMA nm(Y) collate(C) sortorder(Z). {
|
||||
A = parserAddExprIdListTerm(pParse, A, &Y, C, Z);
|
||||
}
|
||||
eidlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
||||
A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z);
|
||||
A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z); /*A-overwrites-Y*/
|
||||
}
|
||||
|
||||
%type collate {int}
|
||||
@ -1316,15 +1319,15 @@ cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y).
|
||||
cmd ::= PRAGMA nm(X) dbnm(Z) LP minus_num(Y) RP.
|
||||
{sqlite3Pragma(pParse,&X,&Z,&Y,1);}
|
||||
|
||||
nmnum(A) ::= plus_num(X). {A = X;}
|
||||
nmnum(A) ::= nm(X). {A = X;}
|
||||
nmnum(A) ::= ON(X). {A = X;}
|
||||
nmnum(A) ::= DELETE(X). {A = X;}
|
||||
nmnum(A) ::= DEFAULT(X). {A = X;}
|
||||
nmnum(A) ::= plus_num(A).
|
||||
nmnum(A) ::= nm(A).
|
||||
nmnum(A) ::= ON(A).
|
||||
nmnum(A) ::= DELETE(A).
|
||||
nmnum(A) ::= DEFAULT(A).
|
||||
%endif SQLITE_OMIT_PRAGMA
|
||||
%token_class number INTEGER|FLOAT.
|
||||
plus_num(A) ::= PLUS number(X). {A = X;}
|
||||
plus_num(A) ::= number(X). {A = X;}
|
||||
plus_num(A) ::= number(A).
|
||||
minus_num(A) ::= MINUS number(X). {A = X;}
|
||||
//////////////////////////// The CREATE TRIGGER command /////////////////////
|
||||
|
||||
@ -1341,7 +1344,7 @@ trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z)
|
||||
trigger_time(C) trigger_event(D)
|
||||
ON fullname(E) foreach_clause when_clause(G). {
|
||||
sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, G, T, NOERR);
|
||||
A = (Z.n==0?B:Z);
|
||||
A = (Z.n==0?B:Z); /*A-overwrites-T*/
|
||||
}
|
||||
|
||||
%type trigger_time {int}
|
||||
@ -1352,9 +1355,9 @@ trigger_time(A) ::= . { A = TK_BEFORE; }
|
||||
|
||||
%type trigger_event {struct TrigEvent}
|
||||
%destructor trigger_event {sqlite3IdListDelete(pParse->db, $$.b);}
|
||||
trigger_event(A) ::= DELETE|INSERT(OP). {A.a = @OP; A.b = 0;}
|
||||
trigger_event(A) ::= UPDATE(OP). {A.a = @OP; A.b = 0;}
|
||||
trigger_event(A) ::= UPDATE OF idlist(X). {A.a = TK_UPDATE; A.b = X;}
|
||||
trigger_event(A) ::= DELETE|INSERT(X). {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
|
||||
trigger_event(A) ::= UPDATE(X). {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
|
||||
trigger_event(A) ::= UPDATE OF idlist(X).{A.a = TK_UPDATE; A.b = X;}
|
||||
|
||||
foreach_clause ::= .
|
||||
foreach_clause ::= FOR EACH ROW.
|
||||
@ -1423,24 +1426,23 @@ trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y).
|
||||
{A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);}
|
||||
|
||||
// SELECT
|
||||
trigger_cmd(A) ::= select(X). {A = sqlite3TriggerSelectStep(pParse->db, X); }
|
||||
trigger_cmd(A) ::= select(X).
|
||||
{A = sqlite3TriggerSelectStep(pParse->db, X); /*A-overwrites-X*/}
|
||||
|
||||
// The special RAISE expression that may occur in trigger programs
|
||||
expr(A) ::= RAISE(X) LP IGNORE RP(Y). {
|
||||
spanSet(&A,&X,&Y); /*A-overwrites-X*/
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->affinity = OE_Ignore;
|
||||
}
|
||||
A.zStart = X.z;
|
||||
A.zEnd = &Y.z[Y.n];
|
||||
}
|
||||
expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). {
|
||||
spanSet(&A,&X,&Y); /*A-overwrites-X*/
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &Z);
|
||||
if( A.pExpr ) {
|
||||
A.pExpr->affinity = (char)T;
|
||||
}
|
||||
A.zStart = X.z;
|
||||
A.zEnd = &Y.z[Y.n];
|
||||
}
|
||||
%endif !SQLITE_OMIT_TRIGGER
|
||||
|
||||
@ -1536,7 +1538,7 @@ with(A) ::= WITH wqlist(W). { A = W; }
|
||||
with(A) ::= WITH RECURSIVE wqlist(W). { A = W; }
|
||||
|
||||
wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
|
||||
A = sqlite3WithAdd(pParse, 0, &X, Y, Z);
|
||||
A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/
|
||||
}
|
||||
wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
|
||||
A = sqlite3WithAdd(pParse, A, &X, Y, Z);
|
||||
|
28
tool/lemon.c
28
tool/lemon.c
@ -3476,11 +3476,13 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
|
||||
PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
|
||||
char *cp, *xp;
|
||||
int i;
|
||||
int rc = 0; /* True if yylhsminor is used */
|
||||
char lhsused = 0; /* True if the LHS element has been used */
|
||||
char lhsdirect; /* True if LHS writes directly into stack */
|
||||
char used[MAXRHS]; /* True for each RHS element which is used */
|
||||
char zLhs[50]; /* Convert the LHS symbol into this string */
|
||||
int rc = 0; /* True if yylhsminor is used */
|
||||
const char *zSkip = 0; /* The zOvwrt comment within rp->code, or NULL */
|
||||
char lhsused = 0; /* True if the LHS element has been used */
|
||||
char lhsdirect; /* True if LHS writes directly into stack */
|
||||
char used[MAXRHS]; /* True for each RHS element which is used */
|
||||
char zLhs[50]; /* Convert the LHS symbol into this string */
|
||||
char zOvwrt[900]; /* Comment that to allow LHS to overwrite RHS */
|
||||
|
||||
for(i=0; i<rp->nrhs; i++) used[i] = 0;
|
||||
lhsused = 0;
|
||||
@ -3522,7 +3524,16 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
|
||||
lemp->errorcnt++;
|
||||
}
|
||||
}else{
|
||||
lhsdirect = 0;
|
||||
lemon_sprintf(zOvwrt, "/*%s-overwrites-%s*/",
|
||||
rp->lhsalias, rp->rhsalias[0]);
|
||||
zSkip = strstr(rp->code, zOvwrt);
|
||||
if( zSkip!=0 ){
|
||||
/* The code contains a special comment that indicates that it is safe
|
||||
** for the LHS label to overwrite left-most RHS label. */
|
||||
lhsdirect = 1;
|
||||
}else{
|
||||
lhsdirect = 0;
|
||||
}
|
||||
}
|
||||
if( lhsdirect ){
|
||||
sprintf(zLhs, "yymsp[%d].minor.yy%d",1-rp->nrhs,rp->lhs->dtnum);
|
||||
@ -3535,6 +3546,11 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
|
||||
|
||||
/* This const cast is wrong but harmless, if we're careful. */
|
||||
for(cp=(char *)rp->code; *cp; cp++){
|
||||
if( cp==zSkip ){
|
||||
append_str(zOvwrt,0,0,0);
|
||||
cp += lemonStrlen(zOvwrt)-1;
|
||||
continue;
|
||||
}
|
||||
if( ISALPHA(*cp) && (cp==rp->code || (!ISALNUM(cp[-1]) && cp[-1]!='_')) ){
|
||||
char saved;
|
||||
for(xp= &cp[1]; ISALNUM(*xp) || *xp=='_'; xp++);
|
||||
|
Loading…
Reference in New Issue
Block a user