]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved table compression in lemon reduces the overall library size
authordrh <drh@noemail.net>
Sat, 5 Nov 2005 15:03:59 +0000 (15:03 +0000)
committerdrh <drh@noemail.net>
Sat, 5 Nov 2005 15:03:59 +0000 (15:03 +0000)
by about 1.5KiB. (CVS 2761)

FossilOrigin-Name: 86ac11476962727d2d40b62ce87d689c01969537

manifest
manifest.uuid
tool/lemon.c
tool/lempar.c

index 310cb4676007dde8ee4775d7084a5f1cd352b359..40232dddcf8446abdb0da459e1a123492cfe0991 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C VACUUM\sworks\seven\son\san\sempty\sdatabase.\s\sTicket\s#1512.\s(CVS\s2760)
-D 2005-11-04T22:03:30
+C Improved\stable\scompression\sin\slemon\sreduces\sthe\soverall\slibrary\ssize\nby\sabout\s1.5KiB.\s(CVS\s2761)
+D 2005-11-05T15:04:00
 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -249,8 +249,8 @@ F test/view.test ce0f0ad39fa4a3572acffcf1e634850ee151aae0
 F test/where.test 752728413eab42e5854690d84c7319cdf7edc515
 F test/where2.test 503e2e2b6abe14c5c10222e72d08ef84c1bf1ffb
 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
-F tool/lemon.c c88936c67f6411608db8fa4254d254f509fa40f6
-F tool/lempar.c f0c30abcae762a7d1eb37cd88b2232ab8dd625fb
+F tool/lemon.c 0cedabac11734ec2a40286552de4af01cc859f6e
+F tool/lempar.c 424df14a48736bb961ed47acf30c26d66ed85a62
 F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
 F tool/memleak3.tcl 009da0ea82dc5893edca76cf1a21fb7260e9412e
@@ -317,7 +317,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 7780f5e9d504926f11bd0662c03c88c76fb1d416
-R 1a3d1b527330224886b9cff041619a5d
+P 1b6bf4188e8ebf55cf1972b7081f6d31bf525555
+R 0643dda995921861878ddcf931a00061
 U drh
-Z f1e5a520d02502b659fb8d9e06e8fb3d
+Z 1e38b5f3f01e11660fc6060d64bb658c
index 5d4d99edddbe69000e1872a3a0adb7900e4a17c3..e80907e0ef97b0feb4b94ab96daad57406f229dc 100644 (file)
@@ -1 +1 @@
-1b6bf4188e8ebf55cf1972b7081f6d31bf525555
\ No newline at end of file
+86ac11476962727d2d40b62ce87d689c01969537
\ No newline at end of file
index 8f6e87330a53107940d7f586afb7c1b3c200f502..6cfd2c0bff1e56e3b80db3021d12dee15f2858fd 100644 (file)
@@ -94,6 +94,7 @@ void ReportOutput(/* struct lemon * */);
 void ReportTable(/* struct lemon * */);
 void ReportHeader(/* struct lemon * */);
 void CompressTables(/* struct lemon * */);
+void ResortStates(/* struct lemon * */);
 
 /********** From the file "set.h" ****************************************/
 void  SetSize(/* int N */);             /* All sets will be of size N */
@@ -206,7 +207,7 @@ struct action {
 struct state {
   struct config *bp;       /* The basis configurations for this state */
   struct config *cfp;      /* All configurations in this set */
-  int index;               /* Sequencial number for this state */
+  int statenum;            /* Sequencial number for this state */
   struct action *ap;       /* Array of actions for this state */
   int nTknAct, nNtAct;     /* Number of actions on terminals and nonterminals */
   int iTknOfst, iNtOfst;   /* yy_action[] offset for terminals and nonterms */
@@ -751,7 +752,7 @@ struct lemon *lemp;
     MemoryCheck(stp);
     stp->bp = bp;                /* Remember the configuration basis */
     stp->cfp = cfp;              /* Remember the configuration closure */
-    stp->index = lemp->nstate++; /* Every state gets a sequence number */
+    stp->statenum = lemp->nstate++; /* Every state gets a sequence number */
     stp->ap = 0;                 /* No actions, yet. */
     State_insert(stp,stp->bp);   /* Add to the state table */
     buildshifts(lemp,stp);       /* Recursively compute successor states */
@@ -1445,6 +1446,10 @@ char **argv;
     /* Compress the action tables */
     if( compress==0 ) CompressTables(&lem);
 
+    /* Reorder and renumber the states so that states with fewer choices
+    ** occur at the end. */
+    ResortStates(&lem);
+
     /* Generate a report of the parser generated.  (the "y.output" file) */
     if( !quiet ) ReportOutput(&lem);
 
@@ -2697,7 +2702,7 @@ struct plink *plp;
 char *tag;
 {
   while( plp ){
-    fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->index);
+    fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->statenum);
     ConfigPrint(out,plp->cfp);
     fprintf(out,"\n");
     plp = plp->next;
@@ -2712,7 +2717,7 @@ int PrintAction(struct action *ap, FILE *fp, int indent){
   int result = 1;
   switch( ap->type ){
     case SHIFT:
-      fprintf(fp,"%*s shift  %d",indent,ap->sp->name,ap->x.stp->index);
+      fprintf(fp,"%*s shift  %d",indent,ap->sp->name,ap->x.stp->statenum);
       break;
     case REDUCE:
       fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index);
@@ -2751,7 +2756,7 @@ struct lemon *lemp;
   fprintf(fp," \b");
   for(i=0; i<lemp->nstate; i++){
     stp = lemp->sorted[i];
-    fprintf(fp,"State %d:\n",stp->index);
+    fprintf(fp,"State %d:\n",stp->statenum);
     if( lemp->basisflag ) cfp=stp->bp;
     else                  cfp=stp->cfp;
     while( cfp ){
@@ -2837,7 +2842,7 @@ struct action *ap;
 {
   int act;
   switch( ap->type ){
-    case SHIFT:  act = ap->x.stp->index;               break;
+    case SHIFT:  act = ap->x.stp->statenum;            break;
     case REDUCE: act = ap->x.rp->index + lemp->nstate; break;
     case ERROR:  act = lemp->nstate + lemp->nrule;     break;
     case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break;
@@ -3457,21 +3462,6 @@ int mhflag;     /* Output in makeheaders format if true */
   }
   for(i=0; i<lemp->nstate; i++){
     stp = lemp->sorted[i];
-    stp->nTknAct = stp->nNtAct = 0;
-    stp->iDflt = lemp->nstate + lemp->nrule;
-    stp->iTknOfst = NO_OFFSET;
-    stp->iNtOfst = NO_OFFSET;
-    for(ap=stp->ap; ap; ap=ap->next){
-      if( compute_action(lemp,ap)>=0 ){
-        if( ap->sp->index<lemp->nterminal ){
-          stp->nTknAct++;
-        }else if( ap->sp->index<lemp->nsymbol ){
-          stp->nNtAct++;
-        }else{
-          stp->iDflt = compute_action(lemp, ap);
-        }
-      }
-    }
     ax[i*2].stp = stp;
     ax[i*2].isTkn = 1;
     ax[i*2].nAction = stp->nTknAct;
@@ -3552,9 +3542,11 @@ int mhflag;     /* Output in makeheaders format if true */
 
   /* Output the yy_shift_ofst[] table */
   fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
+  n = lemp->nstate;
+  while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
+  fprintf(out, "#define YY_SHIFT_MAX %d\n", n-1); lineno++;
   fprintf(out, "static const %s yy_shift_ofst[] = {\n", 
           minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++;
-  n = lemp->nstate;
   for(i=j=0; i<n; i++){
     int ofst;
     stp = lemp->sorted[i];
@@ -3573,9 +3565,11 @@ int mhflag;     /* Output in makeheaders format if true */
 
   /* Output the yy_reduce_ofst[] table */
   fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
+  n = lemp->nstate;
+  while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--;
+  fprintf(out, "#define YY_REDUCE_MAX %d\n", n-1); lineno++;
   fprintf(out, "static const %s yy_reduce_ofst[] = {\n", 
           minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++;
-  n = lemp->nstate;
   for(i=j=0; i<n; i++){
     int ofst;
     stp = lemp->sorted[i];
@@ -3789,7 +3783,7 @@ struct lemon *lemp;
 ** of defaults.
 **
 ** In this version, we take the most frequent REDUCE action and make
-** it the default.  Only default a reduce if there are more than one.
+** it the default.
 */
 void CompressTables(lemp)
 struct lemon *lemp;
@@ -3823,8 +3817,8 @@ struct lemon *lemp;
     }
  
     /* Do not make a default if the number of rules to default
-    ** is not at least 2 */
-    if( nbest<2 ) continue;
+    ** is not at least 1 */
+    if( nbest<1 ) continue;
 
 
     /* Combine matching REDUCE actions into a single default */
@@ -3840,6 +3834,63 @@ struct lemon *lemp;
   }
 }
 
+
+/*
+** Compare two states for sorting purposes.  The smaller state is the
+** one with the most non-terminal actions.  If they have the same number
+** of non-terminal actions, then the smaller is the one with the most
+** token actions.
+*/
+static int stateResortCompare(const void *a, const void *b){
+  const struct state *pA = *(const struct state**)a;
+  const struct state *pB = *(const struct state**)b;
+  int n;
+
+  n = pB->nNtAct - pA->nNtAct;
+  if( n==0 ){
+    n = pB->nTknAct - pA->nTknAct;
+  }
+  return n;
+}
+
+
+/*
+** Renumber and resort states so that states with fewer choices
+** occur at the end.  Except, keep state 0 as the first state.
+*/
+void ResortStates(lemp)
+struct lemon *lemp;
+{
+  int i;
+  struct state *stp;
+  struct action *ap;
+
+  for(i=0; i<lemp->nstate; i++){
+    stp = lemp->sorted[i];
+    stp->nTknAct = stp->nNtAct = 0;
+    stp->iDflt = lemp->nstate + lemp->nrule;
+    stp->iTknOfst = NO_OFFSET;
+    stp->iNtOfst = NO_OFFSET;
+    for(ap=stp->ap; ap; ap=ap->next){
+      if( compute_action(lemp,ap)>=0 ){
+        if( ap->sp->index<lemp->nterminal ){
+          stp->nTknAct++;
+        }else if( ap->sp->index<lemp->nsymbol ){
+          stp->nNtAct++;
+        }else{
+          stp->iDflt = compute_action(lemp, ap);
+        }
+      }
+    }
+  }
+  qsort(&lemp->sorted[1], lemp->nstate-1, sizeof(lemp->sorted[0]),
+        stateResortCompare);
+  for(i=0; i<lemp->nstate; i++){
+    lemp->sorted[i]->statenum = i;
+  }
+}
+
+
 /***************** From the file "set.c" ************************************/
 /*
 ** Set manipulation routines for the LEMON parser generator.
index 57ec97f6a87c7cd894e966235e899514d17efe5d..7a549a7c52c5414a22b7b65a29d367888a7dfece 100644 (file)
@@ -326,9 +326,7 @@ static int yy_find_shift_action(
   int i;
   int stateno = pParser->yystack[pParser->yyidx].stateno;
  
-  /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-  i = yy_shift_ofst[stateno];
-  if( i==YY_SHIFT_USE_DFLT ){
+  if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
     return yy_default[stateno];
   }
   if( iLookAhead==YYNOCODE ){
@@ -370,8 +368,8 @@ static int yy_find_reduce_action(
   int i;
   /* int stateno = pParser->yystack[pParser->yyidx].stateno; */
  
-  i = yy_reduce_ofst[stateno];
-  if( i==YY_REDUCE_USE_DFLT ){
+  if( stateno>YY_REDUCE_MAX ||
+      (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){
     return yy_default[stateno];
   }
   if( iLookAhead==YYNOCODE ){