]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Lemon enhancement: avoid unnecessary reduce actions that convert one
authordrh <drh@noemail.net>
Mon, 23 May 2016 16:15:02 +0000 (16:15 +0000)
committerdrh <drh@noemail.net>
Mon, 23 May 2016 16:15:02 +0000 (16:15 +0000)
non-terminal into another but have no side effects.

FossilOrigin-Name: a86e782ad1aa6f5a8b2c54f9dcf0fa61960843f3

manifest
manifest.uuid
tool/lemon.c

index 6ea5de70ebb5ea4acd7a37522b0a2be558bdd230..7893a5758b4ef4f187f787541b36bb8c3b1ee863 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\scomment\stypos\sand\simprove\sclarity\sof\spresention\sin\sLemon.\s\sThe\soutput\nshould\sbe\sidentical.
-D 2016-05-23T14:24:31.372
+C Lemon\senhancement:\savoid\sunnecessary\sreduce\sactions\sthat\sconvert\sone\nnon-terminal\sinto\sanother\sbut\shave\sno\sside\seffects.
+D 2016-05-23T16:15:02.530
 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7
@@ -1420,7 +1420,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 b622032dd14dc1315fedb81d73f4658354329fca
+F tool/lemon.c b4da2f0181b4defe538eb437eb96c721cf342d39
 F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6
 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
@@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 90411a28168f6dacf08242a25bed7d6269041417
-R 996821eb90ee3795d9bf03c89106b9e7
+P b91a5b8297756289d45c8fce0d3399c253517eb0
+R e62078de0c6378c8386e96fef92b2fe6
 U drh
-Z b4115b7928b4702f985a5c5bf63f70fa
+Z f3f44e1ca319aa39a93bd7b358420b1f
index 3a567c6fc656d84da5de2da564250e4ceb0d9f74..4af496871d49ecb794b6b0ad4c4335984d1ed7eb 100644 (file)
@@ -1 +1 @@
-b91a5b8297756289d45c8fce0d3399c253517eb0
\ No newline at end of file
+a86e782ad1aa6f5a8b2c54f9dcf0fa61960843f3
\ No newline at end of file
index 2ad36eec4a195005eba192bc322d79ab2815746e..d643b341e439aee7b413b26a21c0e3a539fc10f2 100644 (file)
@@ -341,6 +341,7 @@ struct action {
     struct state *stp;     /* The new state, if a shift */
     struct rule *rp;       /* The rule, if a reduce */
   } x;
+  struct symbol *spOpt;    /* SHIFTREDUCE optimization to this symbol */
   struct action *next;     /* Next action for this state */
   struct action *collide;  /* Next action with the same hash */
 };
@@ -532,6 +533,7 @@ void Action_add(
   *app = newaction;
   newaction->type = type;
   newaction->sp = sp;
+  newaction->spOpt = 0;
   if( type==SHIFT ){
     newaction->x.stp = (struct state *)arg;
   }else{
@@ -3167,6 +3169,9 @@ int PrintAction(
       result = 0;
       break;
   }
+  if( result && ap->spOpt ){
+    fprintf(fp,"  /* because %s==%s */", ap->sp->name, ap->spOpt->name);
+  }
   return result;
 }
 
@@ -4509,7 +4514,7 @@ void ReportHeader(struct lemon *lemp)
 void CompressTables(struct lemon *lemp)
 {
   struct state *stp;
-  struct action *ap, *ap2;
+  struct action *ap, *ap2, *nextap;
   struct rule *rp, *rp2, *rbest;
   int nbest, n;
   int i;
@@ -4586,6 +4591,36 @@ void CompressTables(struct lemon *lemp)
       }
     }
   }
+
+  /* If a SHIFTREDUCE action specifies a rule that has a single RHS term
+  ** (meaning that the SHIFTREDUCE will land back in the state where it
+  ** started) and if there is no C-code associated with the reduce action,
+  ** then we can go ahead and convert the action to be the same as the
+  ** action for the RHS of the rule.
+  */
+  for(i=0; i<lemp->nstate; i++){
+    stp = lemp->sorted[i];
+    for(ap=stp->ap; ap; ap=nextap){
+      nextap = ap->next;
+      if( ap->type!=SHIFTREDUCE ) continue;
+      rp = ap->x.rp;
+      if( rp->noCode==0 ) continue;
+      if( rp->nrhs!=1 ) continue;
+#if 1
+      /* Only apply this optimization to non-terminals.  It would be OK to
+      ** apply it to terminal symbols too, but that makes the parser tables
+      ** larger. */
+      if( ap->sp->index<lemp->nterminal ) continue;
+#endif
+      /* If we reach this point, it means the optimization can be applied */
+      nextap = ap;
+      for(ap2=stp->ap; ap2 && (ap2==ap || ap2->sp!=rp->lhs); ap2=ap2->next){}
+      assert( ap2!=0 );
+      ap->spOpt = ap2->sp;
+      ap->type = ap2->type;
+      ap->x = ap2->x;
+    }
+  }
 }