From: drh Date: Sun, 27 Apr 2008 22:19:44 +0000 (+0000) Subject: Allow multiple occurrances of %include in lemon input files. X-Git-Tag: version-3.6.10~1124 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5808f31f0e5c8246827f282c8b3b38a716d3551;p=thirdparty%2Fsqlite.git Allow multiple occurrances of %include in lemon input files. Ticket #3001. (CVS 5053) FossilOrigin-Name: f22fa11bde0b77cfc5ff438f2ec6ab95dc87c291 --- diff --git a/manifest b/manifest index 5cf5265021..bc9705bc13 100644 --- a/manifest +++ b/manifest @@ -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) -D 2008-04-27T18:45:11 +C Allow\smultiple\soccurrances\sof\s%include\sin\slemon\sinput\sfiles.\nTicket\s#3001.\s(CVS\s5053) +D 2008-04-27T22:19:45 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -550,7 +550,7 @@ F test/where6.test 42c4373595f4409d9c6a9987b4a60000ad664faf F test/zeroblob.test 7d1854ea79d048e023e5f2e38106a7e99a17435c F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 -F tool/lemon.c 1dc8d53c5ac40f4186ea1bd6ec87a974e18f35a0 +F tool/lemon.c a9c51c1ede7f35dc8746894e7f8cc7e3704ecef8 F tool/lempar.c aab54f1758c554e550ff5c4b191053a819279a2b F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 @@ -630,7 +630,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 6a94d19747a05df2694d3720f76de3dab3836578 -R 79609f1a0af14b94afb1ca285dc546fb +P 20ed749266d099eb35f40ca479db8baa75186b60 +R 9d5f4dcb5bf15e107c27eb9427f5ffc1 U drh -Z dae6fd0d3c11302374c3e38fa9845414 +Z e874612f1bcb163492c64e81d81fe5cd diff --git a/manifest.uuid b/manifest.uuid index 0826360dc1..c8bfc7e6bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20ed749266d099eb35f40ca479db8baa75186b60 \ No newline at end of file +f22fa11bde0b77cfc5ff438f2ec6ab95dc87c291 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index e613f77581..7dcbe6c739 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -134,7 +134,6 @@ struct symbol { 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 */ char *datatype; /* The data type of information held by this ** object. Only used if type==NONTERMINAL */ 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 *stacksize; /* Size of the parser stack */ 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 */ - int errorln; /* Line number for start of error code */ 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 */ - int failureln; /* Line number for start of failure code */ 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 */ - 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 */ @@ -1969,7 +1960,7 @@ struct pstate { struct rule *prevrule; /* Previous rule parsed */ char *declkeyword; /* Keyword of a declaration */ 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 */ int preccounter; /* Assign this precedence to decl arguments */ struct rule *firstrule; /* Pointer to first rule in the grammar */ @@ -2203,46 +2194,45 @@ to follow the previous rule."); if( isalpha(x[0]) ){ psp->declkeyword = x; psp->declargslot = 0; - psp->decllnslot = 0; + psp->insertLineMacro = 1; psp->state = WAITING_FOR_DECL_ARG; if( strcmp(x,"name")==0 ){ psp->declargslot = &(psp->gp->name); + psp->insertLineMacro = 0; }else if( strcmp(x,"include")==0 ){ psp->declargslot = &(psp->gp->include); - psp->decllnslot = &psp->gp->includeln; }else if( strcmp(x,"code")==0 ){ psp->declargslot = &(psp->gp->extracode); - psp->decllnslot = &psp->gp->extracodeln; }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; + psp->insertLineMacro = 0; }else if( strcmp(x,"syntax_error")==0 ){ psp->declargslot = &(psp->gp->error); - psp->decllnslot = &psp->gp->errorln; }else if( strcmp(x,"parse_accept")==0 ){ psp->declargslot = &(psp->gp->accept); - psp->decllnslot = &psp->gp->acceptln; }else if( strcmp(x,"parse_failure")==0 ){ psp->declargslot = &(psp->gp->failure); - psp->decllnslot = &psp->gp->failureln; }else if( strcmp(x,"stack_overflow")==0 ){ psp->declargslot = &(psp->gp->overflow); - psp->decllnslot = &psp->gp->overflowln; }else if( strcmp(x,"extra_argument")==0 ){ psp->declargslot = &(psp->gp->arg); + psp->insertLineMacro = 0; }else if( strcmp(x,"token_type")==0 ){ psp->declargslot = &(psp->gp->tokentype); + psp->insertLineMacro = 0; }else if( strcmp(x,"default_type")==0 ){ psp->declargslot = &(psp->gp->vartype); + psp->insertLineMacro = 0; }else if( strcmp(x,"stack_size")==0 ){ psp->declargslot = &(psp->gp->stacksize); + psp->insertLineMacro = 0; }else if( strcmp(x,"start_symbol")==0 ){ psp->declargslot = &(psp->gp->start); + psp->insertLineMacro = 0; }else if( strcmp(x,"left")==0 ){ psp->preccounter++; psp->declassoc = LEFT; @@ -2286,7 +2276,7 @@ to follow the previous rule."); }else{ struct symbol *sp = Symbol_new(x); psp->declargslot = &sp->destructor; - psp->decllnslot = &sp->destructorln; + psp->insertLineMacro = 1; psp->state = WAITING_FOR_DECL_ARG; } break; @@ -2299,7 +2289,7 @@ to follow the previous rule."); }else{ struct symbol *sp = Symbol_new(x); psp->declargslot = &sp->datatype; - psp->decllnslot = 0; + psp->insertLineMacro = 0; psp->state = WAITING_FOR_DECL_ARG; } break; @@ -2324,18 +2314,50 @@ to follow the previous rule."); } break; case WAITING_FOR_DECL_ARG: - if( (x[0]=='{' || x[0]=='\"' || isalnum(x[0])) ){ - if( *(psp->declargslot)!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The argument \"%s\" to declaration \"%%%s\" is not the first.", - x[0]=='\"' ? &x[1] : x,psp->declkeyword); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - *(psp->declargslot) = (x[0]=='\"' || x[0]=='{') ? &x[1] : x; - if( psp->decllnslot ) *psp->decllnslot = psp->tokenlineno; - psp->state = WAITING_FOR_DECL_OR_RULE; - } + if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){ + char *zOld, *zNew, *zBuf, *z; + int nOld, n, nLine, nNew, nBack; + char zLine[50]; + zNew = x; + if( zNew[0]=='"' || zNew[0]=='{' ) zNew++; + nNew = strlen(zNew); + if( *psp->declargslot ){ + zOld = *psp->declargslot; + }else{ + 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{ ErrorMsg(psp->filename,psp->tokenlineno, "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 */ -PRIVATE void tplt_print(out,lemp,str,strln,lineno) +PRIVATE void tplt_print(out,lemp,str,lineno) FILE *out; struct lemon *lemp; char *str; -int strln; int *lineno; { if( str==0 ) return; - tplt_linedir(out,strln,lemp->filename); (*lineno)++; while( *str ){ if( *str=='\n' ) (*lineno)++; @@ -3113,17 +3133,14 @@ int *lineno; if( sp->type==TERMINAL ){ cp = lemp->tokendest; if( cp==0 ) return; - tplt_linedir(out,lemp->tokendestln,lemp->filename); - fprintf(out,"{"); + fprintf(out,"{\n"); (*lineno)++; }else if( sp->destructor ){ cp = sp->destructor; - tplt_linedir(out,sp->destructorln,lemp->filename); - fprintf(out,"{"); + fprintf(out,"{\n"); (*lineno)++; }else if( lemp->vardest ){ cp = lemp->vardest; if( cp==0 ) return; - tplt_linedir(out,lemp->vardestln,lemp->filename); - fprintf(out,"{"); + fprintf(out,"{\n"); (*lineno)++; }else{ assert( 0 ); /* Cannot happen */ } @@ -3137,8 +3154,9 @@ int *lineno; fputc(*cp,out); } (*lineno) += 3 + linecnt; - fprintf(out,"}\n"); + fprintf(out,"\n"); tplt_linedir(out,*lineno,lemp->outname); + fprintf(out,"}\n"); return; } @@ -3532,7 +3550,7 @@ int mhflag; /* Output in makeheaders format if true */ tplt_xfer(lemp->name,in,out,&lineno); /* Generate the include code, if any */ - tplt_print(out,lemp,lemp->include,lemp->includeln,&lineno); + tplt_print(out,lemp,lemp->include,&lineno); if( mhflag ){ char *name = file_makename(lemp, ".h"); 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); /* 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); /* 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); /* 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); /* 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); /* 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); /* 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(out);