aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lemon/lemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lemon/lemon.c')
-rw-r--r--tools/lemon/lemon.c132
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;
}