1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Bug fixes from Oleg Oleinick (CVS 195)

FossilOrigin-Name: 1f0197d504fa2bde15b287ac6c0102cacdb1e482
This commit is contained in:
drh
2001-04-03 16:53:21 +00:00
parent 15c29be81c
commit 960e8c6317
17 changed files with 266 additions and 68 deletions

View File

@ -3,8 +3,8 @@
**
** This file contains all sources (including headers) to the LEMON
** LALR(1) parser generator. The sources have been combined into a
** single file to make it easy to include LEMON as part of another
** program.
** single file to make it easy to include LEMON in the source tree
** and Makefile of another program.
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public
@ -263,6 +263,7 @@ struct lemon {
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 */
char *vartype; /* The default type of non-terminal symbols */
char *start; /* Name of the start symbol for the grammar */
char *stacksize; /* Size of the parser stack */
char *include; /* Code to put at the start of the C file */
@ -279,6 +280,8 @@ struct lemon {
int extracodeln; /* Line number for the start of the extra code */
char *tokendest; /* Code to execute to destroy token data */
int tokendestln; /* Line number for token destroyer code */
char *vardest; /* Code for the default non-terminal destructor */
int vardestln; /* Line number for default non-term destructor code*/
char *filename; /* Name of the input file */
char *outname; /* Name of the current output file */
char *tokenprefix; /* A prefix added to token names in the .h file */
@ -1216,9 +1219,11 @@ char **argv;
lem.basisflag = basisflag;
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");
@ -1967,6 +1972,9 @@ to follow the previous rule.");
}else if( strcmp(x,"token_destructor")==0 ){
psp->declargslot = &psp->gp->tokendest;
psp->decllnslot = &psp->gp->tokendestln;
}else if( strcmp(x,"default_destructor")==0 ){
psp->declargslot = &psp->gp->vardest;
psp->decllnslot = &psp->gp->vardestln;
}else if( strcmp(x,"token_prefix")==0 ){
psp->declargslot = &psp->gp->tokenprefix;
}else if( strcmp(x,"syntax_error")==0 ){
@ -1985,6 +1993,8 @@ to follow the previous rule.");
psp->declargslot = &(psp->gp->arg);
}else if( strcmp(x,"token_type")==0 ){
psp->declargslot = &(psp->gp->tokentype);
}else if( strcmp(x,"default_type")==0 ){
psp->declargslot = &(psp->gp->vartype);
}else if( strcmp(x,"stack_size")==0 ){
psp->declargslot = &(psp->gp->stacksize);
}else if( strcmp(x,"start_symbol")==0 ){
@ -2210,7 +2220,7 @@ struct lemon *gp;
}
}
if( c==0 ){
ErrorMsg(ps.filename,startline,
ErrorMsg(ps.filename,ps.tokenlineno,
"C code starting on this line is not terminated before the end of the file.");
ps.errorcnt++;
nextcp = cp;
@ -2643,6 +2653,8 @@ struct lemon *lemp;
}
if( access(buf,004)==0 ){
tpltname = buf;
}else if( access(templatename,004)==0 ){
tpltname = templatename;
}else{
tpltname = pathsearch(lemp->argv0,templatename,0);
}
@ -2697,10 +2709,13 @@ int *lineno;
cp = lemp->tokendest;
if( cp==0 ) return;
fprintf(out,"#line %d \"%s\"\n{",lemp->tokendestln,lemp->filename);
}else{
}else if( sp->destructor ){
cp = sp->destructor;
if( cp==0 ) return;
fprintf(out,"#line %d \"%s\"\n{",sp->destructorln,lemp->filename);
}else if( lemp->vardest ){
cp = lemp->vardest;
if( cp==0 ) return;
fprintf(out,"#line %d \"%s\"\n{",lemp->vardestln,lemp->filename);
}
for(; *cp; cp++){
if( *cp=='$' && cp[1]=='$' ){
@ -2717,7 +2732,7 @@ int *lineno;
}
/*
** Return TRUE (non-zero) if the given symbol has a distructor.
** Return TRUE (non-zero) if the given symbol has a destructor.
*/
int has_destructor(sp, lemp)
struct symbol *sp;
@ -2727,7 +2742,7 @@ struct lemon *lemp;
if( sp->type==TERMINAL ){
ret = lemp->tokendest!=0;
}else{
ret = sp->destructor!=0;
ret = lemp->vardest!=0 || sp->destructor!=0;
}
return ret;
}
@ -2796,7 +2811,7 @@ int *lineno;
for(i=0; i<rp->nrhs; i++){
if( rp->rhsalias[i] && !used[i] ){
ErrorMsg(lemp->filename,rp->ruleline,
"Label $%s$ for \"%s(%s)\" is never used.",
"Label %s for \"%s(%s)\" is never used.",
rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
lemp->errorcnt++;
}else if( rp->rhsalias[i]==0 ){
@ -2840,6 +2855,9 @@ int mhflag; /* True if generating makeheaders output */
types = (char**)malloc( arraysize * sizeof(char*) );
for(i=0; i<arraysize; i++) types[i] = 0;
maxdtlength = 0;
if( lemp->vartype ){
maxdtlength = strlen(lemp->vartype);
}
for(i=0; i<lemp->nsymbol; i++){
int len;
struct symbol *sp = lemp->symbols[i];
@ -2855,8 +2873,10 @@ int mhflag; /* True if generating makeheaders output */
/* Build a hash table of datatypes. The ".dtnum" field of each symbol
** is filled in with the hash index plus 1. A ".dtnum" value of 0 is
** used for terminal symbols and for nonterminals which don't specify
** a datatype using the %type directive. */
** used for terminal symbols. If there is no %default_type defined then
** 0 is also used as the .dtnum value for nonterminals which do not specify
** a datatype using the %type directive.
*/
for(i=0; i<lemp->nsymbol; i++){
struct symbol *sp = lemp->symbols[i];
char *cp;
@ -2864,11 +2884,12 @@ int mhflag; /* True if generating makeheaders output */
sp->dtnum = arraysize+1;
continue;
}
if( sp->type!=NONTERMINAL || sp->datatype==0 ){
if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){
sp->dtnum = 0;
continue;
}
cp = sp->datatype;
if( cp==0 ) cp = lemp->vartype;
j = 0;
while( isspace(*cp) ) cp++;
while( *cp ) stddt[j++] = *cp++;
@ -3159,6 +3180,20 @@ int mhflag; /* Output in makeheaders format if true */
emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
fprintf(out," break;\n"); lineno++;
}
if( lemp->vardest ){
struct symbol *dflt_sp = 0;
for(i=0; i<lemp->nsymbol; i++){
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++;
dflt_sp = sp;
}
if( dflt_sp!=0 ){
emit_destructor_code(out,dflt_sp,lemp,&lineno);
fprintf(out," break;\n"); lineno++;
}
}
tplt_xfer(lemp->name,in,out,&lineno);
/* Generate code which executes whenever the parser stack overflows */