diff options
Diffstat (limited to 'tools/lemon/lemon.c')
-rw-r--r-- | tools/lemon/lemon.c | 871 |
1 files changed, 427 insertions, 444 deletions
diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index f2e541a549..ce4e364ba5 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -6,9 +6,6 @@ ** ** The author of this program disclaims copyright. */ - -#include <config.h> - #include <stdio.h> #include <stdarg.h> #include <string.h> @@ -16,8 +13,6 @@ #include <stdlib.h> #include <assert.h> -#include "ws_attributes.h" - #define ISSPACE(X) isspace((unsigned char)(X)) #define ISDIGIT(X) isdigit((unsigned char)(X)) #define ISALNUM(X) isalnum((unsigned char)(X)) @@ -44,8 +39,8 @@ extern int access(const char *path, int mode); #include <unistd.h> #endif -#define PRIVATE static -/* #define PRIVATE */ +/* #define PRIVATE static */ +#define PRIVATE #ifdef TEST #define MAXRHS 5 /* Set low to exercise exception code */ @@ -196,10 +191,8 @@ void Configlist_reset(void); void ErrorMsg(const char *, int,const char *, ...); /****** From the file "option.h" ******************************************/ -enum option_type { - OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, - OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR -}; +enum option_type { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, + OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR}; struct s_options { enum option_type type; const char *label; @@ -209,9 +202,7 @@ struct s_options { int OptInit(char**,struct s_options*,FILE*); int OptNArgs(void); char *OptArg(int); -#if 0 void OptErr(int); -#endif void OptPrint(void); /******** From the file "parse.h" *****************************************/ @@ -279,6 +270,8 @@ struct symbol { int dtnum; /* The data type number. In the parser, the value ** stack is a union. The .yy%d element of this ** union is the correct data type for this object */ + int bContent; /* True if this symbol ever carries content - if + ** it is ever more than just syntax */ /* The following fields are used by MULTITERMINALs only */ int nsubsym; /* Number of constituent symbols in the MULTI */ struct symbol **subsym; /* Array of constituent symbols */ @@ -405,6 +398,7 @@ struct lemon { struct symbol *wildcard; /* Token that matches anything */ char *name; /* Name of the generated parser */ char *arg; /* Declaration of the 3th argument to parser */ + char *ctx; /* Declaration of 2nd argument to constructor */ 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 */ @@ -418,7 +412,6 @@ struct lemon { char *tokendest; /* Code to execute to destroy token data */ char *vardest; /* Code for the default non-terminal destructor */ char *filename; /* Name of the input file */ - char *basename; /* Basename of inputer file (no directory or path) */ char *outname; /* Name of the current output file */ char *tokenprefix; /* A prefix added to token names in the .h file */ int nconflict; /* Number of parsing conflicts */ @@ -432,8 +425,8 @@ struct lemon { }; #define MemoryCheck(X) if((X)==0){ \ - fprintf(stderr,"Out of memory. Aborting...\n"); \ - exit(1); \ + extern void memory_error(); \ + memory_error(); \ } /**************** From the file "table.h" *********************************/ @@ -540,13 +533,12 @@ static struct action *Action_sort( return ap; } -PRIVATE void Action_add( +void Action_add( struct action **app, enum e_action type, struct symbol *sp, char *arg ){ - assert(app); struct action *newaction; newaction = Action_new(); newaction->next = *app; @@ -615,23 +607,23 @@ struct acttab { #define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) /* Free all memory associated with the given acttab */ -PRIVATE void acttab_free(acttab *p){ +void acttab_free(acttab *p){ free( p->aAction ); free( p->aLookahead ); free( p ); } /* Allocate a new acttab structure */ -PRIVATE acttab *acttab_alloc(int nsymbol, int nterminal) { - acttab *p = (acttab *)calloc(1, sizeof(*p)); - if (p == 0) { - fprintf(stderr, "Unable to allocate memory for a new acttab."); - exit(1); - } - memset(p, 0, sizeof(*p)); - p->nsymbol = nsymbol; - p->nterminal = nterminal; - return p; +acttab *acttab_alloc(int nsymbol, int nterminal){ + acttab *p = (acttab *) calloc( 1, sizeof(*p) ); + if( p==0 ){ + fprintf(stderr,"Unable to allocate memory for a new acttab."); + exit(1); + } + memset(p, 0, sizeof(*p)); + p->nsymbol = nsymbol; + p->nterminal = nterminal; + return p; } /* Add a new action to the current transaction set. @@ -639,14 +631,14 @@ PRIVATE acttab *acttab_alloc(int nsymbol, int nterminal) { ** This routine is called once for each lookahead for a particular ** state. */ -PRIVATE void acttab_action(acttab *p, int lookahead, int action){ +void acttab_action(acttab *p, int lookahead, int action){ if( p->nLookahead>=p->nLookaheadAlloc ){ p->nLookaheadAlloc += 25; p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead, sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); - if (p->aLookahead == 0) { - fprintf(stderr, "malloc failed\n"); - exit(1); + if( p->aLookahead==0 ){ + fprintf(stderr,"malloc failed\n"); + exit(1); } } if( p->nLookahead==0 ){ @@ -680,9 +672,9 @@ PRIVATE void acttab_action(acttab *p, int lookahead, int action){ ** a smaller table. For non-terminal symbols, which are never syntax errors, ** makeItSafe can be false. */ -PRIVATE int acttab_insert(acttab *p, int makeItSafe) { - int i, j, k, n, end; - assert(p->nLookahead>0); +int acttab_insert(acttab *p, int makeItSafe){ + int i, j, k, n, end; + assert( p->nLookahead>0 ); /* Make sure we have enough space to hold the expanded action table ** in the worst case. The worst case occurs if the transaction set @@ -694,15 +686,17 @@ PRIVATE int acttab_insert(acttab *p, int makeItSafe) { p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; p->aAction = (struct lookahead_action *) realloc( p->aAction, sizeof(p->aAction[0])*p->nActionAlloc); - if (p->aAction == 0) { - fprintf(stderr, "malloc failed\n"); - exit(1); + if( p->aAction==0 ){ + fprintf(stderr,"malloc failed\n"); + exit(1); } + assert(oldAlloc < p->nActionAlloc); /* hint for CSA */ for(i=oldAlloc; i<p->nActionAlloc; i++){ p->aAction[i].lookahead = -1; p->aAction[i].action = -1; } } + assert(p->aAction); /* Hint for CSA (for p->aAction[i] below) */ /* Scan the existing action table looking for an offset that is a ** duplicate of the current transaction set. Fall out of the loop @@ -711,7 +705,7 @@ PRIVATE int acttab_insert(acttab *p, int makeItSafe) { ** i is the index in p->aAction[] where p->mnLookahead is inserted. */ end = makeItSafe ? p->mnLookahead : 0; - for (i = p->nAction - 1; i >= end; i--) { + for(i=p->nAction-1; i>=end; i--){ if( p->aAction[i].lookahead==p->mnLookahead ){ /* All lookaheads and actions in the aLookahead[] transaction ** must match against the candidate aAction[i] entry. */ @@ -741,13 +735,13 @@ PRIVATE int acttab_insert(acttab *p, int makeItSafe) { ** an empty offset in the aAction[] table in which we can add the ** aLookahead[] transaction. */ - if (i<end) { + if( i<end ){ /* Look for holes in the aAction[] table that fit the current ** aLookahead[] transaction. Leave i set to the offset of the hole. ** If no holes are found, i is left at p->nAction, which means the ** transaction will be appended. */ - i = makeItSafe ? p->mnLookahead : 0; - for (; i<p->nActionAlloc - p->mxLookahead; i++) { + i = makeItSafe ? p->mnLookahead : 0; + for(; i<p->nActionAlloc - p->mxLookahead; i++){ if( p->aAction[i].lookahead<0 ){ for(j=0; j<p->nLookahead; j++){ k = p->aLookahead[j].lookahead - p->mnLookahead + i; @@ -767,8 +761,8 @@ PRIVATE int acttab_insert(acttab *p, int makeItSafe) { /* Insert transaction set at index i. */ #if 0 printf("Acttab:"); - for (j = 0; j<p->nLookahead; j++) { - printf(" %d", p->aLookahead[j].lookahead); + for(j=0; j<p->nLookahead; j++){ + printf(" %d", p->aLookahead[j].lookahead); } printf(" inserted at %d\n", i); #endif @@ -777,7 +771,7 @@ PRIVATE int acttab_insert(acttab *p, int makeItSafe) { p->aAction[k] = p->aLookahead[j]; if( k>=p->nAction ) p->nAction = k+1; } - if (makeItSafe && i + p->nterminal >= p->nAction) p->nAction = i + p->nterminal + 1; + if( makeItSafe && i+p->nterminal>=p->nAction ) p->nAction = i+p->nterminal+1; p->nLookahead = 0; /* Return the offset that is added to the lookahead in order to get the @@ -789,10 +783,10 @@ PRIVATE int acttab_insert(acttab *p, int makeItSafe) { ** Return the size of the action table without the trailing syntax error ** entries. */ -static int acttab_action_size(acttab *p) { - int n = p->nAction; - while (n>0 && p->aAction[n - 1].lookahead<0) { n--; } - return n; +int acttab_action_size(acttab *p){ + int n = p->nAction; + while( n>0 && p->aAction[n-1].lookahead<0 ){ n--; } + return n; } /********************** From the file "build.c" *****************************/ @@ -897,7 +891,6 @@ void FindFirstSets(struct lemon *lemp) return; } -#ifndef __clang_analyzer__ /* Compute all LR(0) states for the grammar. Links ** are added to between some states so that the LR(1) follow sets ** can be computed later. @@ -957,7 +950,6 @@ does not work properly.",sp->name); (void)getstate(lemp); return; } -#endif /* Return a pointer to a state which is described by the configuration ** list which has been built from calls to Configlist_add. @@ -998,7 +990,11 @@ PRIVATE struct state *getstate(struct lemon *lemp) stp->cfp = cfp; /* Remember the configuration closure */ stp->statenum = lemp->nstate++; /* Every state gets a sequence number */ stp->ap = 0; /* No actions, yet. */ +#ifndef NDEBUG + int ret = +#endif State_insert(stp,stp->bp); /* Add to the state table */ + assert(ret == 1); /* CSA hint: stp did not leak, it has escaped. */ buildshifts(lemp,stp); /* Recursively compute successor states */ } return stp; @@ -1007,7 +1003,7 @@ PRIVATE struct state *getstate(struct lemon *lemp) /* ** Return true if two symbols are the same. */ -PRIVATE int same_symbol(struct symbol *a, struct symbol *b) +int same_symbol(struct symbol *a, struct symbol *b) { int i; if( a==b ) return 1; @@ -1020,7 +1016,6 @@ PRIVATE int same_symbol(struct symbol *a, struct symbol *b) return 1; } -#ifndef __clang_analyzer__ /* Construct all successor states to the given state. A "successor" ** state is any state which can be reached by a shift action. */ @@ -1089,10 +1084,9 @@ void FindLinks(struct lemon *lemp) ** which the link is attached. */ for(i=0; i<lemp->nstate; i++){ stp = lemp->sorted[i]; - if(stp){ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - cfp->stp = stp; - } + assert(stp); /* Hint for CSA */ + for(cfp=stp->cfp; cfp; cfp=cfp->next){ + cfp->stp = stp; } } @@ -1100,17 +1094,14 @@ void FindLinks(struct lemon *lemp) ** links are used in the follow-set computation. */ for(i=0; i<lemp->nstate; i++){ stp = lemp->sorted[i]; - if(stp){ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - for(plp=cfp->bplp; plp; plp=plp->next){ - other = plp->cfp; - Plink_add(&other->fplp,cfp); - } + for(cfp=stp->cfp; cfp; cfp=cfp->next){ + for(plp=cfp->bplp; plp; plp=plp->next){ + other = plp->cfp; + Plink_add(&other->fplp,cfp); } } } } -#endif /* Compute all followsets. ** @@ -1126,28 +1117,24 @@ void FindFollowSets(struct lemon *lemp) int change; for(i=0; i<lemp->nstate; i++){ - if(lemp->sorted[i]){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - cfp->status = INCOMPLETE; - } + for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ + cfp->status = INCOMPLETE; } } do{ progress = 0; for(i=0; i<lemp->nstate; i++){ - if(lemp->sorted[i]){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; - for(plp=cfp->fplp; plp; plp=plp->next){ - change = SetUnion(plp->cfp->fws,cfp->fws); - if( change ){ - plp->cfp->status = INCOMPLETE; - progress = 1; - } + for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ + if( cfp->status==COMPLETE ) continue; + for(plp=cfp->fplp; plp; plp=plp->next){ + change = SetUnion(plp->cfp->fws,cfp->fws); + if( change ){ + plp->cfp->status = INCOMPLETE; + progress = 1; } - cfp->status = COMPLETE; } + cfp->status = COMPLETE; } } }while( progress ); @@ -1171,15 +1158,13 @@ void FindActions(struct lemon *lemp) */ for(i=0; i<lemp->nstate; i++){ /* Loop over all states */ stp = lemp->sorted[i]; - if(stp){ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ - if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ - for(j=0; j<lemp->nterminal; j++){ - if( SetFind(cfp->fws,j) ){ - /* Add a reduce action to the state "stp" which will reduce by the - ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ - Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); - } + for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ + if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ + for(j=0; j<lemp->nterminal; j++){ + if( SetFind(cfp->fws,j) ){ + /* Add a reduce action to the state "stp" which will reduce by the + ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ + Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); } } } @@ -1527,46 +1512,13 @@ void ErrorMsg(const char *filename, int lineno, const char *format, ...){ ** Main program file for the LEMON parser generator. */ -/* Locates the basename in a string possibly containing paths, - * including forward-slash and backward-slash delimiters on Windows, - * and allocates a new string containing just the basename. - * Returns the pointer to that string. - */ -PRIVATE char* -make_basename(char* fullname) -{ - char *cp; - char *new_string; - - /* Find the last forward slash */ - cp = strrchr(fullname, '/'); - -#ifdef _WIN32 - /* On Windows, if no forward slash was found, look ofr - * backslash also */ - if (!cp) - cp = strrchr(fullname, '\\'); -#endif - - if (!cp) { - new_string = (char *) malloc( strlen(fullname) + 1 ); - MemoryCheck( new_string ); - strcpy(new_string, fullname); - } - else { - /* skip the slash */ - cp++; - new_string = (char *) malloc( strlen(cp) + 1 ); - MemoryCheck( new_string ); - strcpy(new_string, cp); - } - - return new_string; -} - /* Report an out-of-memory condition and abort. This function ** is used mostly by the "MemoryCheck" macro in struct.h */ +void memory_error(void){ + fprintf(stderr,"Out of memory. Aborting...\n"); + exit(1); +} static int nDefine = 0; /* Number of -D options on the command line */ static char **azDefine = 0; /* Name of the -D macros */ @@ -1574,29 +1526,43 @@ static char **azDefine = 0; /* Name of the -D macros */ /* This routine is called with the argument to each -D command-line option. ** Add the macro defined to the azDefine array. */ -static void handle_D_option(char *z) { +static void handle_D_option(char *z){ char **paz; nDefine++; azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine); - if (azDefine == 0) { - fprintf(stderr, "out of memory\n"); - exit(1); + if( azDefine==0 ){ + fprintf(stderr,"out of memory\n"); + exit(1); } paz = &azDefine[nDefine-1]; *paz = (char *) malloc( lemonStrlen(z)+1 ); - if (*paz == 0) { - fprintf(stderr, "out of memory\n"); - exit(1); + if( *paz==0 ){ + fprintf(stderr,"out of memory\n"); + exit(1); } lemon_strcpy(*paz, z); for(z=*paz; *z && *z!='='; z++){} *z = 0; } +/* Rember the name of the output directory +*/ +static char *outputDir = NULL; +static void handle_d_option(char *z){ + outputDir = (char *) malloc( lemonStrlen(z)+1 ); + if( outputDir==0 ){ + fprintf(stderr,"out of memory\n"); + exit(1); + } + lemon_strcpy(outputDir, z); +} + static char *user_templatename = NULL; -static void handle_T_option(char *z) { +static void handle_T_option(char *z){ user_templatename = (char *) malloc( lemonStrlen(z)+1 ); - MemoryCheck(user_templatename); + if( user_templatename==0 ){ + memory_error(); + } lemon_strcpy(user_templatename, z); } @@ -1627,7 +1593,7 @@ static struct rule *Rule_merge(struct rule *pA, struct rule *pB){ ** Sort a list of rules in order of increasing iRule value */ static struct rule *Rule_sort(struct rule *rp){ - unsigned int i; + int i; struct rule *pNext; struct rule *x[32]; memset(x, 0, sizeof(x)); @@ -1661,7 +1627,7 @@ static void stats_line(const char *zLabel, int iValue){ } /* The main program. Parse the command line and do it... */ -int main(int argc _U_, char **argv) +int main(int argc, char **argv) { static int version = 0; static int rpflag = 0; @@ -1672,35 +1638,33 @@ int main(int argc _U_, char **argv) static int mhflag = 0; static int nolinenosflag = 0; static int noResort = 0; + static struct s_options options[] = { - { OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report." }, - { OPT_FLAG, "c", (char*)&compress, "Don't compress the action table." }, - { OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro." }, - { OPT_FSTR, "f", 0, "Ignored. (Placeholder for -f compiler options.)" }, - { OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions." }, - { OPT_FSTR, "I", 0, "Ignored. (Placeholder for '-I' compiler options.)" }, - { OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file." }, - { OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements." }, - { OPT_FSTR, "O", 0, "Ignored. (Placeholder for '-O' compiler options.)" }, - { OPT_FLAG, "p", (char*)&showPrecedenceConflict, - "Show conflicts resolved by precedence rules" }, - { OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file." }, - { OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states" }, - { OPT_FLAG, "s", (char*)&statistics, - "Print parser stats to standard output." }, - { OPT_FLAG, "x", (char*)&version, "Print the version number." }, - { OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file." }, - { OPT_FSTR, "W", NULL, "Ignored. (Placeholder for '-W' compiler options.)" }, - {OPT_FLAG, NULL, NULL, NULL} + {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, + {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, + {OPT_FSTR, "d", (char*)&handle_d_option, "Output directory. Default '.'"}, + {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, + {OPT_FSTR, "f", 0, "Ignored. (Placeholder for -f compiler options.)"}, + {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, + {OPT_FSTR, "I", 0, "Ignored. (Placeholder for '-I' compiler options.)"}, + {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."}, + {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."}, + {OPT_FSTR, "O", 0, "Ignored. (Placeholder for '-O' compiler options.)"}, + {OPT_FLAG, "p", (char*)&showPrecedenceConflict, + "Show conflicts resolved by precedence rules"}, + {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, + {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"}, + {OPT_FLAG, "s", (char*)&statistics, + "Print parser stats to standard output."}, + {OPT_FLAG, "x", (char*)&version, "Print the version number."}, + {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."}, + {OPT_FSTR, "W", 0, "Ignored. (Placeholder for '-W' compiler options.)"}, + {OPT_FLAG,0,0,0} }; int i; int exitcode; struct lemon lem; struct rule *rp; - struct symbol *dollar_sym; - struct symbol *default_sym; - - memset(&lem, 0x0, sizeof(lem)); OptInit(argv,options,stderr); if( version ){ @@ -1722,36 +1686,22 @@ int main(int argc _U_, char **argv) lem.filename = OptArg(0); lem.basisflag = basisflag; lem.nolinenosflag = nolinenosflag; - dollar_sym = Symbol_new("$"); - lem.errsym = Symbol_new("error"); - lem.errsym->useCnt = 0; - - lem.basename = make_basename(lem.filename); - + Symbol_new("$"); /* Parse the input file */ Parse(&lem); if( lem.errorcnt ) exit(lem.errorcnt); - if( lem.nrule==0 || lem.rule == NULL ){ - free(dollar_sym); + assert(lem.rule); /* Hint for CSA (no errors => rule found). */ + if( lem.nrule==0 ){ fprintf(stderr,"Empty grammar.\n"); exit(1); } + lem.errsym = Symbol_find("error"); /* Count and index the symbols of the grammar */ - default_sym = Symbol_new("{default}"); + Symbol_new("{default}"); lem.nsymbol = Symbol_count(); lem.symbols = Symbol_arrayof(); - if (lem.nsymbol == 0 || !lem.symbols) { - free(dollar_sym); - free(default_sym); - free(lem.errsym); - if (lem.symbols) - free(lem.symbols); - fprintf(stderr, "Can't find symbols\n"); - exit(1); - } - for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i; qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp); for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i; @@ -1838,9 +1788,6 @@ int main(int argc _U_, char **argv) fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); } - free(default_sym); - free(dollar_sym); - /* return 0 on success, 1 on failure. */ exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0; exit(exitcode); @@ -1958,13 +1905,13 @@ static char *msort( list = NEXT(list); NEXT(ep) = 0; for(i=0; i<LISTSIZE-1 && set[i]!=0; i++){ - ep = merge(ep, set[i], cmp, (int)offset); + ep = merge(ep,set[i],cmp,offset); set[i] = 0; } set[i] = ep; } ep = 0; - for (i = 0; i<LISTSIZE; i++) if (set[i]) ep = merge(set[i], ep, cmp, (int)offset); + for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset); return ep; } /************************ From the file "option.c" **************************/ @@ -1980,11 +1927,9 @@ static FILE *errstream; */ static void errline(int n, int k, FILE *err) { - int spcnt = 0, i; - if( argv[0] ) { - fprintf(err,"%s",argv[0]); - spcnt = lemonStrlen(argv[0]) + 1; - } + int spcnt, i; + if( argv[0] ) fprintf(err,"%s",argv[0]); + spcnt = lemonStrlen(argv[0]) + 1; for(i=1; i<n && argv[i]; i++){ fprintf(err," %s",argv[i]); spcnt += lemonStrlen(argv[i])+1; @@ -2025,35 +1970,35 @@ static char emsg[] = "Command line syntax error: "; */ static int handleflags(int i, FILE *err) { - int v; - int errcnt = 0; - int j; - for (j = 0; op[j].label; j++) { - if (strncmp(&argv[i][1], op[j].label, lemonStrlen(op[j].label)) == 0) break; + int v; + int errcnt = 0; + int j; + for(j=0; op[j].label; j++){ + if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break; + } + v = argv[i][0]=='-' ? 1 : 0; + if( op[j].label==0 ){ + if( err ){ + fprintf(err,"%sundefined option.\n",emsg); + errline(i,1,err); } - v = argv[i][0] == '-' ? 1 : 0; - if (op[j].label == 0) { - if (err) { - fprintf(err, "%sundefined option.\n", emsg); - errline(i, 1, err); - } - errcnt++; - } else if (op[j].arg == 0) { - /* Ignore this option */ - } else if (op[j].type == OPT_FLAG) { - *((int*)op[j].arg) = v; - } else if (op[j].type == OPT_FFLAG) { - (*(void(*)(int))(op[j].arg))(v); - } else if (op[j].type == OPT_FSTR) { - (*(void(*)(char *))(op[j].arg))(&argv[i][2]); - } else { - if (err) { - fprintf(err, "%smissing argument on switch.\n", emsg); - errline(i, 1, err); - } - errcnt++; + errcnt++; + }else if( op[j].arg==0 ){ + /* Ignore this option */ + }else if( op[j].type==OPT_FLAG ){ + *((int*)op[j].arg) = v; + }else if( op[j].type==OPT_FFLAG ){ + (*(void(*)(int))(op[j].arg))(v); + }else if( op[j].type==OPT_FSTR ){ + (*(void(*)(char *))(op[j].arg))(&argv[i][2]); + }else{ + if( err ){ + fprintf(err,"%smissing argument on switch.\n",emsg); + errline(i,1,err); } - return errcnt; + errcnt++; + } + return errcnt; } /* @@ -2061,13 +2006,12 @@ static int handleflags(int i, FILE *err) */ static int handleswitch(int i, FILE *err) { - int errcnt = 0; -#ifndef __clang_analyzer__ int lv = 0; double dv = 0.0; char *sv = 0, *end; char *cp; int j; + int errcnt = 0; cp = strchr(argv[i],'='); assert( cp!=0 ); *cp = 0; @@ -2106,7 +2050,7 @@ static int handleswitch(int i, FILE *err) break; case OPT_INT: case OPT_FINT: - lv = (int)strtol(cp,&end,0); + lv = strtol(cp,&end,0); if( *end ){ if( err ){ fprintf(err,"%sillegal character in integer argument.\n",emsg); @@ -2128,23 +2072,22 @@ static int handleswitch(int i, FILE *err) *(double*)(op[j].arg) = dv; break; case OPT_FDBL: - (*(void(*)(double))(op[j].arg))(dv); - break; + (*(void(*)(double))(op[j].arg))(dv); + break; case OPT_INT: - *(int*)(op[j].arg) = lv; - break; + *(int*)(op[j].arg) = lv; + break; case OPT_FINT: - (*(void(*)(int))(op[j].arg))((int)lv); - break; + (*(void(*)(int))(op[j].arg))((int)lv); + break; case OPT_STR: - *(char**)(op[j].arg) = sv; - break; + *(char**)(op[j].arg) = sv; + break; case OPT_FSTR: - (*(void(*)(char *))(op[j].arg))(sv); - break; + (*(void(*)(char *))(op[j].arg))(sv); + break; } } -#endif return errcnt; } @@ -2192,14 +2135,12 @@ char *OptArg(int n) return i>=0 ? argv[i] : 0; } -#if 0 void OptErr(int n) { int i; i = argindex(n); if( i>=0 ) errline(i,0,errstream); } -#endif void OptPrint(void){ int i; @@ -2321,7 +2262,7 @@ static void parseonetoken(struct pstate *psp) psp->preccounter = 0; psp->firstrule = psp->lastrule = 0; psp->gp->nrule = 0; - /* FALL THROUGH */ + /* Fall thru to next case */ case WAITING_FOR_DECL_OR_RULE: if( x[0]=='%' ){ psp->state = WAITING_FOR_DECL_KEYWORD; @@ -2446,6 +2387,7 @@ to follow the previous rule."); for(i=0; i<psp->nrhs; i++){ rp->rhs[i] = psp->rhs[i]; rp->rhsalias[i] = psp->alias[i]; + if( rp->rhsalias[i]!=0 ){ rp->rhs[i]->bContent = 1; } } rp->lhs = psp->lhs; rp->lhsalias = psp->lhsalias; @@ -2494,7 +2436,6 @@ to follow the previous rule."); msp->nsubsym++; msp->subsym = (struct symbol **) realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); - MemoryCheck( msp->subsym ); msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]); if( ISLOWER(x[1]) || ISLOWER(msp->subsym[0]->name[0]) ){ ErrorMsg(psp->filename,psp->tokenlineno, @@ -2564,6 +2505,9 @@ to follow the previous rule."); }else if( strcmp(x,"extra_argument")==0 ){ psp->declargslot = &(psp->gp->arg); psp->insertLineMacro = 0; + }else if( strcmp(x,"extra_context")==0 ){ + psp->declargslot = &(psp->gp->ctx); + psp->insertLineMacro = 0; }else if( strcmp(x,"token_type")==0 ){ psp->declargslot = &(psp->gp->tokentype); psp->insertLineMacro = 0; @@ -2595,8 +2539,8 @@ to follow the previous rule."); }else if( strcmp(x,"fallback")==0 ){ psp->fallback = 0; psp->state = WAITING_FOR_FALLBACK_ID; - } else if (strcmp(x, "token") == 0) { - psp->state = WAITING_FOR_TOKEN_NAME; + }else if( strcmp(x,"token")==0 ){ + psp->state = WAITING_FOR_TOKEN_NAME; }else if( strcmp(x,"wildcard")==0 ){ psp->state = WAITING_FOR_WILDCARD_ID; }else if( strcmp(x,"token_class")==0 ){ @@ -2699,7 +2643,6 @@ to follow the previous rule."); n += nLine + lemonStrlen(psp->filename) + nBack; } *psp->declargslot = (char *) realloc(*psp->declargslot, n); - MemoryCheck( *psp->declargslot ); zBuf = *psp->declargslot + nOld; if( addLineMacro ){ if( nOld && zBuf[-1]!='\n' ){ @@ -2753,25 +2696,25 @@ to follow the previous rule."); } break; case WAITING_FOR_TOKEN_NAME: - /* Tokens do not have to be declared before use. But they can be - ** in order to control their assigned integer number. The number for - ** each token is assigned when it is first seen. So by including - ** - ** %token ONE TWO THREE - ** - ** early in the grammar file, that assigns small consecutive values - ** to each of the tokens ONE TWO and THREE. - */ - if (x[0] == '.') { - psp->state = WAITING_FOR_DECL_OR_RULE; - } else if (!ISUPPER(x[0])) { - ErrorMsg(psp->filename, psp->tokenlineno, - "%%token argument \"%s\" should be a token", x); - psp->errorcnt++; - } else { - (void)Symbol_new(x); - } - break; + /* Tokens do not have to be declared before use. But they can be + ** in order to control their assigned integer number. The number for + ** each token is assigned when it is first seen. So by including + ** + ** %token ONE TWO THREE + ** + ** early in the grammar file, that assigns small consecutive values + ** to each of the tokens ONE TWO and THREE. + */ + if( x[0]=='.' ){ + psp->state = WAITING_FOR_DECL_OR_RULE; + }else if( !ISUPPER(x[0]) ){ + ErrorMsg(psp->filename, psp->tokenlineno, + "%%token argument \"%s\" should be a token", x); + psp->errorcnt++; + }else{ + (void)Symbol_new(x); + } + break; case WAITING_FOR_WILDCARD_ID: if( x[0]=='.' ){ psp->state = WAITING_FOR_DECL_OR_RULE; @@ -2815,7 +2758,6 @@ to follow the previous rule."); msp->nsubsym++; msp->subsym = (struct symbol **) realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); - MemoryCheck( msp->subsym ); if( !ISUPPER(x[0]) ) x++; msp->subsym[msp->nsubsym-1] = Symbol_new(x); }else{ @@ -2896,7 +2838,7 @@ void Parse(struct lemon *gp) struct pstate ps; FILE *fp; char *filebuf; - unsigned long int filesize; + unsigned int filesize; int lineno; int c; char *cp, *nextcp; @@ -2915,14 +2857,14 @@ void Parse(struct lemon *gp) gp->errorcnt++; return; } - fseek(fp, 0, SEEK_END); + fseek(fp,0,2); filesize = ftell(fp); rewind(fp); filebuf = (char *)malloc( filesize+1 ); if( filesize>100000000 || filebuf==0 ){ ErrorMsg(ps.filename,0,"Input file too large."); - gp->errorcnt++; free(filebuf); + gp->errorcnt++; fclose(fp); return; } @@ -3113,31 +3055,34 @@ PRIVATE char *file_makename(struct lemon *lemp, const char *suffix) { char *name; char *cp; - - name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 ); + char *filename = lemp->filename; + int sz; + + if( outputDir ){ + cp = strrchr(filename, '/'); + if( cp ) filename = cp + 1; + } + sz = lemonStrlen(filename); + sz += lemonStrlen(suffix); + if( outputDir ) sz += lemonStrlen(outputDir) + 1; + sz += 5; + name = (char*)malloc( sz ); if( name==0 ){ fprintf(stderr,"Can't allocate space for a filename.\n"); exit(1); } - lemon_strcpy(name,lemp->filename); + name[0] = 0; + if( outputDir ){ + lemon_strcpy(name, outputDir); + lemon_strcat(name, "/"); + } + lemon_strcat(name,filename); cp = strrchr(name,'.'); if( cp ) *cp = 0; lemon_strcat(name,suffix); return name; } -/* Generate a filename with the given suffix. Uses only -** the basename of the input file, not the entire path. This -** is useful for creating output files when using outdirname. -** Space to hold this name comes from malloc() and must be -** freed by the calling function. -*/ -PRIVATE char *file_makename_using_basename(struct lemon *lemp, const char *suffix) -{ - lemp->filename = lemp->basename; - return file_makename(lemp, suffix); -} - /* Open a file with a name based on the name of the input file, ** but with a different (specified) suffix, and return a pointer ** to the stream */ @@ -3148,8 +3093,8 @@ PRIVATE FILE *file_open( ){ FILE *fp; - if (lemp->outname) free(lemp->outname); - lemp->outname = file_makename_using_basename(lemp, suffix); + if( lemp->outname ) free(lemp->outname); + lemp->outname = file_makename(lemp, suffix); fp = fopen(lemp->outname,mode); if( fp==0 && *mode=='w' ){ fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); @@ -3161,23 +3106,23 @@ PRIVATE FILE *file_open( /* Print the text of a rule */ -static void rule_print(FILE *out, struct rule *rp) { - int i, j; - fprintf(out, "%s", rp->lhs->name); - /* if( rp->lhsalias ) fprintf(out,"(%s)",rp->lhsalias); */ - fprintf(out, " ::="); - for (i = 0; i<rp->nrhs; i++) { - struct symbol *sp = rp->rhs[i]; - if (sp->type == MULTITERMINAL) { - fprintf(out, " %s", sp->subsym[0]->name); - for (j = 1; j<sp->nsubsym; j++) { - fprintf(out, "|%s", sp->subsym[j]->name); - } - } else { - fprintf(out, " %s", sp->name); - } - /* if( rp->rhsalias[i] ) fprintf(out,"(%s)",rp->rhsalias[i]); */ +void rule_print(FILE *out, struct rule *rp){ + int i, j; + fprintf(out, "%s",rp->lhs->name); + /* if( rp->lhsalias ) fprintf(out,"(%s)",rp->lhsalias); */ + fprintf(out," ::="); + for(i=0; i<rp->nrhs; i++){ + struct symbol *sp = rp->rhs[i]; + if( sp->type==MULTITERMINAL ){ + fprintf(out," %s", sp->subsym[0]->name); + for(j=1; j<sp->nsubsym; j++){ + fprintf(out,"|%s", sp->subsym[j]->name); + } + }else{ + fprintf(out," %s", sp->name); } + /* if( rp->rhsalias[i] ) fprintf(out,"(%s)",rp->rhsalias[i]); */ + } } /* Duplicate the input file without comments and without actions @@ -3217,7 +3162,7 @@ void Reprint(struct lemon *lemp) /* Print a single rule. */ -PRIVATE void RulePrint(FILE *fp, struct rule *rp, int iCursor){ +void RulePrint(FILE *fp, struct rule *rp, int iCursor){ struct symbol *sp; int i, j; fprintf(fp,"%s ::=",rp->lhs->name); @@ -3238,7 +3183,7 @@ PRIVATE void RulePrint(FILE *fp, struct rule *rp, int iCursor){ /* Print the rule for a configuration. */ -PRIVATE void ConfigPrint(FILE *fp, struct config *cfp){ +void ConfigPrint(FILE *fp, struct config *cfp){ RulePrint(fp, cfp->rp, cfp->dot); } @@ -3281,7 +3226,7 @@ char *tag; /* Print an action to the given file descriptor. Return FALSE if ** nothing was actually printed. */ -PRIVATE int PrintAction( +int PrintAction( struct action *ap, /* The action to print */ FILE *fp, /* Print the action here */ int indent /* Indent by this amount */ @@ -3349,48 +3294,47 @@ PRIVATE int PrintAction( /* Generate the "*.out" log file */ void ReportOutput(struct lemon *lemp) { - int i; + int i, n; struct state *stp; struct config *cfp; struct action *ap; + struct rule *rp; FILE *fp; fp = file_open(lemp,".out","wb"); if( fp==0 ) return; for(i=0; i<lemp->nxstate; i++){ stp = lemp->sorted[i]; - if(stp){ - fprintf(fp,"State %d:\n",stp->statenum); - if( lemp->basisflag ) cfp=stp->bp; - else cfp=stp->cfp; - while( cfp ){ - char buf[20]; - if( cfp->dot==cfp->rp->nrhs ){ - lemon_sprintf(buf,"(%d)",cfp->rp->iRule); - fprintf(fp," %5s ",buf); - }else{ - fprintf(fp," "); - } - ConfigPrint(fp,cfp); - fprintf(fp,"\n"); -#if 0 - SetPrint(fp,cfp->fws,lemp); - PlinkPrint(fp,cfp->fplp,"To "); - PlinkPrint(fp,cfp->bplp,"From"); -#endif - if( lemp->basisflag ) cfp=cfp->bp; - else cfp=cfp->next; - + fprintf(fp,"State %d:\n",stp->statenum); + if( lemp->basisflag ) cfp=stp->bp; + else cfp=stp->cfp; + while( cfp ){ + char buf[20]; + if( cfp->dot==cfp->rp->nrhs ){ + lemon_sprintf(buf,"(%d)",cfp->rp->iRule); + fprintf(fp," %5s ",buf); + }else{ + fprintf(fp," "); } + ConfigPrint(fp,cfp); fprintf(fp,"\n"); - for(ap=stp->ap; ap; ap=ap->next){ - if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); - } +#if 0 + SetPrint(fp,cfp->fws,lemp); + PlinkPrint(fp,cfp->fplp,"To "); + PlinkPrint(fp,cfp->bplp,"From"); +#endif + if( lemp->basisflag ) cfp=cfp->bp; + else cfp=cfp->next; + } + fprintf(fp,"\n"); + for(ap=stp->ap; ap; ap=ap->next){ + if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); } fprintf(fp,"\n"); } fprintf(fp, "----------------------------------------------------\n"); fprintf(fp, "Symbols:\n"); + fprintf(fp, "The first-set of non-terminals is shown after the name.\n\n"); for(i=0; i<lemp->nsymbol; i++){ int j; struct symbol *sp; @@ -3408,8 +3352,41 @@ void ReportOutput(struct lemon *lemp) } } } + if( sp->prec>=0 ) fprintf(fp," (precedence=%d)", sp->prec); fprintf(fp, "\n"); } + fprintf(fp, "----------------------------------------------------\n"); + fprintf(fp, "Syntax-only Symbols:\n"); + fprintf(fp, "The following symbols never carry semantic content.\n\n"); + for(i=n=0; i<lemp->nsymbol; i++){ + int w; + struct symbol *sp = lemp->symbols[i]; + if( sp->bContent ) continue; + w = (int)strlen(sp->name); + if( n>0 && n+w>75 ){ + fprintf(fp,"\n"); + n = 0; + } + if( n>0 ){ + fprintf(fp, " "); + n++; + } + fprintf(fp, "%s", sp->name); + n += w; + } + if( n>0 ) fprintf(fp, "\n"); + fprintf(fp, "----------------------------------------------------\n"); + fprintf(fp, "Rules:\n"); + for(rp=lemp->rule; rp; rp=rp->next){ + fprintf(fp, "%4d: ", rp->iRule); + rule_print(fp, rp); + fprintf(fp,"."); + if( rp->precsym ){ + fprintf(fp," [%s precedence=%d]", + rp->precsym->name, rp->precsym->prec); + } + fprintf(fp,"\n"); + } fclose(fp); return; } @@ -3439,11 +3416,10 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) pathlist = getenv("PATH"); if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 ); - if( pathbuf == 0 ) - return NULL; - pathbufptr = pathbuf; path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); - if( (path!=0) ){ + MemoryCheck(pathbuf); MemoryCheck(path); /* Fail on allocation failure. */ + if( (pathbuf != 0) && (path!=0) ){ + pathbufptr = pathbuf; lemon_strcpy(pathbuf, pathlist); while( *pathbuf ){ cp = strchr(pathbuf,':'); @@ -3456,8 +3432,8 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) else pathbuf = &cp[1]; if( access(path,modemask)==0 ) break; } + free(pathbufptr); } - free(pathbufptr); } return path; } @@ -3468,26 +3444,26 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) */ PRIVATE int compute_action(struct lemon *lemp, struct action *ap) { - int act; - switch (ap->type) { + int act; + switch( ap->type ){ case SHIFT: act = ap->x.stp->statenum; break; case SHIFTREDUCE: { - /* Since a SHIFT is inherient after a prior REDUCE, convert any - ** SHIFTREDUCE action with a nonterminal on the LHS into a simple - ** REDUCE action: */ - if (ap->sp->index >= lemp->nterminal) { - act = lemp->minReduce + ap->x.rp->iRule; - } else { - act = lemp->minShiftReduce + ap->x.rp->iRule; - } - break; + /* Since a SHIFT is inherient after a prior REDUCE, convert any + ** SHIFTREDUCE action with a nonterminal on the LHS into a simple + ** REDUCE action: */ + if( ap->sp->index>=lemp->nterminal ){ + act = lemp->minReduce + ap->x.rp->iRule; + }else{ + act = lemp->minShiftReduce + ap->x.rp->iRule; + } + break; } case REDUCE: act = lemp->minReduce + ap->x.rp->iRule; break; case ERROR: act = lemp->errAction; break; case ACCEPT: act = lemp->accAction; break; default: act = -1; break; - } - return act; + } + return act; } #define LINESIZE 1000 @@ -3531,9 +3507,11 @@ PRIVATE FILE *tplt_open(struct lemon *lemp) char buf[1000]; FILE *in; char *tpltname; - int tpltname_allocd = LEMON_FALSE; char *cp; + /* We always require the -T option, avoid memleak in the other code path. */ + assert(user_templatename); + /* first, see if user specified a template filename on the command line. */ if (user_templatename != 0) { if( access(user_templatename,004)==-1 ){ @@ -3564,27 +3542,19 @@ PRIVATE FILE *tplt_open(struct lemon *lemp) tpltname = templatename; }else{ tpltname = pathsearch(lemp->argv0,templatename,0); - tpltname_allocd = LEMON_TRUE; } if( tpltname==0 ){ fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", templatename); lemp->errorcnt++; - if (tpltname_allocd) - free(tpltname); return 0; } in = fopen(tpltname,"rb"); if( in==0 ){ fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); lemp->errorcnt++; - if (tpltname_allocd) - free(tpltname); return 0; } - - if (tpltname_allocd) - free(tpltname); return in; } @@ -3623,7 +3593,7 @@ PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, int *lineno) ** The following routine emits code for the destructor for the ** symbol sp */ -PRIVATE void emit_destructor_code( +void emit_destructor_code( FILE *out, struct symbol *sp, struct lemon *lemp, @@ -3669,7 +3639,7 @@ PRIVATE void emit_destructor_code( /* ** Return TRUE (non-zero) if the given symbol has a destructor. */ -PRIVATE int has_destructor(struct symbol *sp, struct lemon *lemp) +int has_destructor(struct symbol *sp, struct lemon *lemp) { int ret; if( sp->type==TERMINAL ){ @@ -3712,9 +3682,8 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){ n = lemonStrlen(zText); } if( (int) (n+sizeof(zInt)*2+used) >= alloced ){ - alloced = (int)(n + sizeof(zInt)*2 + used + 200); + alloced = n + sizeof(zInt)*2 + used + 200; z = (char *) realloc(z, alloced); - MemoryCheck( z ); } if( z==0 ) return empty; while( n-- > 0 ){ @@ -3817,7 +3786,6 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ append_str(0,0,0,0); - #ifndef __clang_analyzer__ /* This const cast is wrong but harmless, if we're careful. */ for(cp=(char *)rp->code; *cp; cp++){ if( cp==zSkip ){ @@ -3867,7 +3835,6 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ } append_str(cp, 1, 0, 0); } /* End loop */ - #endif /* Main code generation completed */ cp = append_str(0,0,0,0); @@ -3989,13 +3956,13 @@ PRIVATE void emit_code( ** union, also set the ".dtnum" field of every terminal and nonterminal ** symbol. */ -PRIVATE void print_stack_union( +void print_stack_union( FILE *out, /* The output stream */ struct lemon *lemp, /* The main info structure for this parser */ int *plineno, /* Pointer to the line number */ int mhflag /* True if generating makeheaders output */ ){ - int lineno = *plineno; /* The line number of the output */ + int lineno; /* The line number of the output */ char **types; /* A hash table of datatypes */ int arraysize; /* Size of the "types" array */ int maxdtlength; /* Maximum length of any ".datatype" field. */ @@ -4024,9 +3991,9 @@ PRIVATE void print_stack_union( if( len>maxdtlength ) maxdtlength = len; } stddt = (char*)malloc( maxdtlength*2 + 1 ); - if (stddt == 0) { - fprintf(stderr, "Out of memory.\n"); - exit(1); + if( stddt==0 ){ + fprintf(stderr,"Out of memory.\n"); + exit(1); } /* Build a hash table of datatypes. The ".dtnum" field of each symbol @@ -4073,9 +4040,9 @@ PRIVATE void print_stack_union( if( types[hash]==0 ){ sp->dtnum = hash + 1; types[hash] = (char*)malloc( lemonStrlen(stddt)+1 ); - if (types[hash] == 0) { - fprintf(stderr, "Out of memory.\n"); - exit(1); + if( types[hash]==0 ){ + fprintf(stderr,"Out of memory.\n"); + exit(1); } lemon_strcpy(types[hash],stddt); } @@ -4083,6 +4050,7 @@ PRIVATE void print_stack_union( /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ name = lemp->name ? lemp->name : "Parse"; + lineno = *plineno; if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } fprintf(out,"#define %sTOKENTYPE %s\n",name, lemp->tokentype?lemp->tokentype:"void*"); lineno++; @@ -4095,7 +4063,7 @@ PRIVATE void print_stack_union( fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; free(types[i]); } - if( lemp->errsym->useCnt ){ + if( lemp->errsym && lemp->errsym->useCnt ){ fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; } free(stddt); @@ -4151,8 +4119,8 @@ struct axset { ** Compare to axset structures for sorting purposes */ static int axset_compare(const void *a, const void *b){ - const struct axset *p1 = (const struct axset*)a; - const struct axset *p2 = (const struct axset*)b; + struct axset *p1 = (struct axset*)a; + struct axset *p2 = (struct axset*)b; int c; c = p2->nAction - p1->nAction; if( c==0 ){ @@ -4245,10 +4213,10 @@ void ReportTable( /* Generate the defines */ fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(0, lemp->nsymbol+1, &szCodeType)); lineno++; - fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; + minimum_size_type(0, lemp->nsymbol, &szCodeType)); lineno++; + fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol); lineno++; fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(0, lemp->maxAction, &szActionType)); lineno++; + minimum_size_type(0,lemp->maxAction,&szActionType)); lineno++; if( lemp->wildcard ){ fprintf(out,"#define YYWILDCARD %d\n", lemp->wildcard->index); lineno++; @@ -4271,20 +4239,40 @@ void ReportTable( while( i>=1 && (ISALNUM(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", + fprintf(out,"#define %sARG_PARAM ,%s\n",name,&lemp->arg[i]); lineno++; + fprintf(out,"#define %sARG_FETCH %s=yypParser->%s;\n", name,lemp->arg,&lemp->arg[i]); lineno++; - fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", + fprintf(out,"#define %sARG_STORE yypParser->%s=%s;\n", name,&lemp->arg[i],&lemp->arg[i]); lineno++; }else{ - fprintf(out,"#define %sARG_SDECL\n",name); lineno++; - fprintf(out,"#define %sARG_PDECL\n",name); lineno++; + fprintf(out,"#define %sARG_SDECL\n",name); lineno++; + fprintf(out,"#define %sARG_PDECL\n",name); lineno++; + fprintf(out,"#define %sARG_PARAM\n",name); lineno++; fprintf(out,"#define %sARG_FETCH\n",name); lineno++; fprintf(out,"#define %sARG_STORE\n",name); lineno++; } + if( lemp->ctx && lemp->ctx[0] ){ + i = lemonStrlen(lemp->ctx); + while( i>=1 && ISSPACE(lemp->ctx[i-1]) ) i--; + while( i>=1 && (ISALNUM(lemp->ctx[i-1]) || lemp->ctx[i-1]=='_') ) i--; + fprintf(out,"#define %sCTX_SDECL %s;\n",name,lemp->ctx); lineno++; + fprintf(out,"#define %sCTX_PDECL ,%s\n",name,lemp->ctx); lineno++; + fprintf(out,"#define %sCTX_PARAM ,%s\n",name,&lemp->ctx[i]); lineno++; + fprintf(out,"#define %sCTX_FETCH %s=yypParser->%s;\n", + name,lemp->ctx,&lemp->ctx[i]); lineno++; + fprintf(out,"#define %sCTX_STORE yypParser->%s=%s;\n", + name,&lemp->ctx[i],&lemp->ctx[i]); lineno++; + }else{ + fprintf(out,"#define %sCTX_SDECL\n",name); lineno++; + fprintf(out,"#define %sCTX_PDECL\n",name); lineno++; + fprintf(out,"#define %sCTX_PARAM\n",name); lineno++; + fprintf(out,"#define %sCTX_FETCH\n",name); lineno++; + fprintf(out,"#define %sCTX_STORE\n",name); lineno++; + } if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } - if( lemp->errsym->useCnt ){ + if( lemp->errsym && lemp->errsym->useCnt ){ fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; } @@ -4297,9 +4285,9 @@ void ReportTable( ** we need to know how many states can be eliminated. */ ax = (struct axset *) calloc(lemp->nxstate*2, sizeof(ax[0])); - if (ax == 0) { - fprintf(stderr, "malloc failed\n"); - exit(1); + if( ax==0 ){ + fprintf(stderr,"malloc failed\n"); + exit(1); } for(i=0; i<lemp->nxstate; i++){ stp = lemp->sorted[i]; @@ -4363,28 +4351,28 @@ void ReportTable( for(i=0; i<lemp->nxstate; i++){ for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){ - ap->x.rp->doesReduce = i ? LEMON_TRUE : LEMON_FALSE ; + ap->x.rp->doesReduce = 1; } } } /* Finish rendering the constants now that the action table has ** been computed */ - fprintf(out, "#define YYNSTATE %d\n", lemp->nxstate); lineno++; - fprintf(out, "#define YYNRULE %d\n", lemp->nrule); lineno++; - fprintf(out, "#define YYNTOKEN %d\n", lemp->nterminal); lineno++; - fprintf(out, "#define YY_MAX_SHIFT %d\n", lemp->nxstate - 1); lineno++; + fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++; + fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; + fprintf(out,"#define YYNTOKEN %d\n",lemp->nterminal); lineno++; + fprintf(out,"#define YY_MAX_SHIFT %d\n",lemp->nxstate-1); lineno++; i = lemp->minShiftReduce; - fprintf(out, "#define YY_MIN_SHIFTREDUCE %d\n", i); lineno++; + fprintf(out,"#define YY_MIN_SHIFTREDUCE %d\n",i); lineno++; i += lemp->nrule; - fprintf(out, "#define YY_MAX_SHIFTREDUCE %d\n", i - 1); lineno++; - fprintf(out, "#define YY_ERROR_ACTION %d\n", lemp->errAction); lineno++; - fprintf(out, "#define YY_ACCEPT_ACTION %d\n", lemp->accAction); lineno++; - fprintf(out, "#define YY_NO_ACTION %d\n", lemp->noAction); lineno++; - fprintf(out, "#define YY_MIN_REDUCE %d\n", lemp->minReduce); lineno++; + fprintf(out,"#define YY_MAX_SHIFTREDUCE %d\n", i-1); lineno++; + fprintf(out,"#define YY_ERROR_ACTION %d\n", lemp->errAction); lineno++; + fprintf(out,"#define YY_ACCEPT_ACTION %d\n", lemp->accAction); lineno++; + fprintf(out,"#define YY_NO_ACTION %d\n", lemp->noAction); lineno++; + fprintf(out,"#define YY_MIN_REDUCE %d\n", lemp->minReduce); lineno++; i = lemp->minReduce + lemp->nrule; - fprintf(out, "#define YY_MAX_REDUCE %d\n", i - 1); lineno++; - tplt_xfer(lemp->name, in, out, &lineno); + fprintf(out,"#define YY_MAX_REDUCE %d\n", i-1); lineno++; + tplt_xfer(lemp->name,in,out,&lineno); /* Now output the action table and its associates: ** @@ -4403,17 +4391,17 @@ void ReportTable( lemp->tablesize += n*szActionType; fprintf(out,"#define YY_ACTTAB_COUNT (%d)\n", n); lineno++; fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; - for (i = j = 0; i<n; i++) { - int action = acttab_yyaction(pActtab, i); - if (action<0) action = lemp->noAction; - if (j == 0) fprintf(out, " /* %5d */ ", i); - fprintf(out, " %4d,", action); - if (j == 9 || i == n - 1) { - fprintf(out, "\n"); lineno++; - j = 0; - } else { - j++; - } + for(i=j=0; i<n; i++){ + int action = acttab_yyaction(pActtab, i); + if( action<0 ) action = lemp->noAction; + if( j==0 ) fprintf(out," /* %5d */ ", i); + fprintf(out, " %4d,", action); + if( j==9 || i==n-1 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } } fprintf(out, "};\n"); lineno++; @@ -4491,20 +4479,20 @@ void ReportTable( fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++; n = lemp->nxstate; lemp->tablesize += n*szActionType; - for (i = j = 0; i<n; i++) { - stp = lemp->sorted[i]; - if (j == 0) fprintf(out, " /* %5d */ ", i); - if (stp->iDfltReduce<0) { - fprintf(out, " %4d,", lemp->errAction); - } else { - fprintf(out, " %4d,", stp->iDfltReduce + lemp->minReduce); - } - if (j == 9 || i == n - 1) { - fprintf(out, "\n"); lineno++; - j = 0; - } else { - j++; - } + for(i=j=0; i<n; i++){ + stp = lemp->sorted[i]; + if( j==0 ) fprintf(out," /* %5d */ ", i); + if( stp->iDfltReduce<0 ){ + fprintf(out, " %4d,", lemp->errAction); + }else{ + fprintf(out, " %4d,", stp->iDfltReduce + lemp->minReduce); + } + if( j==9 || i==n-1 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } } fprintf(out, "};\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); @@ -4530,9 +4518,9 @@ void ReportTable( /* Generate a table containing the symbolic name of every symbol */ - for (i = 0; i<lemp->nsymbol; i++) { - lemon_sprintf(line, "\"%s\",", lemp->symbols[i]->name); - fprintf(out, " /* %4d */ \"%s\",\n", i, lemp->symbols[i]->name); lineno++; + for(i=0; i<lemp->nsymbol; i++){ + lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name); + fprintf(out," /* %4d */ \"%s\",\n",i, lemp->symbols[i]->name); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); @@ -4577,7 +4565,7 @@ void ReportTable( if( sp==0 || sp->type==TERMINAL || sp->index<=0 || sp->destructor!=0 ) continue; if( once ){ - fprintf(out, " /* Default NON-TERMINAL Destructor */\n"); lineno++; + fprintf(out, " /* Default NON-TERMINAL Destructor */\n");lineno++; once = 0; } fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; @@ -4620,10 +4608,10 @@ void ReportTable( ** Note: This code depends on the fact that rules are number ** sequentually beginning with 0. */ - for (i = 0, rp = lemp->rule; rp; rp = rp->next, i++) { - fprintf(out, " { %4d, %4d }, /* (%d) ", rp->lhs->index, -rp->nrhs, i); - rule_print(out, rp); - fprintf(out, " */\n"); lineno++; + for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ + fprintf(out," { %4d, %4d }, /* (%d) ",rp->lhs->index,-rp->nrhs,i); + rule_print(out, rp); + fprintf(out," */\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); @@ -4860,8 +4848,8 @@ void CompressTables(struct lemon *lemp) ** token actions. */ static int stateResortCompare(const void *a, const void *b){ - const struct state *pA = *(const struct state *const *)a; - const struct state *pB = *(const struct state *const *)b; + const struct state *pA = *(const struct state**)a; + const struct state *pB = *(const struct state**)b; int n; n = pB->nNtAct - pA->nNtAct; @@ -4935,7 +4923,10 @@ void SetSize(int n) char *SetNew(void){ char *s; s = (char*)calloc( size, 1); - MemoryCheck( s ); + if( s==0 ){ + extern void memory_error(); + memory_error(); + } return s; } @@ -5094,9 +5085,8 @@ int Strsafe_insert(const char *data) array.ht[h] = newnp; } free(x1a->tbl); - *x1a = array; + memcpy(x1a, &array, sizeof(array)); /* *x1a = array; */ } -#ifndef __clang_analyzer__ /* Insert the new data */ h = ph & (x1a->size-1); np = &(x1a->tbl[x1a->count++]); @@ -5105,7 +5095,6 @@ int Strsafe_insert(const char *data) np->next = x1a->ht[h]; x1a->ht[h] = np; np->from = &(x1a->ht[h]); -#endif return 1; } @@ -5171,8 +5160,8 @@ struct symbol *Symbol_new(const char *x) */ int Symbolcmpp(const void *_a, const void *_b) { - const struct symbol *a = *(const struct symbol *const *) _a; - const struct symbol *b = *(const struct symbol *const *) _b; + const struct symbol *a = *(const struct symbol **) _a; + const struct symbol *b = *(const struct symbol **) _b; int i1 = a->type==MULTITERMINAL ? 3 : a->name[0]>'Z' ? 2 : 1; int i2 = b->type==MULTITERMINAL ? 3 : b->name[0]>'Z' ? 2 : 1; return i1==i2 ? a->index - b->index : i1 - i2; @@ -5264,9 +5253,8 @@ int Symbol_insert(struct symbol *data, const char *key) array.ht[h] = newnp; } free(x2a->tbl); - *x2a = array; + memcpy(x2a, &array, sizeof(array)); /* *x2a = array; */ } -#ifndef __clang_analyzer__ /* Insert the new data */ h = ph & (x2a->size-1); np = &(x2a->tbl[x2a->count++]); @@ -5276,7 +5264,6 @@ int Symbol_insert(struct symbol *data, const char *key) np->next = x2a->ht[h]; x2a->ht[h] = np; np->from = &(x2a->ht[h]); -#endif return 1; } @@ -5310,7 +5297,7 @@ struct symbol *Symbol_Nth(int n) } /* Return the size of the array */ -int Symbol_count(void) +int Symbol_count() { return x2a ? x2a->count : 0; } @@ -5318,7 +5305,7 @@ int Symbol_count(void) /* Return an array of pointers to all data in the table. ** The array is obtained from malloc. Return NULL if memory allocation ** problems, or if the array is empty. */ -struct symbol **Symbol_arrayof(void) +struct symbol **Symbol_arrayof() { struct symbol **array; int i,arrSize; @@ -5334,8 +5321,8 @@ struct symbol **Symbol_arrayof(void) /* Compare two configurations */ int Configcmp(const char *_a,const char *_b) { - const struct config *a = (const struct config *) _a; - const struct config *b = (const struct config *) _b; + const struct config *a = (struct config *) _a; + const struct config *b = (struct config *) _b; int x; x = a->rp->index - b->rp->index; if( x==0 ) x = a->dot - b->dot; @@ -5369,7 +5356,7 @@ PRIVATE unsigned statehash(struct config *a) } /* Allocate a new state structure */ -struct state *State_new(void) +struct state *State_new() { struct state *newstate; newstate = (struct state *)calloc(1, sizeof(struct state) ); @@ -5463,9 +5450,8 @@ int State_insert(struct state *data, struct config *key) array.ht[h] = newnp; } free(x3a->tbl); - *x3a = array; + memcpy(x3a, &array, sizeof(array)); /* *x3a = array; */ } -#ifndef __clang_analyzer__ /* Insert the new data */ h = ph & (x3a->size-1); np = &(x3a->tbl[x3a->count++]); @@ -5475,7 +5461,6 @@ int State_insert(struct state *data, struct config *key) np->next = x3a->ht[h]; x3a->ht[h] = np; np->from = &(x3a->ht[h]); -#endif return 1; } @@ -5604,9 +5589,8 @@ int Configtable_insert(struct config *data) array.ht[h] = newnp; } free(x4a->tbl); - *x4a = array; + memcpy(x4a, &array, sizeof(array)); /* *x4a = array; */ } -#ifndef __clang_analyzer__ /* Insert the new data */ h = ph & (x4a->size-1); np = &(x4a->tbl[x4a->count++]); @@ -5615,7 +5599,6 @@ int Configtable_insert(struct config *data) np->next = x4a->ht[h]; x4a->ht[h] = np; np->from = &(x4a->ht[h]); -#endif return 1; } |