1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Allow multiple occurrances of %include in lemon input files.

Ticket #3001. (CVS 5053)

FossilOrigin-Name: f22fa11bde0b77cfc5ff438f2ec6ab95dc87c291
This commit is contained in:
drh
2008-04-27 22:19:44 +00:00
parent 7f7c257b6b
commit a5808f31f0
3 changed files with 74 additions and 56 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sthe\slemon\sparser\sgenerator\sso\sthat\sit\sworks\sagain\swith\sthe\s"error"\nsymbol.\s\sTicket\s#3079\s(CVS\s5052) C Allow\smultiple\soccurrances\sof\s%include\sin\slemon\sinput\sfiles.\nTicket\s#3001.\s(CVS\s5053)
D 2008-04-27T18:45:11 D 2008-04-27T22:19:45
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -550,7 +550,7 @@ F test/where6.test 42c4373595f4409d9c6a9987b4a60000ad664faf
F test/zeroblob.test 7d1854ea79d048e023e5f2e38106a7e99a17435c F test/zeroblob.test 7d1854ea79d048e023e5f2e38106a7e99a17435c
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/lemon.c 1dc8d53c5ac40f4186ea1bd6ec87a974e18f35a0 F tool/lemon.c a9c51c1ede7f35dc8746894e7f8cc7e3704ecef8
F tool/lempar.c aab54f1758c554e550ff5c4b191053a819279a2b F tool/lempar.c aab54f1758c554e550ff5c4b191053a819279a2b
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133 F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
@@ -630,7 +630,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P 6a94d19747a05df2694d3720f76de3dab3836578 P 20ed749266d099eb35f40ca479db8baa75186b60
R 79609f1a0af14b94afb1ca285dc546fb R 9d5f4dcb5bf15e107c27eb9427f5ffc1
U drh U drh
Z dae6fd0d3c11302374c3e38fa9845414 Z e874612f1bcb163492c64e81d81fe5cd

View File

@@ -1 +1 @@
20ed749266d099eb35f40ca479db8baa75186b60 f22fa11bde0b77cfc5ff438f2ec6ab95dc87c291

View File

@@ -134,7 +134,6 @@ struct symbol {
int useCnt; /* Number of times used */ int useCnt; /* Number of times used */
char *destructor; /* Code which executes whenever this symbol is char *destructor; /* Code which executes whenever this symbol is
** popped from the stack during error processing */ ** popped from the stack during error processing */
int destructorln; /* Line number of destructor code */
char *datatype; /* The data type of information held by this char *datatype; /* The data type of information held by this
** object. Only used if type==NONTERMINAL */ ** object. Only used if type==NONTERMINAL */
int dtnum; /* The data type number. In the parser, the value int dtnum; /* The data type number. In the parser, the value
@@ -250,21 +249,13 @@ struct lemon {
char *start; /* Name of the start symbol for the grammar */ char *start; /* Name of the start symbol for the grammar */
char *stacksize; /* Size of the parser stack */ char *stacksize; /* Size of the parser stack */
char *include; /* Code to put at the start of the C file */ char *include; /* Code to put at the start of the C file */
int includeln; /* Line number for start of include code */
char *error; /* Code to execute when an error is seen */ char *error; /* Code to execute when an error is seen */
int errorln; /* Line number for start of error code */
char *overflow; /* Code to execute on a stack overflow */ char *overflow; /* Code to execute on a stack overflow */
int overflowln; /* Line number for start of overflow code */
char *failure; /* Code to execute on parser failure */ char *failure; /* Code to execute on parser failure */
int failureln; /* Line number for start of failure code */
char *accept; /* Code to execute when the parser excepts */ char *accept; /* Code to execute when the parser excepts */
int acceptln; /* Line number for the start of accept code */
char *extracode; /* Code appended to the generated file */ char *extracode; /* Code appended to the generated file */
int extracodeln; /* Line number for the start of the extra code */
char *tokendest; /* Code to execute to destroy token data */ 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 */ 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 *filename; /* Name of the input file */
char *outname; /* Name of the current output file */ char *outname; /* Name of the current output file */
char *tokenprefix; /* A prefix added to token names in the .h file */ char *tokenprefix; /* A prefix added to token names in the .h file */
@@ -1969,7 +1960,7 @@ struct pstate {
struct rule *prevrule; /* Previous rule parsed */ struct rule *prevrule; /* Previous rule parsed */
char *declkeyword; /* Keyword of a declaration */ char *declkeyword; /* Keyword of a declaration */
char **declargslot; /* Where the declaration argument should be put */ char **declargslot; /* Where the declaration argument should be put */
int *decllnslot; /* Where the declaration linenumber is put */ int insertLineMacro; /* Add #line before declaration insert */
enum e_assoc declassoc; /* Assign this association to decl arguments */ enum e_assoc declassoc; /* Assign this association to decl arguments */
int preccounter; /* Assign this precedence to decl arguments */ int preccounter; /* Assign this precedence to decl arguments */
struct rule *firstrule; /* Pointer to first rule in the grammar */ struct rule *firstrule; /* Pointer to first rule in the grammar */
@@ -2203,46 +2194,45 @@ to follow the previous rule.");
if( isalpha(x[0]) ){ if( isalpha(x[0]) ){
psp->declkeyword = x; psp->declkeyword = x;
psp->declargslot = 0; psp->declargslot = 0;
psp->decllnslot = 0; psp->insertLineMacro = 1;
psp->state = WAITING_FOR_DECL_ARG; psp->state = WAITING_FOR_DECL_ARG;
if( strcmp(x,"name")==0 ){ if( strcmp(x,"name")==0 ){
psp->declargslot = &(psp->gp->name); psp->declargslot = &(psp->gp->name);
psp->insertLineMacro = 0;
}else if( strcmp(x,"include")==0 ){ }else if( strcmp(x,"include")==0 ){
psp->declargslot = &(psp->gp->include); psp->declargslot = &(psp->gp->include);
psp->decllnslot = &psp->gp->includeln;
}else if( strcmp(x,"code")==0 ){ }else if( strcmp(x,"code")==0 ){
psp->declargslot = &(psp->gp->extracode); psp->declargslot = &(psp->gp->extracode);
psp->decllnslot = &psp->gp->extracodeln;
}else if( strcmp(x,"token_destructor")==0 ){ }else if( strcmp(x,"token_destructor")==0 ){
psp->declargslot = &psp->gp->tokendest; psp->declargslot = &psp->gp->tokendest;
psp->decllnslot = &psp->gp->tokendestln;
}else if( strcmp(x,"default_destructor")==0 ){ }else if( strcmp(x,"default_destructor")==0 ){
psp->declargslot = &psp->gp->vardest; psp->declargslot = &psp->gp->vardest;
psp->decllnslot = &psp->gp->vardestln;
}else if( strcmp(x,"token_prefix")==0 ){ }else if( strcmp(x,"token_prefix")==0 ){
psp->declargslot = &psp->gp->tokenprefix; psp->declargslot = &psp->gp->tokenprefix;
psp->insertLineMacro = 0;
}else if( strcmp(x,"syntax_error")==0 ){ }else if( strcmp(x,"syntax_error")==0 ){
psp->declargslot = &(psp->gp->error); psp->declargslot = &(psp->gp->error);
psp->decllnslot = &psp->gp->errorln;
}else if( strcmp(x,"parse_accept")==0 ){ }else if( strcmp(x,"parse_accept")==0 ){
psp->declargslot = &(psp->gp->accept); psp->declargslot = &(psp->gp->accept);
psp->decllnslot = &psp->gp->acceptln;
}else if( strcmp(x,"parse_failure")==0 ){ }else if( strcmp(x,"parse_failure")==0 ){
psp->declargslot = &(psp->gp->failure); psp->declargslot = &(psp->gp->failure);
psp->decllnslot = &psp->gp->failureln;
}else if( strcmp(x,"stack_overflow")==0 ){ }else if( strcmp(x,"stack_overflow")==0 ){
psp->declargslot = &(psp->gp->overflow); psp->declargslot = &(psp->gp->overflow);
psp->decllnslot = &psp->gp->overflowln;
}else if( strcmp(x,"extra_argument")==0 ){ }else if( strcmp(x,"extra_argument")==0 ){
psp->declargslot = &(psp->gp->arg); psp->declargslot = &(psp->gp->arg);
psp->insertLineMacro = 0;
}else if( strcmp(x,"token_type")==0 ){ }else if( strcmp(x,"token_type")==0 ){
psp->declargslot = &(psp->gp->tokentype); psp->declargslot = &(psp->gp->tokentype);
psp->insertLineMacro = 0;
}else if( strcmp(x,"default_type")==0 ){ }else if( strcmp(x,"default_type")==0 ){
psp->declargslot = &(psp->gp->vartype); psp->declargslot = &(psp->gp->vartype);
psp->insertLineMacro = 0;
}else if( strcmp(x,"stack_size")==0 ){ }else if( strcmp(x,"stack_size")==0 ){
psp->declargslot = &(psp->gp->stacksize); psp->declargslot = &(psp->gp->stacksize);
psp->insertLineMacro = 0;
}else if( strcmp(x,"start_symbol")==0 ){ }else if( strcmp(x,"start_symbol")==0 ){
psp->declargslot = &(psp->gp->start); psp->declargslot = &(psp->gp->start);
psp->insertLineMacro = 0;
}else if( strcmp(x,"left")==0 ){ }else if( strcmp(x,"left")==0 ){
psp->preccounter++; psp->preccounter++;
psp->declassoc = LEFT; psp->declassoc = LEFT;
@@ -2286,7 +2276,7 @@ to follow the previous rule.");
}else{ }else{
struct symbol *sp = Symbol_new(x); struct symbol *sp = Symbol_new(x);
psp->declargslot = &sp->destructor; psp->declargslot = &sp->destructor;
psp->decllnslot = &sp->destructorln; psp->insertLineMacro = 1;
psp->state = WAITING_FOR_DECL_ARG; psp->state = WAITING_FOR_DECL_ARG;
} }
break; break;
@@ -2299,7 +2289,7 @@ to follow the previous rule.");
}else{ }else{
struct symbol *sp = Symbol_new(x); struct symbol *sp = Symbol_new(x);
psp->declargslot = &sp->datatype; psp->declargslot = &sp->datatype;
psp->decllnslot = 0; psp->insertLineMacro = 0;
psp->state = WAITING_FOR_DECL_ARG; psp->state = WAITING_FOR_DECL_ARG;
} }
break; break;
@@ -2324,18 +2314,50 @@ to follow the previous rule.");
} }
break; break;
case WAITING_FOR_DECL_ARG: case WAITING_FOR_DECL_ARG:
if( (x[0]=='{' || x[0]=='\"' || isalnum(x[0])) ){ if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){
if( *(psp->declargslot)!=0 ){ char *zOld, *zNew, *zBuf, *z;
ErrorMsg(psp->filename,psp->tokenlineno, int nOld, n, nLine, nNew, nBack;
"The argument \"%s\" to declaration \"%%%s\" is not the first.", char zLine[50];
x[0]=='\"' ? &x[1] : x,psp->declkeyword); zNew = x;
psp->errorcnt++; if( zNew[0]=='"' || zNew[0]=='{' ) zNew++;
psp->state = RESYNC_AFTER_DECL_ERROR; nNew = strlen(zNew);
}else{ if( *psp->declargslot ){
*(psp->declargslot) = (x[0]=='\"' || x[0]=='{') ? &x[1] : x; zOld = *psp->declargslot;
if( psp->decllnslot ) *psp->decllnslot = psp->tokenlineno; }else{
psp->state = WAITING_FOR_DECL_OR_RULE; zOld = "";
} }
nOld = strlen(zOld);
n = nOld + nNew + 20;
if( psp->insertLineMacro ){
for(z=psp->filename, nBack=0; *z; z++){
if( *z=='\\' ) nBack++;
}
sprintf(zLine, "#line %d ", psp->tokenlineno);
nLine = strlen(zLine);
n += nLine + strlen(psp->filename) + nBack;
}
*psp->declargslot = zBuf = realloc(*psp->declargslot, n);
zBuf += nOld;
if( psp->insertLineMacro ){
if( nOld && zBuf[-1]!='\n' ){
*(zBuf++) = '\n';
}
memcpy(zBuf, zLine, nLine);
zBuf += nLine;
*(zBuf++) = '"';
for(z=psp->filename; *z; z++){
if( *z=='\\' ){
*(zBuf++) = '\\';
}
*(zBuf++) = *z;
}
*(zBuf++) = '"';
*(zBuf++) = '\n';
}
memcpy(zBuf, zNew, nNew);
zBuf += nNew;
*zBuf = 0;
psp->state = WAITING_FOR_DECL_OR_RULE;
}else{ }else{
ErrorMsg(psp->filename,psp->tokenlineno, ErrorMsg(psp->filename,psp->tokenlineno,
"Illegal argument to %%%s: %s",psp->declkeyword,x); "Illegal argument to %%%s: %s",psp->declkeyword,x);
@@ -3073,15 +3095,13 @@ char *filename;
} }
/* Print a string to the file and keep the linenumber up to date */ /* Print a string to the file and keep the linenumber up to date */
PRIVATE void tplt_print(out,lemp,str,strln,lineno) PRIVATE void tplt_print(out,lemp,str,lineno)
FILE *out; FILE *out;
struct lemon *lemp; struct lemon *lemp;
char *str; char *str;
int strln;
int *lineno; int *lineno;
{ {
if( str==0 ) return; if( str==0 ) return;
tplt_linedir(out,strln,lemp->filename);
(*lineno)++; (*lineno)++;
while( *str ){ while( *str ){
if( *str=='\n' ) (*lineno)++; if( *str=='\n' ) (*lineno)++;
@@ -3113,17 +3133,14 @@ int *lineno;
if( sp->type==TERMINAL ){ if( sp->type==TERMINAL ){
cp = lemp->tokendest; cp = lemp->tokendest;
if( cp==0 ) return; if( cp==0 ) return;
tplt_linedir(out,lemp->tokendestln,lemp->filename); fprintf(out,"{\n"); (*lineno)++;
fprintf(out,"{");
}else if( sp->destructor ){ }else if( sp->destructor ){
cp = sp->destructor; cp = sp->destructor;
tplt_linedir(out,sp->destructorln,lemp->filename); fprintf(out,"{\n"); (*lineno)++;
fprintf(out,"{");
}else if( lemp->vardest ){ }else if( lemp->vardest ){
cp = lemp->vardest; cp = lemp->vardest;
if( cp==0 ) return; if( cp==0 ) return;
tplt_linedir(out,lemp->vardestln,lemp->filename); fprintf(out,"{\n"); (*lineno)++;
fprintf(out,"{");
}else{ }else{
assert( 0 ); /* Cannot happen */ assert( 0 ); /* Cannot happen */
} }
@@ -3137,8 +3154,9 @@ int *lineno;
fputc(*cp,out); fputc(*cp,out);
} }
(*lineno) += 3 + linecnt; (*lineno) += 3 + linecnt;
fprintf(out,"}\n"); fprintf(out,"\n");
tplt_linedir(out,*lineno,lemp->outname); tplt_linedir(out,*lineno,lemp->outname);
fprintf(out,"}\n");
return; return;
} }
@@ -3532,7 +3550,7 @@ int mhflag; /* Output in makeheaders format if true */
tplt_xfer(lemp->name,in,out,&lineno); tplt_xfer(lemp->name,in,out,&lineno);
/* Generate the include code, if any */ /* Generate the include code, if any */
tplt_print(out,lemp,lemp->include,lemp->includeln,&lineno); tplt_print(out,lemp,lemp->include,&lineno);
if( mhflag ){ if( mhflag ){
char *name = file_makename(lemp, ".h"); char *name = file_makename(lemp, ".h");
fprintf(out,"#include \"%s\"\n", name); lineno++; fprintf(out,"#include \"%s\"\n", name); lineno++;
@@ -3862,7 +3880,7 @@ int mhflag; /* Output in makeheaders format if true */
tplt_xfer(lemp->name,in,out,&lineno); tplt_xfer(lemp->name,in,out,&lineno);
/* Generate code which executes whenever the parser stack overflows */ /* Generate code which executes whenever the parser stack overflows */
tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno); tplt_print(out,lemp,lemp->overflow,&lineno);
tplt_xfer(lemp->name,in,out,&lineno); tplt_xfer(lemp->name,in,out,&lineno);
/* Generate the table of rule information /* Generate the table of rule information
@@ -3899,19 +3917,19 @@ int mhflag; /* Output in makeheaders format if true */
tplt_xfer(lemp->name,in,out,&lineno); tplt_xfer(lemp->name,in,out,&lineno);
/* Generate code which executes if a parse fails */ /* Generate code which executes if a parse fails */
tplt_print(out,lemp,lemp->failure,lemp->failureln,&lineno); tplt_print(out,lemp,lemp->failure,&lineno);
tplt_xfer(lemp->name,in,out,&lineno); tplt_xfer(lemp->name,in,out,&lineno);
/* Generate code which executes when a syntax error occurs */ /* Generate code which executes when a syntax error occurs */
tplt_print(out,lemp,lemp->error,lemp->errorln,&lineno); tplt_print(out,lemp,lemp->error,&lineno);
tplt_xfer(lemp->name,in,out,&lineno); tplt_xfer(lemp->name,in,out,&lineno);
/* Generate code which executes when the parser accepts its input */ /* Generate code which executes when the parser accepts its input */
tplt_print(out,lemp,lemp->accept,lemp->acceptln,&lineno); tplt_print(out,lemp,lemp->accept,&lineno);
tplt_xfer(lemp->name,in,out,&lineno); tplt_xfer(lemp->name,in,out,&lineno);
/* Append any addition code the user desires */ /* Append any addition code the user desires */
tplt_print(out,lemp,lemp->extracode,lemp->extracodeln,&lineno); tplt_print(out,lemp,lemp->extracode,&lineno);
fclose(in); fclose(in);
fclose(out); fclose(out);