diff options
| author | Ilia Alshanetsky <iliaa@php.net> | 2006-08-14 16:35:23 +0000 |
|---|---|---|
| committer | Ilia Alshanetsky <iliaa@php.net> | 2006-08-14 16:35:23 +0000 |
| commit | 5c01690d9b6b84ad576787f38805a85f75b3b82f (patch) | |
| tree | 701b795de27a18b9ee9e376eedd186a834cfa86a /ext/pdo_sqlite/sqlite/tool/lemon.c | |
| parent | 3717342c9f6c08005cf3c32c721c81611a21d268 (diff) | |
| download | php-git-5c01690d9b6b84ad576787f38805a85f75b3b82f.tar.gz | |
MFB: Upgraded libsqlite in pdo_sqlite to 3.3.7
Diffstat (limited to 'ext/pdo_sqlite/sqlite/tool/lemon.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/tool/lemon.c | 298 |
1 files changed, 239 insertions, 59 deletions
diff --git a/ext/pdo_sqlite/sqlite/tool/lemon.c b/ext/pdo_sqlite/sqlite/tool/lemon.c index 8f6e87330a..759e1c3786 100644 --- a/ext/pdo_sqlite/sqlite/tool/lemon.c +++ b/ext/pdo_sqlite/sqlite/tool/lemon.c @@ -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 */ @@ -119,7 +120,8 @@ struct symbol { int index; /* Index number for this symbol */ enum { TERMINAL, - NONTERMINAL + NONTERMINAL, + MULTITERMINAL } type; /* Symbols are all either TERMINALS or NTs */ struct rule *rule; /* Linked list of rules of this (if an NT) */ struct symbol *fallback; /* fallback token in case this token doesn't parse */ @@ -140,6 +142,9 @@ struct symbol { int dtnum; /* The data type number. In the parser, the value ** stack is a union. The .yy%d element of this ** union is the correct data type for this object */ + /* The following fields are used by MULTITERMINALs only */ + int nsubsym; /* Number of constituent symbols in the MULTI */ + struct symbol **subsym; /* Array of constituent symbols */ }; /* Each production rule in the grammar is stored in the following @@ -206,7 +211,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 */ @@ -236,6 +241,7 @@ struct lemon { struct symbol **symbols; /* Sorted array of pointers to symbols */ int errorcnt; /* Number of errors */ struct symbol *errsym; /* The error symbol */ + struct symbol *wildcard; /* Token that matches anything */ char *name; /* Name of the generated parser */ char *arg; /* Declaration of the 3th argument to parser */ char *tokentype; /* Type of terminal symbols in the parser stack */ @@ -584,11 +590,18 @@ struct lemon *xp; struct rule *rp; for(rp=xp->rule; rp; rp=rp->next){ if( rp->precsym==0 ){ - int i; - for(i=0; i<rp->nrhs; i++){ - if( rp->rhs[i]->prec>=0 ){ + int i, j; + for(i=0; i<rp->nrhs && rp->precsym==0; i++){ + struct symbol *sp = rp->rhs[i]; + if( sp->type==MULTITERMINAL ){ + for(j=0; j<sp->nsubsym; j++){ + if( sp->subsym[j]->prec>=0 ){ + rp->precsym = sp->subsym[j]; + break; + } + } + }else if( sp->prec>=0 ){ rp->precsym = rp->rhs[i]; - break; } } } @@ -604,7 +617,7 @@ struct lemon *xp; void FindFirstSets(lemp) struct lemon *lemp; { - int i; + int i, j; struct rule *rp; int progress; @@ -621,7 +634,8 @@ struct lemon *lemp; for(rp=lemp->rule; rp; rp=rp->next){ if( rp->lhs->lambda ) continue; for(i=0; i<rp->nrhs; i++){ - if( rp->rhs[i]->lambda==B_FALSE ) break; + struct symbol *sp = rp->rhs[i]; + if( sp->type!=TERMINAL || sp->lambda==B_FALSE ) break; } if( i==rp->nrhs ){ rp->lhs->lambda = B_TRUE; @@ -641,6 +655,11 @@ struct lemon *lemp; if( s2->type==TERMINAL ){ progress += SetAdd(s1->firstset,s2->index); break; + }else if( s2->type==MULTITERMINAL ){ + for(j=0; j<s2->nsubsym; j++){ + progress += SetAdd(s1->firstset,s2->subsym[j]->index); + } + break; }else if( s1==s2 ){ if( s1->lambda==B_FALSE ) break; }else{ @@ -687,7 +706,7 @@ symbol instead.",lemp->start,lemp->rule->lhs->name); for(rp=lemp->rule; rp; rp=rp->next){ int i; for(i=0; i<rp->nrhs; i++){ - if( rp->rhs[i]==sp ){ + if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */ ErrorMsg(lemp->filename,0, "The start symbol \"%s\" occurs on the \ right-hand side of a rule. This will result in a parser which \ @@ -751,7 +770,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 */ @@ -759,6 +778,24 @@ struct lemon *lemp; return stp; } +/* +** Return true if two symbols are the same. +*/ +int same_symbol(a,b) +struct symbol *a; +struct symbol *b; +{ + int i; + if( a==b ) return 1; + if( a->type!=MULTITERMINAL ) return 0; + if( b->type!=MULTITERMINAL ) return 0; + if( a->nsubsym!=b->nsubsym ) return 0; + for(i=0; i<a->nsubsym; i++){ + if( a->subsym[i]!=b->subsym[i] ) return 0; + } + return 1; +} + /* Construct all successor states to the given state. A "successor" ** state is any state which can be reached by a shift action. */ @@ -791,7 +828,7 @@ struct state *stp; /* The state from which successors are computed */ if( bcfp->status==COMPLETE ) continue; /* Already used */ if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */ bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */ - if( bsp!=sp ) continue; /* Must be same as for "cfp" */ + if( !same_symbol(bsp,sp) ) continue; /* Must be same as for "cfp" */ bcfp->status = COMPLETE; /* Mark this config as used */ new = Configlist_addbasis(bcfp->rp,bcfp->dot+1); Plink_add(&new->bplp,bcfp); @@ -803,7 +840,14 @@ struct state *stp; /* The state from which successors are computed */ /* The state "newstp" is reached from the state "stp" by a shift action ** on the symbol "sp" */ - Action_add(&stp->ap,SHIFT,sp,(char *)newstp); + if( sp->type==MULTITERMINAL ){ + int i; + for(i=0; i<sp->nsubsym; i++){ + Action_add(&stp->ap,SHIFT,sp->subsym[i],(char*)newstp); + } + }else{ + Action_add(&stp->ap,SHIFT,sp,(char *)newstp); + } } } @@ -1166,6 +1210,12 @@ struct lemon *lemp; if( xsp->type==TERMINAL ){ SetAdd(newcfp->fws,xsp->index); break; + }else if( xsp->type==MULTITERMINAL ){ + int k; + for(k=0; k<xsp->nsubsym; k++){ + SetAdd(newcfp->fws, xsp->subsym[k]->index); + } + break; }else{ SetUnion(newcfp->fws,xsp->firstset); if( xsp->lambda==B_FALSE ) break; @@ -1373,6 +1423,7 @@ char **argv; fprintf(stderr,"Exactly one filename argument is required.\n"); exit(1); } + memset(&lem, 0, sizeof(lem)); lem.errorcnt = 0; /* Initialize the machine */ @@ -1382,22 +1433,13 @@ char **argv; lem.argv0 = argv[0]; lem.filename = OptArg(0); lem.basisflag = basisflag; - lem.has_fallback = 0; - lem.nconflict = 0; - lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0; - lem.vartype = 0; - lem.stacksize = 0; - lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest = - lem.tokenprefix = lem.outname = lem.extracode = 0; - lem.vardest = 0; - lem.tablesize = 0; Symbol_new("$"); lem.errsym = Symbol_new("error"); /* Parse the input file */ Parse(&lem); if( lem.errorcnt ) exit(lem.errorcnt); - if( lem.rule==0 ){ + if( lem.nrule==0 ){ fprintf(stderr,"Empty grammar.\n"); exit(1); } @@ -1445,6 +1487,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); @@ -1694,6 +1740,7 @@ FILE *err; int j; int errcnt = 0; cp = strchr(argv[i],'='); + assert( cp!=0 ); *cp = 0; for(j=0; op[j].label; j++){ if( strcmp(argv[i],op[j].label)==0 ) break; @@ -1906,7 +1953,8 @@ struct pstate { RESYNC_AFTER_DECL_ERROR, WAITING_FOR_DESTRUCTOR_SYMBOL, WAITING_FOR_DATATYPE_SYMBOL, - WAITING_FOR_FALLBACK_ID + WAITING_FOR_FALLBACK_ID, + WAITING_FOR_WILDCARD_ID } state; /* The state of the parser */ struct symbol *fallback; /* The fallback token */ struct symbol *lhs; /* Left-hand side of current rule */ @@ -2086,7 +2134,7 @@ to follow the previous rule."); }else if( isalpha(x[0]) ){ if( psp->nrhs>=MAXRHS ){ ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbol on RHS or rule beginning at \"%s\".", + "Too many symbols on RHS or rule beginning at \"%s\".", x); psp->errorcnt++; psp->state = RESYNC_AFTER_RULE_ERROR; @@ -2095,6 +2143,27 @@ to follow the previous rule."); psp->alias[psp->nrhs] = 0; psp->nrhs++; } + }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){ + struct symbol *msp = psp->rhs[psp->nrhs-1]; + if( msp->type!=MULTITERMINAL ){ + struct symbol *origsp = msp; + msp = malloc(sizeof(*msp)); + memset(msp, 0, sizeof(*msp)); + msp->type = MULTITERMINAL; + msp->nsubsym = 1; + msp->subsym = malloc(sizeof(struct symbol*)); + msp->subsym[0] = origsp; + msp->name = origsp->name; + psp->rhs[psp->nrhs-1] = msp; + } + msp->nsubsym++; + msp->subsym = realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); + msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]); + if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){ + ErrorMsg(psp->filename,psp->tokenlineno, + "Cannot form a compound containing a non-terminal"); + psp->errorcnt++; + } }else if( x[0]=='(' && psp->nrhs>0 ){ psp->state = RHS_ALIAS_1; }else{ @@ -2189,6 +2258,8 @@ to follow the previous rule."); }else if( strcmp(x,"fallback")==0 ){ psp->fallback = 0; psp->state = WAITING_FOR_FALLBACK_ID; + }else if( strcmp(x,"wildcard")==0 ){ + psp->state = WAITING_FOR_WILDCARD_ID; }else{ ErrorMsg(psp->filename,psp->tokenlineno, "Unknown declaration keyword: \"%%%s\".",x); @@ -2289,6 +2360,24 @@ to follow the previous rule."); } } break; + case WAITING_FOR_WILDCARD_ID: + if( x[0]=='.' ){ + psp->state = WAITING_FOR_DECL_OR_RULE; + }else if( !isupper(x[0]) ){ + ErrorMsg(psp->filename, psp->tokenlineno, + "%%wildcard argument \"%s\" should be a token", x); + psp->errorcnt++; + }else{ + struct symbol *sp = Symbol_new(x); + if( psp->gp->wildcard==0 ){ + psp->gp->wildcard = sp; + }else{ + ErrorMsg(psp->filename, psp->tokenlineno, + "Extra wildcard to token: %s", x); + psp->errorcnt++; + } + } + break; case RESYNC_AFTER_RULE_ERROR: /* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; ** break; */ @@ -2482,6 +2571,10 @@ struct lemon *gp; }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */ cp += 3; nextcp = cp; + }else if( (c=='/' || c=='|') && isalpha(cp[1]) ){ + cp += 2; + while( (c = *cp)!=0 && (isalnum(c) || c=='_') ) cp++; + nextcp = cp; }else{ /* All other (one character) operators */ cp++; nextcp = cp; @@ -2641,15 +2734,21 @@ struct lemon *lemp; } for(rp=lemp->rule; rp; rp=rp->next){ printf("%s",rp->lhs->name); -/* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ + /* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ printf(" ::="); for(i=0; i<rp->nrhs; i++){ - printf(" %s",rp->rhs[i]->name); -/* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ + sp = rp->rhs[i]; + printf(" %s", sp->name); + if( sp->type==MULTITERMINAL ){ + for(j=1; j<sp->nsubsym; j++){ + printf("|%s", sp->subsym[j]->name); + } + } + /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ } printf("."); if( rp->precsym ) printf(" [%s]",rp->precsym->name); -/* if( rp->code ) printf("\n %s",rp->code); */ + /* if( rp->code ) printf("\n %s",rp->code); */ printf("\n"); } } @@ -2659,18 +2758,25 @@ FILE *fp; struct config *cfp; { struct rule *rp; - int i; + struct symbol *sp; + int i, j; rp = cfp->rp; fprintf(fp,"%s ::=",rp->lhs->name); for(i=0; i<=rp->nrhs; i++){ if( i==cfp->dot ) fprintf(fp," *"); if( i==rp->nrhs ) break; - fprintf(fp," %s",rp->rhs[i]->name); + sp = rp->rhs[i]; + fprintf(fp," %s", sp->name); + if( sp->type==MULTITERMINAL ){ + for(j=1; j<sp->nsubsym; j++){ + fprintf(fp,"|%s",sp->subsym[j]->name); + } + } } } /* #define TEST */ -#ifdef TEST +#if 0 /* Print a set */ PRIVATE void SetPrint(out,set,lemp) FILE *out; @@ -2697,7 +2803,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 +2818,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 +2857,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 ){ @@ -2764,7 +2870,7 @@ struct lemon *lemp; } ConfigPrint(fp,cfp); fprintf(fp,"\n"); -#ifdef TEST +#if 0 SetPrint(fp,cfp->fws,lemp); PlinkPrint(fp,cfp->fplp,"To "); PlinkPrint(fp,cfp->bplp,"From"); @@ -2837,7 +2943,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; @@ -3108,8 +3214,14 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ ** the token number of X, not the value of X */ append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); }else{ - append_str("yymsp[%d].minor.yy%d",0, - i-rp->nrhs+1,rp->rhs[i]->dtnum); + struct symbol *sp = rp->rhs[i]; + int dtnum; + if( sp->type==MULTITERMINAL ){ + dtnum = sp->subsym[0]->dtnum; + }else{ + dtnum = sp->dtnum; + } + append_str("yymsp[%d].minor.yy%d",0,i-rp->nrhs+1, dtnum); } cp = xp; used[i] = 1; @@ -3391,6 +3503,10 @@ int mhflag; /* Output in makeheaders format if true */ fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; fprintf(out,"#define YYACTIONTYPE %s\n", minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; + if( lemp->wildcard ){ + fprintf(out,"#define YYWILDCARD %d\n", + lemp->wildcard->index); lineno++; + } print_stack_union(out,lemp,&lineno,mhflag); if( lemp->stacksize ){ if( atoi(lemp->stacksize)<=0 ){ @@ -3457,21 +3573,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 +3653,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 +3676,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]; @@ -3642,7 +3747,16 @@ int mhflag; /* Output in makeheaders format if true */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ assert( rp->index==i ); fprintf(out," /* %3d */ \"%s ::=", i, rp->lhs->name); - for(j=0; j<rp->nrhs; j++) fprintf(out," %s",rp->rhs[j]->name); + for(j=0; j<rp->nrhs; j++){ + struct symbol *sp = rp->rhs[j]; + fprintf(out," %s", sp->name); + if( sp->type==MULTITERMINAL ){ + int k; + for(k=1; k<sp->nsubsym; k++){ + fprintf(out,"|%s",sp->subsym[k]->name); + } + } + } fprintf(out,"\",\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); @@ -3789,7 +3903,8 @@ 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. Except, there is no default if the wildcard token +** is a possible look-ahead. */ void CompressTables(lemp) struct lemon *lemp; @@ -3799,13 +3914,18 @@ struct lemon *lemp; struct rule *rp, *rp2, *rbest; int nbest, n; int i; + int usesWildcard; for(i=0; i<lemp->nstate; i++){ stp = lemp->sorted[i]; nbest = 0; rbest = 0; + usesWildcard = 0; for(ap=stp->ap; ap; ap=ap->next){ + if( ap->type==SHIFT && ap->sp==lemp->wildcard ){ + usesWildcard = 1; + } if( ap->type!=REDUCE ) continue; rp = ap->x.rp; if( rp==rbest ) continue; @@ -3823,8 +3943,10 @@ 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 or if the wildcard token is a possible + ** lookahead. + */ + if( nbest<1 || usesWildcard ) continue; /* Combine matching REDUCE actions into a single default */ @@ -3840,6 +3962,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. @@ -3932,6 +4111,7 @@ char *y; { char *z; + if( y==0 ) return 0; z = Strsafe_find(y); if( z==0 && (z=malloc( strlen(y)+1 ))!=0 ){ strcpy(z,y); |
