From f16371d650bb49073dbe7da68a47e1d8982807d3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Nov 2009 19:18:31 +0000 Subject: [PATCH] Enhancements to lemon to generate more compact action tables and to avoid making array bounds tests that can never fail on action table calculations. FossilOrigin-Name: 27d8e684db4651155c4bcb8bb44bf1c692b8c48b --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/lempar.c | 26 ++++++++++++++++---------- tool/lemon.c | 50 +++++++++++++++++++++++++++++++------------------- tool/lempar.c | 24 ++++++++++++++++-------- 5 files changed, 75 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index 47cd8d0ac1..2bfb130083 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Force\sall\sqsort()\scalls\sin\smkkeywordhash.c\sto\sbe\sstable\sso\sthat\swe\sget\npredictable\sresults\son\sdifferent\splatforms. -D 2009-11-03T13:08:17 +C Enhancements\sto\slemon\sto\sgenerate\smore\scompact\saction\stables\sand\sto\savoid\nmaking\sarray\sbounds\stests\sthat\scan\snever\sfail\son\saction\stable\scalculations. +D 2009-11-03T19:18:32 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a77dfde96ad86aafd3f71651a4333a104debe86a F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -128,7 +128,7 @@ F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb F src/insert.c 2fe2ef7bd03d6e0120e4525727c4ae7de5a2d571 F src/journal.c e00df0c0da8413ab6e1bb7d7cab5665d4a9000d0 F src/legacy.c 303b4ffcf1ae652fcf5ef635846c563c254564f6 -F src/lempar.c 0c4d1ab0a5ef2b0381eb81a732c54f68f27a574d +F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 0e88a335665db0b2fb4cece3e49dcb65d832635a F src/main.c 5e12af46a6e6149b755830f9c035be6eb77995a6 F src/malloc.c 685561d2f1602042e349aea5d7a88c3f10a63454 @@ -743,8 +743,8 @@ F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 -F tool/lemon.c ee5e39ce2b344ce7c81306b27a59da7698114a2d -F tool/lempar.c 2ed70b3fc896a47e07fedfe543324f008f53d223 +F tool/lemon.c 3088e4dec7f93c6b0925cf5bac04c8b7c8688835 +F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c 9216336085e7a7c226a35c0bd780239968f8304f F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -764,14 +764,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P d66a0f31ebcc56e6f0f462b3db6aab54f7fab816 -R 91e31635600cb3800baa14d4687e1d08 +P 3b02df27ab63936226a90098d88535ed19c2b782 +R 9657839e8a1b2321f27513cd9ab14412 U drh -Z 0bb2002d9c9d8d6a6987522657519773 +Z 79535e58caedc3efe5879d698faec6dd -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFK8CtFoxKgR168RlERAvt+AJkBQI2LJH6CUrPXrZkZDQd5FHmWKwCeNWmo -X0wFI2+tf0Wum9Vwm5FmTGU= -=YTMU +iD8DBQFK8IILoxKgR168RlERAhAJAJ9pB6KdOuaqs+7SONUxYOVTE6z/WwCfZnDD +8HkIYKOVL/iazNE6Eoivw5I= +=rFC0 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index e261fd0d44..7b80eb5b4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b02df27ab63936226a90098d88535ed19c2b782 \ No newline at end of file +27d8e684db4651155c4bcb8bb44bf1c692b8c48b \ No newline at end of file diff --git a/src/lempar.c b/src/lempar.c index 8439bd71c7..fb52490e4c 100644 --- a/src/lempar.c +++ b/src/lempar.c @@ -131,7 +131,6 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** yy_default[] Default action for each state. */ %% -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) /* The next table maps tokens into fallback tokens. If a construct ** like the following: @@ -396,14 +395,13 @@ static int yy_find_shift_action( int i; int stateno = pParser->yystack[pParser->yyidx].stateno; - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + if( stateno>YY_SHIFT_COUNT + || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ return yy_default[stateno]; } assert( iLookAhead!=YYNOCODE ); i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - /* The user of ";" instead of "\000" as a statement terminator in SQLite - ** means that we always have a look-ahead token. */ + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ if( iLookAhead>0 ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ @@ -421,7 +419,15 @@ static int yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j=0 && +#endif +#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT + j %s\n", @@ -453,22 +459,22 @@ static int yy_find_reduce_action( ){ int i; #ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ + if( stateno>YY_REDUCE_COUNT ){ return yy_default[stateno]; } #else - assert( stateno<=YY_REDUCE_MAX ); + assert( stateno<=YY_REDUCE_COUNT ); #endif i = yy_reduce_ofst[stateno]; assert( i!=YY_REDUCE_USE_DFLT ); assert( iLookAhead!=YYNOCODE ); i += iLookAhead; #ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ return yy_default[stateno]; } #else - assert( i>=0 && i=0 && iaAction[] where p->mnLookahead is inserted. */ - for(i=0; inAction+p->mnLookahead; i++){ - if( p->aAction[i].lookahead<0 ){ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 ) break; - if( p->aAction[k].lookahead>=0 ) break; - } - if( jnLookahead ) continue; - for(j=0; jnAction; j++){ - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; - } - if( j==p->nAction ){ - break; /* Fits in empty slots */ - } - }else if( p->aAction[i].lookahead==p->mnLookahead ){ + for(i=p->nAction-1; i>=0; i--){ + /* First look for an existing action table entry that can be reused */ + if( p->aAction[i].lookahead==p->mnLookahead ){ if( p->aAction[i].action!=p->mnAction ) continue; for(j=0; jnLookahead; j++){ k = p->aLookahead[j].lookahead - p->mnLookahead + i; @@ -553,6 +541,25 @@ int acttab_insert(acttab *p){ } } } + if( i<0 ){ + /* If no reusable entry is found, look for an empty slot */ + for(i=0; inAction; i++){ + if( p->aAction[i].lookahead<0 ){ + for(j=0; jnLookahead; j++){ + k = p->aLookahead[j].lookahead - p->mnLookahead + i; + if( k<0 ) break; + if( p->aAction[k].lookahead>=0 ) break; + } + if( jnLookahead ) continue; + for(j=0; jnAction; j++){ + if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; + } + if( j==p->nAction ){ + break; /* Fits in empty slots */ + } + } + } + } /* Insert transaction set at index i. */ for(j=0; jnLookahead; j++){ k = p->aLookahead[j].lookahead - p->mnLookahead + i; @@ -3568,7 +3575,7 @@ int mhflag; /* Output in makeheaders format if true */ struct action *ap; struct rule *rp; struct acttab *pActtab; - int i, j, n; + int i, j, k, n; char *name; int mnTknOfst, mxTknOfst; int mnNtOfst, mxNtOfst; @@ -3727,8 +3734,9 @@ int mhflag; /* Output in makeheaders format if true */ free(ax); /* Output the yy_action table */ - fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; n = acttab_size(pActtab); + fprintf(out,"#define YY_ACTTAB_COUNT (%d)\n", n); lineno++; + fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; for(i=j=0; instate + lemp->nrule + 2; @@ -3763,7 +3771,9 @@ int mhflag; /* Output in makeheaders format if true */ 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, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; + fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; + fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; fprintf(out, "static const %s yy_shift_ofst[] = {\n", minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; for(i=j=0; instate; while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_REDUCE_MAX %d\n", n-1); lineno++; + fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++; + fprintf(out, "#define YY_REDUCE_MIN (%d)\n", mnNtOfst); lineno++; + fprintf(out, "#define YY_REDUCE_MAX (%d)\n", mxNtOfst); lineno++; fprintf(out, "static const %s yy_reduce_ofst[] = {\n", minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; for(i=j=0; iyystack[pParser->yyidx].stateno; - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + if( stateno>YY_SHIFT_COUNT + || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ return yy_default[stateno]; } assert( iLookAhead!=YYNOCODE ); i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ if( iLookAhead>0 ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ @@ -409,7 +409,15 @@ static int yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j=0 && +#endif +#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT + j %s\n", @@ -441,22 +449,22 @@ static int yy_find_reduce_action( ){ int i; #ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ + if( stateno>YY_REDUCE_COUNT ){ return yy_default[stateno]; } #else - assert( stateno<=YY_REDUCE_MAX ); + assert( stateno<=YY_REDUCE_COUNT ); #endif i = yy_reduce_ofst[stateno]; assert( i!=YY_REDUCE_USE_DFLT ); assert( iLookAhead!=YYNOCODE ); i += iLookAhead; #ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ return yy_default[stateno]; } #else - assert( i>=0 && i=0 && i