Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: third_party/sqlite/src/tool/lemon.c

Issue 6990047: Import SQLite 3.7.6.3. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/src/tool/genfkey.test ('k') | third_party/sqlite/src/tool/lempar.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/src/tool/lemon.c
diff --git a/third_party/sqlite/src/tool/lemon.c b/third_party/sqlite/src/tool/lemon.c
index 8336e9a1ba2b249e12a320de13cf3078cba8ee1c..898022e28c1589b5c99bac7a990422dce6e089e4 100644
--- a/third_party/sqlite/src/tool/lemon.c
+++ b/third_party/sqlite/src/tool/lemon.c
@@ -20,7 +20,13 @@
#endif
#ifdef __WIN32__
-extern int access();
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int access(const char *path, int mode);
+#ifdef __cplusplus
+}
+#endif
#else
#include <unistd.h>
#endif
@@ -34,6 +40,24 @@ 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*));
/*
@@ -43,6 +67,11 @@ static char *msort(char*,char**,int(*)(const char*,const char*));
*/
#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 *);
@@ -55,59 +84,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" *************************************/
@@ -119,23 +149,25 @@ 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 precedence 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 */
@@ -156,14 +188,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 */
@@ -176,6 +208,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 */
@@ -183,29 +219,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 */
@@ -292,41 +327,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.
@@ -335,7 +370,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;
@@ -348,9 +383,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
@@ -369,6 +404,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;
}
@@ -381,22 +419,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 ***********/
@@ -406,16 +444,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 */
@@ -442,7 +498,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);
@@ -451,12 +507,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");
@@ -498,7 +557,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");
@@ -510,28 +569,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;
@@ -540,13 +587,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 */
+ }
}
}
}
@@ -578,8 +655,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){
@@ -608,8 +684,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;
@@ -670,9 +745,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;
@@ -730,9 +804,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;
@@ -776,9 +849,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;
@@ -794,13 +865,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 */
@@ -825,8 +894,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
@@ -849,8 +918,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;
@@ -885,8 +953,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;
@@ -918,12 +985,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;
@@ -1006,11 +1072,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 */
@@ -1025,7 +1091,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;
@@ -1083,7 +1149,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;
@@ -1095,14 +1161,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;
@@ -1129,10 +1194,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 );
@@ -1156,9 +1221,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;
@@ -1186,8 +1249,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;
@@ -1266,8 +1328,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){
@@ -1284,72 +1345,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 = lemonStrlen(prefix);
- availablewidth = LINEWIDTH - prefixsize;
-
- /* Generate the error message */
- vsprintf(errmsg,format,ap);
+ vfprintf(stderr,format,ap);
va_end(ap);
- errmsgsize = lemonStrlen(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" ************************************/
/*
@@ -1373,13 +1375,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( lemonStrlen(z)+1 );
+ *paz = (char *) malloc( lemonStrlen(z)+1 );
if( *paz==0 ){
fprintf(stderr,"out of memory\n");
exit(1);
@@ -1389,11 +1391,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;
@@ -1403,22 +1411,30 @@ char **argv;
static int statistics = 0;
static int mhflag = 0;
static int nolinenosflag = 0;
+ static int noResort = 0;
static struct s_options options[] = {
{OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},
{OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},
{OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
+ {OPT_FSTR, "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, "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, "x", (char*)&version, "Print the version number."},
{OPT_FLAG,0,0,0}
};
int i;
+ int exitcode;
struct lemon lem;
+ atexit(LemonAtExit);
+
OptInit(argv,options,stderr);
if( version ){
printf("Lemon version 1.0\n");
@@ -1456,8 +1472,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;
@@ -1495,8 +1510,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);
@@ -1515,11 +1531,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" *******************************/
/*
@@ -1578,7 +1598,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{
@@ -1587,7 +1607,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);
@@ -1639,7 +1659,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" **************************/
@@ -1653,10 +1673,7 @@ 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]);
@@ -1678,8 +1695,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;
@@ -1700,9 +1716,7 @@ 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;
@@ -1720,9 +1734,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);
@@ -1736,9 +1750,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;
@@ -1805,29 +1817,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;
@@ -1864,16 +1873,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);
@@ -1935,42 +1942,43 @@ 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 insertLineMacro; /* Add #line before declaration insert */
int *decllinenoslot; /* Where to write declaration line number */
@@ -1981,10 +1989,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,
@@ -2116,7 +2123,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];
@@ -2155,17 +2162,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,
@@ -2284,7 +2292,7 @@ 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{
@@ -2298,14 +2306,24 @@ to follow the previous rule.");
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->insertLineMacro = 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:
@@ -2330,7 +2348,8 @@ to follow the previous rule.");
break;
case WAITING_FOR_DECL_ARG:
if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){
- char *zOld, *zNew, *zBuf, *z;
+ const char *zOld, *zNew;
+ char *zBuf, *z;
int nOld, n, nLine, nNew, nBack;
int addLineMacro;
char zLine[50];
@@ -2354,8 +2373,8 @@ to follow the previous rule.");
nLine = lemonStrlen(zLine);
n += nLine + lemonStrlen(psp->filename) + nBack;
}
- *psp->declargslot = zBuf = realloc(*psp->declargslot, n);
- zBuf += nOld;
+ *psp->declargslot = (char *) realloc(*psp->declargslot, n);
+ zBuf = *psp->declargslot + nOld;
if( addLineMacro ){
if( nOld && zBuf[-1]!='\n' ){
*(zBuf++) = '\n';
@@ -2491,8 +2510,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;
@@ -2646,7 +2664,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;
@@ -2660,27 +2678,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 ){
@@ -2692,8 +2706,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;
@@ -2713,14 +2726,12 @@ 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( lemonStrlen(lemp->filename) + lemonStrlen(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);
@@ -2735,11 +2746,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);
@@ -2750,13 +2761,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;
@@ -2801,9 +2828,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;
@@ -2883,11 +2908,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;
@@ -2896,8 +2935,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;
@@ -2963,12 +3001,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;
@@ -2984,22 +3021,25 @@ int modemask;
if( path ) sprintf(path,"%s/%s",argv0,name);
*cp = c;
}else{
- extern char *getenv();
pathlist = getenv("PATH");
if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
+ pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 );
path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
- if( path!=0 ){
- while( *pathlist ){
- cp = strchr(pathlist,':');
- if( cp==0 ) cp = &pathlist[lemonStrlen(pathlist)];
+ 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;
@@ -3009,9 +3049,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 ){
@@ -3034,11 +3072,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];
@@ -3063,8 +3097,7 @@ 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];
@@ -3072,6 +3105,23 @@ struct lemon *lemp;
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);
@@ -3101,10 +3151,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 ){
@@ -3116,11 +3163,7 @@ char *filename;
}
/* Print a string to the file and keep the linenumber up to date */
-PRIVATE void tplt_print(out,lemp,str,lineno)
-FILE *out;
-struct lemon *lemp;
-char *str;
-int *lineno;
+PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, int *lineno)
{
if( str==0 ) return;
while( *str ){
@@ -3142,12 +3185,12 @@ 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;
if( sp->type==TERMINAL ){
@@ -3185,9 +3228,7 @@ int *lineno;
/*
** 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 ){
@@ -3210,13 +3251,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;
@@ -3228,11 +3269,11 @@ PRIVATE char *append_str(char *zText, int n, int p1, int p2){
}
n = lemonStrlen(zText);
}
- if( n+sizeof(zInt)*2+used >= alloced ){
+ if( (int) (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' ){
@@ -3265,12 +3306,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++);
@@ -3343,13 +3387,13 @@ 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;
+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 ){
@@ -3372,12 +3416,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 */
@@ -3385,7 +3429,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;
@@ -3516,6 +3560,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 */
};
/*
@@ -3524,7 +3569,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;
}
/*
@@ -3547,10 +3598,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;
@@ -3559,7 +3610,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;
@@ -3585,7 +3636,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 = "";
@@ -3663,7 +3714,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);
@@ -3684,6 +3735,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++){
@@ -3716,8 +3768,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;
@@ -3752,7 +3805,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++){
@@ -3775,7 +3830,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++){
@@ -3985,11 +4042,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;
@@ -4025,8 +4081,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;
@@ -4097,7 +4152,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;
}
@@ -4106,8 +4165,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;
@@ -4147,8 +4205,7 @@ struct lemon *lemp;
static int size = 0;
/* Set the set size */
-void SetSize(n)
-int n;
+void SetSize(int n)
{
size = n+1;
}
@@ -4165,17 +4222,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 );
@@ -4185,9 +4239,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;
@@ -4213,8 +4265,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++);
@@ -4225,15 +4276,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( lemonStrlen(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);
@@ -4256,7 +4308,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;
@@ -4285,8 +4337,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;
@@ -4342,8 +4393,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;
@@ -4361,8 +4411,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;
@@ -4398,9 +4447,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;
}
@@ -4420,8 +4473,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;
@@ -4450,9 +4503,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;
@@ -4510,8 +4561,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;
@@ -4527,8 +4577,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 ){
@@ -4562,10 +4611,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;
@@ -4573,9 +4622,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){
@@ -4590,8 +4637,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 ){
@@ -4604,10 +4650,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
@@ -4656,9 +4702,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;
@@ -4716,8 +4760,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;
@@ -4749,8 +4792,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;
@@ -4802,8 +4844,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;
@@ -4814,7 +4855,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;
@@ -4859,8 +4900,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;
@@ -4869,7 +4909,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;
@@ -4877,8 +4917,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;
« no previous file with comments | « third_party/sqlite/src/tool/genfkey.test ('k') | third_party/sqlite/src/tool/lempar.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698