diff options
Diffstat (limited to 'tools/lemon/lemon.c')
-rw-r--r-- | tools/lemon/lemon.c | 76 |
1 files changed, 34 insertions, 42 deletions
diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 709f8c87d5..8f408343a2 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -2733,7 +2733,7 @@ PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, PRIVATE void emit_destructor_code(FILE *out, struct symbol *sp, struct lemon *lemp, int *lineno) { - char *cp = 0; + char *cp; int linecnt = 0; if( sp->type==TERMINAL ){ @@ -2763,7 +2763,7 @@ PRIVATE void emit_destructor_code(FILE *out, struct symbol *sp, struct lemon *le } /* -** Return TRUE (non-zero) if the given symbol has a destructor. ++** Return TRUE (non-zero) if the given symbol has a destructor. */ PRIVATE int has_destructor(struct symbol *sp, struct lemon *lemp) { @@ -2796,9 +2796,9 @@ PRIVATE void emit_code(FILE *out, struct rule *rp, struct lemon *lemp, if( rp->code ){ fprintf(out,"#line %d \"%s\"\n{",rp->line,lemp->filename); for(cp=rp->code; *cp; cp++){ - if( safe_isalpha(*cp) && (cp==rp->code || (!safe_isalnum(cp[-1]) && cp[-1]!='_')) ){ + if( safe_isalpha(*cp) && (cp==rp->code || !safe_isalnum(cp[-1])) ){ char saved; - for(xp= &cp[1]; safe_isalnum(*xp)|| *xp=='_'; xp++); + for(xp= &cp[1]; safe_isalnum(*xp); xp++); saved = *xp; *xp = 0; if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ @@ -2966,21 +2966,6 @@ PRIVATE void print_stack_union( *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( struct lemon *lemp, @@ -3032,10 +3017,10 @@ void ReportTable( /* Generate the defines */ fprintf(out,"/* \001 */\n"); fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(lemp->nsymbol+5)); lineno++; + lemp->nsymbol>250?"int":"unsigned char"); 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++; + lemp->nstate+lemp->nrule>250?"int":"unsigned char"); lineno++; print_stack_union(out,lemp,&lineno,mhflag); if( lemp->stacksize ){ if( atoi(lemp->stacksize)<=0 ){ @@ -3081,16 +3066,13 @@ void ReportTable( ** 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 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. + ** parser state. The hash table has a size which is the smallest + ** power of two needed to hold all entries. */ tablecnt = 0; @@ -3110,7 +3092,8 @@ void ReportTable( stp->naction++; } } - tablesize = stp->naction; + tablesize = 1; + while( tablesize<stp->naction ) tablesize += tablesize; assert( tablesize<= sizeof(table)/sizeof(table[0]) ); for(j=0; j<tablesize; j++){ table[j] = 0; @@ -3125,7 +3108,7 @@ void ReportTable( if( ap->sp->index==lemp->nsymbol ){ stp->tabdfltact = action; }else if( action>=0 ){ - h = ap->sp->index % tablesize; + h = ap->sp->index & (tablesize-1); ap->collide = table[h]; table[h] = ap; } @@ -3143,18 +3126,24 @@ void ReportTable( } /* Print the hash table */ - if( tablesize>0 ){ - fprintf(out,"/* State %d */\n",stp->index); lineno++; - } + fprintf(out,"/* State %d */\n",stp->index); lineno++; for(j=0; j<tablesize; j++){ - assert( table[j]!=0 ); - fprintf(out," {%4d,%4d,%4d}, /* %2d: ", + if( table[j]==0 ){ + fprintf(out, + " {YYNOCODE,0,0}, /* Unused */\n"); + }else{ + fprintf(out," {%4d,%4d, ", table[j]->sp->index, - collide[j]+1, - compute_action(lemp,table[j]), - j+1); - PrintAction(table[j],out,22); - fprintf(out," */\n"); + 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"); + } lineno++; } @@ -3169,15 +3158,18 @@ void ReportTable( ** Each entry is an element of the following structure: ** struct yyStateEntry { ** struct yyActionEntry *hashtbl; - ** YYCODETYPE nEntry; + ** int mask; ** YYACTIONTYPE actionDefault; ** } */ for(i=0; i<lemp->nstate; i++){ + size_t tablesize; stp = lemp->sorted[i]; - fprintf(out," { &yyActionTable[%d],%4d,%4d },\n", + tablesize = 1; + while( tablesize<stp->naction ) tablesize += tablesize; + fprintf(out," { &yyActionTable[%d], %lu, %d},\n", stp->tabstart, - stp->naction, + (unsigned long)tablesize - 1, stp->tabdfltact); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); |