[libgda] Use the (patched) Lemon parser from SQLite version 3.7.3
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Use the (patched) Lemon parser from SQLite version 3.7.3
- Date: Sun, 10 Oct 2010 20:20:23 +0000 (UTC)
commit 33eda0d6d15329d69ae50e530cf2e127963321bb
Author: Vivien Malerba <malerba gnome-db org>
Date: Sun Oct 10 22:19:52 2010 +0200
Use the (patched) Lemon parser from SQLite version 3.7.3
libgda/sql-parser/LemonPatch | 111 +--
libgda/sql-parser/Makefile.am | 4 +-
libgda/sql-parser/lemon.c | 1326 +++++++++++++-----------
libgda/sql-parser/lempar.c | 141 ++-
providers/firebird/Makefile.am | 2 +-
providers/oracle/Makefile.am | 2 +-
providers/reuseable/mysql/Makefile.am | 2 +-
providers/reuseable/postgres/Makefile.am | 2 +-
providers/skel-implementation/capi/Makefile.am | 2 +-
9 files changed, 848 insertions(+), 744 deletions(-)
---
diff --git a/libgda/sql-parser/LemonPatch b/libgda/sql-parser/LemonPatch
index 550d609..ef1c815 100644
--- a/libgda/sql-parser/LemonPatch
+++ b/libgda/sql-parser/LemonPatch
@@ -1,114 +1,43 @@
---- lemon.c.3.5.7
-+++ lemon.c
-@@ -266,6 +266,8 @@
- 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 *base_filename; /* Name of the input file, without the path part */
-+ char *tmplname; /* Name of the template file */
- 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 */
-@@ -1402,6 +1404,7 @@
+--- lemon.c.3.7.3 2010-10-10 17:27:59.000000000 +0200
++++ lemon.c 2010-10-10 22:14:05.000000000 +0200
+@@ -1404,11 +1404,13 @@
static int quiet = 0;
static int statistics = 0;
static int mhflag = 0;
+ static int local_out_dir = 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."},
-@@ -1411,19 +1414,21 @@
- {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."},
- {OPT_FLAG, "s", (char*)&statistics,
- "Print parser stats to standard output."},
+ {OPT_FLAG, "d", (char*)&local_out_dir, "Output files in the current directory."},
- {OPT_FLAG, "x", (char*)&version, "Print the version number."},
- {OPT_FLAG,0,0,0}
- };
- int i;
+ {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
+ {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
+ {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
+@@ -1427,7 +1429,7 @@
+ int exitcode;
struct lemon lem;
-+ char *def_tmpl_name = "lempar.c";
+
+- atexit(LemonAtExit);
++ /*atexit(LemonAtExit);*/
OptInit(argv,options,stderr);
if( version ){
- printf("Lemon version 1.0\n");
- exit(0);
- }
-- if( OptNArgs()!=1 ){
-- fprintf(stderr,"Exactly one filename argument is required.\n");
-+ if( (OptNArgs() != 1) && (OptNArgs() != 2) ){
-+ fprintf(stderr,"Usage: %s file.y [path to lempar.c file].\n", argv[0]);
- exit(1);
- }
- memset(&lem, 0, sizeof(lem));
-@@ -1435,6 +1440,21 @@
+@@ -1447,6 +1449,17 @@
State_init();
lem.argv0 = argv[0];
lem.filename = OptArg(0);
+ if (local_out_dir) {
+ char *ptr;
-+ lem.base_filename = malloc (sizeof (char) * strlen (lem.filename) + 1);
-+ memcpy (lem.base_filename, lem.filename, sizeof (char) * strlen (lem.filename) + 1);
+#ifdef __WIN32__
-+ for (ptr = lem.base_filename + strlen (lem.filename) - 1; (ptr > lem.base_filename) && (*ptr != '\\'); ptr--);
++ for (ptr = lem.filename + strlen (lem.filename) - 1; (ptr > lem.filename) && (*ptr != '\\'); ptr--);
+#else
-+ for (ptr = lem.base_filename + strlen (lem.filename) - 1; (ptr > lem.base_filename) && (*ptr != '/'); ptr--);
++ for (ptr = lem.filename + strlen (lem.filename) - 1; (ptr > lem.filename) && (*ptr != '/'); ptr--);
+#endif
-+ if (ptr > lem.base_filename)
-+ lem.base_filename = ptr + 1;
++ if (ptr > lem.filename)
++ lem.filename = ptr + 1;
+ }
-+ else
-+ lem.base_filename = OptArg(0);
-+ lem.tmplname = (OptNArgs() == 2) ? OptArg(1) : def_tmpl_name;
++
lem.basisflag = basisflag;
+ lem.nolinenosflag = nolinenosflag;
Symbol_new("$");
- lem.errsym = Symbol_new("error");
-@@ -2677,12 +2697,12 @@
- char *name;
- char *cp;
-
-- name = malloc( strlen(lemp->filename) + strlen(suffix) + 5 );
-+ name = malloc( strlen(lemp->base_filename) + strlen(suffix) + 5 );
- if( name==0 ){
- fprintf(stderr,"Can't allocate space for a filename.\n");
- exit(1);
- }
-- strcpy(name,lemp->filename);
-+ strcpy(name,lemp->base_filename);
- cp = strrchr(name,'.');
- if( cp ) *cp = 0;
- strcat(name,suffix);
-@@ -3023,7 +3043,6 @@
- PRIVATE FILE *tplt_open(lemp)
- struct lemon *lemp;
- {
-- static char templatename[] = "lempar.c";
- char buf[1000];
- FILE *in;
- char *tpltname;
-@@ -3037,20 +3056,20 @@
- }
- if( access(buf,004)==0 ){
- tpltname = buf;
-- }else if( access(templatename,004)==0 ){
-- tpltname = templatename;
-+ }else if( access(lemp->tmplname,004)==0 ){
-+ tpltname = lemp->tmplname;
- }else{
-- tpltname = pathsearch(lemp->argv0,templatename,0);
-+ tpltname = pathsearch(lemp->argv0,lemp->tmplname,0);
- }
- if( tpltname==0 ){
- fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
-- templatename);
-+ lemp->tmplname);
- lemp->errorcnt++;
- return 0;
- }
- in = fopen(tpltname,"rb");
- if( in==0 ){
-- fprintf(stderr,"Can't open the template file \"%s\".\n",templatename);
-+ fprintf(stderr,"Can't open the template file \"%s\".\n",lemp->tmplname);
- lemp->errorcnt++;
- return 0;
- }
diff --git a/libgda/sql-parser/Makefile.am b/libgda/sql-parser/Makefile.am
index f1f0040..6aacb20 100644
--- a/libgda/sql-parser/Makefile.am
+++ b/libgda/sql-parser/Makefile.am
@@ -13,10 +13,10 @@ gen_def$(EXEEXT_FOR_BUILD): gen_def.c
$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DSRCDIR=\"$(srcdir)\" $(srcdir)/gen_def.c
parser.c parser.h: parser.y lemon$(EXEEXT_FOR_BUILD)
- - ./lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(srcdir)/lempar.c
+ - ./lemon$(EXEEXT_FOR_BUILD) -d -T$(srcdir)/lempar.c $(srcdir)/parser.y
delimiter.c delimiter.h: delimiter.y lemon$(EXEEXT_FOR_BUILD)
- ./lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/delimiter.y $(srcdir)/lempar.c
+ ./lemon$(EXEEXT_FOR_BUILD) -q -d -T$(srcdir)/lempar.c $(srcdir)/delimiter.y
token_types.h: gen_def$(EXEEXT_FOR_BUILD) delimiter.h parser.h
./gen_def$(EXEEXT_FOR_BUILD) > token_types.h
diff --git a/libgda/sql-parser/lemon.c b/libgda/sql-parser/lemon.c
index 67dcbb8..64f2665 100644
--- a/libgda/sql-parser/lemon.c
+++ b/libgda/sql-parser/lemon.c
@@ -34,8 +34,38 @@ extern int access();
#define MAXRHS 1000
#endif
+static int showPrecedenceConflict = 0;
+static const char **made_files = NULL;
+static int made_files_count = 0;
+static int successful_exit = 0;
+static void LemonAtExit(void)
+{
+ /* if we failed, delete (most) files we made, to unconfuse build tools. */
+ int i;
+ for (i = 0; i < made_files_count; i++) {
+ if (!successful_exit) {
+ remove(made_files[i]);
+ }
+ }
+ free(made_files);
+ made_files_count = 0;
+ made_files = NULL;
+}
+
static char *msort(char*,char**,int(*)(const char*,const char*));
+/*
+** Compilers are getting increasingly pedantic about type conversions
+** as C evolves ever closer to Ada.... To work around the latest problems
+** we have to define the following variant of strlen().
+*/
+#define lemonStrlen(X) ((int)strlen(X))
+
+/* a few forward declarations... */
+struct rule;
+struct lemon;
+struct action;
+
static struct action *Action_new(void);
static struct action *Action_sort(struct action *);
@@ -48,59 +78,60 @@ void FindFollowSets();
void FindActions();
/********* From the file "configlist.h" *********************************/
-void Configlist_init(/* void */);
-struct config *Configlist_add(/* struct rule *, int */);
-struct config *Configlist_addbasis(/* struct rule *, int */);
-void Configlist_closure(/* void */);
-void Configlist_sort(/* void */);
-void Configlist_sortbasis(/* void */);
-struct config *Configlist_return(/* void */);
-struct config *Configlist_basis(/* void */);
-void Configlist_eat(/* struct config * */);
-void Configlist_reset(/* void */);
+void Configlist_init(void);
+struct config *Configlist_add(struct rule *, int);
+struct config *Configlist_addbasis(struct rule *, int);
+void Configlist_closure(struct lemon *);
+void Configlist_sort(void);
+void Configlist_sortbasis(void);
+struct config *Configlist_return(void);
+struct config *Configlist_basis(void);
+void Configlist_eat(struct config *);
+void Configlist_reset(void);
/********* From the file "error.h" ***************************************/
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};
struct s_options {
- enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR,
- OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type;
- char *label;
+ enum option_type type;
+ const char *label;
char *arg;
- char *message;
+ const char *message;
};
-int OptInit(/* char**,struct s_options*,FILE* */);
-int OptNArgs(/* void */);
-char *OptArg(/* int */);
-void OptErr(/* int */);
-void OptPrint(/* void */);
+int OptInit(char**,struct s_options*,FILE*);
+int OptNArgs(void);
+char *OptArg(int);
+void OptErr(int);
+void OptPrint(void);
/******** From the file "parse.h" *****************************************/
-void Parse(/* struct lemon *lemp */);
+void Parse(struct lemon *lemp);
/********* From the file "plink.h" ***************************************/
-struct plink *Plink_new(/* void */);
-void Plink_add(/* struct plink **, struct config * */);
-void Plink_copy(/* struct plink **, struct plink * */);
-void Plink_delete(/* struct plink * */);
+struct plink *Plink_new(void);
+void Plink_add(struct plink **, struct config *);
+void Plink_copy(struct plink **, struct plink *);
+void Plink_delete(struct plink *);
/********** From the file "report.h" *************************************/
-void Reprint(/* struct lemon * */);
-void ReportOutput(/* struct lemon * */);
-void ReportTable(/* struct lemon * */);
-void ReportHeader(/* struct lemon * */);
-void CompressTables(/* struct lemon * */);
-void ResortStates(/* struct lemon * */);
+void Reprint(struct lemon *);
+void ReportOutput(struct lemon *);
+void ReportTable(struct lemon *, int);
+void ReportHeader(struct lemon *);
+void CompressTables(struct lemon *);
+void ResortStates(struct lemon *);
/********** From the file "set.h" ****************************************/
-void SetSize(/* int N */); /* All sets will be of size N */
-char *SetNew(/* void */); /* A new set for element 0..N */
-void SetFree(/* char* */); /* Deallocate a set */
-
-int SetAdd(/* char*,int */); /* Add element to a set */
-int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */
+void SetSize(int); /* All sets will be of size N */
+char *SetNew(void); /* A new set for element 0..N */
+void SetFree(char*); /* Deallocate a set */
+char *SetNew(void); /* A new set for element 0..N */
+int SetAdd(char*,int); /* Add element to a set */
+int SetUnion(char *,char *); /* A <- A U B, thru element N */
#define SetFind(X,Y) (X[Y]) /* True if Y is in set X */
/********** From the file "struct.h" *************************************/
@@ -112,29 +143,31 @@ typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean;
/* Symbols (terminals and nonterminals) of the grammar are stored
** in the following: */
+enum symbol_type {
+ TERMINAL,
+ NONTERMINAL,
+ MULTITERMINAL
+};
+enum e_assoc {
+ LEFT,
+ RIGHT,
+ NONE,
+ UNK
+};
struct symbol {
- char *name; /* Name of the symbol */
+ const char *name; /* Name of the symbol */
int index; /* Index number for this symbol */
- enum {
- TERMINAL,
- NONTERMINAL,
- MULTITERMINAL
- } type; /* Symbols are all either TERMINALS or NTs */
+ enum symbol_type type; /* Symbols are all either TERMINALS or NTs */
struct rule *rule; /* Linked list of rules of this (if an NT) */
struct symbol *fallback; /* fallback token in case this token doesn't parse */
int prec; /* Precedence if defined (-1 otherwise) */
- enum e_assoc {
- LEFT,
- RIGHT,
- NONE,
- UNK
- } assoc; /* Associativity if predecence is defined */
+ enum e_assoc assoc; /* Associativity if precedence 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 */
+ int destLineno; /* Line number for start of destructor */
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
@@ -149,14 +182,14 @@ struct symbol {
** structure. */
struct rule {
struct symbol *lhs; /* Left-hand side of the rule */
- char *lhsalias; /* Alias for the LHS (NULL if none) */
+ const char *lhsalias; /* Alias for the LHS (NULL if none) */
int lhsStart; /* True if left-hand side is the start symbol */
int ruleline; /* Line number for the rule */
int nrhs; /* Number of RHS symbols */
struct symbol **rhs; /* The RHS symbols */
- char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
+ const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
int line; /* Line number at which code begins */
- char *code; /* The code executed when this rule is reduced */
+ const char *code; /* The code executed when this rule is reduced */
struct symbol *precsym; /* Precedence symbol for this rule */
int index; /* An index number for this rule */
Boolean canReduce; /* True if this rule is ever reduced */
@@ -169,6 +202,10 @@ struct rule {
** Configurations also contain a follow-set which is a list of terminal
** symbols which are allowed to immediately follow the end of the rule.
** Every configuration is recorded as an instance of the following: */
+enum cfgstatus {
+ COMPLETE,
+ INCOMPLETE
+};
struct config {
struct rule *rp; /* The rule upon which the configuration is based */
int dot; /* The parse point */
@@ -176,29 +213,28 @@ struct config {
struct plink *fplp; /* Follow-set forward propagation links */
struct plink *bplp; /* Follow-set backwards propagation links */
struct state *stp; /* Pointer to state which contains this */
- enum {
- COMPLETE, /* The status is used during followset and */
- INCOMPLETE /* shift computations */
- } status;
+ enum cfgstatus status; /* used during followset and shift computations */
struct config *next; /* Next configuration in the state */
struct config *bp; /* The next basis configuration */
};
+enum e_action {
+ SHIFT,
+ ACCEPT,
+ REDUCE,
+ ERROR,
+ 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 */
+};
+
/* Every shift or reduce operation is stored as one of the following */
struct action {
struct symbol *sp; /* The look-ahead symbol */
- enum e_action {
- SHIFT,
- ACCEPT,
- REDUCE,
- ERROR,
- 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 */
- } type;
+ enum e_action type;
union {
struct state *stp; /* The new state, if a shift */
struct rule *rp; /* The rule, if a reduce */
@@ -212,7 +248,7 @@ struct action {
struct state {
struct config *bp; /* The basis configurations for this state */
struct config *cfp; /* All configurations in this set */
- int statenum; /* Sequencial number for this state */
+ int statenum; /* Sequential number for this state */
struct action *ap; /* Array of actions for this state */
int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */
int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */
@@ -250,30 +286,21 @@ 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 *base_filename; /* Name of the input file, without the path part */
- char *tmplname; /* Name of the template file */
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 */
int tablesize; /* Size of the parse tables */
int basisflag; /* Print only basis configurations */
- int has_fallback; /* True if any %fallback is seen in the grammer */
+ int has_fallback; /* True if any %fallback is seen in the grammar */
+ int nolinenosflag; /* True if #line statements should not be printed */
char *argv0; /* Name of the program */
};
@@ -294,41 +321,41 @@ struct lemon {
/*
** Code for processing tables in the LEMON parser generator.
*/
-
/* Routines for handling a strings */
-char *Strsafe();
+const char *Strsafe(const char *);
-void Strsafe_init(/* void */);
-int Strsafe_insert(/* char * */);
-char *Strsafe_find(/* char * */);
+void Strsafe_init(void);
+int Strsafe_insert(const char *);
+const char *Strsafe_find(const char *);
/* Routines for handling symbols of the grammar */
-struct symbol *Symbol_new();
-int Symbolcmpp(/* struct symbol **, struct symbol ** */);
-void Symbol_init(/* void */);
-int Symbol_insert(/* struct symbol *, char * */);
-struct symbol *Symbol_find(/* char * */);
-struct symbol *Symbol_Nth(/* int */);
-int Symbol_count(/* */);
-struct symbol **Symbol_arrayof(/* */);
+struct symbol *Symbol_new(const char *);
+int Symbolcmpp(const void *, const void *);
+void Symbol_init(void);
+int Symbol_insert(struct symbol *, const char *);
+struct symbol *Symbol_find(const char *);
+struct symbol *Symbol_Nth(int);
+int Symbol_count(void);
+struct symbol **Symbol_arrayof(void);
/* Routines to manage the state table */
-int Configcmp(/* struct config *, struct config * */);
-struct state *State_new();
-void State_init(/* void */);
-int State_insert(/* struct state *, struct config * */);
-struct state *State_find(/* struct config * */);
+int Configcmp(const char *, const char *);
+struct state *State_new(void);
+void State_init(void);
+int State_insert(struct state *, struct config *);
+struct state *State_find(struct config *);
struct state **State_arrayof(/* */);
/* Routines used for efficiency in Configlist_add */
-void Configtable_init(/* void */);
-int Configtable_insert(/* struct config * */);
-struct config *Configtable_find(/* struct config * */);
-void Configtable_clear(/* int(*)(struct config *) */);
+void Configtable_init(void);
+int Configtable_insert(struct config *);
+struct config *Configtable_find(struct config *);
+void Configtable_clear(int(*)(struct config *));
+
/****************** From the file "action.c" *******************************/
/*
** Routines processing parser actions in the LEMON parser generator.
@@ -337,7 +364,7 @@ void Configtable_clear(/* int(*)(struct config *) */);
/* Allocate a new parser action */
static struct action *Action_new(void){
static struct action *freelist = 0;
- struct action *new;
+ struct action *newaction;
if( freelist==0 ){
int i;
@@ -350,9 +377,9 @@ static struct action *Action_new(void){
for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
freelist[amt-1].next = 0;
}
- new = freelist;
+ newaction = freelist;
freelist = freelist->next;
- return new;
+ return newaction;
}
/* Compare two actions for sorting purposes. Return negative, zero, or
@@ -371,6 +398,9 @@ static int actioncmp(
if( rc==0 && ap1->type==REDUCE ){
rc = ap1->x.rp->index - ap2->x.rp->index;
}
+ if( rc==0 ){
+ rc = (int) (ap2 - ap1);
+ }
return rc;
}
@@ -383,22 +413,22 @@ static struct action *Action_sort(
return ap;
}
-void Action_add(app,type,sp,arg)
-struct action **app;
-enum e_action type;
-struct symbol *sp;
-char *arg;
-{
- struct action *new;
- new = Action_new();
- new->next = *app;
- *app = new;
- new->type = type;
- new->sp = sp;
+void Action_add(
+ struct action **app,
+ enum e_action type,
+ struct symbol *sp,
+ char *arg
+){
+ struct action *newaction;
+ newaction = Action_new();
+ newaction->next = *app;
+ *app = newaction;
+ newaction->type = type;
+ newaction->sp = sp;
if( type==SHIFT ){
- new->x.stp = (struct state *)arg;
+ newaction->x.stp = (struct state *)arg;
}else{
- new->x.rp = (struct rule *)arg;
+ newaction->x.rp = (struct rule *)arg;
}
}
/********************** New code to implement the "acttab" module ***********/
@@ -408,16 +438,34 @@ char *arg;
/*
** The state of the yy_action table under construction is an instance of
-** the following structure
+** the following structure.
+**
+** The yy_action table maps the pair (state_number, lookahead) into an
+** action_number. The table is an array of integers pairs. The state_number
+** determines an initial offset into the yy_action array. The lookahead
+** value is then added to this initial offset to get an index X into the
+** yy_action array. If the aAction[X].lookahead equals the value of the
+** of the lookahead input, then the value of the action_number output is
+** aAction[X].action. If the lookaheads do not match then the
+** default action for the state_number is returned.
+**
+** All actions associated with a single state_number are first entered
+** into aLookahead[] using multiple calls to acttab_action(). Then the
+** actions for that single state_number are placed into the aAction[]
+** array with a single call to acttab_insert(). The acttab_insert() call
+** also resets the aLookahead[] array in preparation for the next
+** state number.
*/
+struct lookahead_action {
+ int lookahead; /* Value of the lookahead token */
+ int action; /* Action to take on the given lookahead */
+};
typedef struct acttab acttab;
struct acttab {
int nAction; /* Number of used slots in aAction[] */
int nActionAlloc; /* Slots allocated for aAction[] */
- struct {
- int lookahead; /* Value of the lookahead token */
- int action; /* Action to take on the given lookahead */
- } *aAction, /* The yy_action[] table under construction */
+ struct lookahead_action
+ *aAction, /* The yy_action[] table under construction */
*aLookahead; /* A single new transaction set */
int mnLookahead; /* Minimum aLookahead[].lookahead */
int mnAction; /* Action associated with mnLookahead */
@@ -444,7 +492,7 @@ void acttab_free(acttab *p){
/* Allocate a new acttab structure */
acttab *acttab_alloc(void){
- acttab *p = calloc( 1, sizeof(*p) );
+ acttab *p = (acttab *) calloc( 1, sizeof(*p) );
if( p==0 ){
fprintf(stderr,"Unable to allocate memory for a new acttab.");
exit(1);
@@ -453,12 +501,15 @@ acttab *acttab_alloc(void){
return p;
}
-/* Add a new action to the current transaction set
+/* Add a new action to the current transaction set.
+**
+** This routine is called once for each lookahead for a particular
+** state.
*/
void acttab_action(acttab *p, int lookahead, int action){
if( p->nLookahead>=p->nLookaheadAlloc ){
p->nLookaheadAlloc += 25;
- p->aLookahead = realloc( p->aLookahead,
+ p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead,
sizeof(p->aLookahead[0])*p->nLookaheadAlloc );
if( p->aLookahead==0 ){
fprintf(stderr,"malloc failed\n");
@@ -500,7 +551,7 @@ int acttab_insert(acttab *p){
if( p->nAction + n >= p->nActionAlloc ){
int oldAlloc = p->nActionAlloc;
p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20;
- p->aAction = realloc( p->aAction,
+ p->aAction = (struct lookahead_action *) realloc( p->aAction,
sizeof(p->aAction[0])*p->nActionAlloc);
if( p->aAction==0 ){
fprintf(stderr,"malloc failed\n");
@@ -512,28 +563,16 @@ int acttab_insert(acttab *p){
}
}
- /* Scan the existing action table looking for an offset where we can
- ** insert the current transaction set. Fall out of the loop when that
- ** offset is found. In the worst case, we fall out of the loop when
- ** i reaches p->nAction, which means we append the new transaction set.
+ /* Scan the existing action table looking for an offset that is a
+ ** duplicate of the current transaction set. Fall out of the loop
+ ** if and when the duplicate is found.
**
** i is the index in p->aAction[] where p->mnLookahead is inserted.
*/
- for(i=0; i<p->nAction+p->mnLookahead; i++){
- if( p->aAction[i].lookahead<0 ){
- for(j=0; j<p->nLookahead; j++){
- k = p->aLookahead[j].lookahead - p->mnLookahead + i;
- if( k<0 ) break;
- if( p->aAction[k].lookahead>=0 ) break;
- }
- if( j<p->nLookahead ) continue;
- for(j=0; j<p->nAction; j++){
- if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
- }
- if( j==p->nAction ){
- break; /* Fits in empty slots */
- }
- }else if( p->aAction[i].lookahead==p->mnLookahead ){
+ for(i=p->nAction-1; i>=0; i--){
+ if( p->aAction[i].lookahead==p->mnLookahead ){
+ /* All lookaheads and actions in the aLookahead[] transaction
+ ** must match against the candidate aAction[i] entry. */
if( p->aAction[i].action!=p->mnAction ) continue;
for(j=0; j<p->nLookahead; j++){
k = p->aLookahead[j].lookahead - p->mnLookahead + i;
@@ -542,13 +581,43 @@ int acttab_insert(acttab *p){
if( p->aLookahead[j].action!=p->aAction[k].action ) break;
}
if( j<p->nLookahead ) continue;
+
+ /* No possible lookahead value that is not in the aLookahead[]
+ ** transaction is allowed to match aAction[i] */
n = 0;
for(j=0; j<p->nAction; j++){
if( p->aAction[j].lookahead<0 ) continue;
if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++;
}
if( n==p->nLookahead ){
- break; /* Same as a prior transaction set */
+ break; /* An exact match is found at offset i */
+ }
+ }
+ }
+
+ /* If no existing offsets exactly match the current transaction, find an
+ ** an empty offset in the aAction[] table in which we can add the
+ ** aLookahead[] transaction.
+ */
+ if( i<0 ){
+ /* 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. */
+ for(i=0; 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;
+ if( k<0 ) break;
+ if( p->aAction[k].lookahead>=0 ) break;
+ }
+ if( j<p->nLookahead ) continue;
+ for(j=0; j<p->nAction; j++){
+ if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
+ }
+ if( j==p->nAction ){
+ break; /* Fits in empty slots */
+ }
}
}
}
@@ -580,8 +649,7 @@ int acttab_insert(acttab *p){
** are not RHS symbols with a defined precedence, the precedence
** symbol field is left blank.
*/
-void FindRulePrecedences(xp)
-struct lemon *xp;
+void FindRulePrecedences(struct lemon *xp)
{
struct rule *rp;
for(rp=xp->rule; rp; rp=rp->next){
@@ -610,8 +678,7 @@ struct lemon *xp;
** The first set is the set of all terminal symbols which can begin
** a string generated by that nonterminal.
*/
-void FindFirstSets(lemp)
-struct lemon *lemp;
+void FindFirstSets(struct lemon *lemp)
{
int i, j;
struct rule *rp;
@@ -672,9 +739,8 @@ struct lemon *lemp;
** are added to between some states so that the LR(1) follow sets
** can be computed later.
*/
-PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */
-void FindStates(lemp)
-struct lemon *lemp;
+PRIVATE struct state *getstate(struct lemon *); /* forward reference */
+void FindStates(struct lemon *lemp)
{
struct symbol *sp;
struct rule *rp;
@@ -732,9 +798,8 @@ does not work properly.",sp->name);
/* Return a pointer to a state which is described by the configuration
** list which has been built from calls to Configlist_add.
*/
-PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */
-PRIVATE struct state *getstate(lemp)
-struct lemon *lemp;
+PRIVATE void buildshifts(struct lemon *, struct state *); /* Forwd ref */
+PRIVATE struct state *getstate(struct lemon *lemp)
{
struct config *cfp, *bp;
struct state *stp;
@@ -778,9 +843,7 @@ struct lemon *lemp;
/*
** Return true if two symbols are the same.
*/
-int same_symbol(a,b)
-struct symbol *a;
-struct symbol *b;
+int same_symbol(struct symbol *a, struct symbol *b)
{
int i;
if( a==b ) return 1;
@@ -796,13 +859,11 @@ struct symbol *b;
/* Construct all successor states to the given state. A "successor"
** state is any state which can be reached by a shift action.
*/
-PRIVATE void buildshifts(lemp,stp)
-struct lemon *lemp;
-struct state *stp; /* The state from which successors are computed */
+PRIVATE void buildshifts(struct lemon *lemp, struct state *stp)
{
struct config *cfp; /* For looping thru the config closure of "stp" */
struct config *bcfp; /* For the inner loop on config closure of "stp" */
- struct config *new; /* */
+ struct config *newcfg; /* */
struct symbol *sp; /* Symbol following the dot in configuration "cfp" */
struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */
struct state *newstp; /* A pointer to a successor state */
@@ -827,8 +888,8 @@ struct state *stp; /* The state from which successors are computed */
bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */
if( !same_symbol(bsp,sp) ) continue; /* Must be same as for "cfp" */
bcfp->status = COMPLETE; /* Mark this config as used */
- new = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
- Plink_add(&new->bplp,bcfp);
+ newcfg = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
+ Plink_add(&newcfg->bplp,bcfp);
}
/* Get a pointer to the state described by the basis configuration set
@@ -851,8 +912,7 @@ struct state *stp; /* The state from which successors are computed */
/*
** Construct the propagation links
*/
-void FindLinks(lemp)
-struct lemon *lemp;
+void FindLinks(struct lemon *lemp)
{
int i;
struct config *cfp, *other;
@@ -887,8 +947,7 @@ struct lemon *lemp;
** A followset is the set of all symbols which can come immediately
** after a configuration.
*/
-void FindFollowSets(lemp)
-struct lemon *lemp;
+void FindFollowSets(struct lemon *lemp)
{
int i;
struct config *cfp;
@@ -920,12 +979,11 @@ struct lemon *lemp;
}while( progress );
}
-static int resolve_conflict();
+static int resolve_conflict(struct action *,struct action *, struct symbol *);
/* Compute the reduce actions, and resolve conflicts.
*/
-void FindActions(lemp)
-struct lemon *lemp;
+void FindActions(struct lemon *lemp)
{
int i,j;
struct config *cfp;
@@ -996,7 +1054,7 @@ struct lemon *lemp;
}
/* Resolve a conflict between the two given actions. If the
-** conflict can't be resolve, return non-zero.
+** conflict can't be resolved, return non-zero.
**
** NO LONGER TRUE:
** To resolve a conflict, first look to see if either action
@@ -1008,11 +1066,11 @@ struct lemon *lemp;
** If either action is a SHIFT, then it must be apx. This
** function won't work if apx->type==REDUCE and apy->type==SHIFT.
*/
-static int resolve_conflict(apx,apy,errsym)
-struct action *apx;
-struct action *apy;
-struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
-{
+static int resolve_conflict(
+ struct action *apx,
+ struct action *apy,
+ struct symbol *errsym /* The error symbol (if defined. NULL otherwise) */
+){
struct symbol *spx, *spy;
int errcnt = 0;
assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */
@@ -1027,7 +1085,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
/* Not enough precedence information. */
apy->type = SRCONFLICT;
errcnt++;
- }else if( spx->prec>spy->prec ){ /* Lower precedence wins */
+ }else if( spx->prec>spy->prec ){ /* higher precedence wins */
apy->type = RD_RESOLVED;
}else if( spx->prec<spy->prec ){
apx->type = SH_RESOLVED;
@@ -1085,7 +1143,7 @@ static struct config **basisend = 0; /* End of list of basis configs */
/* Return a pointer to a new configuration */
PRIVATE struct config *newconfig(){
- struct config *new;
+ struct config *newcfg;
if( freelist==0 ){
int i;
int amt = 3;
@@ -1097,14 +1155,13 @@ PRIVATE struct config *newconfig(){
for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
freelist[amt-1].next = 0;
}
- new = freelist;
+ newcfg = freelist;
freelist = freelist->next;
- return new;
+ return newcfg;
}
/* The configuration "old" is no longer used */
-PRIVATE void deleteconfig(old)
-struct config *old;
+PRIVATE void deleteconfig(struct config *old)
{
old->next = freelist;
freelist = old;
@@ -1131,10 +1188,10 @@ void Configlist_reset(){
}
/* Add another configuration to the configuration list */
-struct config *Configlist_add(rp,dot)
-struct rule *rp; /* The rule */
-int dot; /* Index into the RHS of the rule where the dot goes */
-{
+struct config *Configlist_add(
+ struct rule *rp, /* The rule */
+ int dot /* Index into the RHS of the rule where the dot goes */
+){
struct config *cfp, model;
assert( currentend!=0 );
@@ -1158,9 +1215,7 @@ int dot; /* Index into the RHS of the rule where the dot goes */
}
/* Add a basis configuration to the configuration list */
-struct config *Configlist_addbasis(rp,dot)
-struct rule *rp;
-int dot;
+struct config *Configlist_addbasis(struct rule *rp, int dot)
{
struct config *cfp, model;
@@ -1188,8 +1243,7 @@ int dot;
}
/* Compute the closure of the configuration list */
-void Configlist_closure(lemp)
-struct lemon *lemp;
+void Configlist_closure(struct lemon *lemp)
{
struct config *cfp, *newcfp;
struct rule *rp, *newrp;
@@ -1268,8 +1322,7 @@ struct config *Configlist_basis(){
}
/* Free all elements of the given configuration list */
-void Configlist_eat(cfp)
-struct config *cfp;
+void Configlist_eat(struct config *cfp)
{
struct config *nextcfp;
for(; cfp; cfp=nextcfp){
@@ -1286,72 +1339,13 @@ struct config *cfp;
** Code for printing error message.
*/
-/* Find a good place to break "msg" so that its length is at least "min"
-** but no more than "max". Make the point as close to max as possible.
-*/
-static int findbreak(msg,min,max)
-char *msg;
-int min;
-int max;
-{
- int i,spot;
- char c;
- for(i=spot=min; i<=max; i++){
- c = msg[i];
- if( c=='\t' ) msg[i] = ' ';
- if( c=='\n' ){ msg[i] = ' '; spot = i; break; }
- if( c==0 ){ spot = i; break; }
- if( c=='-' && i<max-1 ) spot = i+1;
- if( c==' ' ) spot = i;
- }
- return spot;
-}
-
-/*
-** The error message is split across multiple lines if necessary. The
-** splits occur at a space, if there is a space available near the end
-** of the line.
-*/
-#define ERRMSGSIZE 10000 /* Hope this is big enough. No way to error check */
-#define LINEWIDTH 79 /* Max width of any output line */
-#define PREFIXLIMIT 30 /* Max width of the prefix on each line */
void ErrorMsg(const char *filename, int lineno, const char *format, ...){
- char errmsg[ERRMSGSIZE];
- char prefix[PREFIXLIMIT+10];
- int errmsgsize;
- int prefixsize;
- int availablewidth;
va_list ap;
- int end, restart, base;
-
+ fprintf(stderr, "%s:%d: ", filename, lineno);
va_start(ap, format);
- /* Prepare a prefix to be prepended to every output line */
- if( lineno>0 ){
- sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno);
- }else{
- sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename);
- }
- prefixsize = strlen(prefix);
- availablewidth = LINEWIDTH - prefixsize;
-
- /* Generate the error message */
- vsprintf(errmsg,format,ap);
+ vfprintf(stderr,format,ap);
va_end(ap);
- errmsgsize = strlen(errmsg);
- /* Remove trailing '\n's from the error message. */
- while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){
- errmsg[--errmsgsize] = 0;
- }
-
- /* Print the error message */
- base = 0;
- while( errmsg[base]!=0 ){
- end = restart = findbreak(&errmsg[base],0,availablewidth);
- restart += base;
- while( errmsg[restart]==' ' ) restart++;
- fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]);
- base = restart;
- }
+ fprintf(stderr, "\n");
}
/**************** From the file "main.c" ************************************/
/*
@@ -1375,13 +1369,13 @@ static char **azDefine = 0; /* Name of the -D macros */
static void handle_D_option(char *z){
char **paz;
nDefine++;
- azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine);
+ azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine);
if( azDefine==0 ){
fprintf(stderr,"out of memory\n");
exit(1);
}
paz = &azDefine[nDefine-1];
- *paz = malloc( strlen(z)+1 );
+ *paz = (char *) malloc( lemonStrlen(z)+1 );
if( *paz==0 ){
fprintf(stderr,"out of memory\n");
exit(1);
@@ -1391,11 +1385,17 @@ static void handle_D_option(char *z){
*z = 0;
}
+static char *user_templatename = NULL;
+static void handle_T_option(char *z){
+ user_templatename = (char *) malloc( lemonStrlen(z)+1 );
+ if( user_templatename==0 ){
+ memory_error();
+ }
+ strcpy(user_templatename, z);
+}
/* The main program. Parse the command line and do it... */
-int main(argc,argv)
-int argc;
-char **argv;
+int main(int argc, char **argv)
{
static int version = 0;
static int rpflag = 0;
@@ -1405,30 +1405,39 @@ char **argv;
static int statistics = 0;
static int mhflag = 0;
static int local_out_dir = 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_FLAG, "d", (char*)&local_out_dir, "Output files in the current directory."},
{OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
+ {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
{OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
- {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file"},
+ {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."},
+ {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."},
+ {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, "d", (char*)&local_out_dir, "Output files in the current directory."},
{OPT_FLAG, "x", (char*)&version, "Print the version number."},
{OPT_FLAG,0,0,0}
};
int i;
+ int exitcode;
struct lemon lem;
- char *def_tmpl_name = "lempar.c";
+
+ /*atexit(LemonAtExit);*/
OptInit(argv,options,stderr);
if( version ){
printf("Lemon version 1.0\n");
exit(0);
}
- if( (OptNArgs() != 1) && (OptNArgs() != 2) ){
- fprintf(stderr,"Usage: %s file.y [path to lempar.c file].\n", argv[0]);
+ if( OptNArgs()!=1 ){
+ fprintf(stderr,"Exactly one filename argument is required.\n");
exit(1);
}
memset(&lem, 0, sizeof(lem));
@@ -1442,20 +1451,17 @@ char **argv;
lem.filename = OptArg(0);
if (local_out_dir) {
char *ptr;
- lem.base_filename = malloc (sizeof (char) * strlen (lem.filename) + 1);
- memcpy (lem.base_filename, lem.filename, sizeof (char) * strlen (lem.filename) + 1);
#ifdef __WIN32__
- for (ptr = lem.base_filename + strlen (lem.filename) - 1; (ptr > lem.base_filename) && (*ptr != '\\'); ptr--);
+ for (ptr = lem.filename + strlen (lem.filename) - 1; (ptr > lem.filename) && (*ptr != '\\'); ptr--);
#else
- for (ptr = lem.base_filename + strlen (lem.filename) - 1; (ptr > lem.base_filename) && (*ptr != '/'); ptr--);
+ for (ptr = lem.filename + strlen (lem.filename) - 1; (ptr > lem.filename) && (*ptr != '/'); ptr--);
#endif
- if (ptr > lem.base_filename)
- lem.base_filename = ptr + 1;
+ if (ptr > lem.filename)
+ lem.filename = ptr + 1;
}
- else
- lem.base_filename = OptArg(0);
- lem.tmplname = (OptNArgs() == 2) ? OptArg(1) : def_tmpl_name;
+
lem.basisflag = basisflag;
+ lem.nolinenosflag = nolinenosflag;
Symbol_new("$");
lem.errsym = Symbol_new("error");
lem.errsym->useCnt = 0;
@@ -1473,8 +1479,7 @@ char **argv;
Symbol_new("{default}");
lem.symbols = Symbol_arrayof();
for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
- qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*),
- (int(*)())Symbolcmpp);
+ qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), Symbolcmpp);
for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
for(i=1; isupper(lem.symbols[i]->name[0]); i++);
lem.nterminal = i;
@@ -1512,8 +1517,9 @@ char **argv;
if( compress==0 ) CompressTables(&lem);
/* Reorder and renumber the states so that states with fewer choices
- ** occur at the end. */
- ResortStates(&lem);
+ ** occur at the end. This is an optimization that helps make the
+ ** generated parser tables smaller. */
+ if( noResort==0 ) ResortStates(&lem);
/* Generate a report of the parser generated. (the "y.output" file) */
if( !quiet ) ReportOutput(&lem);
@@ -1532,11 +1538,15 @@ char **argv;
printf(" %d states, %d parser table entries, %d conflicts\n",
lem.nstate, lem.tablesize, lem.nconflict);
}
- if( lem.nconflict ){
+ if( lem.nconflict > 0 ){
fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
}
- exit(lem.errorcnt + lem.nconflict);
- return (lem.errorcnt + lem.nconflict);
+
+ /* return 0 on success, 1 on failure. */
+ exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0;
+ successful_exit = (exitcode == 0);
+ exit(exitcode);
+ return (exitcode);
}
/******************** From the file "msort.c" *******************************/
/*
@@ -1595,7 +1605,7 @@ static char *merge(
}else if( b==0 ){
head = a;
}else{
- if( (*cmp)(a,b)<0 ){
+ if( (*cmp)(a,b)<=0 ){
ptr = a;
a = NEXT(a);
}else{
@@ -1604,7 +1614,7 @@ static char *merge(
}
head = ptr;
while( a && b ){
- if( (*cmp)(a,b)<0 ){
+ if( (*cmp)(a,b)<=0 ){
NEXT(ptr) = a;
ptr = a;
a = NEXT(a);
@@ -1656,7 +1666,7 @@ static char *msort(
set[i] = ep;
}
ep = 0;
- for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(ep,set[i],cmp,offset);
+ for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset);
return ep;
}
/************************ From the file "option.c" **************************/
@@ -1670,17 +1680,14 @@ static FILE *errstream;
** Print the command line with a carrot pointing to the k-th character
** of the n-th field.
*/
-static void errline(n,k,err)
-int n;
-int k;
-FILE *err;
+static void errline(int n, int k, FILE *err)
{
int spcnt, i;
if( argv[0] ) fprintf(err,"%s",argv[0]);
- spcnt = strlen(argv[0]) + 1;
+ spcnt = lemonStrlen(argv[0]) + 1;
for(i=1; i<n && argv[i]; i++){
fprintf(err," %s",argv[i]);
- spcnt += strlen(argv[i])+1;
+ spcnt += lemonStrlen(argv[i])+1;
}
spcnt += k;
for(; argv[i]; i++) fprintf(err," %s",argv[i]);
@@ -1695,8 +1702,7 @@ FILE *err;
** Return the index of the N-th non-switch argument. Return -1
** if N is out of range.
*/
-static int argindex(n)
-int n;
+static int argindex(int n)
{
int i;
int dashdash = 0;
@@ -1717,15 +1723,13 @@ static char emsg[] = "Command line syntax error: ";
/*
** Process a flag command line argument.
*/
-static int handleflags(i,err)
-int i;
-FILE *err;
+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,strlen(op[j].label))==0 ) break;
+ 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 ){
@@ -1737,9 +1741,9 @@ FILE *err;
}else if( op[j].type==OPT_FLAG ){
*((int*)op[j].arg) = v;
}else if( op[j].type==OPT_FFLAG ){
- (*(void(*)())(op[j].arg))(v);
+ (*(void(*)(int))(op[j].arg))(v);
}else if( op[j].type==OPT_FSTR ){
- (*(void(*)())(op[j].arg))(&argv[i][2]);
+ (*(void(*)(char *))(op[j].arg))(&argv[i][2]);
}else{
if( err ){
fprintf(err,"%smissing argument on switch.\n",emsg);
@@ -1753,9 +1757,7 @@ FILE *err;
/*
** Process a command line switch which has an argument.
*/
-static int handleswitch(i,err)
-int i;
-FILE *err;
+static int handleswitch(int i, FILE *err)
{
int lv = 0;
double dv = 0.0;
@@ -1822,29 +1824,26 @@ FILE *err;
*(double*)(op[j].arg) = dv;
break;
case OPT_FDBL:
- (*(void(*)())(op[j].arg))(dv);
+ (*(void(*)(double))(op[j].arg))(dv);
break;
case OPT_INT:
*(int*)(op[j].arg) = lv;
break;
case OPT_FINT:
- (*(void(*)())(op[j].arg))((int)lv);
+ (*(void(*)(int))(op[j].arg))((int)lv);
break;
case OPT_STR:
*(char**)(op[j].arg) = sv;
break;
case OPT_FSTR:
- (*(void(*)())(op[j].arg))(sv);
+ (*(void(*)(char *))(op[j].arg))(sv);
break;
}
}
return errcnt;
}
-int OptInit(a,o,err)
-char **a;
-struct s_options *o;
-FILE *err;
+int OptInit(char **a, struct s_options *o, FILE *err)
{
int errcnt = 0;
argv = a;
@@ -1881,16 +1880,14 @@ int OptNArgs(){
return cnt;
}
-char *OptArg(n)
-int n;
+char *OptArg(int n)
{
int i;
i = argindex(n);
return i>=0 ? argv[i] : 0;
}
-void OptErr(n)
-int n;
+void OptErr(int n)
{
int i;
i = argindex(n);
@@ -1902,7 +1899,7 @@ void OptPrint(){
int max, len;
max = 0;
for(i=0; op[i].label; i++){
- len = strlen(op[i].label) + 1;
+ len = lemonStrlen(op[i].label) + 1;
switch( op[i].type ){
case OPT_FLAG:
case OPT_FFLAG:
@@ -1931,17 +1928,17 @@ void OptPrint(){
case OPT_INT:
case OPT_FINT:
fprintf(errstream," %s=<integer>%*s %s\n",op[i].label,
- (int)(max-strlen(op[i].label)-9),"",op[i].message);
+ (int)(max-lemonStrlen(op[i].label)-9),"",op[i].message);
break;
case OPT_DBL:
case OPT_FDBL:
fprintf(errstream," %s=<real>%*s %s\n",op[i].label,
- (int)(max-strlen(op[i].label)-6),"",op[i].message);
+ (int)(max-lemonStrlen(op[i].label)-6),"",op[i].message);
break;
case OPT_STR:
case OPT_FSTR:
fprintf(errstream," %s=<string>%*s %s\n",op[i].label,
- (int)(max-strlen(op[i].label)-8),"",op[i].message);
+ (int)(max-lemonStrlen(op[i].label)-8),"",op[i].message);
break;
}
}
@@ -1952,44 +1949,46 @@ void OptPrint(){
*/
/* The state of the parser */
+enum e_state {
+ INITIALIZE,
+ WAITING_FOR_DECL_OR_RULE,
+ WAITING_FOR_DECL_KEYWORD,
+ WAITING_FOR_DECL_ARG,
+ WAITING_FOR_PRECEDENCE_SYMBOL,
+ WAITING_FOR_ARROW,
+ IN_RHS,
+ LHS_ALIAS_1,
+ LHS_ALIAS_2,
+ LHS_ALIAS_3,
+ RHS_ALIAS_1,
+ RHS_ALIAS_2,
+ PRECEDENCE_MARK_1,
+ PRECEDENCE_MARK_2,
+ RESYNC_AFTER_RULE_ERROR,
+ RESYNC_AFTER_DECL_ERROR,
+ WAITING_FOR_DESTRUCTOR_SYMBOL,
+ WAITING_FOR_DATATYPE_SYMBOL,
+ WAITING_FOR_FALLBACK_ID,
+ WAITING_FOR_WILDCARD_ID
+};
struct pstate {
char *filename; /* Name of the input file */
int tokenlineno; /* Linenumber at which current token starts */
int errorcnt; /* Number of errors so far */
char *tokenstart; /* Text of current token */
struct lemon *gp; /* Global state vector */
- enum e_state {
- INITIALIZE,
- WAITING_FOR_DECL_OR_RULE,
- WAITING_FOR_DECL_KEYWORD,
- WAITING_FOR_DECL_ARG,
- WAITING_FOR_PRECEDENCE_SYMBOL,
- WAITING_FOR_ARROW,
- IN_RHS,
- LHS_ALIAS_1,
- LHS_ALIAS_2,
- LHS_ALIAS_3,
- RHS_ALIAS_1,
- RHS_ALIAS_2,
- PRECEDENCE_MARK_1,
- PRECEDENCE_MARK_2,
- RESYNC_AFTER_RULE_ERROR,
- RESYNC_AFTER_DECL_ERROR,
- WAITING_FOR_DESTRUCTOR_SYMBOL,
- WAITING_FOR_DATATYPE_SYMBOL,
- WAITING_FOR_FALLBACK_ID,
- WAITING_FOR_WILDCARD_ID
- } state; /* The state of the parser */
+ enum e_state state; /* The state of the parser */
struct symbol *fallback; /* The fallback token */
struct symbol *lhs; /* Left-hand side of current rule */
- char *lhsalias; /* Alias for the LHS */
+ const char *lhsalias; /* Alias for the LHS */
int nrhs; /* Number of right-hand side symbols seen */
struct symbol *rhs[MAXRHS]; /* RHS symbols */
- char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */
+ const char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */
struct rule *prevrule; /* Previous rule parsed */
- char *declkeyword; /* Keyword of a declaration */
+ const 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 */
+ int *decllinenoslot; /* Where to write declaration line number */
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 */
@@ -1997,10 +1996,9 @@ struct pstate {
};
/* Parse a single token */
-static void parseonetoken(psp)
-struct pstate *psp;
+static void parseonetoken(struct pstate *psp)
{
- char *x;
+ const char *x;
x = Strsafe(psp->tokenstart); /* Save the token permanently */
#if 0
printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno,
@@ -2024,7 +2022,7 @@ struct pstate *psp;
}else if( x[0]=='{' ){
if( psp->prevrule==0 ){
ErrorMsg(psp->filename,psp->tokenlineno,
-"There is not prior rule opon which to attach the code \
+"There is no prior rule opon which to attach the code \
fragment which begins on this line.");
psp->errorcnt++;
}else if( psp->prevrule->code!=0 ){
@@ -2132,7 +2130,7 @@ to follow the previous rule.");
int i;
rp->ruleline = psp->tokenlineno;
rp->rhs = (struct symbol**)&rp[1];
- rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]);
+ rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
for(i=0; i<psp->nrhs; i++){
rp->rhs[i] = psp->rhs[i];
rp->rhsalias[i] = psp->alias[i];
@@ -2171,17 +2169,18 @@ to follow the previous rule.");
struct symbol *msp = psp->rhs[psp->nrhs-1];
if( msp->type!=MULTITERMINAL ){
struct symbol *origsp = msp;
- msp = calloc(1,sizeof(*msp));
+ msp = (struct symbol *) calloc(1,sizeof(*msp));
memset(msp, 0, sizeof(*msp));
msp->type = MULTITERMINAL;
msp->nsubsym = 1;
- msp->subsym = calloc(1,sizeof(struct symbol*));
+ msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*));
msp->subsym[0] = origsp;
msp->name = origsp->name;
psp->rhs[psp->nrhs-1] = msp;
}
msp->nsubsym++;
- msp->subsym = realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym);
+ msp->subsym = (struct symbol **) realloc(msp->subsym,
+ sizeof(struct symbol*)*msp->nsubsym);
msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]);
if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){
ErrorMsg(psp->filename,psp->tokenlineno,
@@ -2223,46 +2222,46 @@ to follow the previous rule.");
if( isalpha(x[0]) ){
psp->declkeyword = x;
psp->declargslot = 0;
- psp->decllnslot = 0;
+ psp->decllinenoslot = 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;
@@ -2300,27 +2299,38 @@ to follow the previous rule.");
case WAITING_FOR_DESTRUCTOR_SYMBOL:
if( !isalpha(x[0]) ){
ErrorMsg(psp->filename,psp->tokenlineno,
- "Symbol name missing after %destructor keyword");
+ "Symbol name missing after %%destructor keyword");
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
}else{
struct symbol *sp = Symbol_new(x);
psp->declargslot = &sp->destructor;
- psp->decllnslot = &sp->destructorln;
+ psp->decllinenoslot = &sp->destLineno;
+ psp->insertLineMacro = 1;
psp->state = WAITING_FOR_DECL_ARG;
}
break;
case WAITING_FOR_DATATYPE_SYMBOL:
if( !isalpha(x[0]) ){
ErrorMsg(psp->filename,psp->tokenlineno,
- "Symbol name missing after %destructor keyword");
+ "Symbol name missing after %%type keyword");
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
}else{
- struct symbol *sp = Symbol_new(x);
- psp->declargslot = &sp->datatype;
- psp->decllnslot = 0;
- psp->state = WAITING_FOR_DECL_ARG;
+ struct symbol *sp = Symbol_find(x);
+ if((sp) && (sp->datatype)){
+ ErrorMsg(psp->filename,psp->tokenlineno,
+ "Symbol %%type \"%s\" already defined", x);
+ psp->errorcnt++;
+ psp->state = RESYNC_AFTER_DECL_ERROR;
+ }else{
+ if (!sp){
+ sp = Symbol_new(x);
+ }
+ psp->declargslot = &sp->datatype;
+ psp->insertLineMacro = 0;
+ psp->state = WAITING_FOR_DECL_ARG;
+ }
}
break;
case WAITING_FOR_PRECEDENCE_SYMBOL:
@@ -2344,18 +2354,57 @@ 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]) ){
+ const char *zOld, *zNew;
+ char *zBuf, *z;
+ int nOld, n, nLine, nNew, nBack;
+ int addLineMacro;
+ char zLine[50];
+ zNew = x;
+ if( zNew[0]=='"' || zNew[0]=='{' ) zNew++;
+ nNew = lemonStrlen(zNew);
+ if( *psp->declargslot ){
+ zOld = *psp->declargslot;
+ }else{
+ zOld = "";
+ }
+ nOld = lemonStrlen(zOld);
+ n = nOld + nNew + 20;
+ addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro &&
+ (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0);
+ if( addLineMacro ){
+ for(z=psp->filename, nBack=0; *z; z++){
+ if( *z=='\\' ) nBack++;
+ }
+ sprintf(zLine, "#line %d ", psp->tokenlineno);
+ nLine = lemonStrlen(zLine);
+ n += nLine + lemonStrlen(psp->filename) + nBack;
+ }
+ *psp->declargslot = (char *) realloc(*psp->declargslot, n);
+ zBuf = *psp->declargslot + nOld;
+ if( addLineMacro ){
+ 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';
+ }
+ if( psp->decllinenoslot && psp->decllinenoslot[0]==0 ){
+ psp->decllinenoslot[0] = psp->tokenlineno;
+ }
+ 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);
@@ -2412,7 +2461,7 @@ to follow the previous rule.");
}
}
-/* Run the proprocessor over the input file text. The global variables
+/* Run the preprocessor over the input file text. The global variables
** azDefine[0] through azDefine[nDefine-1] contains the names of all defined
** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and
** comments them out. Text in between is also commented out as appropriate.
@@ -2443,7 +2492,7 @@ static void preprocess_input(char *z){
for(n=0; z[j+n] && !isspace(z[j+n]); n++){}
exclude = 1;
for(k=0; k<nDefine; k++){
- if( strncmp(azDefine[k],&z[j],n)==0 && strlen(azDefine[k])==n ){
+ if( strncmp(azDefine[k],&z[j],n)==0 && lemonStrlen(azDefine[k])==n ){
exclude = 0;
break;
}
@@ -2468,8 +2517,7 @@ static void preprocess_input(char *z){
** token is passed to the function "parseonetoken" which builds all
** the appropriate data structures in the global state vector "gp".
*/
-void Parse(gp)
-struct lemon *gp;
+void Parse(struct lemon *gp)
{
struct pstate ps;
FILE *fp;
@@ -2623,7 +2671,7 @@ static struct plink *plink_freelist = 0;
/* Allocate a new plink */
struct plink *Plink_new(){
- struct plink *new;
+ struct plink *newlink;
if( plink_freelist==0 ){
int i;
@@ -2637,27 +2685,23 @@ struct plink *Plink_new(){
for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1];
plink_freelist[amt-1].next = 0;
}
- new = plink_freelist;
+ newlink = plink_freelist;
plink_freelist = plink_freelist->next;
- return new;
+ return newlink;
}
/* Add a plink to a plink list */
-void Plink_add(plpp,cfp)
-struct plink **plpp;
-struct config *cfp;
+void Plink_add(struct plink **plpp, struct config *cfp)
{
- struct plink *new;
- new = Plink_new();
- new->next = *plpp;
- *plpp = new;
- new->cfp = cfp;
+ struct plink *newlink;
+ newlink = Plink_new();
+ newlink->next = *plpp;
+ *plpp = newlink;
+ newlink->cfp = cfp;
}
/* Transfer every plink on the list "from" to the list "to" */
-void Plink_copy(to,from)
-struct plink **to;
-struct plink *from;
+void Plink_copy(struct plink **to, struct plink *from)
{
struct plink *nextpl;
while( from ){
@@ -2669,8 +2713,7 @@ struct plink *from;
}
/* Delete every plink on the list */
-void Plink_delete(plp)
-struct plink *plp;
+void Plink_delete(struct plink *plp)
{
struct plink *nextpl;
@@ -2690,19 +2733,17 @@ struct plink *plp;
** name comes from malloc() and must be freed by the calling
** function.
*/
-PRIVATE char *file_makename(lemp,suffix)
-struct lemon *lemp;
-char *suffix;
+PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
{
char *name;
char *cp;
- name = malloc( strlen(lemp->base_filename) + strlen(suffix) + 5 );
+ name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 );
if( name==0 ){
fprintf(stderr,"Can't allocate space for a filename.\n");
exit(1);
}
- strcpy(name,lemp->base_filename);
+ strcpy(name,lemp->filename);
cp = strrchr(name,'.');
if( cp ) *cp = 0;
strcat(name,suffix);
@@ -2712,11 +2753,11 @@ char *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 */
-PRIVATE FILE *file_open(lemp,suffix,mode)
-struct lemon *lemp;
-char *suffix;
-char *mode;
-{
+PRIVATE FILE *file_open(
+ struct lemon *lemp,
+ const char *suffix,
+ const char *mode
+){
FILE *fp;
if( lemp->outname ) free(lemp->outname);
@@ -2727,13 +2768,29 @@ char *mode;
lemp->errorcnt++;
return 0;
}
+
+ /* Add files we create to a list, so we can delete them if we fail. This
+ ** is to keep makefiles from getting confused. We don't include .out files,
+ ** though: this is debug information, and you don't want it deleted if there
+ ** was an error you need to track down.
+ */
+ if(( *mode=='w' ) && (strcmp(suffix, ".out") != 0)){
+ const char **ptr = (const char **)
+ realloc(made_files, sizeof (const char **) * (made_files_count + 1));
+ const char *fname = Strsafe(lemp->outname);
+ if ((ptr == NULL) || (fname == NULL)) {
+ free(ptr);
+ memory_error();
+ }
+ made_files = ptr;
+ made_files[made_files_count++] = fname;
+ }
return fp;
}
/* Duplicate the input file without comments and without actions
** on rules */
-void Reprint(lemp)
-struct lemon *lemp;
+void Reprint(struct lemon *lemp)
{
struct rule *rp;
struct symbol *sp;
@@ -2742,7 +2799,7 @@ struct lemon *lemp;
maxlen = 10;
for(i=0; i<lemp->nsymbol; i++){
sp = lemp->symbols[i];
- len = strlen(sp->name);
+ len = lemonStrlen(sp->name);
if( len>maxlen ) maxlen = len;
}
ncolumns = 76/(maxlen+5);
@@ -2778,9 +2835,7 @@ struct lemon *lemp;
}
}
-void ConfigPrint(fp,cfp)
-FILE *fp;
-struct config *cfp;
+void ConfigPrint(FILE *fp, struct config *cfp)
{
struct rule *rp;
struct symbol *sp;
@@ -2860,11 +2915,25 @@ int PrintAction(struct action *ap, FILE *fp, int indent){
indent,ap->sp->name,ap->x.rp->index);
break;
case SSCONFLICT:
- fprintf(fp,"%*s shift %d ** Parsing conflict **",
+ fprintf(fp,"%*s shift %-3d ** Parsing conflict **",
indent,ap->sp->name,ap->x.stp->statenum);
break;
case SH_RESOLVED:
+ if( showPrecedenceConflict ){
+ fprintf(fp,"%*s shift %-3d -- dropped by precedence",
+ indent,ap->sp->name,ap->x.stp->statenum);
+ }else{
+ result = 0;
+ }
+ break;
case RD_RESOLVED:
+ if( showPrecedenceConflict ){
+ fprintf(fp,"%*s reduce %-3d -- dropped by precedence",
+ indent,ap->sp->name,ap->x.rp->index);
+ }else{
+ result = 0;
+ }
+ break;
case NOT_USED:
result = 0;
break;
@@ -2873,8 +2942,7 @@ int PrintAction(struct action *ap, FILE *fp, int indent){
}
/* Generate the "y.output" log file */
-void ReportOutput(lemp)
-struct lemon *lemp;
+void ReportOutput(struct lemon *lemp)
{
int i;
struct state *stp;
@@ -2940,12 +3008,11 @@ struct lemon *lemp;
/* Search for the file "name" which is in the same directory as
** the exacutable */
-PRIVATE char *pathsearch(argv0,name,modemask)
-char *argv0;
-char *name;
-int modemask;
+PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
{
- char *pathlist;
+ const char *pathlist;
+ char *pathbufptr;
+ char *pathbuf;
char *path,*cp;
char c;
@@ -2957,26 +3024,29 @@ int modemask;
if( cp ){
c = *cp;
*cp = 0;
- path = (char *)malloc( strlen(argv0) + strlen(name) + 2 );
+ path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
if( path ) sprintf(path,"%s/%s",argv0,name);
*cp = c;
}else{
- extern char *getenv();
pathlist = getenv("PATH");
if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
- path = (char *)malloc( strlen(pathlist)+strlen(name)+2 );
- if( path!=0 ){
- while( *pathlist ){
- cp = strchr(pathlist,':');
- if( cp==0 ) cp = &pathlist[strlen(pathlist)];
+ pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 );
+ path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
+ if( (pathbuf != 0) && (path!=0) ){
+ pathbufptr = pathbuf;
+ strcpy(pathbuf, pathlist);
+ while( *pathbuf ){
+ cp = strchr(pathbuf,':');
+ if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)];
c = *cp;
*cp = 0;
- sprintf(path,"%s/%s",pathlist,name);
+ sprintf(path,"%s/%s",pathbuf,name);
*cp = c;
- if( c==0 ) pathlist = "";
- else pathlist = &cp[1];
+ if( c==0 ) pathbuf[0] = 0;
+ else pathbuf = &cp[1];
if( access(path,modemask)==0 ) break;
}
+ free(pathbufptr);
}
}
return path;
@@ -2986,9 +3056,7 @@ int modemask;
** which is to be put in the action table of the generated machine.
** Return negative if no action should be generated.
*/
-PRIVATE int compute_action(lemp,ap)
-struct lemon *lemp;
-struct action *ap;
+PRIVATE int compute_action(struct lemon *lemp, struct action *ap)
{
int act;
switch( ap->type ){
@@ -3011,11 +3079,7 @@ struct action *ap;
** if name!=0, then any word that begin with "Parse" is changed to
** begin with *name instead.
*/
-PRIVATE void tplt_xfer(name,in,out,lineno)
-char *name;
-FILE *in;
-FILE *out;
-int *lineno;
+PRIVATE void tplt_xfer(char *name, FILE *in, FILE *out, int *lineno)
{
int i, iStart;
char line[LINESIZE];
@@ -3040,14 +3104,31 @@ int *lineno;
/* The next function finds the template file and opens it, returning
** a pointer to the opened file. */
-PRIVATE FILE *tplt_open(lemp)
-struct lemon *lemp;
+PRIVATE FILE *tplt_open(struct lemon *lemp)
{
+ static char templatename[] = "lempar.c";
char buf[1000];
FILE *in;
char *tpltname;
char *cp;
+ /* first, see if user specified a template filename on the command line. */
+ if (user_templatename != 0) {
+ if( access(user_templatename,004)==-1 ){
+ fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
+ user_templatename);
+ lemp->errorcnt++;
+ return 0;
+ }
+ in = fopen(user_templatename,"rb");
+ if( in==0 ){
+ fprintf(stderr,"Can't open the template file \"%s\".\n",user_templatename);
+ lemp->errorcnt++;
+ return 0;
+ }
+ return in;
+ }
+
cp = strrchr(lemp->filename,'.');
if( cp ){
sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename);
@@ -3056,20 +3137,20 @@ struct lemon *lemp;
}
if( access(buf,004)==0 ){
tpltname = buf;
- }else if( access(lemp->tmplname,004)==0 ){
- tpltname = lemp->tmplname;
+ }else if( access(templatename,004)==0 ){
+ tpltname = templatename;
}else{
- tpltname = pathsearch(lemp->argv0,lemp->tmplname,0);
+ tpltname = pathsearch(lemp->argv0,templatename,0);
}
if( tpltname==0 ){
fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
- lemp->tmplname);
+ templatename);
lemp->errorcnt++;
return 0;
}
in = fopen(tpltname,"rb");
if( in==0 ){
- fprintf(stderr,"Can't open the template file \"%s\".\n",lemp->tmplname);
+ fprintf(stderr,"Can't open the template file \"%s\".\n",templatename);
lemp->errorcnt++;
return 0;
}
@@ -3077,10 +3158,7 @@ struct lemon *lemp;
}
/* Print a #line directive line to the output file. */
-PRIVATE void tplt_linedir(out,lineno,filename)
-FILE *out;
-int lineno;
-char *filename;
+PRIVATE void tplt_linedir(FILE *out, int lineno, char *filename)
{
fprintf(out,"#line %d \"",lineno);
while( *filename ){
@@ -3092,27 +3170,21 @@ char *filename;
}
/* Print a string to the file and keep the linenumber up to date */
-PRIVATE void tplt_print(out,lemp,str,strln,lineno)
-FILE *out;
-struct lemon *lemp;
-char *str;
-int strln;
-int *lineno;
+PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, int *lineno)
{
if( str==0 ) return;
- tplt_linedir(out,strln,lemp->filename);
- (*lineno)++;
while( *str ){
- if( *str=='\n' ) (*lineno)++;
putc(*str,out);
+ if( *str=='\n' ) (*lineno)++;
str++;
}
if( str[-1]!='\n' ){
putc('\n',out);
(*lineno)++;
}
- tplt_linedir(out,*lineno+2,lemp->outname);
- (*lineno)+=2;
+ if (!lemp->nolinenosflag) {
+ (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
+ }
return;
}
@@ -3120,29 +3192,26 @@ int *lineno;
** The following routine emits code for the destructor for the
** symbol sp
*/
-void emit_destructor_code(out,sp,lemp,lineno)
-FILE *out;
-struct symbol *sp;
-struct lemon *lemp;
-int *lineno;
-{
+void emit_destructor_code(
+ FILE *out,
+ struct symbol *sp,
+ struct lemon *lemp,
+ int *lineno
+){
char *cp = 0;
- int linecnt = 0;
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)++;
+ if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,sp->destLineno,lemp->filename); }
}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 */
}
@@ -3152,21 +3221,21 @@ int *lineno;
cp++;
continue;
}
- if( *cp=='\n' ) linecnt++;
+ if( *cp=='\n' ) (*lineno)++;
fputc(*cp,out);
}
- (*lineno) += 3 + linecnt;
- fprintf(out,"}\n");
- tplt_linedir(out,*lineno,lemp->outname);
+ fprintf(out,"\n"); (*lineno)++;
+ if (!lemp->nolinenosflag) {
+ (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
+ }
+ fprintf(out,"}\n"); (*lineno)++;
return;
}
/*
** Return TRUE (non-zero) if the given symbol has a destructor.
*/
-int has_destructor(sp, lemp)
-struct symbol *sp;
-struct lemon *lemp;
+int has_destructor(struct symbol *sp, struct lemon *lemp)
{
int ret;
if( sp->type==TERMINAL ){
@@ -3189,13 +3258,13 @@ struct lemon *lemp;
**
** If n==-1, then the previous character is overwritten.
*/
-PRIVATE char *append_str(char *zText, int n, int p1, int p2){
+PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
+ static char empty[1] = { 0 };
static char *z = 0;
static int alloced = 0;
static int used = 0;
int c;
char zInt[40];
-
if( zText==0 ){
used = 0;
return z;
@@ -3205,20 +3274,20 @@ PRIVATE char *append_str(char *zText, int n, int p1, int p2){
used += n;
assert( used>=0 );
}
- n = strlen(zText);
+ n = lemonStrlen(zText);
}
if( n+sizeof(zInt)*2+used >= alloced ){
alloced = n + sizeof(zInt)*2 + used + 200;
- z = realloc(z, alloced);
+ z = (char *) realloc(z, alloced);
}
- if( z==0 ) return "";
+ if( z==0 ) return empty;
while( n-- > 0 ){
c = *(zText++);
if( c=='%' && n>0 && zText[0]=='d' ){
sprintf(zInt, "%d", p1);
p1 = p2;
strcpy(&z[used], zInt);
- used += strlen(&z[used]);
+ used += lemonStrlen(&z[used]);
zText++;
n--;
}else{
@@ -3244,12 +3313,15 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
lhsused = 0;
if( rp->code==0 ){
- rp->code = "\n";
+ static char newlinestr[2] = { '\n', '\0' };
+ rp->code = newlinestr;
rp->line = rp->ruleline;
}
append_str(0,0,0,0);
- for(cp=rp->code; *cp; cp++){
+
+ /* This const cast is wrong but harmless, if we're careful. */
+ for(cp=(char *)rp->code; *cp; cp++){
if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
char saved;
for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
@@ -3305,7 +3377,7 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
lemp->errorcnt++;
}else if( rp->rhsalias[i]==0 ){
if( has_destructor(rp->rhs[i],lemp) ){
- append_str(" yy_destructor(%d,&yymsp[%d].minor);\n", 0,
+ append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
rp->rhs[i]->index,i-rp->nrhs+1);
}else{
/* No destructor defined for this term */
@@ -3322,25 +3394,23 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
** Generate code which executes when the rule "rp" is reduced. Write
** the code to "out". Make sure lineno stays up-to-date.
*/
-PRIVATE void emit_code(out,rp,lemp,lineno)
-FILE *out;
-struct rule *rp;
-struct lemon *lemp;
-int *lineno;
-{
- char *cp;
- int linecnt = 0;
+PRIVATE void emit_code(
+ FILE *out,
+ struct rule *rp,
+ struct lemon *lemp,
+ int *lineno
+){
+ const char *cp;
/* Generate code to do the reduce action */
if( rp->code ){
- tplt_linedir(out,rp->line,lemp->filename);
+ if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,rp->line,lemp->filename); }
fprintf(out,"{%s",rp->code);
for(cp=rp->code; *cp; cp++){
- if( *cp=='\n' ) linecnt++;
+ if( *cp=='\n' ) (*lineno)++;
} /* End loop */
- (*lineno) += 3 + linecnt;
- fprintf(out,"}\n");
- tplt_linedir(out,*lineno,lemp->outname);
+ fprintf(out,"}\n"); (*lineno)++;
+ if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); }
} /* End if( rp->code ) */
return;
@@ -3353,12 +3423,12 @@ int *lineno;
** union, also set the ".dtnum" field of every terminal and nonterminal
** symbol.
*/
-void print_stack_union(out,lemp,plineno,mhflag)
-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 */
-{
+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 */
char **types; /* A hash table of datatypes */
int arraysize; /* Size of the "types" array */
@@ -3366,7 +3436,7 @@ int mhflag; /* True if generating makeheaders output */
char *stddt; /* Standardized name for a datatype */
int i,j; /* Loop counters */
int hash; /* For hashing the name of a type */
- char *name; /* Name of the parser */
+ const char *name; /* Name of the parser */
/* Allocate and initialize types[] and allocate stddt[] */
arraysize = lemp->nsymbol * 2;
@@ -3374,13 +3444,13 @@ int mhflag; /* True if generating makeheaders output */
for(i=0; i<arraysize; i++) types[i] = 0;
maxdtlength = 0;
if( lemp->vartype ){
- maxdtlength = strlen(lemp->vartype);
+ maxdtlength = lemonStrlen(lemp->vartype);
}
for(i=0; i<lemp->nsymbol; i++){
int len;
struct symbol *sp = lemp->symbols[i];
if( sp->datatype==0 ) continue;
- len = strlen(sp->datatype);
+ len = lemonStrlen(sp->datatype);
if( len>maxdtlength ) maxdtlength = len;
}
stddt = (char*)malloc( maxdtlength*2 + 1 );
@@ -3413,6 +3483,10 @@ int mhflag; /* True if generating makeheaders output */
while( *cp ) stddt[j++] = *cp++;
while( j>0 && isspace(stddt[j-1]) ) j--;
stddt[j] = 0;
+ if( lemp->tokentype && strcmp(stddt, lemp->tokentype)==0 ){
+ sp->dtnum = 0;
+ continue;
+ }
hash = 0;
for(j=0; stddt[j]; j++){
hash = hash*53 + stddt[j];
@@ -3428,7 +3502,7 @@ int mhflag; /* True if generating makeheaders output */
}
if( types[hash]==0 ){
sp->dtnum = hash + 1;
- types[hash] = (char*)malloc( strlen(stddt)+1 );
+ types[hash] = (char*)malloc( lemonStrlen(stddt)+1 );
if( types[hash]==0 ){
fprintf(stderr,"Out of memory.\n");
exit(1);
@@ -3445,6 +3519,7 @@ int mhflag; /* True if generating makeheaders output */
lemp->tokentype?lemp->tokentype:"void*"); lineno++;
if( mhflag ){ fprintf(out,"#endif\n"); lineno++; }
fprintf(out,"typedef union {\n"); lineno++;
+ fprintf(out," int yyinit;\n"); lineno++;
fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++;
for(i=0; i<arraysize; i++){
if( types[i]==0 ) continue;
@@ -3492,6 +3567,7 @@ struct axset {
struct state *stp; /* A pointer to a state */
int isTkn; /* True to use tokens. False for non-terminals */
int nAction; /* Number of actions */
+ int iOrder; /* Original order of action sets */
};
/*
@@ -3500,7 +3576,13 @@ struct axset {
static int axset_compare(const void *a, const void *b){
struct axset *p1 = (struct axset*)a;
struct axset *p2 = (struct axset*)b;
- return p2->nAction - p1->nAction;
+ int c;
+ c = p2->nAction - p1->nAction;
+ if( c==0 ){
+ c = p2->iOrder - p1->iOrder;
+ }
+ assert( c!=0 || p1==p2 );
+ return c;
}
/*
@@ -3523,10 +3605,10 @@ static void writeRuleText(FILE *out, struct rule *rp){
/* Generate C source code for the parser */
-void ReportTable(lemp, mhflag)
-struct lemon *lemp;
-int mhflag; /* Output in makeheaders format if true */
-{
+void ReportTable(
+ struct lemon *lemp,
+ int mhflag /* Output in makeheaders format if true */
+){
FILE *out, *in;
char line[LINESIZE];
int lineno;
@@ -3535,7 +3617,7 @@ int mhflag; /* Output in makeheaders format if true */
struct rule *rp;
struct acttab *pActtab;
int i, j, n;
- char *name;
+ const char *name;
int mnTknOfst, mxTknOfst;
int mnNtOfst, mxNtOfst;
struct axset *ax;
@@ -3551,7 +3633,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++;
@@ -3561,7 +3643,7 @@ int mhflag; /* Output in makeheaders format if true */
/* Generate #defines for all tokens */
if( mhflag ){
- char *prefix;
+ const char *prefix;
fprintf(out,"#if INTERFACE\n"); lineno++;
if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
else prefix = "";
@@ -3575,7 +3657,7 @@ int mhflag; /* Output in makeheaders format if true */
/* Generate the defines */
fprintf(out,"#define YYCODETYPE %s\n",
- minimum_size_type(0, lemp->nsymbol+5)); lineno++;
+ minimum_size_type(0, lemp->nsymbol+1)); lineno++;
fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++;
fprintf(out,"#define YYACTIONTYPE %s\n",
minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++;
@@ -3597,7 +3679,7 @@ int mhflag; /* Output in makeheaders format if true */
name = lemp->name ? lemp->name : "Parse";
if( lemp->arg && lemp->arg[0] ){
int i;
- i = strlen(lemp->arg);
+ i = lemonStrlen(lemp->arg);
while( i>=1 && isspace(lemp->arg[i-1]) ) i--;
while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;
fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++;
@@ -3639,7 +3721,7 @@ int mhflag; /* Output in makeheaders format if true */
*/
/* Compute the actions on all states and count them up */
- ax = calloc(lemp->nstate*2, sizeof(ax[0]));
+ ax = (struct axset *) calloc(lemp->nstate*2, sizeof(ax[0]));
if( ax==0 ){
fprintf(stderr,"malloc failed\n");
exit(1);
@@ -3660,6 +3742,7 @@ int mhflag; /* Output in makeheaders format if true */
** action table to a minimum, the heuristic of placing the largest action
** sets first is used.
*/
+ for(i=0; i<lemp->nstate*2; i++) ax[i].iOrder = i;
qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare);
pActtab = acttab_alloc();
for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){
@@ -3692,8 +3775,9 @@ int mhflag; /* Output in makeheaders format if true */
free(ax);
/* Output the yy_action table */
- fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++;
n = acttab_size(pActtab);
+ 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->nstate + lemp->nrule + 2;
@@ -3728,7 +3812,9 @@ int mhflag; /* Output in makeheaders format if true */
fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
n = lemp->nstate;
while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
- fprintf(out, "#define YY_SHIFT_MAX %d\n", n-1); lineno++;
+ fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++;
+ fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++;
+ fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++;
fprintf(out, "static const %s yy_shift_ofst[] = {\n",
minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++;
for(i=j=0; i<n; i++){
@@ -3751,7 +3837,9 @@ int mhflag; /* Output in makeheaders format if true */
fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
n = lemp->nstate;
while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--;
- fprintf(out, "#define YY_REDUCE_MAX %d\n", n-1); lineno++;
+ fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++;
+ fprintf(out, "#define YY_REDUCE_MIN (%d)\n", mnNtOfst); lineno++;
+ fprintf(out, "#define YY_REDUCE_MAX (%d)\n", mxNtOfst); lineno++;
fprintf(out, "static const %s yy_reduce_ofst[] = {\n",
minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++;
for(i=j=0; i<n; i++){
@@ -3790,7 +3878,9 @@ int mhflag; /* Output in makeheaders format if true */
/* Generate the table of fallback tokens.
*/
if( lemp->has_fallback ){
- for(i=0; i<lemp->nterminal; i++){
+ int mx = lemp->nterminal - 1;
+ while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; }
+ for(i=0; i<=mx; i++){
struct symbol *p = lemp->symbols[i];
if( p->fallback==0 ){
fprintf(out, " 0, /* %10s => nothing */\n", p->name);
@@ -3814,7 +3904,7 @@ int mhflag; /* Output in makeheaders format if true */
tplt_xfer(lemp->name,in,out,&lineno);
/* Generate a table containing a text string that describes every
- ** rule in the rule set of the grammer. This information is used
+ ** rule in the rule set of the grammar. This information is used
** when tracing REDUCE actions.
*/
for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
@@ -3830,11 +3920,15 @@ int mhflag; /* Output in makeheaders format if true */
** (In other words, generate the %destructor actions)
*/
if( lemp->tokendest ){
+ int once = 1;
for(i=0; i<lemp->nsymbol; i++){
struct symbol *sp = lemp->symbols[i];
if( sp==0 || sp->type!=TERMINAL ) continue;
- fprintf(out," case %d: /* %s */\n",
- sp->index, sp->name); lineno++;
+ if( once ){
+ fprintf(out, " /* TERMINAL Destructor */\n"); lineno++;
+ once = 0;
+ }
+ 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 ){
@@ -3844,24 +3938,27 @@ int mhflag; /* Output in makeheaders format if true */
}
if( lemp->vardest ){
struct symbol *dflt_sp = 0;
+ int once = 1;
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: /* %s */\n",
- sp->index, sp->name); lineno++;
+ if( once ){
+ fprintf(out, " /* Default NON-TERMINAL Destructor */\n"); lineno++;
+ once = 0;
+ }
+ fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++;
dflt_sp = sp;
}
if( dflt_sp!=0 ){
emit_destructor_code(out,dflt_sp,lemp,&lineno);
- fprintf(out," break;\n"); lineno++;
}
+ fprintf(out," break;\n"); lineno++;
}
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: /* %s */\n",
- sp->index, sp->name); 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++){
@@ -3881,7 +3978,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
@@ -3898,9 +3995,11 @@ int mhflag; /* Output in makeheaders format if true */
for(rp=lemp->rule; rp; rp=rp->next){
translate_code(lemp, rp);
}
+ /* First output rules other than the default: rule */
for(rp=lemp->rule; rp; rp=rp->next){
- struct rule *rp2;
+ struct rule *rp2; /* Other rules with the same action */
if( rp->code==0 ) continue;
+ if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */
fprintf(out," case %d: /* ", rp->index);
writeRuleText(out, rp);
fprintf(out, " */\n"); lineno++;
@@ -3908,29 +4007,41 @@ int mhflag; /* Output in makeheaders format if true */
if( rp2->code==rp->code ){
fprintf(out," case %d: /* ", rp2->index);
writeRuleText(out, rp2);
- fprintf(out," */\n"); lineno++;
+ fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++;
rp2->code = 0;
}
}
emit_code(out,rp,lemp,&lineno);
fprintf(out," break;\n"); lineno++;
+ rp->code = 0;
+ }
+ /* Finally, output the default: rule. We choose as the default: all
+ ** empty actions. */
+ fprintf(out," default:\n"); lineno++;
+ for(rp=lemp->rule; rp; rp=rp->next){
+ if( rp->code==0 ) continue;
+ assert( rp->code[0]=='\n' && rp->code[1]==0 );
+ fprintf(out," /* (%d) ", rp->index);
+ writeRuleText(out, rp);
+ fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++;
}
+ fprintf(out," break;\n"); lineno++;
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);
@@ -3938,11 +4049,10 @@ int mhflag; /* Output in makeheaders format if true */
}
/* Generate a header file for the parser */
-void ReportHeader(lemp)
-struct lemon *lemp;
+void ReportHeader(struct lemon *lemp)
{
FILE *out, *in;
- char *prefix;
+ const char *prefix;
char line[LINESIZE];
char pattern[LINESIZE];
int i;
@@ -3978,8 +4088,7 @@ struct lemon *lemp;
** it the default. Except, there is no default if the wildcard token
** is a possible look-ahead.
*/
-void CompressTables(lemp)
-struct lemon *lemp;
+void CompressTables(struct lemon *lemp)
{
struct state *stp;
struct action *ap, *ap2;
@@ -4050,7 +4159,11 @@ static int stateResortCompare(const void *a, const void *b){
n = pB->nNtAct - pA->nNtAct;
if( n==0 ){
n = pB->nTknAct - pA->nTknAct;
+ if( n==0 ){
+ n = pB->statenum - pA->statenum;
+ }
}
+ assert( n!=0 );
return n;
}
@@ -4059,8 +4172,7 @@ static int stateResortCompare(const void *a, const void *b){
** Renumber and resort states so that states with fewer choices
** occur at the end. Except, keep state 0 as the first state.
*/
-void ResortStates(lemp)
-struct lemon *lemp;
+void ResortStates(struct lemon *lemp)
{
int i;
struct state *stp;
@@ -4100,8 +4212,7 @@ struct lemon *lemp;
static int size = 0;
/* Set the set size */
-void SetSize(n)
-int n;
+void SetSize(int n)
{
size = n+1;
}
@@ -4118,17 +4229,14 @@ char *SetNew(){
}
/* Deallocate a set */
-void SetFree(s)
-char *s;
+void SetFree(char *s)
{
free(s);
}
/* Add a new element to the set. Return TRUE if the element was added
** and FALSE if it was already there. */
-int SetAdd(s,e)
-char *s;
-int e;
+int SetAdd(char *s, int e)
{
int rv;
assert( e>=0 && e<size );
@@ -4138,9 +4246,7 @@ int e;
}
/* Add every element of s2 to s1. Return TRUE if s1 changes. */
-int SetUnion(s1,s2)
-char *s1;
-char *s2;
+int SetUnion(char *s1, char *s2)
{
int i, progress;
progress = 0;
@@ -4166,8 +4272,7 @@ char *s2;
** Code for processing tables in the LEMON parser generator.
*/
-PRIVATE int strhash(x)
-char *x;
+PRIVATE int strhash(const char *x)
{
int h = 0;
while( *x) h = h*13 + *(x++);
@@ -4178,15 +4283,16 @@ char *x;
** keep strings in a table so that the same string is not in more
** than one place.
*/
-char *Strsafe(y)
-char *y;
+const char *Strsafe(const char *y)
{
- char *z;
+ const char *z;
+ char *cpy;
if( y==0 ) return 0;
z = Strsafe_find(y);
- if( z==0 && (z=malloc( strlen(y)+1 ))!=0 ){
- strcpy(z,y);
+ if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
+ strcpy(cpy,y);
+ z = cpy;
Strsafe_insert(z);
}
MemoryCheck(z);
@@ -4209,7 +4315,7 @@ struct s_x1 {
** in an associative array of type "x1".
*/
typedef struct s_x1node {
- char *data; /* The data */
+ const char *data; /* The data */
struct s_x1node *next; /* Next entry with the same hash */
struct s_x1node **from; /* Previous link */
} x1node;
@@ -4238,8 +4344,7 @@ void Strsafe_init(){
}
/* Insert a new record into the array. Return TRUE if successful.
** Prior data with the same key is NOT overwritten */
-int Strsafe_insert(data)
-char *data;
+int Strsafe_insert(const char *data)
{
x1node *np;
int h;
@@ -4295,8 +4400,7 @@ char *data;
/* Return a pointer to data assigned to the given key. Return NULL
** if no such key. */
-char *Strsafe_find(key)
-char *key;
+const char *Strsafe_find(const char *key)
{
int h;
x1node *np;
@@ -4314,8 +4418,7 @@ char *key;
/* Return a pointer to the (terminal or nonterminal) symbol "x".
** Create a new symbol if this is the first time "x" has been seen.
*/
-struct symbol *Symbol_new(x)
-char *x;
+struct symbol *Symbol_new(const char *x)
{
struct symbol *sp;
@@ -4332,6 +4435,7 @@ char *x;
sp->firstset = 0;
sp->lambda = LEMON_FALSE;
sp->destructor = 0;
+ sp->destLineno = 0;
sp->datatype = 0;
sp->useCnt = 0;
Symbol_insert(sp,sp->name);
@@ -4350,9 +4454,13 @@ char *x;
** order (the order they appeared in the grammar file) gives the
** smallest parser tables in SQLite.
*/
-int Symbolcmpp(struct symbol **a, struct symbol **b){
+int Symbolcmpp(const void *_a, const void *_b)
+{
+ const struct symbol **a = (const struct symbol **) _a;
+ const struct symbol **b = (const struct symbol **) _b;
int i1 = (**a).index + 10000000*((**a).name[0]>'Z');
int i2 = (**b).index + 10000000*((**b).name[0]>'Z');
+ assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 );
return i1-i2;
}
@@ -4372,8 +4480,8 @@ struct s_x2 {
** in an associative array of type "x2".
*/
typedef struct s_x2node {
- struct symbol *data; /* The data */
- char *key; /* The key */
+ struct symbol *data; /* The data */
+ const char *key; /* The key */
struct s_x2node *next; /* Next entry with the same hash */
struct s_x2node **from; /* Previous link */
} x2node;
@@ -4402,9 +4510,7 @@ void Symbol_init(){
}
/* Insert a new record into the array. Return TRUE if successful.
** Prior data with the same key is NOT overwritten */
-int Symbol_insert(data,key)
-struct symbol *data;
-char *key;
+int Symbol_insert(struct symbol *data, const char *key)
{
x2node *np;
int h;
@@ -4462,8 +4568,7 @@ char *key;
/* Return a pointer to data assigned to the given key. Return NULL
** if no such key. */
-struct symbol *Symbol_find(key)
-char *key;
+struct symbol *Symbol_find(const char *key)
{
int h;
x2node *np;
@@ -4479,8 +4584,7 @@ char *key;
}
/* Return the n-th data. Return NULL if n is out of range. */
-struct symbol *Symbol_Nth(n)
-int n;
+struct symbol *Symbol_Nth(int n)
{
struct symbol *data;
if( x2a && n>0 && n<=x2a->count ){
@@ -4514,10 +4618,10 @@ struct symbol **Symbol_arrayof()
}
/* Compare two configurations */
-int Configcmp(a,b)
-struct config *a;
-struct config *b;
+int Configcmp(const char *_a,const char *_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;
@@ -4525,9 +4629,7 @@ struct config *b;
}
/* Compare two states */
-PRIVATE int statecmp(a,b)
-struct config *a;
-struct config *b;
+PRIVATE int statecmp(struct config *a, struct config *b)
{
int rc;
for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){
@@ -4542,8 +4644,7 @@ struct config *b;
}
/* Hash a state */
-PRIVATE int statehash(a)
-struct config *a;
+PRIVATE int statehash(struct config *a)
{
int h=0;
while( a ){
@@ -4556,10 +4657,10 @@ struct config *a;
/* Allocate a new state structure */
struct state *State_new()
{
- struct state *new;
- new = (struct state *)calloc(1, sizeof(struct state) );
- MemoryCheck(new);
- return new;
+ struct state *newstate;
+ newstate = (struct state *)calloc(1, sizeof(struct state) );
+ MemoryCheck(newstate);
+ return newstate;
}
/* There is one instance of the following structure for each
@@ -4608,9 +4709,7 @@ void State_init(){
}
/* Insert a new record into the array. Return TRUE if successful.
** Prior data with the same key is NOT overwritten */
-int State_insert(data,key)
-struct state *data;
-struct config *key;
+int State_insert(struct state *data, struct config *key)
{
x3node *np;
int h;
@@ -4668,8 +4767,7 @@ struct config *key;
/* Return a pointer to data assigned to the given key. Return NULL
** if no such key. */
-struct state *State_find(key)
-struct config *key;
+struct state *State_find(struct config *key)
{
int h;
x3node *np;
@@ -4701,8 +4799,7 @@ struct state **State_arrayof()
}
/* Hash a configuration */
-PRIVATE int confighash(a)
-struct config *a;
+PRIVATE int confighash(struct config *a)
{
int h=0;
h = h*571 + a->rp->index*37 + a->dot;
@@ -4754,8 +4851,7 @@ void Configtable_init(){
}
/* Insert a new record into the array. Return TRUE if successful.
** Prior data with the same key is NOT overwritten */
-int Configtable_insert(data)
-struct config *data;
+int Configtable_insert(struct config *data)
{
x4node *np;
int h;
@@ -4766,7 +4862,7 @@ struct config *data;
h = ph & (x4a->size-1);
np = x4a->ht[h];
while( np ){
- if( Configcmp(np->data,data)==0 ){
+ if( Configcmp((const char *) np->data,(const char *) data)==0 ){
/* An existing entry with the same key is found. */
/* Fail because overwrite is not allows. */
return 0;
@@ -4811,8 +4907,7 @@ struct config *data;
/* Return a pointer to data assigned to the given key. Return NULL
** if no such key. */
-struct config *Configtable_find(key)
-struct config *key;
+struct config *Configtable_find(struct config *key)
{
int h;
x4node *np;
@@ -4821,7 +4916,7 @@ struct config *key;
h = confighash(key) & (x4a->size-1);
np = x4a->ht[h];
while( np ){
- if( Configcmp(np->data,key)==0 ) break;
+ if( Configcmp((const char *) np->data,(const char *) key)==0 ) break;
np = np->next;
}
return np ? np->data : 0;
@@ -4829,8 +4924,7 @@ struct config *key;
/* Remove all data from the table. Pass each data to the function "f"
** as it is removed. ("f" may be null to avoid this step.) */
-void Configtable_clear(f)
-int(*f)(/* struct config * */);
+void Configtable_clear(int(*f)(struct config *))
{
int i;
if( x4a==0 || x4a->count==0 ) return;
diff --git a/libgda/sql-parser/lempar.c b/libgda/sql-parser/lempar.c
index cca91ad..fe56d2d 100644
--- a/libgda/sql-parser/lempar.c
+++ b/libgda/sql-parser/lempar.c
@@ -1,8 +1,8 @@
/* Driver template for the LEMON parser generator.
** The author disclaims copyright to this source code.
*/
-/* First off, code is include which follows the "include" declaration
-** in the input file. */
+/* First off, code is included that follows the "include" declaration
+** in the input grammar file. */
#include <stdio.h>
%%
/* Next is all token values, in a form suitable for use by makeheaders.
@@ -60,7 +60,24 @@
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
-/* Next are that tables used to determine what action to take based on the
+/* The yyzerominor constant is used to initialize instances of
+** YYMINORTYPE objects to zero. */
+static const YYMINORTYPE yyzerominor = { 0 };
+
+/* Define the yytestcase() macro to be a no-op if is not already defined
+** otherwise.
+**
+** Applications can choose to define yytestcase() in the %include section
+** to a macro that can assist in verifying code coverage. For production
+** code the yytestcase() macro should be turned off. But it is useful
+** for testing.
+*/
+#ifndef yytestcase
+# define yytestcase(X)
+#endif
+
+
+/* Next are the tables used to determine what action to take based on the
** current state and lookahead token. These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.
@@ -108,14 +125,13 @@
** yy_default[] Default action for each state.
*/
%%
-#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
/* The next table maps tokens into fallback tokens. If a construct
** like the following:
**
** %fallback ID X Y Z.
**
-** appears in the grammer, then ID becomes a fallback token for X, Y,
+** appears in the grammar, then ID becomes a fallback token for X, Y,
** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
@@ -139,11 +155,11 @@ static const YYCODETYPE yyFallback[] = {
** It is sometimes called the "minor" token.
*/
struct yyStackEntry {
- int stateno; /* The state-number */
- int major; /* The major token value. This is the code
- ** number for the token at this stack level */
- YYMINORTYPE minor; /* The user-supplied minor token value. This
- ** is the value of the token */
+ YYACTIONTYPE stateno; /* The state-number */
+ YYCODETYPE major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
};
typedef struct yyStackEntry yyStackEntry;
@@ -151,6 +167,9 @@ typedef struct yyStackEntry yyStackEntry;
** the following structure */
struct yyParser {
int yyidx; /* Index of top element in stack */
+#ifdef YYTRACKMAXSTACKDEPTH
+ int yyidxMax; /* Maximum value of yyidx */
+#endif
int yyerrcnt; /* Shifts left before out of the error */
ParseARG_SDECL /* A place to hold %extra_argument */
#if YYSTACKDEPTH<=0
@@ -251,7 +270,12 @@ void *ParseAlloc(void *(*mallocProc)(size_t)){
pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
if( pParser ){
pParser->yyidx = -1;
+#ifdef YYTRACKMAXSTACKDEPTH
+ pParser->yyidxMax = 0;
+#endif
#if YYSTACKDEPTH<=0
+ pParser->yystack = NULL;
+ pParser->yystksz = 0;
yyGrowStack(pParser);
#endif
}
@@ -263,7 +287,12 @@ void *ParseAlloc(void *(*mallocProc)(size_t)){
** "yymajor" is the symbol code, and "yypminor" is a pointer to
** the value.
*/
-static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
+static void yy_destructor(
+ yyParser *yypParser, /* The parser */
+ YYCODETYPE yymajor, /* Type code for object to destroy */
+ YYMINORTYPE *yypminor /* The object to be destroyed */
+){
+ ParseARG_FETCH;
switch( yymajor ){
/* Here is inserted the actions which take place when a
** terminal or non-terminal is destroyed. This can happen
@@ -301,7 +330,7 @@ static int yy_pop_parser_stack(yyParser *pParser){
}
#endif
yymajor = yytos->major;
- yy_destructor( yymajor, &yytos->minor);
+ yy_destructor(pParser, yymajor, &yytos->minor);
pParser->yyidx--;
return yymajor;
}
@@ -332,6 +361,16 @@ void ParseFree(
}
/*
+** Return the peak depth of the stack for a parser.
+*/
+#ifdef YYTRACKMAXSTACKDEPTH
+int ParseStackPeak(void *p){
+ yyParser *pParser = (yyParser*)p;
+ return pParser->yyidxMax;
+}
+#endif
+
+/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
**
@@ -346,15 +385,16 @@ static int yy_find_shift_action(
int i;
int stateno = pParser->yystack[pParser->yyidx].stateno;
- if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
+ if( stateno>YY_SHIFT_COUNT
+ || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
return yy_default[stateno];
}
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
- if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
if( iLookAhead>0 ){
#ifdef YYFALLBACK
- int iFallback; /* Fallback token */
+ YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
&& (iFallback = yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
@@ -369,7 +409,15 @@ static int yy_find_shift_action(
#ifdef YYWILDCARD
{
int j = i - iLookAhead + YYWILDCARD;
- if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){
+ if(
+#if YY_SHIFT_MIN+YYWILDCARD<0
+ j>=0 &&
+#endif
+#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
+ j<YY_ACTTAB_COUNT &&
+#endif
+ yy_lookahead[j]==YYWILDCARD
+ ){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
@@ -400,13 +448,25 @@ static int yy_find_reduce_action(
YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
- assert( stateno<=YY_REDUCE_MAX );
+#ifdef YYERRORSYMBOL
+ if( stateno>YY_REDUCE_COUNT ){
+ return yy_default[stateno];
+ }
+#else
+ assert( stateno<=YY_REDUCE_COUNT );
+#endif
i = yy_reduce_ofst[stateno];
assert( i!=YY_REDUCE_USE_DFLT );
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
- assert( i>=0 && i<YY_SZ_ACTTAB );
+#ifdef YYERRORSYMBOL
+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+ return yy_default[stateno];
+ }
+#else
+ assert( i>=0 && i<YY_ACTTAB_COUNT );
assert( yy_lookahead[i]==iLookAhead );
+#endif
return yy_action[i];
}
@@ -435,10 +495,15 @@ static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */
int yyNewState, /* The new state to shift in */
int yyMajor, /* The major token to shift in */
- YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
+ YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
){
yyStackEntry *yytos;
yypParser->yyidx++;
+#ifdef YYTRACKMAXSTACKDEPTH
+ if( yypParser->yyidx>yypParser->yyidxMax ){
+ yypParser->yyidxMax = yypParser->yyidx;
+ }
+#endif
#if YYSTACKDEPTH>0
if( yypParser->yyidx>=YYSTACKDEPTH ){
yyStackOverflow(yypParser, yypMinor);
@@ -454,8 +519,8 @@ static void yy_shift(
}
#endif
yytos = &yypParser->yystack[yypParser->yyidx];
- yytos->stateno = yyNewState;
- yytos->major = yyMajor;
+ yytos->stateno = (YYACTIONTYPE)yyNewState;
+ yytos->major = (YYCODETYPE)yyMajor;
yytos->minor = *yypMinor;
#ifndef NDEBUG
if( yyTraceFILE && yypParser->yyidx>0 ){
@@ -518,7 +583,8 @@ static void yy_reduce(
** from wireshark this week. Clearly they are stressing Lemon in ways
** that it has not been previously stressed... (SQLite ticket #2172)
*/
- memset(&yygotominor, 0, sizeof(yygotominor));
+ /*memset(&yygotominor, 0, sizeof(yygotominor));*/
+ yygotominor = yyzerominor;
switch( yyruleno ){
@@ -535,7 +601,7 @@ static void yy_reduce(
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
yypParser->yyidx -= yysize;
- yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
+ yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
if( yyact < YYNSTATE ){
#ifdef NDEBUG
/* If we are not debugging and the reduce action popped at least
@@ -545,8 +611,8 @@ static void yy_reduce(
if( yysize ){
yypParser->yyidx++;
yymsp -= yysize-1;
- yymsp->stateno = yyact;
- yymsp->major = yygoto;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
yymsp->minor = yygotominor;
}else
#endif
@@ -562,6 +628,7 @@ static void yy_reduce(
/*
** The following code executes when the parse fails
*/
+#ifndef YYNOERRORRECOVERY
static void yy_parse_failed(
yyParser *yypParser /* The parser */
){
@@ -577,6 +644,7 @@ static void yy_parse_failed(
%%
ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
+#endif /* YYNOERRORRECOVERY */
/*
** The following code executes when a syntax error first occurs.
@@ -649,7 +717,8 @@ void Parse(
if( yypParser->yyidx<0 ){
#if YYSTACKDEPTH<=0
if( yypParser->yystksz <=0 ){
- memset(&yyminorunion, 0, sizeof(yyminorunion));
+ /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
+ yyminorunion = yyzerominor;
yyStackOverflow(yypParser, &yyminorunion);
return;
}
@@ -670,7 +739,7 @@ void Parse(
#endif
do{
- yyact = yy_find_shift_action(yypParser,yymajor);
+ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
if( yyact<YYNSTATE ){
assert( !yyendofinput ); /* Impossible to shift the $ token */
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
@@ -719,7 +788,7 @@ void Parse(
yyTracePrompt,yyTokenName[yymajor]);
}
#endif
- yy_destructor(yymajor,&yyminorunion);
+ yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
yymajor = YYNOCODE;
}else{
while(
@@ -732,7 +801,7 @@ void Parse(
yy_pop_parser_stack(yypParser);
}
if( yypParser->yyidx < 0 || yymajor==0 ){
- yy_destructor(yymajor,&yyminorunion);
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
yy_parse_failed(yypParser);
yymajor = YYNOCODE;
}else if( yymx!=YYERRORSYMBOL ){
@@ -743,6 +812,18 @@ void Parse(
}
yypParser->yyerrcnt = 3;
yyerrorhit = 1;
+#elif defined(YYNOERRORRECOVERY)
+ /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
+ ** do any kind of error recovery. Instead, simply invoke the syntax
+ ** error routine and continue going as if nothing had happened.
+ **
+ ** Applications can set this macro (for example inside %include) if
+ ** they intend to abandon the parse upon the first syntax error seen.
+ */
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+
#else /* YYERRORSYMBOL is not defined */
/* This is what we do if the grammar does not define ERROR:
**
@@ -757,7 +838,7 @@ void Parse(
yy_syntax_error(yypParser,yymajor,yyminorunion);
}
yypParser->yyerrcnt = 3;
- yy_destructor(yymajor,&yyminorunion);
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
if( yyendofinput ){
yy_parse_failed(yypParser);
}
diff --git a/providers/firebird/Makefile.am b/providers/firebird/Makefile.am
index 42bed2d..5156d93 100644
--- a/providers/firebird/Makefile.am
+++ b/providers/firebird/Makefile.am
@@ -12,7 +12,7 @@ AM_CPPFLAGS = \
# parser generation
parser.c parser.h: parser.y $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD)
- - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
+ - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d -T$(top_srcdir)/libgda/sql-parser/lempar.c $(srcdir)/parser.y
gen_def$(EXEEXT_FOR_BUILD): gen_def.c
$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
diff --git a/providers/oracle/Makefile.am b/providers/oracle/Makefile.am
index 17d257b..48059c0 100644
--- a/providers/oracle/Makefile.am
+++ b/providers/oracle/Makefile.am
@@ -22,7 +22,7 @@ keywords_hash.c: mkkeywordhash$(EXEEXT_FOR_BUILD) $(pkeyword_files)
# parser generation
parser.c parser.h: parser.y $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD)
- - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
+ - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d -T$(top_srcdir)/libgda/sql-parser/lempar.c $(srcdir)/parser.y
gen_def$(EXEEXT_FOR_BUILD): gen_def.c
$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_builddir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
diff --git a/providers/reuseable/mysql/Makefile.am b/providers/reuseable/mysql/Makefile.am
index d7bd0ea..bff3c12 100644
--- a/providers/reuseable/mysql/Makefile.am
+++ b/providers/reuseable/mysql/Makefile.am
@@ -20,7 +20,7 @@ keywords_hash.c: mkkeywordhash$(EXEEXT_FOR_BUILD) $(pkeyword_files)
# parser generation
parser.c parser.h: parser.y $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD)
- - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
+ - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d -T$(top_srcdir)/libgda/sql-parser/lempar.c $(srcdir)/parser.y
gen_def$(EXEEXT_FOR_BUILD): gen_def.c
$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_builddir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
diff --git a/providers/reuseable/postgres/Makefile.am b/providers/reuseable/postgres/Makefile.am
index c6efa21..09bcbd4 100644
--- a/providers/reuseable/postgres/Makefile.am
+++ b/providers/reuseable/postgres/Makefile.am
@@ -19,7 +19,7 @@ keywords_hash.c: mkkeywordhash$(EXEEXT_FOR_BUILD) $(pkeyword_files)
# parser generation
parser.c parser.h: parser.y $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD)
- - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
+ - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d -T$(top_srcdir)/libgda/sql-parser/lempar.c $(srcdir)/parser.y
gen_def$(EXEEXT_FOR_BUILD): gen_def.c
$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_builddir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
diff --git a/providers/skel-implementation/capi/Makefile.am b/providers/skel-implementation/capi/Makefile.am
index 10ae6c6..2752e34 100644
--- a/providers/skel-implementation/capi/Makefile.am
+++ b/providers/skel-implementation/capi/Makefile.am
@@ -23,7 +23,7 @@ keywords_hash.c: mkkeywordhash$(EXEEXT_FOR_BUILD) $(pkeyword_files)
# parser generation
parser.c parser.h: parser.y $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD)
- - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
+ - $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d -T$(top_srcdir)/libgda/sql-parser/lempar.c $(srcdir)/parser.y
gen_def$(EXEEXT_FOR_BUILD): gen_def.c
$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_builddir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]