diff options
Diffstat (limited to 'tools/lemon/lemon.c')
-rw-r--r-- | tools/lemon/lemon.c | 132 |
1 files changed, 85 insertions, 47 deletions
diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 4fcb1ebc95..406388ef54 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -25,7 +25,7 @@ ** drh@acm.org ** http://www.hwaci.com/drh/ ** -** Updated to sqlite lemon version 1.51 +** Updated to sqlite lemon version 1.54 ** $Id$ */ #include <stdio.h> @@ -105,6 +105,7 @@ struct symbol { } assoc; /* Associativity if predecence is defined */ char *firstset; /* First-set for all rules of this symbol */ Boolean lambda; /* True if NT and can generate an empty string */ + int useCnt; /* Number of times used */ char *destructor; /* Code which executes whenever this symbol is ** popped from the stack during error processing */ int destructorln; /* Line number of destructor code */ @@ -165,7 +166,9 @@ struct action { ACCEPT, REDUCE, ERROR, - CONFLICT, /* Was a reduce, but part of a conflict */ + SSCONFLICT, /* A shift/shift conflict */ + SRCONFLICT, /* Was a reduce, but part of a conflict */ + RRCONFLICT, /* Was a reduce, but part of a conflict */ SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ NOT_USED /* Deleted by compression */ @@ -388,7 +391,7 @@ static struct action *Action_new(void){ if( freelist==0 ){ int i; int amt = 100; - freelist = (struct action *)malloc( sizeof(struct action)*amt ); + freelist = (struct action *)calloc(amt, sizeof(struct action)); if( freelist==0 ){ fprintf(stderr,"Unable to allocate memory for a new parser action."); exit(1); @@ -410,8 +413,10 @@ static int actioncmp(const void *ap1_arg, const void *ap2_arg) const struct action *ap1 = ap1_arg, *ap2 = ap2_arg; int rc; rc = ap1->sp->index - ap2->sp->index; - if( rc==0 ) rc = (int)ap1->type - (int)ap2->type; if( rc==0 ){ + rc = (int)ap1->type - (int)ap2->type; + } + if( rc==0 && ap1->type==REDUCE ){ rc = ap1->x.rp->index - ap2->x.rp->index; } return rc; @@ -1040,7 +1045,7 @@ static int resolve_conflict( int errcnt = 0; assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ if( apx->type==SHIFT && apy->type==SHIFT ){ - apy->type = CONFLICT; + apy->type = SSCONFLICT; errcnt++; } if( apx->type==SHIFT && apy->type==REDUCE ){ @@ -1048,7 +1053,7 @@ static int resolve_conflict( spy = apy->x.rp->precsym; if( spy==0 || spx->prec<0 || spy->prec<0 ){ /* Not enough precedence information. */ - apy->type = CONFLICT; + apy->type = SRCONFLICT; errcnt++; }else if( spx->prec>spy->prec ){ /* Lower precedence wins */ apy->type = RD_RESOLVED; @@ -1060,7 +1065,7 @@ static int resolve_conflict( apx->type = SH_RESOLVED; }else{ assert( spx->prec==spy->prec && spx->assoc==NONE ); - apy->type = CONFLICT; + apy->type = SRCONFLICT; errcnt++; } }else if( apx->type==REDUCE && apy->type==REDUCE ){ @@ -1068,7 +1073,7 @@ static int resolve_conflict( spy = apy->x.rp->precsym; if( spx==0 || spy==0 || spx->prec<0 || spy->prec<0 || spx->prec==spy->prec ){ - apy->type = CONFLICT; + apy->type = RRCONFLICT; errcnt++; }else if( spx->prec>spy->prec ){ apy->type = RD_RESOLVED; @@ -1079,10 +1084,14 @@ static int resolve_conflict( assert( apx->type==SH_RESOLVED || apx->type==RD_RESOLVED || - apx->type==CONFLICT || + apx->type==SSCONFLICT || + apx->type==SRCONFLICT || + apx->type==RRCONFLICT || apy->type==SH_RESOLVED || apy->type==RD_RESOLVED || - apy->type==CONFLICT + apy->type==SSCONFLICT || + apy->type==SRCONFLICT || + apy->type==RRCONFLICT ); /* The REDUCE/SHIFT case cannot happen because SHIFTs come before ** REDUCEs on the list. If we reach this point it must be because @@ -1108,7 +1117,7 @@ PRIVATE struct config *newconfig(void){ if( freelist==0 ){ int i; int amt = 3; - freelist = (struct config *)malloc( sizeof(struct config)*amt ); + freelist = (struct config *)calloc( amt, sizeof(struct config) ); if( freelist==0 ){ fprintf(stderr,"Unable to allocate memory for a new configuration."); exit(1); @@ -1492,6 +1501,7 @@ int main(int argc _U_, char **argv) lem.basisflag = basisflag; Symbol_new("$"); lem.errsym = Symbol_new("error"); + lem.errsym->useCnt = 0; lem.outdirname = outdirname; lem.templatename = templatename; lem.basename = make_basename(lem.filename); @@ -1520,7 +1530,7 @@ int main(int argc _U_, char **argv) Reprint(&lem); }else{ /* Initialize the size for all follow and first sets */ - SetSize(lem.nterminal); + SetSize(lem.nterminal+1); /* Find the precedence for every production rule (that has one) */ FindRulePrecedences(&lem); @@ -2141,8 +2151,8 @@ to follow the previous rule."); case IN_RHS: if( x[0]=='.' ){ struct rule *rp; - rp = (struct rule *)malloc( sizeof(struct rule) + - sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs ); + rp = (struct rule *)calloc( sizeof(struct rule) + + sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1); if( rp==0 ){ ErrorMsg(psp->filename,psp->tokenlineno, "Can't allocate enough memory for this rule."); @@ -2178,7 +2188,7 @@ to follow the previous rule."); }else if( safe_isalpha(x[0]) ){ if( psp->nrhs>=MAXRHS ){ ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbols on RHS or rule beginning at \"%s\".", + "Too many symbols on RHS of rule beginning at \"%s\".", x); psp->errorcnt++; psp->state = RESYNC_AFTER_RULE_ERROR; @@ -2191,11 +2201,11 @@ to follow the previous rule."); struct symbol *msp = psp->rhs[psp->nrhs-1]; if( msp->type!=MULTITERMINAL ){ struct symbol *origsp = msp; - msp = malloc(sizeof(*msp)); + msp = calloc(1,sizeof(*msp)); memset(msp, 0, sizeof(*msp)); msp->type = MULTITERMINAL; msp->nsubsym = 1; - msp->subsym = malloc(sizeof(struct symbol*)); + msp->subsym = calloc(1,sizeof(struct symbol*)); msp->subsym[0] = origsp; msp->name = origsp->name; psp->rhs[psp->nrhs-1] = msp; @@ -2661,7 +2671,7 @@ struct plink *Plink_new(void){ if( plink_freelist==0 ){ int i; int amt = 100; - plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt ); + plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) ); if( plink_freelist==0 ){ fprintf(stderr, "Unable to allocate memory for a new follow-set propagation link.\n"); @@ -2906,10 +2916,15 @@ PRIVATE int PrintAction(struct action *ap, FILE *fp, int indent){ case ERROR: fprintf(fp,"%*s error",indent,ap->sp->name); break; - case CONFLICT: + case SRCONFLICT: + case RRCONFLICT: fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", indent,ap->sp->name,ap->x.rp->index); break; + case SSCONFLICT: + fprintf(fp,"%*s shift %d ** Parsing conflict **", + indent,ap->sp->name,ap->x.stp->statenum); + break; case SH_RESOLVED: case RD_RESOLVED: case NOT_USED: @@ -3401,7 +3416,7 @@ PRIVATE void print_stack_union( /* Allocate and initialize types[] and allocate stddt[] */ arraysize = lemp->nsymbol * 2; - types = (char**)malloc( arraysize * sizeof(char*) ); + types = (char**)calloc( arraysize, sizeof(char*) ); for(i=0; i<arraysize; i++) types[i] = 0; maxdtlength = 0; if( lemp->vartype ){ @@ -3482,7 +3497,10 @@ PRIVATE void print_stack_union( fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; free(types[i]); } - fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; + if( lemp->errsym->useCnt ){ + fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; + } + free(stddt); free(types); fprintf(out,"} YYMINORTYPE;\n"); lineno++; @@ -3542,6 +3560,24 @@ static int axset_compare(const void *a, const void *b){ return p2->nAction - p1->nAction; } +/* +** Write text on "out" that describes the rule "rp". +*/ +static void writeRuleText(FILE *out, struct rule *rp){ + int j; + fprintf(out,"%s ::=", rp->lhs->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); + } + } + } +} + /* Generate C source code for the parser */ void ReportTable( struct lemon *lemp, @@ -3637,8 +3673,10 @@ void ReportTable( } fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; - fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; - fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; + if( lemp->errsym->useCnt ){ + fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; + fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; + } if( lemp->has_fallback ){ fprintf(out,"#define YYFALLBACK 1\n"); lineno++; } @@ -3657,7 +3695,7 @@ void ReportTable( */ /* Compute the actions on all states and count them up */ - ax = malloc( sizeof(ax[0])*lemp->nstate*2 ); + ax = calloc(lemp->nstate*2, sizeof(ax[0])); if( ax==0 ){ fprintf(stderr,"malloc failed\n"); exit(1); @@ -3837,17 +3875,8 @@ void ReportTable( */ 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++){ - 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," /* %3d */ \"", i); + writeRuleText(out, rp); fprintf(out,"\",\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); @@ -3860,7 +3889,8 @@ void ReportTable( for(i=0; i<lemp->nsymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type!=TERMINAL ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp->index, sp->name); lineno++; } for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++); if( i<lemp->nsymbol ){ @@ -3874,7 +3904,8 @@ void ReportTable( struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->index<=0 || sp->destructor!=0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp->index, sp->name); lineno++; dflt_sp = sp; } if( dflt_sp!=0 ){ @@ -3885,7 +3916,8 @@ void ReportTable( for(i=0; i<lemp->nsymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp->index, sp->name); lineno++; /* Combine duplicate destructors into a single case */ for(j=i+1; j<lemp->nsymbol; j++){ @@ -3893,7 +3925,8 @@ void ReportTable( if( sp2 && sp2->type!=TERMINAL && sp2->destructor && sp2->dtnum==sp->dtnum && strcmp(sp->destructor,sp2->destructor)==0 ){ - fprintf(out," case %d:\n",sp2->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp2->index, sp2->name); lineno++; sp2->destructor = 0; } } @@ -3924,10 +3957,14 @@ void ReportTable( for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; if( rp->code==0 ) continue; - fprintf(out," case %d:\n",rp->index); lineno++; + fprintf(out," case %d: /* ", rp->index); + writeRuleText(out, rp); + fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ if( rp2->code==rp->code ){ - fprintf(out," case %d:\n",rp2->index); lineno++; + fprintf(out," case %d: /* ", rp2->index); + writeRuleText(out, rp2); + fprintf(out," */\n"); lineno++; rp2->code = 0; } } @@ -4125,12 +4162,10 @@ void SetSize(int n) /* Allocate a new set */ char *SetNew(void){ char *s; - int i; - s = (char*)malloc( size ); + s = (char*)calloc( size, 1); if( s==0 ){ memory_error(); } - for(i=0; i<size; i++) s[i] = 0; return s; } @@ -4145,6 +4180,7 @@ void SetFree(char *s) int SetAdd(char *s, int e) { int rv; + assert( e>=0 && e<size ); rv = s[e]; s[e] = 1; return !rv; @@ -4327,7 +4363,7 @@ struct symbol *Symbol_new(const char *x) sp = Symbol_find(x); if( sp==0 ){ - sp = (struct symbol *)malloc( sizeof(struct symbol) ); + sp = (struct symbol *)calloc(1, sizeof(struct symbol) ); MemoryCheck(sp); sp->name = Strsafe(x); sp->type = safe_isupper(*x) ? TERMINAL : NONTERMINAL; @@ -4339,8 +4375,10 @@ struct symbol *Symbol_new(const char *x) sp->lambda = LEMON_FALSE; sp->destructor = 0; sp->datatype = 0; + sp->useCnt = 0; Symbol_insert(sp,sp->name); } + sp->useCnt++; return sp; } @@ -4508,7 +4546,7 @@ struct symbol **Symbol_arrayof(void) int i,size; if( x2a==0 ) return 0; size = x2a->count; - array = (struct symbol **)malloc( sizeof(struct symbol *)*size ); + array = (struct symbol **)calloc(size, sizeof(struct symbol *)); if( array ){ for(i=0; i<size; i++) array[i] = x2a->tbl[i].data; } @@ -4555,7 +4593,7 @@ PRIVATE int statehash(struct config *a) struct state *State_new(void) { struct state *new; - new = (struct state *)malloc( sizeof(struct state) ); + new = (struct state *)calloc(1, sizeof(struct state) ); MemoryCheck(new); return new; } |