diff --git a/manifest b/manifest index cc6ca48e0c..d7fb996020 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssqlite_progress_handler()\sAPI\sfor\sspecifying\san\sprogress\scallback\s(CVS\s1111) -D 2003-10-18T09:37:26 +C Convert\slemon\sto\suse\sa\ssingle\sperfect\shash\stable\sfor\sstoring\sthe\sactions.\nThis\sshould\smake\sthe\sresulting\sparser\sboth\ssmaller\sand\sfaster.\s(CVS\s1112) +D 2003-10-21T13:16:04 F Makefile.in ab585a91e34bc33928a1b6181fa2f6ebd4fb17e1 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -138,8 +138,8 @@ F test/version.test 605fd0d7e7d571370c32b12dbf395b58953de246 F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53 F test/where.test cb3a2ed062ce4b5f08aff2d08027c6a46d68c47b F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b -F tool/lemon.c 93db920de9479657d04ca73e9368db7fc2969990 -F tool/lempar.c 73a991cc3017fb34804250fa901488b5147b3717 +F tool/lemon.c 37d1493549a238bba56cc8a6e614191f43eac573 +F tool/lempar.c a3406868634ef5e67a8a03675317dcf5623d4740 F tool/memleak.awk 16ef9493dcd36146f806e75148f4bb0201a123ec F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x @@ -174,7 +174,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 -P 06d4e88394217fb1390b069bad82d6ac71981f72 -R cde37f606921798e43de3b54f3499f6d -U danielk1977 -Z a955533f397af1a9a7db7d26a39908ea +P ddb364635a207658664ea92fc677cf16a143a938 +R c217117a68a15b5b6ece4f04bcc9b9b1 +U drh +Z 76b8ed5abf9139dcfee1277f9c2ad231 diff --git a/manifest.uuid b/manifest.uuid index a066bc7a39..78fc3c5f91 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ddb364635a207658664ea92fc677cf16a143a938 \ No newline at end of file +4f955c00076b16166ff837749efb84201eab3c3a \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index b801e6b39e..0fe454b943 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -10,6 +10,7 @@ #include #include #include +#include extern void qsort(); extern double strtod(); @@ -215,10 +216,11 @@ struct state { struct config *cfp; /* All configurations in this set */ int index; /* Sequencial number for this state */ struct action *ap; /* Array of actions for this state */ - int naction; /* Number of actions for this state */ - int tabstart; /* First index of the action table */ - int tabdfltact; /* Default action */ + int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ + int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ + int iDflt; /* Default action */ }; +#define NO_OFFSET (-2147483647) /* A followset propagation link indicates that the contents of one ** configuration followset should be propagated to another whenever @@ -394,6 +396,160 @@ char *arg; new->x.rp = (struct rule *)arg; } } +/********************** New code to implement the "acttab" module ***********/ +/* +** This module implements routines use to construct the yy_action[] table. +*/ + +/* +** The state of the yy_action table under construction is an instance of +** the following structure +*/ +typedef struct acttab acttab; +struct acttab { + int nAction; /* Number of used slots in aAction[] */ + int nActionAlloc; /* Slots allocated for aAction[] */ + struct { + int lookahead; /* Value of the lookahead token */ + int action; /* Action to take on the given lookahead */ + } *aAction, /* The yy_action[] table under construction */ + *aLookahead; /* A single new transaction set */ + int mnLookahead; /* Minimum aLookahead[].lookahead */ + int mnAction; /* Action associated with mnLookahead */ + int mxLookahead; /* Maximum aLookahead[].lookahead */ + int nLookahead; /* Used slots in aLookahead[] */ + int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ +}; + +/* Return the number of entries in the yy_action table */ +#define acttab_size(X) ((X)->nAction) + +/* The value for the N-th entry in yy_action */ +#define acttab_yyaction(X,N) ((X)->aAction[N].action) + +/* The value for the N-th entry in yy_lookahead */ +#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) + +/* Free all memory associated with the given acttab */ +void acttab_free(acttab *p){ + free( p->aAction ); + free( p->aLookahead ); + free( p ); +} + +/* Allocate a new acttab structure */ +acttab *acttab_alloc(void){ + acttab *p = malloc( sizeof(*p) ); + if( p==0 ){ + fprintf(stderr,"Unable to allocate memory for a new acttab."); + exit(1); + } + memset(p, 0, sizeof(*p)); + return p; +} + +/* Add a new action to the current transaction set +*/ +void acttab_action(acttab *p, int lookahead, int action){ + if( p->nLookahead>=p->nLookaheadAlloc ){ + p->nLookaheadAlloc += 25; + p->aLookahead = realloc( p->aLookahead, + sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); + if( p->aLookahead==0 ){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + } + if( p->nLookahead==0 ){ + p->mxLookahead = lookahead; + p->mnLookahead = lookahead; + p->mnAction = action; + }else{ + if( p->mxLookaheadmxLookahead = lookahead; + if( p->mnLookahead>lookahead ){ + p->mnLookahead = lookahead; + p->mnAction = action; + } + } + p->aLookahead[p->nLookahead].lookahead = lookahead; + p->aLookahead[p->nLookahead].action = action; + p->nLookahead++; +} + +/* +** Add the transaction set built up with prior calls to acttab_action() +** into the current action table. Then reset the transaction set back +** to an empty set in preparation for a new round of acttab_action() calls. +** +** Return the offset into the action table of the new transaction. +*/ +int acttab_insert(acttab *p){ + int i, j, k, n; + assert( p->nLookahead>0 ); + + /* Make sure we have enough space to hold the expanded action table + ** in the worst case. The worst case occurs if the transaction set + ** must be appended to the current action table + */ + n = p->mxLookahead - p->mnLookahead + 1; + if( p->nAction + n >= p->nActionAlloc ){ + p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; + p->aAction = realloc( p->aAction, + sizeof(p->aAction[0])*p->nActionAlloc); + if( p->aAction==0 ){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + for(i=p->nAction; inActionAlloc; i++){ + p->aAction[i].lookahead = -1; + p->aAction[i].action = -1; + } + } + + /* Scan the existing action table looking for an offset where we can + ** insert the current transaction set. Fall out of the loop when that + ** offset is found. In the worst case, we fall out of the loop when + ** i reaches p->nAction, which means we append the new transaction set. + ** + ** i is the index in p->aAction[] where p->mnLookahead is inserted. + */ + 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( j==p->nLookahead ) break; /* Fits in empty slots */ + }else 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; + if( k<0 || k>=p->nAction ) break; + if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break; + if( p->aLookahead[j].action!=p->aAction[k].action ) break; + } + if( jnLookahead ) continue; + n = 0; + for(j=0; jnAction; j++){ + if( p->aAction[j].lookahead==j+i-p->mnLookahead ) n++; + } + if( n==p->nLookahead ) break; /* Same as a prior transaction set */ + } + } + /* Insert transaction set at index i. */ + for(j=0; jnLookahead; j++){ + k = p->aLookahead[j].lookahead - p->mnLookahead + i; + p->aAction[k] = p->aLookahead[j]; + if( k>=p->nAction ) p->nAction = k+1; + } + p->nLookahead = 0; + + /* Return the offset that is added to the lookahead in order to get the + ** index into yy_action of the action */ + return i - p->mnLookahead; +} + /********************** From the file "assert.c" ****************************/ /* ** A more efficient way of handling assertions. @@ -1672,17 +1828,17 @@ void OptPrint(){ case OPT_INT: case OPT_FINT: fprintf(errstream," %s=%*s %s\n",op[i].label, - max-strlen(op[i].label)-9,"",op[i].message); + (int)(max-strlen(op[i].label)-9),"",op[i].message); break; case OPT_DBL: case OPT_FDBL: fprintf(errstream," %s=%*s %s\n",op[i].label, - max-strlen(op[i].label)-6,"",op[i].message); + (int)(max-strlen(op[i].label)-6),"",op[i].message); break; case OPT_STR: case OPT_FSTR: fprintf(errstream," %s=%*s %s\n",op[i].label, - max-strlen(op[i].label)-8,"",op[i].message); + (int)(max-strlen(op[i].label)-8),"",op[i].message); break; } } @@ -2654,7 +2810,7 @@ struct lemon *lemp; cp = strrchr(lemp->filename,'.'); if( cp ){ - sprintf(buf,"%.*s.lt",(unsigned long)cp-(unsigned long)lemp->filename,lemp->filename); + sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); }else{ sprintf(buf,"%s.lt",lemp->filename); } @@ -2949,15 +3105,23 @@ int mhflag; /* True if generating makeheaders output */ /* ** Return the name of a C datatype able to represent values between -** 0 and N, inclusive. +** lwr and upr, inclusive. */ -static const char *minimum_size_type(int N){ - if( N<=255 ){ - return "unsigned char"; - }else if( N<65535 ){ - return "unsigned short int"; +static const char *minimum_size_type(int lwr, int upr){ + if( lwr>=0 ){ + if( upr<=255 ){ + return "unsigned char"; + }else if( upr<65535 ){ + return "unsigned short int"; + }else{ + return "unsigned int"; + } + }else if( lwr>=-127 && upr<=127 ){ + return "signed char"; + }else if( lwr>=-32767 && upr<32767 ){ + return "short"; }else{ - return "unsigned int"; + return "int"; } } @@ -2972,9 +3136,11 @@ int mhflag; /* Output in makeheaders format if true */ struct state *stp; struct action *ap; struct rule *rp; - int i, j; - int tablecnt; + struct acttab *pActtab; + int i, j, n; char *name; + int mnTknOfst, mxTknOfst; + int mnNtOfst, mxNtOfst; in = tplt_open(lemp); if( in==0 ) return; @@ -3012,10 +3178,10 @@ int mhflag; /* Output in makeheaders format if true */ /* Generate the defines */ fprintf(out,"/* \001 */\n"); fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(lemp->nsymbol+5)); lineno++; + minimum_size_type(0, lemp->nsymbol+5)); lineno++; fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(lemp->nstate+lemp->nrule+5)); lineno++; + minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; print_stack_union(out,lemp,&lineno,mhflag); if( lemp->stacksize ){ if( atoi(lemp->stacksize)<=0 ){ @@ -3062,111 +3228,161 @@ int mhflag; /* Output in makeheaders format if true */ } tplt_xfer(lemp->name,in,out,&lineno); - /* Generate the action table. + /* Generate the action table and its associates: ** - ** Each entry in the action table is an element of the following - ** structure: - ** struct yyActionEntry { - ** YYCODETYPE lookahead; - ** YYCODETYPE next; - ** YYACTIONTYPE action; - ** } - ** - ** The entries are grouped into hash tables, one hash table for each - ** 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. + ** yy_action[] A single table containing all actions. + ** yy_lookahead[] A table containing the lookahead for each entry in + ** yy_action. Used to detect hash collisions. + ** yy_shift_ofst[] For each state, the offset into yy_action for + ** shifting terminals. + ** yy_reduce_ofst[] For each state, the offset into yy_action for + ** shifting non-terminals after a reduce. + ** yy_default[] Default action for each state. */ - tablecnt = 0; - /* Loop over parser states */ - for(i=0; instate; i++){ - int tablesize; /* size of the hash table */ - int j,k; /* Loop counter */ - int collide[2048]; /* The collision chain for the table */ - struct action *table[2048]; /* Build the hash table here */ - - /* Find the number of actions and initialize the hash table */ - stp = lemp->sorted[i]; - stp->tabstart = tablecnt; - stp->naction = 0; - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->sp->index!=lemp->nsymbol && compute_action(lemp,ap)>=0 ){ - stp->naction++; - } - } - tablesize = stp->naction; - assert( tablesize<= sizeof(table)/sizeof(table[0]) ); - for(j=0; jtabdfltact = lemp->nstate + lemp->nrule; - for(ap=stp->ap; ap; ap=ap->next){ - int action = compute_action(lemp,ap); - int h; - if( ap->sp->index==lemp->nsymbol ){ - stp->tabdfltact = action; - }else if( action>=0 ){ - h = ap->sp->index % tablesize; - ap->collide = table[h]; - table[h] = ap; - } - } - - /* Resolve collisions */ - for(j=k=0; jcollide ){ - while( table[k] ) k++; - table[k] = table[j]->collide; - collide[j] = k; - table[j]->collide = 0; - if( k0 ){ - fprintf(out,"/* State %d */\n",stp->index); lineno++; - } - for(j=0; jsp->index, - collide[j]+1, - compute_action(lemp,table[j]), - j+1); - PrintAction(table[j],out,22); - fprintf(out," */\n"); - lineno++; - } - - /* Update the table count */ - tablecnt += tablesize; - } - tplt_xfer(lemp->name,in,out,&lineno); - lemp->tablesize = tablecnt; - - /* Generate the state table - ** - ** Each entry is an element of the following structure: - ** struct yyStateEntry { - ** struct yyActionEntry *hashtbl; - ** YYCODETYPE nEntry; - ** YYACTIONTYPE actionDefault; - ** } - */ + /* Compute the actions on all states and count them up */ for(i=0; instate; i++){ stp = lemp->sorted[i]; - fprintf(out," { &yyActionTable[%d],%4d,%4d },\n", - stp->tabstart, - stp->naction, - stp->tabdfltact); lineno++; + 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->indexnterminal ){ + stp->nTknAct++; + }else if( ap->sp->indexnsymbol ){ + stp->nNtAct++; + }else{ + stp->iDflt = compute_action(lemp, ap); + } + } + } } + mxTknOfst = mnTknOfst = 0; + mxNtOfst = mnNtOfst = 0; + + /* Compute the action table. Do this in two passes. The first + ** pass does all entries with two or more actions and the second + ** pass does all states with a single action. + */ + pActtab = acttab_alloc(); + for(j=0; j<=1; j++){ + for(i=0; instate; i++){ + stp = lemp->sorted[i]; + if( (j==0 && stp->nTknAct>=2) || (j==1 && stp->nTknAct==1) ){ + for(ap=stp->ap; ap; ap=ap->next){ + int action; + if( ap->sp->index>=lemp->nterminal ) continue; + action = compute_action(lemp, ap); + if( action<0 ) continue; + acttab_action(pActtab, ap->sp->index, action); + } + stp->iTknOfst = acttab_insert(pActtab); + if( stp->iTknOfstiTknOfst; + if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; + } + if( (j==0 && stp->nNtAct>=2) || (j==1 && stp->nNtAct==1) ){ + for(ap=stp->ap; ap; ap=ap->next){ + int action; + if( ap->sp->indexnterminal ) continue; + if( ap->sp->index==lemp->nsymbol ) continue; + action = compute_action(lemp, ap); + if( action<0 ) continue; + acttab_action(pActtab, ap->sp->index, action); + } + stp->iNtOfst = acttab_insert(pActtab); + if( stp->iNtOfstiNtOfst; + if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; + } + } + } + + /* Output the yy_action table */ + fprintf(out,"static YYACTIONTYPE yy_action[] = {\n"); lineno++; + n = acttab_size(pActtab); + for(i=j=0; insymbol + lemp->nrule + 2; + fprintf(out, " %4d,", action); + if( j==9 || i==n-1 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } + } + fprintf(out, "};\n"); lineno++; + + /* Output the yy_lookahead table */ + fprintf(out,"static YYCODETYPE yy_lookahead[] = {\n"); lineno++; + for(i=j=0; insymbol; + fprintf(out, " %4d,", la); + if( j==9 || i==n-1 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } + } + fprintf(out, "};\n"); lineno++; + + /* Output the yy_shift_ofst[] table */ + fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; + fprintf(out, "static %s yy_shift_ofst[] = {\n", + minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; + n = lemp->nstate; + for(i=j=0; isorted[i]; + ofst = stp->iTknOfst; + if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; + fprintf(out, " %4d,", ofst); + if( j==9 || i==n-1 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } + } + fprintf(out, "};\n"); lineno++; + + /* Output the yy_reduce_ofst[] table */ + fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; + fprintf(out, "static %s yy_reduce_ofst[] = {\n", + minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; + n = lemp->nstate; + for(i=j=0; isorted[i]; + ofst = stp->iNtOfst; + if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1; + fprintf(out, " %4d,", ofst); + if( j==9 || i==n-1 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } + } + fprintf(out, "};\n"); lineno++; + + /* Output the default action table */ + fprintf(out, "static YYACTIONTYPE yy_default[] = {\n"); lineno++; + n = lemp->nstate; + for(i=j=0; isorted[i]; + fprintf(out, " %4d,", stp->iDflt); + if( j==9 || i==n-1 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } + } + fprintf(out, "};\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); /* Generate the table of fallback tokens. @@ -3336,7 +3552,6 @@ struct lemon *lemp; struct rule *rp, *rp2, *rbest; int nbest, n; int i; - int cnt; for(i=0; instate; i++){ stp = lemp->sorted[i]; diff --git a/tool/lempar.c b/tool/lempar.c index 5604fe10d4..88d93b5637 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -58,55 +58,49 @@ #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) -/* Next is the action table. Each entry in this table contains -** -** + An integer which is the number representing the look-ahead -** token -** -** + An integer indicating what action to take. Number (N) between -** 0 and YYNSTATE-1 mean shift the look-ahead and go to state N. -** Numbers between YYNSTATE and YYNSTATE+YYNRULE-1 mean reduce by -** rule N-YYNSTATE. Number YYNSTATE+YYNRULE means that a syntax -** error has occurred. Number YYNSTATE+YYNRULE+1 means the parser -** accepts its input. -** -** + A pointer to the next entry with the same hash value. -** -** The action table is really a series of hash tables. Each hash -** table contains a number of entries which is a power of two. The -** "state" table (which follows) contains information about the starting -** point and size of each hash table. -*/ -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 */ -}; -typedef struct yyActionEntry yyActionEntry; -static const yyActionEntry yyActionTable[] = { -%% -}; -/* The state table contains information needed to look up the correct -** action in the action table, given the current state of the parser. -** Information needed includes: +/* Next are that ables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. ** -** + A pointer to the start of the action hash table in yyActionTable. +** The action integer is a number N between +** 0 and YYNSTATE-1 mean shift the look-ahead and go to state N. +** Numbers between YYNSTATE and YYNSTATE+YYNRULE-1 mean reduce by +** rule N-YYNSTATE. Number YYNSTATE+YYNRULE means that a syntax +** error has occurred. Number YYNSTATE+YYNRULE+1 means the parser +** accepts its input. ** -** + The number of entries in the action hash table. +** The action table is constructed as a single large hash table with +** a perfect hash. Given state S and lookahead X, the action is computed +** as ** -** + The default action. This is the action to take if no entry for -** the given look-ahead is found in the action hash table. +** yy_action[ yy_shift_ofst[S] + X ] +** +** If the index yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. +** +** The formula above is for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. */ -struct yyStateEntry { - const yyActionEntry *hashtbl; /* Start of the hash table in yyActionTable */ - YYCODETYPE nEntry; /* Number of entries in action hash table */ - YYACTIONTYPE actionDefault; /* Default action if look-ahead not found */ -}; -typedef struct yyStateEntry yyStateEntry; -static const yyStateEntry yyStateTable[] = { %% -}; +#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) /* The next table maps tokens into fallback tokens. If a construct ** like the following: @@ -312,32 +306,31 @@ void ParseFree( } /* -** Find the appropriate action for a parser given the look-ahead token. +** Find the appropriate action for a parser given the terminal +** look-ahead token iLookAhead. ** ** If the look-ahead token is YYNOCODE, then check to see if the action is ** independent of the look-ahead. If it is, return the action, otherwise ** return YY_NO_ACTION. */ -static int yy_find_parser_action( +static int yy_find_shift_action( yyParser *pParser, /* The parser */ - int iLookAhead /* The look-ahead token */ + int iLookAhead /* The look-ahead token */ ){ - const yyStateEntry *pState; /* Appropriate entry in the state table */ - const yyActionEntry *pAction; /* Action appropriate for the look-ahead */ - int iFallback; /* Fallback token */ + int i; /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */ - pState = &yyStateTable[pParser->yytop->stateno]; - 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; - if( pAction->next==0 ) break; - pAction = &pState->hashtbl[pAction->next-1]; - } + i = yy_shift_ofst[pParser->yytop->stateno]; + if( i==YY_SHIFT_USE_DFLT ){ + return yy_default[pParser->yytop->stateno]; + } + if( iLookAhead==YYNOCODE ){ + return YY_NO_ACTION; + } + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK + int iFallback; /* Fallback token */ if( iLookAheadhashtbl->lookahead!=YYNOCODE ){ + return yy_default[pParser->yytop->stateno]; + }else{ + return yy_action[i]; + } +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_reduce_action( + yyParser *pParser, /* The parser */ + int iLookAhead /* The look-ahead token */ +){ + int i; + + i = yy_reduce_ofst[pParser->yytop->stateno]; + if( i==YY_REDUCE_USE_DFLT ){ + return yy_default[pParser->yytop->stateno]; + } + if( iLookAhead==YYNOCODE ){ return YY_NO_ACTION; } - return pState->actionDefault; + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + return yy_default[pParser->yytop->stateno]; + }else{ + return yy_action[i]; + } } /* @@ -447,7 +469,7 @@ static void yy_reduce( yysize = yyRuleInfo[yyruleno].nrhs; yypParser->yyidx -= yysize; yypParser->yytop -= yysize; - yyact = yy_find_parser_action(yypParser,yygoto); + yyact = yy_find_reduce_action(yypParser,yygoto); if( yyact < YYNSTATE ){ yy_shift(yypParser,yyact,yygoto,&yygotominor); }else if( yyact == YYNSTATE + YYNRULE + 1 ){ @@ -559,7 +581,7 @@ void Parse( #endif do{ - yyact = yy_find_parser_action(yypParser,yymajor); + yyact = yy_find_shift_action(yypParser,yymajor); if( yyactyyerrcnt--; @@ -612,7 +634,7 @@ void Parse( while( yypParser->yyidx >= 0 && yypParser->yytop->major != YYERRORSYMBOL && - (yyact = yy_find_parser_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE + (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE ){ yy_pop_parser_stack(yypParser); }