/ Check-in [1e8b8420]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge in the massive clean-up and ANSI-fication of Lemon carried out by Ryan Gordon. There are no functional changes to SQLite itself - Lemon still generates exactly the same parsing automaton from exactly the same grammar.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1e8b842039cc06b57a321226633c55b94eb8dcd7
User & Date: drh 2010-02-22 19:37:44
References
2011-06-20
18:27
Fix compiler warnings in lemon by removing some of the code added by Ryan Gordon in [1e8b842039cc0]. check-in: 76b18b2b user: drh tags: trunk
Context
2010-02-22
23:17
Fix an assertion-fault/segfault problem that comes up when trying to VACUUM an auto-vacuumed database with a large schema. Ticket [da1151f97df244]. check-in: 86d50ce5 user: drh tags: trunk
19:37
Merge in the massive clean-up and ANSI-fication of Lemon carried out by Ryan Gordon. There are no functional changes to SQLite itself - Lemon still generates exactly the same parsing automaton from exactly the same grammar. check-in: 1e8b8420 user: drh tags: trunk
19:32
Log all error messages if logging is enabled. check-in: a8076aed user: drh tags: trunk
2010-02-17
20:31
Report error if the grammar has multiple %type lines for the same nonterminal. check-in: 721f33e7 user: icculus tags: lemon-update-2010
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to tool/lemon.c.

    29     29   #define PRIVATE
    30     30   
    31     31   #ifdef TEST
    32     32   #define MAXRHS 5       /* Set low to exercise exception code */
    33     33   #else
    34     34   #define MAXRHS 1000
    35     35   #endif
           36  +
           37  +static const char **made_files = NULL;
           38  +static int made_files_count = 0;
           39  +static int successful_exit = 0;
           40  +static void LemonAtExit(void)
           41  +{
           42  +    /* if we failed, delete (most) files we made, to unconfuse build tools. */
           43  +    int i;
           44  +    for (i = 0; i < made_files_count; i++) {
           45  +        if (!successful_exit) {
           46  +            remove(made_files[i]);
           47  +        }
           48  +        free((void *) made_files[i]);
           49  +    }
           50  +    free(made_files);
           51  +    made_files_count = 0;
           52  +    made_files = NULL;
           53  +}
    36     54   
    37     55   static char *msort(char*,char**,int(*)(const char*,const char*));
    38     56   
    39     57   /*
    40     58   ** Compilers are getting increasingly pedantic about type conversions
    41     59   ** as C evolves ever closer to Ada....  To work around the latest problems
    42     60   ** we have to define the following variant of strlen().
    43     61   */
    44     62   #define lemonStrlen(X)   ((int)strlen(X))
           63  +
           64  +/* a few forward declarations... */
           65  +struct rule;
           66  +struct lemon;
           67  +struct action;
    45     68   
    46     69   static struct action *Action_new(void);
    47     70   static struct action *Action_sort(struct action *);
    48     71   
    49     72   /********** From the file "build.h" ************************************/
    50     73   void FindRulePrecedences();
    51     74   void FindFirstSets();
    52     75   void FindStates();
    53     76   void FindLinks();
    54     77   void FindFollowSets();
    55     78   void FindActions();
    56     79   
    57     80   /********* From the file "configlist.h" *********************************/
    58         -void Configlist_init(/* void */);
    59         -struct config *Configlist_add(/* struct rule *, int */);
    60         -struct config *Configlist_addbasis(/* struct rule *, int */);
    61         -void Configlist_closure(/* void */);
    62         -void Configlist_sort(/* void */);
    63         -void Configlist_sortbasis(/* void */);
    64         -struct config *Configlist_return(/* void */);
    65         -struct config *Configlist_basis(/* void */);
    66         -void Configlist_eat(/* struct config * */);
    67         -void Configlist_reset(/* void */);
           81  +void Configlist_init(void);
           82  +struct config *Configlist_add(struct rule *, int);
           83  +struct config *Configlist_addbasis(struct rule *, int);
           84  +void Configlist_closure(struct lemon *);
           85  +void Configlist_sort(void);
           86  +void Configlist_sortbasis(void);
           87  +struct config *Configlist_return(void);
           88  +struct config *Configlist_basis(void);
           89  +void Configlist_eat(struct config *);
           90  +void Configlist_reset(void);
    68     91   
    69     92   /********* From the file "error.h" ***************************************/
    70     93   void ErrorMsg(const char *, int,const char *, ...);
    71     94   
    72     95   /****** From the file "option.h" ******************************************/
           96  +enum option_type { OPT_FLAG=1,  OPT_INT,  OPT_DBL,  OPT_STR,
           97  +         OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR};
    73     98   struct s_options {
    74         -  enum { OPT_FLAG=1,  OPT_INT,  OPT_DBL,  OPT_STR,
    75         -         OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type;
    76         -  char *label;
           99  +  enum option_type type;
          100  +  const char *label;
    77    101     char *arg;
    78         -  char *message;
          102  +  const char *message;
    79    103   };
    80         -int    OptInit(/* char**,struct s_options*,FILE* */);
    81         -int    OptNArgs(/* void */);
    82         -char  *OptArg(/* int */);
    83         -void   OptErr(/* int */);
    84         -void   OptPrint(/* void */);
          104  +int    OptInit(char**,struct s_options*,FILE*);
          105  +int    OptNArgs(void);
          106  +char  *OptArg(int);
          107  +void   OptErr(int);
          108  +void   OptPrint(void);
    85    109   
    86    110   /******** From the file "parse.h" *****************************************/
    87         -void Parse(/* struct lemon *lemp */);
          111  +void Parse(struct lemon *lemp);
    88    112   
    89    113   /********* From the file "plink.h" ***************************************/
    90         -struct plink *Plink_new(/* void */);
    91         -void Plink_add(/* struct plink **, struct config * */);
    92         -void Plink_copy(/* struct plink **, struct plink * */);
    93         -void Plink_delete(/* struct plink * */);
          114  +struct plink *Plink_new(void);
          115  +void Plink_add(struct plink **, struct config *);
          116  +void Plink_copy(struct plink **, struct plink *);
          117  +void Plink_delete(struct plink *);
    94    118   
    95    119   /********** From the file "report.h" *************************************/
    96         -void Reprint(/* struct lemon * */);
    97         -void ReportOutput(/* struct lemon * */);
    98         -void ReportTable(/* struct lemon * */);
    99         -void ReportHeader(/* struct lemon * */);
   100         -void CompressTables(/* struct lemon * */);
   101         -void ResortStates(/* struct lemon * */);
          120  +void Reprint(struct lemon *);
          121  +void ReportOutput(struct lemon *);
          122  +void ReportTable(struct lemon *, int);
          123  +void ReportHeader(struct lemon *);
          124  +void CompressTables(struct lemon *);
          125  +void ResortStates(struct lemon *);
   102    126   
   103    127   /********** From the file "set.h" ****************************************/
   104         -void  SetSize(/* int N */);             /* All sets will be of size N */
   105         -char *SetNew(/* void */);               /* A new set for element 0..N */
   106         -void  SetFree(/* char* */);             /* Deallocate a set */
          128  +void  SetSize(int);             /* All sets will be of size N */
          129  +char *SetNew(void);               /* A new set for element 0..N */
          130  +void  SetFree(char*);             /* Deallocate a set */
   107    131   
   108         -int SetAdd(/* char*,int */);            /* Add element to a set */
   109         -int SetUnion(/* char *A,char *B */);    /* A <- A U B, thru element N */
   110         -
          132  +char *SetNew(void);               /* A new set for element 0..N */
          133  +int SetAdd(char*,int);            /* Add element to a set */
          134  +int SetUnion(char *,char *);    /* A <- A U B, thru element N */
   111    135   #define SetFind(X,Y) (X[Y])       /* True if Y is in set X */
   112    136   
   113    137   /********** From the file "struct.h" *************************************/
   114    138   /*
   115    139   ** Principal data structures for the LEMON parser generator.
   116    140   */
   117    141   
   118    142   typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean;
   119    143   
   120    144   /* Symbols (terminals and nonterminals) of the grammar are stored
   121    145   ** in the following: */
   122         -struct symbol {
   123         -  char *name;              /* Name of the symbol */
   124         -  int index;               /* Index number for this symbol */
   125         -  enum {
   126         -    TERMINAL,
   127         -    NONTERMINAL,
   128         -    MULTITERMINAL
   129         -  } type;                  /* Symbols are all either TERMINALS or NTs */
   130         -  struct rule *rule;       /* Linked list of rules of this (if an NT) */
   131         -  struct symbol *fallback; /* fallback token in case this token doesn't parse */
   132         -  int prec;                /* Precedence if defined (-1 otherwise) */
   133         -  enum e_assoc {
          146  +enum symbol_type {
          147  +  TERMINAL,
          148  +  NONTERMINAL,
          149  +  MULTITERMINAL
          150  +};
          151  +enum e_assoc {
   134    152       LEFT,
   135    153       RIGHT,
   136    154       NONE,
   137    155       UNK
   138         -  } assoc;                 /* Associativity if precedence is defined */
          156  +};
          157  +struct symbol {
          158  +  const char *name;        /* Name of the symbol */
          159  +  int index;               /* Index number for this symbol */
          160  +  enum symbol_type type;   /* Symbols are all either TERMINALS or NTs */
          161  +  struct rule *rule;       /* Linked list of rules of this (if an NT) */
          162  +  struct symbol *fallback; /* fallback token in case this token doesn't parse */
          163  +  int prec;                /* Precedence if defined (-1 otherwise) */
          164  +  enum e_assoc assoc;      /* Associativity if precedence is defined */
   139    165     char *firstset;          /* First-set for all rules of this symbol */
   140    166     Boolean lambda;          /* True if NT and can generate an empty string */
   141    167     int useCnt;              /* Number of times used */
   142    168     char *destructor;        /* Code which executes whenever this symbol is
   143    169                              ** popped from the stack during error processing */
   144    170     int destLineno;          /* Line number for start of destructor */
   145    171     char *datatype;          /* The data type of information held by this
................................................................................
   152    178     struct symbol **subsym;  /* Array of constituent symbols */
   153    179   };
   154    180   
   155    181   /* Each production rule in the grammar is stored in the following
   156    182   ** structure.  */
   157    183   struct rule {
   158    184     struct symbol *lhs;      /* Left-hand side of the rule */
   159         -  char *lhsalias;          /* Alias for the LHS (NULL if none) */
          185  +  const char *lhsalias;    /* Alias for the LHS (NULL if none) */
   160    186     int lhsStart;            /* True if left-hand side is the start symbol */
   161    187     int ruleline;            /* Line number for the rule */
   162    188     int nrhs;                /* Number of RHS symbols */
   163    189     struct symbol **rhs;     /* The RHS symbols */
   164         -  char **rhsalias;         /* An alias for each RHS symbol (NULL if none) */
          190  +  const char **rhsalias;   /* An alias for each RHS symbol (NULL if none) */
   165    191     int line;                /* Line number at which code begins */
   166         -  char *code;              /* The code executed when this rule is reduced */
          192  +  const char *code;        /* The code executed when this rule is reduced */
   167    193     struct symbol *precsym;  /* Precedence symbol for this rule */
   168    194     int index;               /* An index number for this rule */
   169    195     Boolean canReduce;       /* True if this rule is ever reduced */
   170    196     struct rule *nextlhs;    /* Next rule with the same LHS */
   171    197     struct rule *next;       /* Next rule in the global list */
   172    198   };
   173    199   
   174    200   /* A configuration is a production rule of the grammar together with
   175    201   ** a mark (dot) showing how much of that rule has been processed so far.
   176    202   ** Configurations also contain a follow-set which is a list of terminal
   177    203   ** symbols which are allowed to immediately follow the end of the rule.
   178    204   ** Every configuration is recorded as an instance of the following: */
          205  +enum cfgstatus {
          206  +  COMPLETE,
          207  +  INCOMPLETE
          208  +};
   179    209   struct config {
   180    210     struct rule *rp;         /* The rule upon which the configuration is based */
   181    211     int dot;                 /* The parse point */
   182    212     char *fws;               /* Follow-set for this configuration only */
   183    213     struct plink *fplp;      /* Follow-set forward propagation links */
   184    214     struct plink *bplp;      /* Follow-set backwards propagation links */
   185    215     struct state *stp;       /* Pointer to state which contains this */
   186         -  enum {
   187         -    COMPLETE,              /* The status is used during followset and */
   188         -    INCOMPLETE             /*    shift computations */
   189         -  } status;
          216  +  enum cfgstatus status;   /* used during followset and shift computations */
   190    217     struct config *next;     /* Next configuration in the state */
   191    218     struct config *bp;       /* The next basis configuration */
   192    219   };
          220  +
          221  +enum e_action {
          222  +  SHIFT,
          223  +  ACCEPT,
          224  +  REDUCE,
          225  +  ERROR,
          226  +  SSCONFLICT,              /* A shift/shift conflict */
          227  +  SRCONFLICT,              /* Was a reduce, but part of a conflict */
          228  +  RRCONFLICT,              /* Was a reduce, but part of a conflict */
          229  +  SH_RESOLVED,             /* Was a shift.  Precedence resolved conflict */
          230  +  RD_RESOLVED,             /* Was reduce.  Precedence resolved conflict */
          231  +  NOT_USED                 /* Deleted by compression */
          232  +};
   193    233   
   194    234   /* Every shift or reduce operation is stored as one of the following */
   195    235   struct action {
   196    236     struct symbol *sp;       /* The look-ahead symbol */
   197         -  enum e_action {
   198         -    SHIFT,
   199         -    ACCEPT,
   200         -    REDUCE,
   201         -    ERROR,
   202         -    SSCONFLICT,              /* A shift/shift conflict */
   203         -    SRCONFLICT,              /* Was a reduce, but part of a conflict */
   204         -    RRCONFLICT,              /* Was a reduce, but part of a conflict */
   205         -    SH_RESOLVED,             /* Was a shift.  Precedence resolved conflict */
   206         -    RD_RESOLVED,             /* Was reduce.  Precedence resolved conflict */
   207         -    NOT_USED                 /* Deleted by compression */
   208         -  } type;
          237  +  enum e_action type;
   209    238     union {
   210    239       struct state *stp;     /* The new state, if a shift */
   211    240       struct rule *rp;       /* The rule, if a reduce */
   212    241     } x;
   213    242     struct action *next;     /* Next action for this state */
   214    243     struct action *collide;  /* Next action with the same hash */
   215    244   };
................................................................................
   288    317   ** by the associative array code building program "aagen".
   289    318   ** Do not edit this file!  Instead, edit the specification
   290    319   ** file, then rerun aagen.
   291    320   */
   292    321   /*
   293    322   ** Code for processing tables in the LEMON parser generator.
   294    323   */
   295         -
   296    324   /* Routines for handling a strings */
   297    325   
   298         -char *Strsafe();
          326  +const char *Strsafe(const char *);
   299    327   
   300         -void Strsafe_init(/* void */);
   301         -int Strsafe_insert(/* char * */);
   302         -char *Strsafe_find(/* char * */);
          328  +void Strsafe_init(void);
          329  +int Strsafe_insert(const char *);
          330  +const char *Strsafe_find(const char *);
   303    331   
   304    332   /* Routines for handling symbols of the grammar */
   305    333   
   306         -struct symbol *Symbol_new();
   307         -int Symbolcmpp(/* struct symbol **, struct symbol ** */);
   308         -void Symbol_init(/* void */);
   309         -int Symbol_insert(/* struct symbol *, char * */);
   310         -struct symbol *Symbol_find(/* char * */);
   311         -struct symbol *Symbol_Nth(/* int */);
   312         -int Symbol_count(/*  */);
   313         -struct symbol **Symbol_arrayof(/*  */);
          334  +struct symbol *Symbol_new(const char *);
          335  +int Symbolcmpp(const void *, const void *);
          336  +void Symbol_init(void);
          337  +int Symbol_insert(struct symbol *, const char *);
          338  +struct symbol *Symbol_find(const char *);
          339  +struct symbol *Symbol_Nth(int);
          340  +int Symbol_count(void);
          341  +struct symbol **Symbol_arrayof(void);
   314    342   
   315    343   /* Routines to manage the state table */
   316    344   
   317         -int Configcmp(/* struct config *, struct config * */);
   318         -struct state *State_new();
   319         -void State_init(/* void */);
   320         -int State_insert(/* struct state *, struct config * */);
   321         -struct state *State_find(/* struct config * */);
          345  +int Configcmp(const char *, const char *);
          346  +struct state *State_new(void);
          347  +void State_init(void);
          348  +int State_insert(struct state *, struct config *);
          349  +struct state *State_find(struct config *);
   322    350   struct state **State_arrayof(/*  */);
   323    351   
   324    352   /* Routines used for efficiency in Configlist_add */
   325    353   
   326         -void Configtable_init(/* void */);
   327         -int Configtable_insert(/* struct config * */);
   328         -struct config *Configtable_find(/* struct config * */);
   329         -void Configtable_clear(/* int(*)(struct config *) */);
          354  +void Configtable_init(void);
          355  +int Configtable_insert(struct config *);
          356  +struct config *Configtable_find(struct config *);
          357  +void Configtable_clear(int(*)(struct config *));
          358  +
   330    359   /****************** From the file "action.c" *******************************/
   331    360   /*
   332    361   ** Routines processing parser actions in the LEMON parser generator.
   333    362   */
   334    363   
   335    364   /* Allocate a new parser action */
   336    365   static struct action *Action_new(void){
   337    366     static struct action *freelist = 0;
   338         -  struct action *new;
          367  +  struct action *newaction;
   339    368   
   340    369     if( freelist==0 ){
   341    370       int i;
   342    371       int amt = 100;
   343    372       freelist = (struct action *)calloc(amt, sizeof(struct action));
   344    373       if( freelist==0 ){
   345    374         fprintf(stderr,"Unable to allocate memory for a new parser action.");
   346    375         exit(1);
   347    376       }
   348    377       for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
   349    378       freelist[amt-1].next = 0;
   350    379     }
   351         -  new = freelist;
          380  +  newaction = freelist;
   352    381     freelist = freelist->next;
   353         -  return new;
          382  +  return newaction;
   354    383   }
   355    384   
   356    385   /* Compare two actions for sorting purposes.  Return negative, zero, or
   357    386   ** positive if the first action is less than, equal to, or greater than
   358    387   ** the first
   359    388   */
   360    389   static int actioncmp(
................................................................................
   380    409     struct action *ap
   381    410   ){
   382    411     ap = (struct action *)msort((char *)ap,(char **)&ap->next,
   383    412                                 (int(*)(const char*,const char*))actioncmp);
   384    413     return ap;
   385    414   }
   386    415   
   387         -void Action_add(app,type,sp,arg)
   388         -struct action **app;
   389         -enum e_action type;
   390         -struct symbol *sp;
   391         -char *arg;
   392         -{
   393         -  struct action *new;
   394         -  new = Action_new();
   395         -  new->next = *app;
   396         -  *app = new;
   397         -  new->type = type;
   398         -  new->sp = sp;
          416  +void Action_add(
          417  +  struct action **app,
          418  +  enum e_action type,
          419  +  struct symbol *sp,
          420  +  char *arg
          421  +){
          422  +  struct action *newaction;
          423  +  newaction = Action_new();
          424  +  newaction->next = *app;
          425  +  *app = newaction;
          426  +  newaction->type = type;
          427  +  newaction->sp = sp;
   399    428     if( type==SHIFT ){
   400         -    new->x.stp = (struct state *)arg;
          429  +    newaction->x.stp = (struct state *)arg;
   401    430     }else{
   402         -    new->x.rp = (struct rule *)arg;
          431  +    newaction->x.rp = (struct rule *)arg;
   403    432     }
   404    433   }
   405    434   /********************** New code to implement the "acttab" module ***********/
   406    435   /*
   407    436   ** This module implements routines use to construct the yy_action[] table.
   408    437   */
   409    438   
................................................................................
   423    452   ** All actions associated with a single state_number are first entered
   424    453   ** into aLookahead[] using multiple calls to acttab_action().  Then the 
   425    454   ** actions for that single state_number are placed into the aAction[] 
   426    455   ** array with a single call to acttab_insert().  The acttab_insert() call
   427    456   ** also resets the aLookahead[] array in preparation for the next
   428    457   ** state number.
   429    458   */
          459  +struct lookahead_action {
          460  +  int lookahead;             /* Value of the lookahead token */
          461  +  int action;                /* Action to take on the given lookahead */
          462  +};
   430    463   typedef struct acttab acttab;
   431    464   struct acttab {
   432    465     int nAction;                 /* Number of used slots in aAction[] */
   433    466     int nActionAlloc;            /* Slots allocated for aAction[] */
   434         -  struct {
   435         -    int lookahead;             /* Value of the lookahead token */
   436         -    int action;                /* Action to take on the given lookahead */
   437         -  } *aAction,                  /* The yy_action[] table under construction */
          467  +  struct lookahead_action
          468  +    *aAction,                  /* The yy_action[] table under construction */
   438    469       *aLookahead;               /* A single new transaction set */
   439    470     int mnLookahead;             /* Minimum aLookahead[].lookahead */
   440    471     int mnAction;                /* Action associated with mnLookahead */
   441    472     int mxLookahead;             /* Maximum aLookahead[].lookahead */
   442    473     int nLookahead;              /* Used slots in aLookahead[] */
   443    474     int nLookaheadAlloc;         /* Slots allocated in aLookahead[] */
   444    475   };
................................................................................
   457    488     free( p->aAction );
   458    489     free( p->aLookahead );
   459    490     free( p );
   460    491   }
   461    492   
   462    493   /* Allocate a new acttab structure */
   463    494   acttab *acttab_alloc(void){
   464         -  acttab *p = calloc( 1, sizeof(*p) );
          495  +  acttab *p = (acttab *) calloc( 1, sizeof(*p) );
   465    496     if( p==0 ){
   466    497       fprintf(stderr,"Unable to allocate memory for a new acttab.");
   467    498       exit(1);
   468    499     }
   469    500     memset(p, 0, sizeof(*p));
   470    501     return p;
   471    502   }
................................................................................
   474    505   **
   475    506   ** This routine is called once for each lookahead for a particular
   476    507   ** state.
   477    508   */
   478    509   void acttab_action(acttab *p, int lookahead, int action){
   479    510     if( p->nLookahead>=p->nLookaheadAlloc ){
   480    511       p->nLookaheadAlloc += 25;
   481         -    p->aLookahead = realloc( p->aLookahead,
          512  +    p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead,
   482    513                                sizeof(p->aLookahead[0])*p->nLookaheadAlloc );
   483    514       if( p->aLookahead==0 ){
   484    515         fprintf(stderr,"malloc failed\n");
   485    516         exit(1);
   486    517       }
   487    518     }
   488    519     if( p->nLookahead==0 ){
................................................................................
   516    547     ** in the worst case.  The worst case occurs if the transaction set
   517    548     ** must be appended to the current action table
   518    549     */
   519    550     n = p->mxLookahead + 1;
   520    551     if( p->nAction + n >= p->nActionAlloc ){
   521    552       int oldAlloc = p->nActionAlloc;
   522    553       p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20;
   523         -    p->aAction = realloc( p->aAction,
          554  +    p->aAction = (struct lookahead_action *) realloc( p->aAction,
   524    555                             sizeof(p->aAction[0])*p->nActionAlloc);
   525    556       if( p->aAction==0 ){
   526    557         fprintf(stderr,"malloc failed\n");
   527    558         exit(1);
   528    559       }
   529    560       for(i=oldAlloc; i<p->nActionAlloc; i++){
   530    561         p->aAction[i].lookahead = -1;
................................................................................
   614    645   ** Those rules which have a precedence symbol coded in the input
   615    646   ** grammar using the "[symbol]" construct will already have the
   616    647   ** rp->precsym field filled.  Other rules take as their precedence
   617    648   ** symbol the first RHS symbol with a defined precedence.  If there
   618    649   ** are not RHS symbols with a defined precedence, the precedence
   619    650   ** symbol field is left blank.
   620    651   */
   621         -void FindRulePrecedences(xp)
   622         -struct lemon *xp;
          652  +void FindRulePrecedences(struct lemon *xp)
   623    653   {
   624    654     struct rule *rp;
   625    655     for(rp=xp->rule; rp; rp=rp->next){
   626    656       if( rp->precsym==0 ){
   627    657         int i, j;
   628    658         for(i=0; i<rp->nrhs && rp->precsym==0; i++){
   629    659           struct symbol *sp = rp->rhs[i];
................................................................................
   644    674   }
   645    675   
   646    676   /* Find all nonterminals which will generate the empty string.
   647    677   ** Then go back and compute the first sets of every nonterminal.
   648    678   ** The first set is the set of all terminal symbols which can begin
   649    679   ** a string generated by that nonterminal.
   650    680   */
   651         -void FindFirstSets(lemp)
   652         -struct lemon *lemp;
          681  +void FindFirstSets(struct lemon *lemp)
   653    682   {
   654    683     int i, j;
   655    684     struct rule *rp;
   656    685     int progress;
   657    686   
   658    687     for(i=0; i<lemp->nsymbol; i++){
   659    688       lemp->symbols[i]->lambda = LEMON_FALSE;
................................................................................
   706    735     return;
   707    736   }
   708    737   
   709    738   /* Compute all LR(0) states for the grammar.  Links
   710    739   ** are added to between some states so that the LR(1) follow sets
   711    740   ** can be computed later.
   712    741   */
   713         -PRIVATE struct state *getstate(/* struct lemon * */);  /* forward reference */
   714         -void FindStates(lemp)
   715         -struct lemon *lemp;
          742  +PRIVATE struct state *getstate(struct lemon *);  /* forward reference */
          743  +void FindStates(struct lemon *lemp)
   716    744   {
   717    745     struct symbol *sp;
   718    746     struct rule *rp;
   719    747   
   720    748     Configlist_init();
   721    749   
   722    750     /* Find the start symbol */
................................................................................
   766    794     (void)getstate(lemp);
   767    795     return;
   768    796   }
   769    797   
   770    798   /* Return a pointer to a state which is described by the configuration
   771    799   ** list which has been built from calls to Configlist_add.
   772    800   */
   773         -PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */
   774         -PRIVATE struct state *getstate(lemp)
   775         -struct lemon *lemp;
          801  +PRIVATE void buildshifts(struct lemon *, struct state *); /* Forwd ref */
          802  +PRIVATE struct state *getstate(struct lemon *lemp)
   776    803   {
   777    804     struct config *cfp, *bp;
   778    805     struct state *stp;
   779    806   
   780    807     /* Extract the sorted basis of the new state.  The basis was constructed
   781    808     ** by prior calls to "Configlist_addbasis()". */
   782    809     Configlist_sortbasis();
................................................................................
   812    839     }
   813    840     return stp;
   814    841   }
   815    842   
   816    843   /*
   817    844   ** Return true if two symbols are the same.
   818    845   */
   819         -int same_symbol(a,b)
   820         -struct symbol *a;
   821         -struct symbol *b;
          846  +int same_symbol(struct symbol *a, struct symbol *b)
   822    847   {
   823    848     int i;
   824    849     if( a==b ) return 1;
   825    850     if( a->type!=MULTITERMINAL ) return 0;
   826    851     if( b->type!=MULTITERMINAL ) return 0;
   827    852     if( a->nsubsym!=b->nsubsym ) return 0;
   828    853     for(i=0; i<a->nsubsym; i++){
................................................................................
   830    855     }
   831    856     return 1;
   832    857   }
   833    858   
   834    859   /* Construct all successor states to the given state.  A "successor"
   835    860   ** state is any state which can be reached by a shift action.
   836    861   */
   837         -PRIVATE void buildshifts(lemp,stp)
   838         -struct lemon *lemp;
   839         -struct state *stp;     /* The state from which successors are computed */
          862  +PRIVATE void buildshifts(struct lemon *lemp, struct state *stp)
   840    863   {
   841    864     struct config *cfp;  /* For looping thru the config closure of "stp" */
   842    865     struct config *bcfp; /* For the inner loop on config closure of "stp" */
   843         -  struct config *new;  /* */
          866  +  struct config *newcfg;  /* */
   844    867     struct symbol *sp;   /* Symbol following the dot in configuration "cfp" */
   845    868     struct symbol *bsp;  /* Symbol following the dot in configuration "bcfp" */
   846    869     struct state *newstp; /* A pointer to a successor state */
   847    870   
   848    871     /* Each configuration becomes complete after it contibutes to a successor
   849    872     ** state.  Initially, all configurations are incomplete */
   850    873     for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE;
................................................................................
   861    884       ** construction but with the dot shifted one symbol to the right. */
   862    885       for(bcfp=cfp; bcfp; bcfp=bcfp->next){
   863    886         if( bcfp->status==COMPLETE ) continue;    /* Already used */
   864    887         if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */
   865    888         bsp = bcfp->rp->rhs[bcfp->dot];           /* Get symbol after dot */
   866    889         if( !same_symbol(bsp,sp) ) continue;      /* Must be same as for "cfp" */
   867    890         bcfp->status = COMPLETE;                  /* Mark this config as used */
   868         -      new = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
   869         -      Plink_add(&new->bplp,bcfp);
          891  +      newcfg = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
          892  +      Plink_add(&newcfg->bplp,bcfp);
   870    893       }
   871    894   
   872    895       /* Get a pointer to the state described by the basis configuration set
   873    896       ** constructed in the preceding loop */
   874    897       newstp = getstate(lemp);
   875    898   
   876    899       /* The state "newstp" is reached from the state "stp" by a shift action
................................................................................
   885    908       }
   886    909     }
   887    910   }
   888    911   
   889    912   /*
   890    913   ** Construct the propagation links
   891    914   */
   892         -void FindLinks(lemp)
   893         -struct lemon *lemp;
          915  +void FindLinks(struct lemon *lemp)
   894    916   {
   895    917     int i;
   896    918     struct config *cfp, *other;
   897    919     struct state *stp;
   898    920     struct plink *plp;
   899    921   
   900    922     /* Housekeeping detail:
................................................................................
   921    943   }
   922    944   
   923    945   /* Compute all followsets.
   924    946   **
   925    947   ** A followset is the set of all symbols which can come immediately
   926    948   ** after a configuration.
   927    949   */
   928         -void FindFollowSets(lemp)
   929         -struct lemon *lemp;
          950  +void FindFollowSets(struct lemon *lemp)
   930    951   {
   931    952     int i;
   932    953     struct config *cfp;
   933    954     struct plink *plp;
   934    955     int progress;
   935    956     int change;
   936    957   
................................................................................
   954    975   	}
   955    976           cfp->status = COMPLETE;
   956    977         }
   957    978       }
   958    979     }while( progress );
   959    980   }
   960    981   
   961         -static int resolve_conflict();
          982  +static int resolve_conflict(struct action *,struct action *, struct symbol *);
   962    983   
   963    984   /* Compute the reduce actions, and resolve conflicts.
   964    985   */
   965         -void FindActions(lemp)
   966         -struct lemon *lemp;
          986  +void FindActions(struct lemon *lemp)
   967    987   {
   968    988     int i,j;
   969    989     struct config *cfp;
   970    990     struct state *stp;
   971    991     struct symbol *sp;
   972    992     struct rule *rp;
   973    993   
................................................................................
  1042   1062   **   is not associated with the error rule.  If neither or both
  1043   1063   **   actions are associated with an error rule, then try to
  1044   1064   **   use precedence to resolve the conflict.
  1045   1065   **
  1046   1066   ** If either action is a SHIFT, then it must be apx.  This
  1047   1067   ** function won't work if apx->type==REDUCE and apy->type==SHIFT.
  1048   1068   */
  1049         -static int resolve_conflict(apx,apy,errsym)
  1050         -struct action *apx;
  1051         -struct action *apy;
  1052         -struct symbol *errsym;   /* The error symbol (if defined.  NULL otherwise) */
  1053         -{
         1069  +static int resolve_conflict(
         1070  +  struct action *apx,
         1071  +  struct action *apy,
         1072  +  struct symbol *errsym   /* The error symbol (if defined.  NULL otherwise) */
         1073  +){
  1054   1074     struct symbol *spx, *spy;
  1055   1075     int errcnt = 0;
  1056   1076     assert( apx->sp==apy->sp );  /* Otherwise there would be no conflict */
  1057   1077     if( apx->type==SHIFT && apy->type==SHIFT ){
  1058   1078       apy->type = SSCONFLICT;
  1059   1079       errcnt++;
  1060   1080     }
................................................................................
  1119   1139   static struct config *current = 0;       /* Top of list of configurations */
  1120   1140   static struct config **currentend = 0;   /* Last on list of configs */
  1121   1141   static struct config *basis = 0;         /* Top of list of basis configs */
  1122   1142   static struct config **basisend = 0;     /* End of list of basis configs */
  1123   1143   
  1124   1144   /* Return a pointer to a new configuration */
  1125   1145   PRIVATE struct config *newconfig(){
  1126         -  struct config *new;
         1146  +  struct config *newcfg;
  1127   1147     if( freelist==0 ){
  1128   1148       int i;
  1129   1149       int amt = 3;
  1130   1150       freelist = (struct config *)calloc( amt, sizeof(struct config) );
  1131   1151       if( freelist==0 ){
  1132   1152         fprintf(stderr,"Unable to allocate memory for a new configuration.");
  1133   1153         exit(1);
  1134   1154       }
  1135   1155       for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
  1136   1156       freelist[amt-1].next = 0;
  1137   1157     }
  1138         -  new = freelist;
         1158  +  newcfg = freelist;
  1139   1159     freelist = freelist->next;
  1140         -  return new;
         1160  +  return newcfg;
  1141   1161   }
  1142   1162   
  1143   1163   /* The configuration "old" is no longer used */
  1144         -PRIVATE void deleteconfig(old)
  1145         -struct config *old;
         1164  +PRIVATE void deleteconfig(struct config *old)
  1146   1165   {
  1147   1166     old->next = freelist;
  1148   1167     freelist = old;
  1149   1168   }
  1150   1169   
  1151   1170   /* Initialized the configuration list builder */
  1152   1171   void Configlist_init(){
................................................................................
  1165   1184     basis = 0;
  1166   1185     basisend = &basis;
  1167   1186     Configtable_clear(0);
  1168   1187     return;
  1169   1188   }
  1170   1189   
  1171   1190   /* Add another configuration to the configuration list */
  1172         -struct config *Configlist_add(rp,dot)
  1173         -struct rule *rp;    /* The rule */
  1174         -int dot;            /* Index into the RHS of the rule where the dot goes */
  1175         -{
         1191  +struct config *Configlist_add(
         1192  +  struct rule *rp,    /* The rule */
         1193  +  int dot             /* Index into the RHS of the rule where the dot goes */
         1194  +){
  1176   1195     struct config *cfp, model;
  1177   1196   
  1178   1197     assert( currentend!=0 );
  1179   1198     model.rp = rp;
  1180   1199     model.dot = dot;
  1181   1200     cfp = Configtable_find(&model);
  1182   1201     if( cfp==0 ){
................................................................................
  1192   1211       currentend = &cfp->next;
  1193   1212       Configtable_insert(cfp);
  1194   1213     }
  1195   1214     return cfp;
  1196   1215   }
  1197   1216   
  1198   1217   /* Add a basis configuration to the configuration list */
  1199         -struct config *Configlist_addbasis(rp,dot)
  1200         -struct rule *rp;
  1201         -int dot;
         1218  +struct config *Configlist_addbasis(struct rule *rp, int dot)
  1202   1219   {
  1203   1220     struct config *cfp, model;
  1204   1221   
  1205   1222     assert( basisend!=0 );
  1206   1223     assert( currentend!=0 );
  1207   1224     model.rp = rp;
  1208   1225     model.dot = dot;
................................................................................
  1222   1239       basisend = &cfp->bp;
  1223   1240       Configtable_insert(cfp);
  1224   1241     }
  1225   1242     return cfp;
  1226   1243   }
  1227   1244   
  1228   1245   /* Compute the closure of the configuration list */
  1229         -void Configlist_closure(lemp)
  1230         -struct lemon *lemp;
         1246  +void Configlist_closure(struct lemon *lemp)
  1231   1247   {
  1232   1248     struct config *cfp, *newcfp;
  1233   1249     struct rule *rp, *newrp;
  1234   1250     struct symbol *sp, *xsp;
  1235   1251     int i, dot;
  1236   1252   
  1237   1253     assert( currentend!=0 );
................................................................................
  1302   1318     old = basis;
  1303   1319     basis = 0;
  1304   1320     basisend = 0;
  1305   1321     return old;
  1306   1322   }
  1307   1323   
  1308   1324   /* Free all elements of the given configuration list */
  1309         -void Configlist_eat(cfp)
  1310         -struct config *cfp;
         1325  +void Configlist_eat(struct config *cfp)
  1311   1326   {
  1312   1327     struct config *nextcfp;
  1313   1328     for(; cfp; cfp=nextcfp){
  1314   1329       nextcfp = cfp->next;
  1315   1330       assert( cfp->fplp==0 );
  1316   1331       assert( cfp->bplp==0 );
  1317   1332       if( cfp->fws ) SetFree(cfp->fws);
................................................................................
  1320   1335     return;
  1321   1336   }
  1322   1337   /***************** From the file "error.c" *********************************/
  1323   1338   /*
  1324   1339   ** Code for printing error message.
  1325   1340   */
  1326   1341   
  1327         -/* Find a good place to break "msg" so that its length is at least "min"
  1328         -** but no more than "max".  Make the point as close to max as possible.
  1329         -*/
  1330         -static int findbreak(msg,min,max)
  1331         -char *msg;
  1332         -int min;
  1333         -int max;
  1334         -{
  1335         -  int i,spot;
  1336         -  char c;
  1337         -  for(i=spot=min; i<=max; i++){
  1338         -    c = msg[i];
  1339         -    if( c=='\t' ) msg[i] = ' ';
  1340         -    if( c=='\n' ){ msg[i] = ' '; spot = i; break; }
  1341         -    if( c==0 ){ spot = i; break; }
  1342         -    if( c=='-' && i<max-1 ) spot = i+1;
  1343         -    if( c==' ' ) spot = i;
  1344         -  }
  1345         -  return spot;
  1346         -}
  1347         -
  1348         -/*
  1349         -** The error message is split across multiple lines if necessary.  The
  1350         -** splits occur at a space, if there is a space available near the end
  1351         -** of the line.
  1352         -*/
  1353         -#define ERRMSGSIZE  10000 /* Hope this is big enough.  No way to error check */
  1354         -#define LINEWIDTH      79 /* Max width of any output line */
  1355         -#define PREFIXLIMIT    30 /* Max width of the prefix on each line */
  1356   1342   void ErrorMsg(const char *filename, int lineno, const char *format, ...){
  1357         -  char errmsg[ERRMSGSIZE];
  1358         -  char prefix[PREFIXLIMIT+10];
  1359         -  int errmsgsize;
  1360         -  int prefixsize;
  1361         -  int availablewidth;
  1362   1343     va_list ap;
  1363         -  int end, restart, base;
  1364         -
         1344  +  fprintf(stderr, "%s:%d: ", filename, lineno);
  1365   1345     va_start(ap, format);
  1366         -  /* Prepare a prefix to be prepended to every output line */
  1367         -  if( lineno>0 ){
  1368         -    sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno);
  1369         -  }else{
  1370         -    sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename);
  1371         -  }
  1372         -  prefixsize = lemonStrlen(prefix);
  1373         -  availablewidth = LINEWIDTH - prefixsize;
  1374         -
  1375         -  /* Generate the error message */
  1376         -  vsprintf(errmsg,format,ap);
         1346  +  vfprintf(stderr,format,ap);
  1377   1347     va_end(ap);
  1378         -  errmsgsize = lemonStrlen(errmsg);
  1379         -  /* Remove trailing '\n's from the error message. */
  1380         -  while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){
  1381         -     errmsg[--errmsgsize] = 0;
  1382         -  }
  1383         -
  1384         -  /* Print the error message */
  1385         -  base = 0;
  1386         -  while( errmsg[base]!=0 ){
  1387         -    end = restart = findbreak(&errmsg[base],0,availablewidth);
  1388         -    restart += base;
  1389         -    while( errmsg[restart]==' ' ) restart++;
  1390         -    fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]);
  1391         -    base = restart;
  1392         -  }
         1348  +  fprintf(stderr, "\n");
  1393   1349   }
  1394   1350   /**************** From the file "main.c" ************************************/
  1395   1351   /*
  1396   1352   ** Main program file for the LEMON parser generator.
  1397   1353   */
  1398   1354   
  1399   1355   /* Report an out-of-memory condition and abort.  This function
................................................................................
  1409   1365   
  1410   1366   /* This routine is called with the argument to each -D command-line option.
  1411   1367   ** Add the macro defined to the azDefine array.
  1412   1368   */
  1413   1369   static void handle_D_option(char *z){
  1414   1370     char **paz;
  1415   1371     nDefine++;
  1416         -  azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine);
         1372  +  azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine);
  1417   1373     if( azDefine==0 ){
  1418   1374       fprintf(stderr,"out of memory\n");
  1419   1375       exit(1);
  1420   1376     }
  1421   1377     paz = &azDefine[nDefine-1];
  1422         -  *paz = malloc( lemonStrlen(z)+1 );
         1378  +  *paz = (char *) malloc( lemonStrlen(z)+1 );
  1423   1379     if( *paz==0 ){
  1424   1380       fprintf(stderr,"out of memory\n");
  1425   1381       exit(1);
  1426   1382     }
  1427   1383     strcpy(*paz, z);
  1428   1384     for(z=*paz; *z && *z!='='; z++){}
  1429   1385     *z = 0;
  1430   1386   }
  1431   1387   
         1388  +static char *user_templatename = NULL;
         1389  +static void handle_T_option(char *z){
         1390  +  user_templatename = (char *) malloc( lemonStrlen(z)+1 );
         1391  +  if( user_templatename==0 ){
         1392  +    memory_error();
         1393  +  }
         1394  +  strcpy(user_templatename, z);
         1395  +}
  1432   1396   
  1433   1397   /* The main program.  Parse the command line and do it... */
  1434         -int main(argc,argv)
  1435         -int argc;
  1436         -char **argv;
         1398  +int main(int argc, char **argv)
  1437   1399   {
  1438   1400     static int version = 0;
  1439   1401     static int rpflag = 0;
  1440   1402     static int basisflag = 0;
  1441   1403     static int compress = 0;
  1442   1404     static int quiet = 0;
  1443   1405     static int statistics = 0;
  1444   1406     static int mhflag = 0;
  1445   1407     static int nolinenosflag = 0;
  1446   1408     static struct s_options options[] = {
  1447   1409       {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},
  1448   1410       {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},
  1449   1411       {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
         1412  +    {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
  1450   1413       {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
  1451   1414       {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."},
  1452   1415       {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."},
  1453   1416       {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."},
  1454   1417       {OPT_FLAG, "s", (char*)&statistics,
  1455   1418                                      "Print parser stats to standard output."},
  1456   1419       {OPT_FLAG, "x", (char*)&version, "Print the version number."},
  1457   1420       {OPT_FLAG,0,0,0}
  1458   1421     };
  1459   1422     int i;
         1423  +  int exitcode;
  1460   1424     struct lemon lem;
         1425  +
         1426  +  atexit(LemonAtExit);
  1461   1427   
  1462   1428     OptInit(argv,options,stderr);
  1463   1429     if( version ){
  1464   1430        printf("Lemon version 1.0\n");
  1465   1431        exit(0); 
  1466   1432     }
  1467   1433     if( OptNArgs()!=1 ){
................................................................................
  1492   1458     }
  1493   1459   
  1494   1460     /* Count and index the symbols of the grammar */
  1495   1461     lem.nsymbol = Symbol_count();
  1496   1462     Symbol_new("{default}");
  1497   1463     lem.symbols = Symbol_arrayof();
  1498   1464     for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
  1499         -  qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*),
  1500         -        (int(*)())Symbolcmpp);
         1465  +  qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), Symbolcmpp);
  1501   1466     for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
  1502   1467     for(i=1; isupper(lem.symbols[i]->name[0]); i++);
  1503   1468     lem.nterminal = i;
  1504   1469   
  1505   1470     /* Generate a reprint of the grammar, if requested on the command line */
  1506   1471     if( rpflag ){
  1507   1472       Reprint(&lem);
................................................................................
  1551   1516     }
  1552   1517     if( statistics ){
  1553   1518       printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n",
  1554   1519         lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule);
  1555   1520       printf("                   %d states, %d parser table entries, %d conflicts\n",
  1556   1521         lem.nstate, lem.tablesize, lem.nconflict);
  1557   1522     }
  1558         -  if( lem.nconflict ){
         1523  +  if( lem.nconflict > 0 ){
  1559   1524       fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
  1560   1525     }
  1561         -  exit(lem.errorcnt + lem.nconflict);
  1562         -  return (lem.errorcnt + lem.nconflict);
         1526  +
         1527  +  /* return 0 on success, 1 on failure. */
         1528  +  exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0;
         1529  +  successful_exit = (exitcode == 0);
         1530  +  exit(exitcode);
         1531  +  return (exitcode);
  1563   1532   }
  1564   1533   /******************** From the file "msort.c" *******************************/
  1565   1534   /*
  1566   1535   ** A generic merge-sort program.
  1567   1536   **
  1568   1537   ** USAGE:
  1569   1538   ** Let "ptr" be a pointer to some structure which is at the head of
................................................................................
  1689   1658   
  1690   1659   #define ISOPT(X) ((X)[0]=='-'||(X)[0]=='+'||strchr((X),'=')!=0)
  1691   1660   
  1692   1661   /*
  1693   1662   ** Print the command line with a carrot pointing to the k-th character
  1694   1663   ** of the n-th field.
  1695   1664   */
  1696         -static void errline(n,k,err)
  1697         -int n;
  1698         -int k;
  1699         -FILE *err;
         1665  +static void errline(int n, int k, FILE *err)
  1700   1666   {
  1701   1667     int spcnt, i;
  1702   1668     if( argv[0] ) fprintf(err,"%s",argv[0]);
  1703   1669     spcnt = lemonStrlen(argv[0]) + 1;
  1704   1670     for(i=1; i<n && argv[i]; i++){
  1705   1671       fprintf(err," %s",argv[i]);
  1706   1672       spcnt += lemonStrlen(argv[i])+1;
................................................................................
  1714   1680     }
  1715   1681   }
  1716   1682   
  1717   1683   /*
  1718   1684   ** Return the index of the N-th non-switch argument.  Return -1
  1719   1685   ** if N is out of range.
  1720   1686   */
  1721         -static int argindex(n)
  1722         -int n;
         1687  +static int argindex(int n)
  1723   1688   {
  1724   1689     int i;
  1725   1690     int dashdash = 0;
  1726   1691     if( argv!=0 && *argv!=0 ){
  1727   1692       for(i=1; argv[i]; i++){
  1728   1693         if( dashdash || !ISOPT(argv[i]) ){
  1729   1694           if( n==0 ) return i;
................................................................................
  1736   1701   }
  1737   1702   
  1738   1703   static char emsg[] = "Command line syntax error: ";
  1739   1704   
  1740   1705   /*
  1741   1706   ** Process a flag command line argument.
  1742   1707   */
  1743         -static int handleflags(i,err)
  1744         -int i;
  1745         -FILE *err;
         1708  +static int handleflags(int i, FILE *err)
  1746   1709   {
  1747   1710     int v;
  1748   1711     int errcnt = 0;
  1749   1712     int j;
  1750   1713     for(j=0; op[j].label; j++){
  1751   1714       if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break;
  1752   1715     }
................................................................................
  1756   1719         fprintf(err,"%sundefined option.\n",emsg);
  1757   1720         errline(i,1,err);
  1758   1721       }
  1759   1722       errcnt++;
  1760   1723     }else if( op[j].type==OPT_FLAG ){
  1761   1724       *((int*)op[j].arg) = v;
  1762   1725     }else if( op[j].type==OPT_FFLAG ){
  1763         -    (*(void(*)())(op[j].arg))(v);
         1726  +    (*(void(*)(int))(op[j].arg))(v);
  1764   1727     }else if( op[j].type==OPT_FSTR ){
  1765         -    (*(void(*)())(op[j].arg))(&argv[i][2]);
         1728  +    (*(void(*)(char *))(op[j].arg))(&argv[i][2]);
  1766   1729     }else{
  1767   1730       if( err ){
  1768   1731         fprintf(err,"%smissing argument on switch.\n",emsg);
  1769   1732         errline(i,1,err);
  1770   1733       }
  1771   1734       errcnt++;
  1772   1735     }
  1773   1736     return errcnt;
  1774   1737   }
  1775   1738   
  1776   1739   /*
  1777   1740   ** Process a command line switch which has an argument.
  1778   1741   */
  1779         -static int handleswitch(i,err)
  1780         -int i;
  1781         -FILE *err;
         1742  +static int handleswitch(int i, FILE *err)
  1782   1743   {
  1783   1744     int lv = 0;
  1784   1745     double dv = 0.0;
  1785   1746     char *sv = 0, *end;
  1786   1747     char *cp;
  1787   1748     int j;
  1788   1749     int errcnt = 0;
................................................................................
  1841   1802         case OPT_FLAG:
  1842   1803         case OPT_FFLAG:
  1843   1804           break;
  1844   1805         case OPT_DBL:
  1845   1806           *(double*)(op[j].arg) = dv;
  1846   1807           break;
  1847   1808         case OPT_FDBL:
  1848         -        (*(void(*)())(op[j].arg))(dv);
         1809  +        (*(void(*)(double))(op[j].arg))(dv);
  1849   1810           break;
  1850   1811         case OPT_INT:
  1851   1812           *(int*)(op[j].arg) = lv;
  1852   1813           break;
  1853   1814         case OPT_FINT:
  1854         -        (*(void(*)())(op[j].arg))((int)lv);
         1815  +        (*(void(*)(int))(op[j].arg))((int)lv);
  1855   1816           break;
  1856   1817         case OPT_STR:
  1857   1818           *(char**)(op[j].arg) = sv;
  1858   1819           break;
  1859   1820         case OPT_FSTR:
  1860         -        (*(void(*)())(op[j].arg))(sv);
         1821  +        (*(void(*)(char *))(op[j].arg))(sv);
  1861   1822           break;
  1862   1823       }
  1863   1824     }
  1864   1825     return errcnt;
  1865   1826   }
  1866   1827   
  1867         -int OptInit(a,o,err)
  1868         -char **a;
  1869         -struct s_options *o;
  1870         -FILE *err;
         1828  +int OptInit(char **a, struct s_options *o, FILE *err)
  1871   1829   {
  1872   1830     int errcnt = 0;
  1873   1831     argv = a;
  1874   1832     op = o;
  1875   1833     errstream = err;
  1876   1834     if( argv && *argv && op ){
  1877   1835       int i;
................................................................................
  1900   1858         if( dashdash || !ISOPT(argv[i]) ) cnt++;
  1901   1859         if( strcmp(argv[i],"--")==0 ) dashdash = 1;
  1902   1860       }
  1903   1861     }
  1904   1862     return cnt;
  1905   1863   }
  1906   1864   
  1907         -char *OptArg(n)
  1908         -int n;
         1865  +char *OptArg(int n)
  1909   1866   {
  1910   1867     int i;
  1911   1868     i = argindex(n);
  1912   1869     return i>=0 ? argv[i] : 0;
  1913   1870   }
  1914   1871   
  1915         -void OptErr(n)
  1916         -int n;
         1872  +void OptErr(int n)
  1917   1873   {
  1918   1874     int i;
  1919   1875     i = argindex(n);
  1920   1876     if( i>=0 ) errline(i,0,errstream);
  1921   1877   }
  1922   1878   
  1923   1879   void OptPrint(){
................................................................................
  1971   1927   }
  1972   1928   /*********************** From the file "parse.c" ****************************/
  1973   1929   /*
  1974   1930   ** Input file parser for the LEMON parser generator.
  1975   1931   */
  1976   1932   
  1977   1933   /* The state of the parser */
         1934  +enum e_state {
         1935  +  INITIALIZE,
         1936  +  WAITING_FOR_DECL_OR_RULE,
         1937  +  WAITING_FOR_DECL_KEYWORD,
         1938  +  WAITING_FOR_DECL_ARG,
         1939  +  WAITING_FOR_PRECEDENCE_SYMBOL,
         1940  +  WAITING_FOR_ARROW,
         1941  +  IN_RHS,
         1942  +  LHS_ALIAS_1,
         1943  +  LHS_ALIAS_2,
         1944  +  LHS_ALIAS_3,
         1945  +  RHS_ALIAS_1,
         1946  +  RHS_ALIAS_2,
         1947  +  PRECEDENCE_MARK_1,
         1948  +  PRECEDENCE_MARK_2,
         1949  +  RESYNC_AFTER_RULE_ERROR,
         1950  +  RESYNC_AFTER_DECL_ERROR,
         1951  +  WAITING_FOR_DESTRUCTOR_SYMBOL,
         1952  +  WAITING_FOR_DATATYPE_SYMBOL,
         1953  +  WAITING_FOR_FALLBACK_ID,
         1954  +  WAITING_FOR_WILDCARD_ID
         1955  +};
  1978   1956   struct pstate {
  1979   1957     char *filename;       /* Name of the input file */
  1980   1958     int tokenlineno;      /* Linenumber at which current token starts */
  1981   1959     int errorcnt;         /* Number of errors so far */
  1982   1960     char *tokenstart;     /* Text of current token */
  1983   1961     struct lemon *gp;     /* Global state vector */
  1984         -  enum e_state {
  1985         -    INITIALIZE,
  1986         -    WAITING_FOR_DECL_OR_RULE,
  1987         -    WAITING_FOR_DECL_KEYWORD,
  1988         -    WAITING_FOR_DECL_ARG,
  1989         -    WAITING_FOR_PRECEDENCE_SYMBOL,
  1990         -    WAITING_FOR_ARROW,
  1991         -    IN_RHS,
  1992         -    LHS_ALIAS_1,
  1993         -    LHS_ALIAS_2,
  1994         -    LHS_ALIAS_3,
  1995         -    RHS_ALIAS_1,
  1996         -    RHS_ALIAS_2,
  1997         -    PRECEDENCE_MARK_1,
  1998         -    PRECEDENCE_MARK_2,
  1999         -    RESYNC_AFTER_RULE_ERROR,
  2000         -    RESYNC_AFTER_DECL_ERROR,
  2001         -    WAITING_FOR_DESTRUCTOR_SYMBOL,
  2002         -    WAITING_FOR_DATATYPE_SYMBOL,
  2003         -    WAITING_FOR_FALLBACK_ID,
  2004         -    WAITING_FOR_WILDCARD_ID
  2005         -  } state;                   /* The state of the parser */
         1962  +  enum e_state state;        /* The state of the parser */
  2006   1963     struct symbol *fallback;   /* The fallback token */
  2007   1964     struct symbol *lhs;        /* Left-hand side of current rule */
  2008         -  char *lhsalias;            /* Alias for the LHS */
         1965  +  const char *lhsalias;      /* Alias for the LHS */
  2009   1966     int nrhs;                  /* Number of right-hand side symbols seen */
  2010   1967     struct symbol *rhs[MAXRHS];  /* RHS symbols */
  2011         -  char *alias[MAXRHS];       /* Aliases for each RHS symbol (or NULL) */
         1968  +  const char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */
  2012   1969     struct rule *prevrule;     /* Previous rule parsed */
  2013         -  char *declkeyword;         /* Keyword of a declaration */
         1970  +  const char *declkeyword;   /* Keyword of a declaration */
  2014   1971     char **declargslot;        /* Where the declaration argument should be put */
  2015   1972     int insertLineMacro;       /* Add #line before declaration insert */
  2016   1973     int *decllinenoslot;       /* Where to write declaration line number */
  2017   1974     enum e_assoc declassoc;    /* Assign this association to decl arguments */
  2018   1975     int preccounter;           /* Assign this precedence to decl arguments */
  2019   1976     struct rule *firstrule;    /* Pointer to first rule in the grammar */
  2020   1977     struct rule *lastrule;     /* Pointer to the most recently parsed rule */
  2021   1978   };
  2022   1979   
  2023   1980   /* Parse a single token */
  2024         -static void parseonetoken(psp)
  2025         -struct pstate *psp;
         1981  +static void parseonetoken(struct pstate *psp)
  2026   1982   {
  2027         -  char *x;
         1983  +  const char *x;
  2028   1984     x = Strsafe(psp->tokenstart);     /* Save the token permanently */
  2029   1985   #if 0
  2030   1986     printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno,
  2031   1987       x,psp->state);
  2032   1988   #endif
  2033   1989     switch( psp->state ){
  2034   1990       case INITIALIZE:
................................................................................
  2152   2108               "Can't allocate enough memory for this rule.");
  2153   2109             psp->errorcnt++;
  2154   2110             psp->prevrule = 0;
  2155   2111   	}else{
  2156   2112             int i;
  2157   2113             rp->ruleline = psp->tokenlineno;
  2158   2114             rp->rhs = (struct symbol**)&rp[1];
  2159         -          rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]);
         2115  +          rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
  2160   2116             for(i=0; i<psp->nrhs; i++){
  2161   2117               rp->rhs[i] = psp->rhs[i];
  2162   2118               rp->rhsalias[i] = psp->alias[i];
  2163   2119   	  }
  2164   2120             rp->lhs = psp->lhs;
  2165   2121             rp->lhsalias = psp->lhsalias;
  2166   2122             rp->nrhs = psp->nrhs;
................................................................................
  2191   2147             psp->alias[psp->nrhs] = 0;
  2192   2148             psp->nrhs++;
  2193   2149   	}
  2194   2150         }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){
  2195   2151           struct symbol *msp = psp->rhs[psp->nrhs-1];
  2196   2152           if( msp->type!=MULTITERMINAL ){
  2197   2153             struct symbol *origsp = msp;
  2198         -          msp = calloc(1,sizeof(*msp));
         2154  +          msp = (struct symbol *) calloc(1,sizeof(*msp));
  2199   2155             memset(msp, 0, sizeof(*msp));
  2200   2156             msp->type = MULTITERMINAL;
  2201   2157             msp->nsubsym = 1;
  2202         -          msp->subsym = calloc(1,sizeof(struct symbol*));
         2158  +          msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*));
  2203   2159             msp->subsym[0] = origsp;
  2204   2160             msp->name = origsp->name;
  2205   2161             psp->rhs[psp->nrhs-1] = msp;
  2206   2162           }
  2207   2163           msp->nsubsym++;
  2208         -        msp->subsym = realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym);
         2164  +        msp->subsym = (struct symbol **) realloc(msp->subsym,
         2165  +          sizeof(struct symbol*)*msp->nsubsym);
  2209   2166           msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]);
  2210   2167           if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){
  2211   2168             ErrorMsg(psp->filename,psp->tokenlineno,
  2212   2169               "Cannot form a compound containing a non-terminal");
  2213   2170             psp->errorcnt++;
  2214   2171           }
  2215   2172         }else if( x[0]=='(' && psp->nrhs>0 ){
................................................................................
  2320   2277           psp->errorcnt++;
  2321   2278           psp->state = RESYNC_AFTER_DECL_ERROR;
  2322   2279         }
  2323   2280         break;
  2324   2281       case WAITING_FOR_DESTRUCTOR_SYMBOL:
  2325   2282         if( !isalpha(x[0]) ){
  2326   2283           ErrorMsg(psp->filename,psp->tokenlineno,
  2327         -          "Symbol name missing after %destructor keyword");
         2284  +          "Symbol name missing after %%destructor keyword");
  2328   2285           psp->errorcnt++;
  2329   2286           psp->state = RESYNC_AFTER_DECL_ERROR;
  2330   2287         }else{
  2331   2288           struct symbol *sp = Symbol_new(x);
  2332   2289           psp->declargslot = &sp->destructor;
  2333   2290           psp->decllinenoslot = &sp->destLineno;
  2334   2291           psp->insertLineMacro = 1;
  2335   2292           psp->state = WAITING_FOR_DECL_ARG;
  2336   2293         }
  2337   2294         break;
  2338   2295       case WAITING_FOR_DATATYPE_SYMBOL:
  2339   2296         if( !isalpha(x[0]) ){
  2340   2297           ErrorMsg(psp->filename,psp->tokenlineno,
  2341         -          "Symbol name missing after %destructor keyword");
         2298  +          "Symbol name missing after %%type keyword");
  2342   2299           psp->errorcnt++;
  2343   2300           psp->state = RESYNC_AFTER_DECL_ERROR;
  2344   2301         }else{
  2345         -        struct symbol *sp = Symbol_new(x);
  2346         -        psp->declargslot = &sp->datatype;
  2347         -        psp->insertLineMacro = 0;
  2348         -        psp->state = WAITING_FOR_DECL_ARG;
         2302  +        struct symbol *sp = Symbol_find(x);
         2303  +        if((sp) && (sp->datatype)){
         2304  +          ErrorMsg(psp->filename,psp->tokenlineno,
         2305  +            "Symbol %%type \"%s\" already defined", x);
         2306  +          psp->errorcnt++;
         2307  +          psp->state = RESYNC_AFTER_DECL_ERROR;
         2308  +        }else{
         2309  +          if (!sp){
         2310  +            sp = Symbol_new(x);
         2311  +          }
         2312  +          psp->declargslot = &sp->datatype;
         2313  +          psp->insertLineMacro = 0;
         2314  +          psp->state = WAITING_FOR_DECL_ARG;
         2315  +        }
  2349   2316         }
  2350   2317         break;
  2351   2318       case WAITING_FOR_PRECEDENCE_SYMBOL:
  2352   2319         if( x[0]=='.' ){
  2353   2320           psp->state = WAITING_FOR_DECL_OR_RULE;
  2354   2321         }else if( isupper(x[0]) ){
  2355   2322           struct symbol *sp;
................................................................................
  2366   2333           ErrorMsg(psp->filename,psp->tokenlineno,
  2367   2334             "Can't assign a precedence to \"%s\".",x);
  2368   2335           psp->errorcnt++;
  2369   2336         }
  2370   2337         break;
  2371   2338       case WAITING_FOR_DECL_ARG:
  2372   2339         if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){
  2373         -        char *zOld, *zNew, *zBuf, *z;
         2340  +        const char *zOld, *zNew;
         2341  +        char *zBuf, *z;
  2374   2342           int nOld, n, nLine, nNew, nBack;
  2375   2343           int addLineMacro;
  2376   2344           char zLine[50];
  2377   2345           zNew = x;
  2378   2346           if( zNew[0]=='"' || zNew[0]=='{' ) zNew++;
  2379   2347           nNew = lemonStrlen(zNew);
  2380   2348           if( *psp->declargslot ){
................................................................................
  2390   2358             for(z=psp->filename, nBack=0; *z; z++){
  2391   2359               if( *z=='\\' ) nBack++;
  2392   2360             }
  2393   2361             sprintf(zLine, "#line %d ", psp->tokenlineno);
  2394   2362             nLine = lemonStrlen(zLine);
  2395   2363             n += nLine + lemonStrlen(psp->filename) + nBack;
  2396   2364           }
  2397         -        *psp->declargslot = zBuf = realloc(*psp->declargslot, n);
  2398         -        zBuf += nOld;
         2365  +        *psp->declargslot = (char *) realloc(*psp->declargslot, n);
         2366  +        zBuf = *psp->declargslot + nOld;
  2399   2367           if( addLineMacro ){
  2400   2368             if( nOld && zBuf[-1]!='\n' ){
  2401   2369               *(zBuf++) = '\n';
  2402   2370             }
  2403   2371             memcpy(zBuf, zLine, nLine);
  2404   2372             zBuf += nLine;
  2405   2373             *(zBuf++) = '"';
................................................................................
  2527   2495   }
  2528   2496   
  2529   2497   /* In spite of its name, this function is really a scanner.  It read
  2530   2498   ** in the entire input file (all at once) then tokenizes it.  Each
  2531   2499   ** token is passed to the function "parseonetoken" which builds all
  2532   2500   ** the appropriate data structures in the global state vector "gp".
  2533   2501   */
  2534         -void Parse(gp)
  2535         -struct lemon *gp;
         2502  +void Parse(struct lemon *gp)
  2536   2503   {
  2537   2504     struct pstate ps;
  2538   2505     FILE *fp;
  2539   2506     char *filebuf;
  2540   2507     int filesize;
  2541   2508     int lineno;
  2542   2509     int c;
................................................................................
  2682   2649   ** Routines processing configuration follow-set propagation links
  2683   2650   ** in the LEMON parser generator.
  2684   2651   */
  2685   2652   static struct plink *plink_freelist = 0;
  2686   2653   
  2687   2654   /* Allocate a new plink */
  2688   2655   struct plink *Plink_new(){
  2689         -  struct plink *new;
         2656  +  struct plink *newlink;
  2690   2657   
  2691   2658     if( plink_freelist==0 ){
  2692   2659       int i;
  2693   2660       int amt = 100;
  2694   2661       plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) );
  2695   2662       if( plink_freelist==0 ){
  2696   2663         fprintf(stderr,
  2697   2664         "Unable to allocate memory for a new follow-set propagation link.\n");
  2698   2665         exit(1);
  2699   2666       }
  2700   2667       for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1];
  2701   2668       plink_freelist[amt-1].next = 0;
  2702   2669     }
  2703         -  new = plink_freelist;
         2670  +  newlink = plink_freelist;
  2704   2671     plink_freelist = plink_freelist->next;
  2705         -  return new;
         2672  +  return newlink;
  2706   2673   }
  2707   2674   
  2708   2675   /* Add a plink to a plink list */
  2709         -void Plink_add(plpp,cfp)
  2710         -struct plink **plpp;
  2711         -struct config *cfp;
         2676  +void Plink_add(struct plink **plpp, struct config *cfp)
  2712   2677   {
  2713         -  struct plink *new;
  2714         -  new = Plink_new();
  2715         -  new->next = *plpp;
  2716         -  *plpp = new;
  2717         -  new->cfp = cfp;
         2678  +  struct plink *newlink;
         2679  +  newlink = Plink_new();
         2680  +  newlink->next = *plpp;
         2681  +  *plpp = newlink;
         2682  +  newlink->cfp = cfp;
  2718   2683   }
  2719   2684   
  2720   2685   /* Transfer every plink on the list "from" to the list "to" */
  2721         -void Plink_copy(to,from)
  2722         -struct plink **to;
  2723         -struct plink *from;
         2686  +void Plink_copy(struct plink **to, struct plink *from)
  2724   2687   {
  2725   2688     struct plink *nextpl;
  2726   2689     while( from ){
  2727   2690       nextpl = from->next;
  2728   2691       from->next = *to;
  2729   2692       *to = from;
  2730   2693       from = nextpl;
  2731   2694     }
  2732   2695   }
  2733   2696   
  2734   2697   /* Delete every plink on the list */
  2735         -void Plink_delete(plp)
  2736         -struct plink *plp;
         2698  +void Plink_delete(struct plink *plp)
  2737   2699   {
  2738   2700     struct plink *nextpl;
  2739   2701   
  2740   2702     while( plp ){
  2741   2703       nextpl = plp->next;
  2742   2704       plp->next = plink_freelist;
  2743   2705       plink_freelist = plp;
................................................................................
  2749   2711   ** Procedures for generating reports and tables in the LEMON parser generator.
  2750   2712   */
  2751   2713   
  2752   2714   /* Generate a filename with the given suffix.  Space to hold the
  2753   2715   ** name comes from malloc() and must be freed by the calling
  2754   2716   ** function.
  2755   2717   */
  2756         -PRIVATE char *file_makename(lemp,suffix)
  2757         -struct lemon *lemp;
  2758         -char *suffix;
         2718  +PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
  2759   2719   {
  2760   2720     char *name;
  2761   2721     char *cp;
  2762   2722   
  2763         -  name = malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 );
         2723  +  name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 );
  2764   2724     if( name==0 ){
  2765   2725       fprintf(stderr,"Can't allocate space for a filename.\n");
  2766   2726       exit(1);
  2767   2727     }
  2768   2728     strcpy(name,lemp->filename);
  2769   2729     cp = strrchr(name,'.');
  2770   2730     if( cp ) *cp = 0;
................................................................................
  2771   2731     strcat(name,suffix);
  2772   2732     return name;
  2773   2733   }
  2774   2734   
  2775   2735   /* Open a file with a name based on the name of the input file,
  2776   2736   ** but with a different (specified) suffix, and return a pointer
  2777   2737   ** to the stream */
  2778         -PRIVATE FILE *file_open(lemp,suffix,mode)
  2779         -struct lemon *lemp;
  2780         -char *suffix;
  2781         -char *mode;
  2782         -{
         2738  +PRIVATE FILE *file_open(
         2739  +  struct lemon *lemp,
         2740  +  const char *suffix,
         2741  +  const char *mode
         2742  +){
  2783   2743     FILE *fp;
  2784   2744   
  2785   2745     if( lemp->outname ) free(lemp->outname);
  2786   2746     lemp->outname = file_makename(lemp, suffix);
  2787   2747     fp = fopen(lemp->outname,mode);
  2788   2748     if( fp==0 && *mode=='w' ){
  2789   2749       fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname);
  2790   2750       lemp->errorcnt++;
  2791   2751       return 0;
  2792   2752     }
         2753  +
         2754  +  /* Add files we create to a list, so we can delete them if we fail. This
         2755  +  ** is to keep makefiles from getting confused. We don't include .out files,
         2756  +  ** though: this is debug information, and you don't want it deleted if there
         2757  +  ** was an error you need to track down.
         2758  +  */
         2759  +  if(( *mode=='w' ) && (strcmp(suffix, ".out") != 0)){
         2760  +    const char **ptr = (const char **)
         2761  +        realloc(made_files, sizeof (const char **) * (made_files_count + 1));
         2762  +    char *fname = strdup(lemp->outname);
         2763  +    if ((ptr == NULL) || (fname == NULL)) {
         2764  +        free(ptr);
         2765  +        free(fname);
         2766  +        memory_error();
         2767  +    }
         2768  +    made_files = ptr;
         2769  +    made_files[made_files_count++] = fname;
         2770  +  }
  2793   2771     return fp;
  2794   2772   }
  2795   2773   
  2796   2774   /* Duplicate the input file without comments and without actions 
  2797   2775   ** on rules */
  2798         -void Reprint(lemp)
  2799         -struct lemon *lemp;
         2776  +void Reprint(struct lemon *lemp)
  2800   2777   {
  2801   2778     struct rule *rp;
  2802   2779     struct symbol *sp;
  2803   2780     int i, j, maxlen, len, ncolumns, skip;
  2804   2781     printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename);
  2805   2782     maxlen = 10;
  2806   2783     for(i=0; i<lemp->nsymbol; i++){
................................................................................
  2837   2814       printf(".");
  2838   2815       if( rp->precsym ) printf(" [%s]",rp->precsym->name);
  2839   2816       /* if( rp->code ) printf("\n    %s",rp->code); */
  2840   2817       printf("\n");
  2841   2818     }
  2842   2819   }
  2843   2820   
  2844         -void ConfigPrint(fp,cfp)
  2845         -FILE *fp;
  2846         -struct config *cfp;
         2821  +void ConfigPrint(FILE *fp, struct config *cfp)
  2847   2822   {
  2848   2823     struct rule *rp;
  2849   2824     struct symbol *sp;
  2850   2825     int i, j;
  2851   2826     rp = cfp->rp;
  2852   2827     fprintf(fp,"%s ::=",rp->lhs->name);
  2853   2828     for(i=0; i<=rp->nrhs; i++){
................................................................................
  2932   2907         result = 0;
  2933   2908         break;
  2934   2909     }
  2935   2910     return result;
  2936   2911   }
  2937   2912   
  2938   2913   /* Generate the "y.output" log file */
  2939         -void ReportOutput(lemp)
  2940         -struct lemon *lemp;
         2914  +void ReportOutput(struct lemon *lemp)
  2941   2915   {
  2942   2916     int i;
  2943   2917     struct state *stp;
  2944   2918     struct config *cfp;
  2945   2919     struct action *ap;
  2946   2920     FILE *fp;
  2947   2921   
................................................................................
  2999   2973     }
  3000   2974     fclose(fp);
  3001   2975     return;
  3002   2976   }
  3003   2977   
  3004   2978   /* Search for the file "name" which is in the same directory as
  3005   2979   ** the exacutable */
  3006         -PRIVATE char *pathsearch(argv0,name,modemask)
  3007         -char *argv0;
  3008         -char *name;
  3009         -int modemask;
         2980  +PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
  3010   2981   {
  3011         -  char *pathlist;
         2982  +  const char *pathlist;
         2983  +  char *pathbufptr;
         2984  +  char *pathbuf;
  3012   2985     char *path,*cp;
  3013   2986     char c;
  3014   2987   
  3015   2988   #ifdef __WIN32__
  3016   2989     cp = strrchr(argv0,'\\');
  3017   2990   #else
  3018   2991     cp = strrchr(argv0,'/');
................................................................................
  3020   2993     if( cp ){
  3021   2994       c = *cp;
  3022   2995       *cp = 0;
  3023   2996       path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
  3024   2997       if( path ) sprintf(path,"%s/%s",argv0,name);
  3025   2998       *cp = c;
  3026   2999     }else{
  3027         -    extern char *getenv();
  3028   3000       pathlist = getenv("PATH");
  3029   3001       if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
         3002  +    pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 );
  3030   3003       path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
  3031         -    if( path!=0 ){
  3032         -      while( *pathlist ){
  3033         -        cp = strchr(pathlist,':');
  3034         -        if( cp==0 ) cp = &pathlist[lemonStrlen(pathlist)];
         3004  +    if( (pathbuf != 0) && (path!=0) ){
         3005  +      pathbufptr = pathbuf;
         3006  +      strcpy(pathbuf, pathlist);
         3007  +      while( *pathbuf ){
         3008  +        cp = strchr(pathbuf,':');
         3009  +        if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)];
  3035   3010           c = *cp;
  3036   3011           *cp = 0;
  3037         -        sprintf(path,"%s/%s",pathlist,name);
         3012  +        sprintf(path,"%s/%s",pathbuf,name);
  3038   3013           *cp = c;
  3039         -        if( c==0 ) pathlist = "";
  3040         -        else pathlist = &cp[1];
         3014  +        if( c==0 ) pathbuf[0] = 0;
         3015  +        else pathbuf = &cp[1];
  3041   3016           if( access(path,modemask)==0 ) break;
  3042   3017         }
         3018  +      free(pathbufptr);
  3043   3019       }
  3044   3020     }
  3045   3021     return path;
  3046   3022   }
  3047   3023   
  3048   3024   /* Given an action, compute the integer value for that action
  3049   3025   ** which is to be put in the action table of the generated machine.
  3050   3026   ** Return negative if no action should be generated.
  3051   3027   */
  3052         -PRIVATE int compute_action(lemp,ap)
  3053         -struct lemon *lemp;
  3054         -struct action *ap;
         3028  +PRIVATE int compute_action(struct lemon *lemp, struct action *ap)
  3055   3029   {
  3056   3030     int act;
  3057   3031     switch( ap->type ){
  3058   3032       case SHIFT:  act = ap->x.stp->statenum;            break;
  3059   3033       case REDUCE: act = ap->x.rp->index + lemp->nstate; break;
  3060   3034       case ERROR:  act = lemp->nstate + lemp->nrule;     break;
  3061   3035       case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break;
................................................................................
  3070   3044   /* The first function transfers data from "in" to "out" until
  3071   3045   ** a line is seen which begins with "%%".  The line number is
  3072   3046   ** tracked.
  3073   3047   **
  3074   3048   ** if name!=0, then any word that begin with "Parse" is changed to
  3075   3049   ** begin with *name instead.
  3076   3050   */
  3077         -PRIVATE void tplt_xfer(name,in,out,lineno)
  3078         -char *name;
  3079         -FILE *in;
  3080         -FILE *out;
  3081         -int *lineno;
         3051  +PRIVATE void tplt_xfer(char *name, FILE *in, FILE *out, int *lineno)
  3082   3052   {
  3083   3053     int i, iStart;
  3084   3054     char line[LINESIZE];
  3085   3055     while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){
  3086   3056       (*lineno)++;
  3087   3057       iStart = 0;
  3088   3058       if( name ){
................................................................................
  3099   3069       }
  3100   3070       fprintf(out,"%s",&line[iStart]);
  3101   3071     }
  3102   3072   }
  3103   3073   
  3104   3074   /* The next function finds the template file and opens it, returning
  3105   3075   ** a pointer to the opened file. */
  3106         -PRIVATE FILE *tplt_open(lemp)
  3107         -struct lemon *lemp;
         3076  +PRIVATE FILE *tplt_open(struct lemon *lemp)
  3108   3077   {
  3109   3078     static char templatename[] = "lempar.c";
  3110   3079     char buf[1000];
  3111   3080     FILE *in;
  3112   3081     char *tpltname;
  3113   3082     char *cp;
         3083  +
         3084  +  /* first, see if user specified a template filename on the command line. */
         3085  +  if (user_templatename != 0) {
         3086  +    if( access(user_templatename,004)==-1 ){
         3087  +      fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
         3088  +        user_templatename);
         3089  +      lemp->errorcnt++;
         3090  +      return 0;
         3091  +    }
         3092  +    in = fopen(user_templatename,"rb");
         3093  +    if( in==0 ){
         3094  +      fprintf(stderr,"Can't open the template file \"%s\".\n",user_templatename);
         3095  +      lemp->errorcnt++;
         3096  +      return 0;
         3097  +    }
         3098  +    return in;
         3099  +  }
  3114   3100   
  3115   3101     cp = strrchr(lemp->filename,'.');
  3116   3102     if( cp ){
  3117   3103       sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename);
  3118   3104     }else{
  3119   3105       sprintf(buf,"%s.lt",lemp->filename);
  3120   3106     }
................................................................................
  3137   3123       lemp->errorcnt++;
  3138   3124       return 0;
  3139   3125     }
  3140   3126     return in;
  3141   3127   }
  3142   3128   
  3143   3129   /* Print a #line directive line to the output file. */
  3144         -PRIVATE void tplt_linedir(out,lineno,filename)
  3145         -FILE *out;
  3146         -int lineno;
  3147         -char *filename;
         3130  +PRIVATE void tplt_linedir(FILE *out, int lineno, char *filename)
  3148   3131   {
  3149   3132     fprintf(out,"#line %d \"",lineno);
  3150   3133     while( *filename ){
  3151   3134       if( *filename == '\\' ) putc('\\',out);
  3152   3135       putc(*filename,out);
  3153   3136       filename++;
  3154   3137     }
  3155   3138     fprintf(out,"\"\n");
  3156   3139   }
  3157   3140   
  3158   3141   /* Print a string to the file and keep the linenumber up to date */
  3159         -PRIVATE void tplt_print(out,lemp,str,lineno)
  3160         -FILE *out;
  3161         -struct lemon *lemp;
  3162         -char *str;
  3163         -int *lineno;
         3142  +PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, int *lineno)
  3164   3143   {
  3165   3144     if( str==0 ) return;
  3166   3145     while( *str ){
  3167   3146       putc(*str,out);
  3168   3147       if( *str=='\n' ) (*lineno)++;
  3169   3148       str++;
  3170   3149     }
................................................................................
  3178   3157     return;
  3179   3158   }
  3180   3159   
  3181   3160   /*
  3182   3161   ** The following routine emits code for the destructor for the
  3183   3162   ** symbol sp
  3184   3163   */
  3185         -void emit_destructor_code(out,sp,lemp,lineno)
  3186         -FILE *out;
  3187         -struct symbol *sp;
  3188         -struct lemon *lemp;
  3189         -int *lineno;
  3190         -{
         3164  +void emit_destructor_code(
         3165  +  FILE *out,
         3166  +  struct symbol *sp,
         3167  +  struct lemon *lemp,
         3168  +  int *lineno
         3169  +){
  3191   3170    char *cp = 0;
  3192   3171   
  3193   3172    if( sp->type==TERMINAL ){
  3194   3173      cp = lemp->tokendest;
  3195   3174      if( cp==0 ) return;
  3196   3175      fprintf(out,"{\n"); (*lineno)++;
  3197   3176    }else if( sp->destructor ){
................................................................................
  3221   3200    fprintf(out,"}\n"); (*lineno)++;
  3222   3201    return;
  3223   3202   }
  3224   3203   
  3225   3204   /*
  3226   3205   ** Return TRUE (non-zero) if the given symbol has a destructor.
  3227   3206   */
  3228         -int has_destructor(sp, lemp)
  3229         -struct symbol *sp;
  3230         -struct lemon *lemp;
         3207  +int has_destructor(struct symbol *sp, struct lemon *lemp)
  3231   3208   {
  3232   3209     int ret;
  3233   3210     if( sp->type==TERMINAL ){
  3234   3211       ret = lemp->tokendest!=0;
  3235   3212     }else{
  3236   3213       ret = lemp->vardest!=0 || sp->destructor!=0;
  3237   3214     }
................................................................................
  3246   3223   ** n bytes of zText are stored.  If n==0 then all of zText up to the first
  3247   3224   ** \000 terminator is stored.  zText can contain up to two instances of
  3248   3225   ** %d.  The values of p1 and p2 are written into the first and second
  3249   3226   ** %d.
  3250   3227   **
  3251   3228   ** If n==-1, then the previous character is overwritten.
  3252   3229   */
  3253         -PRIVATE char *append_str(char *zText, int n, int p1, int p2){
         3230  +PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
         3231  +  static char empty[1] = { 0 };
  3254   3232     static char *z = 0;
  3255   3233     static int alloced = 0;
  3256   3234     static int used = 0;
  3257   3235     int c;
  3258   3236     char zInt[40];
  3259         -
  3260   3237     if( zText==0 ){
  3261   3238       used = 0;
  3262   3239       return z;
  3263   3240     }
  3264   3241     if( n<=0 ){
  3265   3242       if( n<0 ){
  3266   3243         used += n;
  3267   3244         assert( used>=0 );
  3268   3245       }
  3269   3246       n = lemonStrlen(zText);
  3270   3247     }
  3271   3248     if( n+sizeof(zInt)*2+used >= alloced ){
  3272   3249       alloced = n + sizeof(zInt)*2 + used + 200;
  3273         -    z = realloc(z,  alloced);
         3250  +    z = (char *) realloc(z,  alloced);
  3274   3251     }
  3275         -  if( z==0 ) return "";
         3252  +  if( z==0 ) return empty;
  3276   3253     while( n-- > 0 ){
  3277   3254       c = *(zText++);
  3278   3255       if( c=='%' && n>0 && zText[0]=='d' ){
  3279   3256         sprintf(zInt, "%d", p1);
  3280   3257         p1 = p2;
  3281   3258         strcpy(&z[used], zInt);
  3282   3259         used += lemonStrlen(&z[used]);
................................................................................
  3301   3278     char lhsused = 0;    /* True if the LHS element has been used */
  3302   3279     char used[MAXRHS];   /* True for each RHS element which is used */
  3303   3280   
  3304   3281     for(i=0; i<rp->nrhs; i++) used[i] = 0;
  3305   3282     lhsused = 0;
  3306   3283   
  3307   3284     if( rp->code==0 ){
  3308         -    rp->code = "\n";
         3285  +    static char newlinestr[2] = { '\n', '\0' };
         3286  +    rp->code = newlinestr;
  3309   3287       rp->line = rp->ruleline;
  3310   3288     }
  3311   3289   
  3312   3290     append_str(0,0,0,0);
  3313         -  for(cp=rp->code; *cp; cp++){
         3291  +
         3292  +  /* This const cast is wrong but harmless, if we're careful. */
         3293  +  for(cp=(char *)rp->code; *cp; cp++){
  3314   3294       if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
  3315   3295         char saved;
  3316   3296         for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
  3317   3297         saved = *xp;
  3318   3298         *xp = 0;
  3319   3299         if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
  3320   3300           append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0);
................................................................................
  3379   3359     }
  3380   3360   }
  3381   3361   
  3382   3362   /* 
  3383   3363   ** Generate code which executes when the rule "rp" is reduced.  Write
  3384   3364   ** the code to "out".  Make sure lineno stays up-to-date.
  3385   3365   */
  3386         -PRIVATE void emit_code(out,rp,lemp,lineno)
  3387         -FILE *out;
  3388         -struct rule *rp;
  3389         -struct lemon *lemp;
  3390         -int *lineno;
  3391         -{
  3392         - char *cp;
         3366  +PRIVATE void emit_code(
         3367  +  FILE *out,
         3368  +  struct rule *rp,
         3369  +  struct lemon *lemp,
         3370  +  int *lineno
         3371  +){
         3372  + const char *cp;
  3393   3373   
  3394   3374    /* Generate code to do the reduce action */
  3395   3375    if( rp->code ){
  3396   3376      if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,rp->line,lemp->filename); }
  3397   3377      fprintf(out,"{%s",rp->code);
  3398   3378      for(cp=rp->code; *cp; cp++){
  3399   3379        if( *cp=='\n' ) (*lineno)++;
................................................................................
  3408   3388   /*
  3409   3389   ** Print the definition of the union used for the parser's data stack.
  3410   3390   ** This union contains fields for every possible data type for tokens
  3411   3391   ** and nonterminals.  In the process of computing and printing this
  3412   3392   ** union, also set the ".dtnum" field of every terminal and nonterminal
  3413   3393   ** symbol.
  3414   3394   */
  3415         -void print_stack_union(out,lemp,plineno,mhflag)
  3416         -FILE *out;                  /* The output stream */
  3417         -struct lemon *lemp;         /* The main info structure for this parser */
  3418         -int *plineno;               /* Pointer to the line number */
  3419         -int mhflag;                 /* True if generating makeheaders output */
  3420         -{
         3395  +void print_stack_union(
         3396  +  FILE *out,                  /* The output stream */
         3397  +  struct lemon *lemp,         /* The main info structure for this parser */
         3398  +  int *plineno,               /* Pointer to the line number */
         3399  +  int mhflag                  /* True if generating makeheaders output */
         3400  +){
  3421   3401     int lineno = *plineno;    /* The line number of the output */
  3422   3402     char **types;             /* A hash table of datatypes */
  3423   3403     int arraysize;            /* Size of the "types" array */
  3424   3404     int maxdtlength;          /* Maximum length of any ".datatype" field. */
  3425   3405     char *stddt;              /* Standardized name for a datatype */
  3426   3406     int i,j;                  /* Loop counters */
  3427   3407     int hash;                 /* For hashing the name of a type */
  3428         -  char *name;               /* Name of the parser */
         3408  +  const char *name;         /* Name of the parser */
  3429   3409   
  3430   3410     /* Allocate and initialize types[] and allocate stddt[] */
  3431   3411     arraysize = lemp->nsymbol * 2;
  3432   3412     types = (char**)calloc( arraysize, sizeof(char*) );
  3433   3413     for(i=0; i<arraysize; i++) types[i] = 0;
  3434   3414     maxdtlength = 0;
  3435   3415     if( lemp->vartype ){
................................................................................
  3590   3570         }
  3591   3571       }
  3592   3572     }
  3593   3573   }
  3594   3574   
  3595   3575   
  3596   3576   /* Generate C source code for the parser */
  3597         -void ReportTable(lemp, mhflag)
  3598         -struct lemon *lemp;
  3599         -int mhflag;     /* Output in makeheaders format if true */
  3600         -{
         3577  +void ReportTable(
         3578  +  struct lemon *lemp,
         3579  +  int mhflag     /* Output in makeheaders format if true */
         3580  +){
  3601   3581     FILE *out, *in;
  3602   3582     char line[LINESIZE];
  3603   3583     int  lineno;
  3604   3584     struct state *stp;
  3605   3585     struct action *ap;
  3606   3586     struct rule *rp;
  3607   3587     struct acttab *pActtab;
  3608         -  int i, j, k, n;
  3609         -  char *name;
         3588  +  int i, j, n;
         3589  +  const char *name;
  3610   3590     int mnTknOfst, mxTknOfst;
  3611   3591     int mnNtOfst, mxNtOfst;
  3612   3592     struct axset *ax;
  3613   3593   
  3614   3594     in = tplt_open(lemp);
  3615   3595     if( in==0 ) return;
  3616   3596     out = file_open(lemp,".c","wb");
................................................................................
  3628   3608       fprintf(out,"#include \"%s\"\n", name); lineno++;
  3629   3609       free(name);
  3630   3610     }
  3631   3611     tplt_xfer(lemp->name,in,out,&lineno);
  3632   3612   
  3633   3613     /* Generate #defines for all tokens */
  3634   3614     if( mhflag ){
  3635         -    char *prefix;
         3615  +    const char *prefix;
  3636   3616       fprintf(out,"#if INTERFACE\n"); lineno++;
  3637   3617       if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
  3638   3618       else                    prefix = "";
  3639   3619       for(i=1; i<lemp->nterminal; i++){
  3640   3620         fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
  3641   3621         lineno++;
  3642   3622       }
................................................................................
  3706   3686     **                     shifting terminals.
  3707   3687     **  yy_reduce_ofst[]   For each state, the offset into yy_action for
  3708   3688     **                     shifting non-terminals after a reduce.
  3709   3689     **  yy_default[]       Default action for each state.
  3710   3690     */
  3711   3691   
  3712   3692     /* Compute the actions on all states and count them up */
  3713         -  ax = calloc(lemp->nstate*2, sizeof(ax[0]));
         3693  +  ax = (struct axset *) calloc(lemp->nstate*2, sizeof(ax[0]));
  3714   3694     if( ax==0 ){
  3715   3695       fprintf(stderr,"malloc failed\n");
  3716   3696       exit(1);
  3717   3697     }
  3718   3698     for(i=0; i<lemp->nstate; i++){
  3719   3699       stp = lemp->sorted[i];
  3720   3700       ax[i*2].stp = stp;
................................................................................
  4034   4014   
  4035   4015     fclose(in);
  4036   4016     fclose(out);
  4037   4017     return;
  4038   4018   }
  4039   4019   
  4040   4020   /* Generate a header file for the parser */
  4041         -void ReportHeader(lemp)
  4042         -struct lemon *lemp;
         4021  +void ReportHeader(struct lemon *lemp)
  4043   4022   {
  4044   4023     FILE *out, *in;
  4045         -  char *prefix;
         4024  +  const char *prefix;
  4046   4025     char line[LINESIZE];
  4047   4026     char pattern[LINESIZE];
  4048   4027     int i;
  4049   4028   
  4050   4029     if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
  4051   4030     else                    prefix = "";
  4052   4031     in = file_open(lemp,".h","rb");
................................................................................
  4074   4053   /* Reduce the size of the action tables, if possible, by making use
  4075   4054   ** of defaults.
  4076   4055   **
  4077   4056   ** In this version, we take the most frequent REDUCE action and make
  4078   4057   ** it the default.  Except, there is no default if the wildcard token
  4079   4058   ** is a possible look-ahead.
  4080   4059   */
  4081         -void CompressTables(lemp)
  4082         -struct lemon *lemp;
         4060  +void CompressTables(struct lemon *lemp)
  4083   4061   {
  4084   4062     struct state *stp;
  4085   4063     struct action *ap, *ap2;
  4086   4064     struct rule *rp, *rp2, *rbest;
  4087   4065     int nbest, n;
  4088   4066     int i;
  4089   4067     int usesWildcard;
................................................................................
  4159   4137   }
  4160   4138   
  4161   4139   
  4162   4140   /*
  4163   4141   ** Renumber and resort states so that states with fewer choices
  4164   4142   ** occur at the end.  Except, keep state 0 as the first state.
  4165   4143   */
  4166         -void ResortStates(lemp)
  4167         -struct lemon *lemp;
         4144  +void ResortStates(struct lemon *lemp)
  4168   4145   {
  4169   4146     int i;
  4170   4147     struct state *stp;
  4171   4148     struct action *ap;
  4172   4149   
  4173   4150     for(i=0; i<lemp->nstate; i++){
  4174   4151       stp = lemp->sorted[i];
................................................................................
  4200   4177   /*
  4201   4178   ** Set manipulation routines for the LEMON parser generator.
  4202   4179   */
  4203   4180   
  4204   4181   static int size = 0;
  4205   4182   
  4206   4183   /* Set the set size */
  4207         -void SetSize(n)
  4208         -int n;
         4184  +void SetSize(int n)
  4209   4185   {
  4210   4186     size = n+1;
  4211   4187   }
  4212   4188   
  4213   4189   /* Allocate a new set */
  4214   4190   char *SetNew(){
  4215   4191     char *s;
................................................................................
  4218   4194       extern void memory_error();
  4219   4195       memory_error();
  4220   4196     }
  4221   4197     return s;
  4222   4198   }
  4223   4199   
  4224   4200   /* Deallocate a set */
  4225         -void SetFree(s)
  4226         -char *s;
         4201  +void SetFree(char *s)
  4227   4202   {
  4228   4203     free(s);
  4229   4204   }
  4230   4205   
  4231   4206   /* Add a new element to the set.  Return TRUE if the element was added
  4232   4207   ** and FALSE if it was already there. */
  4233         -int SetAdd(s,e)
  4234         -char *s;
  4235         -int e;
         4208  +int SetAdd(char *s, int e)
  4236   4209   {
  4237   4210     int rv;
  4238   4211     assert( e>=0 && e<size );
  4239   4212     rv = s[e];
  4240   4213     s[e] = 1;
  4241   4214     return !rv;
  4242   4215   }
  4243   4216   
  4244   4217   /* Add every element of s2 to s1.  Return TRUE if s1 changes. */
  4245         -int SetUnion(s1,s2)
  4246         -char *s1;
  4247         -char *s2;
         4218  +int SetUnion(char *s1, char *s2)
  4248   4219   {
  4249   4220     int i, progress;
  4250   4221     progress = 0;
  4251   4222     for(i=0; i<size; i++){
  4252   4223       if( s2[i]==0 ) continue;
  4253   4224       if( s1[i]==0 ){
  4254   4225         progress = 1;
................................................................................
  4266   4237   ** Do not edit this file!  Instead, edit the specification
  4267   4238   ** file, then rerun aagen.
  4268   4239   */
  4269   4240   /*
  4270   4241   ** Code for processing tables in the LEMON parser generator.
  4271   4242   */
  4272   4243   
  4273         -PRIVATE int strhash(x)
  4274         -char *x;
         4244  +PRIVATE int strhash(const char *x)
  4275   4245   {
  4276   4246     int h = 0;
  4277   4247     while( *x) h = h*13 + *(x++);
  4278   4248     return h;
  4279   4249   }
  4280   4250   
  4281   4251   /* Works like strdup, sort of.  Save a string in malloced memory, but
  4282   4252   ** keep strings in a table so that the same string is not in more
  4283   4253   ** than one place.
  4284   4254   */
  4285         -char *Strsafe(y)
  4286         -char *y;
         4255  +const char *Strsafe(const char *y)
  4287   4256   {
  4288         -  char *z;
         4257  +  const char *z;
         4258  +  char *cpy;
  4289   4259   
  4290   4260     if( y==0 ) return 0;
  4291   4261     z = Strsafe_find(y);
  4292         -  if( z==0 && (z=malloc( lemonStrlen(y)+1 ))!=0 ){
  4293         -    strcpy(z,y);
         4262  +  if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
         4263  +    strcpy(cpy,y);
         4264  +    z = cpy;
  4294   4265       Strsafe_insert(z);
  4295   4266     }
  4296   4267     MemoryCheck(z);
  4297   4268     return z;
  4298   4269   }
  4299   4270   
  4300   4271   /* There is one instance of the following structure for each
................................................................................
  4309   4280     struct s_x1node **ht;  /* Hash table for lookups */
  4310   4281   };
  4311   4282   
  4312   4283   /* There is one instance of this structure for every data element
  4313   4284   ** in an associative array of type "x1".
  4314   4285   */
  4315   4286   typedef struct s_x1node {
  4316         -  char *data;                  /* The data */
         4287  +  const char *data;        /* The data */
  4317   4288     struct s_x1node *next;   /* Next entry with the same hash */
  4318   4289     struct s_x1node **from;  /* Previous link */
  4319   4290   } x1node;
  4320   4291   
  4321   4292   /* There is only one instance of the array, which is the following */
  4322   4293   static struct s_x1 *x1a;
  4323   4294   
................................................................................
  4338   4309         x1a->ht = (x1node**)&(x1a->tbl[1024]);
  4339   4310         for(i=0; i<1024; i++) x1a->ht[i] = 0;
  4340   4311       }
  4341   4312     }
  4342   4313   }
  4343   4314   /* Insert a new record into the array.  Return TRUE if successful.
  4344   4315   ** Prior data with the same key is NOT overwritten */
  4345         -int Strsafe_insert(data)
  4346         -char *data;
         4316  +int Strsafe_insert(const char *data)
  4347   4317   {
  4348   4318     x1node *np;
  4349   4319     int h;
  4350   4320     int ph;
  4351   4321   
  4352   4322     if( x1a==0 ) return 0;
  4353   4323     ph = strhash(data);
................................................................................
  4395   4365     x1a->ht[h] = np;
  4396   4366     np->from = &(x1a->ht[h]);
  4397   4367     return 1;
  4398   4368   }
  4399   4369   
  4400   4370   /* Return a pointer to data assigned to the given key.  Return NULL
  4401   4371   ** if no such key. */
  4402         -char *Strsafe_find(key)
  4403         -char *key;
         4372  +const char *Strsafe_find(const char *key)
  4404   4373   {
  4405   4374     int h;
  4406   4375     x1node *np;
  4407   4376   
  4408   4377     if( x1a==0 ) return 0;
  4409   4378     h = strhash(key) & (x1a->size-1);
  4410   4379     np = x1a->ht[h];
................................................................................
  4414   4383     }
  4415   4384     return np ? np->data : 0;
  4416   4385   }
  4417   4386   
  4418   4387   /* Return a pointer to the (terminal or nonterminal) symbol "x".
  4419   4388   ** Create a new symbol if this is the first time "x" has been seen.
  4420   4389   */
  4421         -struct symbol *Symbol_new(x)
  4422         -char *x;
         4390  +struct symbol *Symbol_new(const char *x)
  4423   4391   {
  4424   4392     struct symbol *sp;
  4425   4393   
  4426   4394     sp = Symbol_find(x);
  4427   4395     if( sp==0 ){
  4428   4396       sp = (struct symbol *)calloc(1, sizeof(struct symbol) );
  4429   4397       MemoryCheck(sp);
................................................................................
  4451   4419   ** must sort before symbols that begin with lower case letters
  4452   4420   ** (non-terminals).  Other than that, the order does not matter.
  4453   4421   **
  4454   4422   ** We find experimentally that leaving the symbols in their original
  4455   4423   ** order (the order they appeared in the grammar file) gives the
  4456   4424   ** smallest parser tables in SQLite.
  4457   4425   */
  4458         -int Symbolcmpp(struct symbol **a, struct symbol **b){
         4426  +int Symbolcmpp(const void *_a, const void *_b)
         4427  +{
         4428  +  const struct symbol **a = (const struct symbol **) _a;
         4429  +  const struct symbol **b = (const struct symbol **) _b;
  4459   4430     int i1 = (**a).index + 10000000*((**a).name[0]>'Z');
  4460   4431     int i2 = (**b).index + 10000000*((**b).name[0]>'Z');
  4461   4432     assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 );
  4462   4433     return i1-i2;
  4463   4434   }
  4464   4435   
  4465   4436   /* There is one instance of the following structure for each
................................................................................
  4474   4445     struct s_x2node **ht;  /* Hash table for lookups */
  4475   4446   };
  4476   4447   
  4477   4448   /* There is one instance of this structure for every data element
  4478   4449   ** in an associative array of type "x2".
  4479   4450   */
  4480   4451   typedef struct s_x2node {
  4481         -  struct symbol *data;                  /* The data */
  4482         -  char *key;                   /* The key */
         4452  +  struct symbol *data;     /* The data */
         4453  +  const char *key;         /* The key */
  4483   4454     struct s_x2node *next;   /* Next entry with the same hash */
  4484   4455     struct s_x2node **from;  /* Previous link */
  4485   4456   } x2node;
  4486   4457   
  4487   4458   /* There is only one instance of the array, which is the following */
  4488   4459   static struct s_x2 *x2a;
  4489   4460   
................................................................................
  4504   4475         x2a->ht = (x2node**)&(x2a->tbl[128]);
  4505   4476         for(i=0; i<128; i++) x2a->ht[i] = 0;
  4506   4477       }
  4507   4478     }
  4508   4479   }
  4509   4480   /* Insert a new record into the array.  Return TRUE if successful.
  4510   4481   ** Prior data with the same key is NOT overwritten */
  4511         -int Symbol_insert(data,key)
  4512         -struct symbol *data;
  4513         -char *key;
         4482  +int Symbol_insert(struct symbol *data, const char *key)
  4514   4483   {
  4515   4484     x2node *np;
  4516   4485     int h;
  4517   4486     int ph;
  4518   4487   
  4519   4488     if( x2a==0 ) return 0;
  4520   4489     ph = strhash(key);
................................................................................
  4564   4533     x2a->ht[h] = np;
  4565   4534     np->from = &(x2a->ht[h]);
  4566   4535     return 1;
  4567   4536   }
  4568   4537   
  4569   4538   /* Return a pointer to data assigned to the given key.  Return NULL
  4570   4539   ** if no such key. */
  4571         -struct symbol *Symbol_find(key)
  4572         -char *key;
         4540  +struct symbol *Symbol_find(const char *key)
  4573   4541   {
  4574   4542     int h;
  4575   4543     x2node *np;
  4576   4544   
  4577   4545     if( x2a==0 ) return 0;
  4578   4546     h = strhash(key) & (x2a->size-1);
  4579   4547     np = x2a->ht[h];
................................................................................
  4581   4549       if( strcmp(np->key,key)==0 ) break;
  4582   4550       np = np->next;
  4583   4551     }
  4584   4552     return np ? np->data : 0;
  4585   4553   }
  4586   4554   
  4587   4555   /* Return the n-th data.  Return NULL if n is out of range. */
  4588         -struct symbol *Symbol_Nth(n)
  4589         -int n;
         4556  +struct symbol *Symbol_Nth(int n)
  4590   4557   {
  4591   4558     struct symbol *data;
  4592   4559     if( x2a && n>0 && n<=x2a->count ){
  4593   4560       data = x2a->tbl[n-1].data;
  4594   4561     }else{
  4595   4562       data = 0;
  4596   4563     }
................................................................................
  4616   4583     if( array ){
  4617   4584       for(i=0; i<size; i++) array[i] = x2a->tbl[i].data;
  4618   4585     }
  4619   4586     return array;
  4620   4587   }
  4621   4588   
  4622   4589   /* Compare two configurations */
  4623         -int Configcmp(a,b)
  4624         -struct config *a;
  4625         -struct config *b;
         4590  +int Configcmp(const char *_a,const char *_b)
  4626   4591   {
         4592  +  const struct config *a = (struct config *) _a;
         4593  +  const struct config *b = (struct config *) _b;
  4627   4594     int x;
  4628   4595     x = a->rp->index - b->rp->index;
  4629   4596     if( x==0 ) x = a->dot - b->dot;
  4630   4597     return x;
  4631   4598   }
  4632   4599   
  4633   4600   /* Compare two states */
  4634         -PRIVATE int statecmp(a,b)
  4635         -struct config *a;
  4636         -struct config *b;
         4601  +PRIVATE int statecmp(struct config *a, struct config *b)
  4637   4602   {
  4638   4603     int rc;
  4639   4604     for(rc=0; rc==0 && a && b;  a=a->bp, b=b->bp){
  4640   4605       rc = a->rp->index - b->rp->index;
  4641   4606       if( rc==0 ) rc = a->dot - b->dot;
  4642   4607     }
  4643   4608     if( rc==0 ){
................................................................................
  4644   4609       if( a ) rc = 1;
  4645   4610       if( b ) rc = -1;
  4646   4611     }
  4647   4612     return rc;
  4648   4613   }
  4649   4614   
  4650   4615   /* Hash a state */
  4651         -PRIVATE int statehash(a)
  4652         -struct config *a;
         4616  +PRIVATE int statehash(struct config *a)
  4653   4617   {
  4654   4618     int h=0;
  4655   4619     while( a ){
  4656   4620       h = h*571 + a->rp->index*37 + a->dot;
  4657   4621       a = a->bp;
  4658   4622     }
  4659   4623     return h;
  4660   4624   }
  4661   4625   
  4662   4626   /* Allocate a new state structure */
  4663   4627   struct state *State_new()
  4664   4628   {
  4665         -  struct state *new;
  4666         -  new = (struct state *)calloc(1, sizeof(struct state) );
  4667         -  MemoryCheck(new);
  4668         -  return new;
         4629  +  struct state *newstate;
         4630  +  newstate = (struct state *)calloc(1, sizeof(struct state) );
         4631  +  MemoryCheck(newstate);
         4632  +  return newstate;
  4669   4633   }
  4670   4634   
  4671   4635   /* There is one instance of the following structure for each
  4672   4636   ** associative array of type "x3".
  4673   4637   */
  4674   4638   struct s_x3 {
  4675   4639     int size;               /* The number of available slots. */
................................................................................
  4710   4674         x3a->ht = (x3node**)&(x3a->tbl[128]);
  4711   4675         for(i=0; i<128; i++) x3a->ht[i] = 0;
  4712   4676       }
  4713   4677     }
  4714   4678   }
  4715   4679   /* Insert a new record into the array.  Return TRUE if successful.
  4716   4680   ** Prior data with the same key is NOT overwritten */
  4717         -int State_insert(data,key)
  4718         -struct state *data;
  4719         -struct config *key;
         4681  +int State_insert(struct state *data, struct config *key)
  4720   4682   {
  4721   4683     x3node *np;
  4722   4684     int h;
  4723   4685     int ph;
  4724   4686   
  4725   4687     if( x3a==0 ) return 0;
  4726   4688     ph = statehash(key);
................................................................................
  4770   4732     x3a->ht[h] = np;
  4771   4733     np->from = &(x3a->ht[h]);
  4772   4734     return 1;
  4773   4735   }
  4774   4736   
  4775   4737   /* Return a pointer to data assigned to the given key.  Return NULL
  4776   4738   ** if no such key. */
  4777         -struct state *State_find(key)
  4778         -struct config *key;
         4739  +struct state *State_find(struct config *key)
  4779   4740   {
  4780   4741     int h;
  4781   4742     x3node *np;
  4782   4743   
  4783   4744     if( x3a==0 ) return 0;
  4784   4745     h = statehash(key) & (x3a->size-1);
  4785   4746     np = x3a->ht[h];
................................................................................
  4803   4764     if( array ){
  4804   4765       for(i=0; i<size; i++) array[i] = x3a->tbl[i].data;
  4805   4766     }
  4806   4767     return array;
  4807   4768   }
  4808   4769   
  4809   4770   /* Hash a configuration */
  4810         -PRIVATE int confighash(a)
  4811         -struct config *a;
         4771  +PRIVATE int confighash(struct config *a)
  4812   4772   {
  4813   4773     int h=0;
  4814   4774     h = h*571 + a->rp->index*37 + a->dot;
  4815   4775     return h;
  4816   4776   }
  4817   4777   
  4818   4778   /* There is one instance of the following structure for each
................................................................................
  4856   4816         x4a->ht = (x4node**)&(x4a->tbl[64]);
  4857   4817         for(i=0; i<64; i++) x4a->ht[i] = 0;
  4858   4818       }
  4859   4819     }
  4860   4820   }
  4861   4821   /* Insert a new record into the array.  Return TRUE if successful.
  4862   4822   ** Prior data with the same key is NOT overwritten */
  4863         -int Configtable_insert(data)
  4864         -struct config *data;
         4823  +int Configtable_insert(struct config *data)
  4865   4824   {
  4866   4825     x4node *np;
  4867   4826     int h;
  4868   4827     int ph;
  4869   4828   
  4870   4829     if( x4a==0 ) return 0;
  4871   4830     ph = confighash(data);
  4872   4831     h = ph & (x4a->size-1);
  4873   4832     np = x4a->ht[h];
  4874   4833     while( np ){
  4875         -    if( Configcmp(np->data,data)==0 ){
         4834  +    if( Configcmp((const char *) np->data,(const char *) data)==0 ){
  4876   4835         /* An existing entry with the same key is found. */
  4877   4836         /* Fail because overwrite is not allows. */
  4878   4837         return 0;
  4879   4838       }
  4880   4839       np = np->next;
  4881   4840     }
  4882   4841     if( x4a->count>=x4a->size ){
................................................................................
  4913   4872     x4a->ht[h] = np;
  4914   4873     np->from = &(x4a->ht[h]);
  4915   4874     return 1;
  4916   4875   }
  4917   4876   
  4918   4877   /* Return a pointer to data assigned to the given key.  Return NULL
  4919   4878   ** if no such key. */
  4920         -struct config *Configtable_find(key)
  4921         -struct config *key;
         4879  +struct config *Configtable_find(struct config *key)
  4922   4880   {
  4923   4881     int h;
  4924   4882     x4node *np;
  4925   4883   
  4926   4884     if( x4a==0 ) return 0;
  4927   4885     h = confighash(key) & (x4a->size-1);
  4928   4886     np = x4a->ht[h];
  4929   4887     while( np ){
  4930         -    if( Configcmp(np->data,key)==0 ) break;
         4888  +    if( Configcmp((const char *) np->data,(const char *) key)==0 ) break;
  4931   4889       np = np->next;
  4932   4890     }
  4933   4891     return np ? np->data : 0;
  4934   4892   }
  4935   4893   
  4936   4894   /* Remove all data from the table.  Pass each data to the function "f"
  4937   4895   ** as it is removed.  ("f" may be null to avoid this step.) */
  4938         -void Configtable_clear(f)
  4939         -int(*f)(/* struct config * */);
         4896  +void Configtable_clear(int(*f)(struct config *))
  4940   4897   {
  4941   4898     int i;
  4942   4899     if( x4a==0 || x4a->count==0 ) return;
  4943   4900     if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data);
  4944   4901     for(i=0; i<x4a->size; i++) x4a->ht[i] = 0;
  4945   4902     x4a->count = 0;
  4946   4903     return;
  4947   4904   }