-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
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
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
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 */
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 */
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 */
/* 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);
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;
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);
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 ){
{
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;
}
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;
/* 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];
/* 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];
** 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;
}
/* 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 */
}
}
+
+/*
+** 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.