]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance Lemon so that if reduce code contains a comment of the form
authordrh <drh@noemail.net>
Wed, 17 Feb 2016 04:33:10 +0000 (04:33 +0000)
committerdrh <drh@noemail.net>
Wed, 17 Feb 2016 04:33:10 +0000 (04:33 +0000)
"/*A-overwrites-X*/" then a LHS label A is allowed to overwrite the
RHS label X.

FossilOrigin-Name: 5cfe9545d478a2c500083613dd20e14b2ffce645

manifest
manifest.uuid
src/parse.y
tool/lemon.c

index afad0890ac3a15d6f038a8ac6dc74df096403f9c..c34c4dda4bfdf9d286ec78de751e2a6933fa4d68 100644 (file)
--- a/manifest
+++ b/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
index e8f5fde5d6d52622c0ebb0d69b8109ecdc64cf38..2c12f2f200c5416371fad7c6d7e36081232f0b32 100644 (file)
@@ -1 +1 @@
-ef95a7d6490e33a9af4bc7b4b622de7328742ca7
\ No newline at end of file
+5cfe9545d478a2c500083613dd20e14b2ffce645
\ No newline at end of file
index cf9bc0f2bb2f15255361528bb8b261a7e601bfb2..f1060305eef3714ecbcc353c7cc733f8a7767a81 100644 (file)
@@ -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);
index 1f81717c7c69580324f2c9e723512d45670df455..1058d14ae6354c9b0e9e76625140e6a1f07f38c4 100644 (file)
@@ -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++);