]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify lemon to use much less memory for its parser tables. This reduces
authordrh <drh@noemail.net>
Sat, 23 Feb 2002 19:39:46 +0000 (19:39 +0000)
committerdrh <drh@noemail.net>
Sat, 23 Feb 2002 19:39:46 +0000 (19:39 +0000)
the size of the library by 50K, which is important for an embedded library. (CVS 389)

FossilOrigin-Name: 67a135a051e7c96ddbfe85976539b4b8372c7026

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

index 721b6f83263fb245d87ed07c4de4743022aa1eec..6d41043211c6a4a6b627f03c6a148b7e8131924c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Bug\sfix\sin\slemon:\s3-way\sconflicts\s(SHIFT/REDUCE/REDUCE)\swere\snot\sdetected\sor\nresolved.\s\sThis\sis\snow\sfixed.\s\sAlso,\stable\scompression\sworks\sa\slittle\sbetter.\s(CVS\s388)
-D 2002-02-23T18:45:13
+C Modify\slemon\sto\suse\smuch\sless\smemory\sfor\sits\sparser\stables.\s\sThis\sreduces\nthe\ssize\sof\sthe\slibrary\sby\s50K,\swhich\sis\simportant\sfor\san\sembedded\slibrary.\s(CVS\s389)
+D 2002-02-23T19:39:47
 F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
 F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -99,8 +99,8 @@ F test/unique.test 07776624b82221a80c8b4138ce0dd8b0853bb3ea
 F test/update.test 3cf1ca0565f678063c2dfa9a7948d2d66ae1a778
 F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e
 F test/where.test 032d581c3de4893eba33b569e581c46b941bb02a
-F tool/lemon.c 7502222a5d704d9d5d1ac437f73667855d687862
-F tool/lempar.c 9b604e6a8b3d55c0b9cbcb130a7302fb8bafe2b9
+F tool/lemon.c d4b4e127e70633be1bbea49c2ccba5cdb4b77a5f
+F tool/lempar.c 2ff255186fffb38a43a9f7b010e87eee6308edcc
 F tool/memleak.awk 296dfbce7a9ca499b95ce04e30334e64a50052e0
 F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
@@ -125,7 +125,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 39fed2df11382b9855d518502a6c2ca200fa66b8
-R bbf759a9eca350d9e39199c34c6ab1fb
+P 8da0ac9a8bb859377613dd18f4f423eb49c7338b
+R a10568441a27cde980e4058838f315f0
 U drh
-Z 95f9230334dd6740861a9a25c1c709f1
+Z 77767b7d4f55ba40f2761ab26d448e78
index 01153779598f3f28fb15b3f617b555a84d475e6d..ed839134c2f1be45785f3b45f6a54abd9b73801c 100644 (file)
@@ -1 +1 @@
-8da0ac9a8bb859377613dd18f4f423eb49c7338b
\ No newline at end of file
+67a135a051e7c96ddbfe85976539b4b8372c7026
\ No newline at end of file
index 3e641a4d460a6c43ba953e60970c4df384049fc5..eae3c09fd4295e33207ff337e19834bc97db79c8 100644 (file)
@@ -2927,6 +2927,20 @@ int mhflag;                 /* True if generating makeheaders output */
   *plineno = lineno;
 }
 
+/*
+** Return the name of a C datatype able to represent values between
+** 0 and N, inclusive.
+*/
+static const char *minimum_size_type(int N){
+  if( N<=255 ){
+    return "unsigned char";
+  }else if( N<65535 ){
+    return "unsigned short int";
+  }else{
+    return "unsigned int";
+  }
+}
+
 /* Generate C source code for the parser */
 void ReportTable(lemp, mhflag)
 struct lemon *lemp;
@@ -2978,10 +2992,10 @@ int mhflag;     /* Output in makeheaders format if true */
   /* Generate the defines */
   fprintf(out,"/* \001 */\n");
   fprintf(out,"#define YYCODETYPE %s\n",
-    lemp->nsymbol>250?"int":"unsigned char");  lineno++;
+    minimum_size_type(lemp->nsymbol+5)); lineno++;
   fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1);  lineno++;
   fprintf(out,"#define YYACTIONTYPE %s\n",
-    lemp->nstate+lemp->nrule>250?"int":"unsigned char");  lineno++;
+    minimum_size_type(lemp->nstate+lemp->nrule+5));  lineno++;
   print_stack_union(out,lemp,&lineno,mhflag);
   if( lemp->stacksize ){
     if( atoi(lemp->stacksize)<=0 ){
@@ -3027,13 +3041,16 @@ int mhflag;     /* Output in makeheaders format if true */
   ** structure:
   **   struct yyActionEntry {
   **       YYCODETYPE            lookahead;
+  **       YYCODETYPE            next;
   **       YYACTIONTYPE          action;
-  **       struct yyActionEntry *next;
   **   }
   **
   ** The entries are grouped into hash tables, one hash table for each
-  ** parser state.  The hash table has a size which is the smallest
-  ** power of two needed to hold all entries.
+  ** parser state.  The hash table has a size which is the number of
+  ** entries in that table.  In case of a collision, the "next" value
+  ** contains one more than the index into the hash table of the next
+  ** entry in the collision chain.  A "next" value of 0 means the end
+  ** of the chain has been reached.
   */
   tablecnt = 0;
 
@@ -3053,8 +3070,7 @@ int mhflag;     /* Output in makeheaders format if true */
         stp->naction++;
       }
     }
-    tablesize = 1;
-    while( tablesize<stp->naction ) tablesize += tablesize;
+    tablesize = stp->naction;
     assert( tablesize<= sizeof(table)/sizeof(table[0]) );
     for(j=0; j<tablesize; j++){
       table[j] = 0;
@@ -3069,7 +3085,7 @@ int mhflag;     /* Output in makeheaders format if true */
       if( ap->sp->index==lemp->nsymbol ){
         stp->tabdfltact = action;
       }else if( action>=0 ){
-        h = ap->sp->index & (tablesize-1);
+        h = ap->sp->index % tablesize;
         ap->collide = table[h];
         table[h] = ap;
       }
@@ -3089,22 +3105,13 @@ int mhflag;     /* Output in makeheaders format if true */
     /* Print the hash table */
     fprintf(out,"/* State %d */\n",stp->index); lineno++;
     for(j=0; j<tablesize; j++){
-      if( table[j]==0 ){
-        fprintf(out,
-          "  {YYNOCODE,0,0}, /* Unused */\n");
-      }else{
-        fprintf(out,"  {%4d,%4d, ",
+      assert( table[j]!=0 );
+      fprintf(out,"  {%4d,%4d,%4d}, /* ",
           table[j]->sp->index,
+          collide[j]+1,
           compute_action(lemp,table[j]));
-        if( collide[j]>=0 ){
-          fprintf(out,"&yyActionTable[%4d] }, /* ",
-            collide[j] + tablecnt);
-        }else{
-          fprintf(out,"0                    }, /* ");
-        }
-        PrintAction(table[j],out,22);
-        fprintf(out," */\n"); 
-      }
+      PrintAction(table[j],out,22);
+      fprintf(out," */\n"); 
       lineno++;
     }
 
@@ -3119,18 +3126,15 @@ int mhflag;     /* Output in makeheaders format if true */
   ** Each entry is an element of the following structure:
   **    struct yyStateEntry {
   **      struct yyActionEntry *hashtbl;
-  **      int mask;
+  **      YYCODETYPE nEntry;
   **      YYACTIONTYPE actionDefault;
   **    }
   */
   for(i=0; i<lemp->nstate; i++){
-    int tablesize;
     stp = lemp->sorted[i];
-    tablesize = 1;
-    while( tablesize<stp->naction ) tablesize += tablesize;
-    fprintf(out,"  { &yyActionTable[%d], %d, %d},\n",
+    fprintf(out,"  { &yyActionTable[%d],%4d,%4d },\n",
       stp->tabstart,
-      tablesize - 1,
+      stp->naction,
       stp->tabdfltact); lineno++;
   }
   tplt_xfer(lemp->name,in,out,&lineno);
index a0b066f9d84c15b2a002d48e55fff629fdad5afa..6a2cd08747ce1d940deebcd171f853f07ea84770 100644 (file)
@@ -76,8 +76,8 @@
 */
 struct yyActionEntry {
   YYCODETYPE   lookahead;   /* The value of the look-ahead token */
+  YYCODETYPE   next;        /* Next entry + 1. Zero at end of collision chain */
   YYACTIONTYPE action;      /* Action to take for this look-ahead */
-  struct yyActionEntry *next; /* Next look-ahead with the same hash, or NULL */
 };
 static struct yyActionEntry yyActionTable[] = {
 %%
@@ -89,15 +89,14 @@ static struct yyActionEntry yyActionTable[] = {
 **
 **  +  A pointer to the start of the action hash table in yyActionTable.
 **
-**  +  A mask used to hash the look-ahead token.  The mask is an integer
-**     which is one less than the size of the hash table.  
+**  +  The number of entries in the action hash table.
 **
 **  +  The default action.  This is the action to take if no entry for
 **     the given look-ahead is found in the action hash table.
 */
 struct yyStateEntry {
   struct yyActionEntry *hashtbl; /* Start of the hash table in yyActionTable */
-  int mask;                      /* Mask used for hashing the look-ahead */
+  YYCODETYPE nEntry;             /* Number of entries in action hash table */
   YYACTIONTYPE actionDefault;    /* Default action if look-ahead not found */
 };
 static struct yyStateEntry yyStateTable[] = {
@@ -297,13 +296,16 @@ static int yy_find_parser_action(
  
   /* if( pParser->idx<0 ) return YY_NO_ACTION;  */
   pState = &yyStateTable[pParser->top->stateno];
-  if( iLookAhead!=YYNOCODE ){
-    pAction = &pState->hashtbl[iLookAhead & pState->mask];
-    while( pAction ){
+  if( pState->nEntry==0 ){
+    return pState->actionDefault;
+  }else if( iLookAhead!=YYNOCODE ){
+    pAction = &pState->hashtbl[iLookAhead % pState->nEntry];
+    while( 1 ){
       if( pAction->lookahead==iLookAhead ) return pAction->action;
-      pAction = pAction->next;
+      if( pAction->next==0 ) return pState->actionDefault;
+      pAction = &pState->hashtbl[pAction->next-1];
     }
-  }else if( pState->mask!=0 || pState->hashtbl->lookahead!=YYNOCODE ){
+  }else if( pState->hashtbl->lookahead!=YYNOCODE ){
     return YY_NO_ACTION;
   }
   return pState->actionDefault;