xref: /sqlite-3.40.0/tool/lemon.c (revision 38d69855)
1 /*
2 ** This file contains all sources (including headers) to the LEMON
3 ** LALR(1) parser generator.  The sources have been combined into a
4 ** single file to make it easy to include LEMON in the source tree
5 ** and Makefile of another program.
6 **
7 ** The author of this program disclaims copyright.
8 */
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <stdlib.h>
14 #include <assert.h>
15 
16 #define ISSPACE(X) isspace((unsigned char)(X))
17 #define ISDIGIT(X) isdigit((unsigned char)(X))
18 #define ISALNUM(X) isalnum((unsigned char)(X))
19 #define ISALPHA(X) isalpha((unsigned char)(X))
20 #define ISUPPER(X) isupper((unsigned char)(X))
21 #define ISLOWER(X) islower((unsigned char)(X))
22 
23 
24 #ifndef __WIN32__
25 #   if defined(_WIN32) || defined(WIN32)
26 #       define __WIN32__
27 #   endif
28 #endif
29 
30 #ifdef __WIN32__
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 extern int access(const char *path, int mode);
35 #ifdef __cplusplus
36 }
37 #endif
38 #else
39 #include <unistd.h>
40 #endif
41 
42 /* #define PRIVATE static */
43 #define PRIVATE
44 
45 #ifdef TEST
46 #define MAXRHS 5       /* Set low to exercise exception code */
47 #else
48 #define MAXRHS 1000
49 #endif
50 
51 static int showPrecedenceConflict = 0;
52 static char *msort(char*,char**,int(*)(const char*,const char*));
53 
54 /*
55 ** Compilers are getting increasingly pedantic about type conversions
56 ** as C evolves ever closer to Ada....  To work around the latest problems
57 ** we have to define the following variant of strlen().
58 */
59 #define lemonStrlen(X)   ((int)strlen(X))
60 
61 /*
62 ** Compilers are starting to complain about the use of sprintf() and strcpy(),
63 ** saying they are unsafe.  So we define our own versions of those routines too.
64 **
65 ** There are three routines here:  lemon_sprintf(), lemon_vsprintf(), and
66 ** lemon_addtext(). The first two are replacements for sprintf() and vsprintf().
67 ** The third is a helper routine for vsnprintf() that adds texts to the end of a
68 ** buffer, making sure the buffer is always zero-terminated.
69 **
70 ** The string formatter is a minimal subset of stdlib sprintf() supporting only
71 ** a few simply conversions:
72 **
73 **   %d
74 **   %s
75 **   %.*s
76 **
77 */
78 static void lemon_addtext(
79   char *zBuf,           /* The buffer to which text is added */
80   int *pnUsed,          /* Slots of the buffer used so far */
81   const char *zIn,      /* Text to add */
82   int nIn,              /* Bytes of text to add.  -1 to use strlen() */
83   int iWidth            /* Field width.  Negative to left justify */
84 ){
85   if( nIn<0 ) for(nIn=0; zIn[nIn]; nIn++){}
86   while( iWidth>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth--; }
87   if( nIn==0 ) return;
88   memcpy(&zBuf[*pnUsed], zIn, nIn);
89   *pnUsed += nIn;
90   while( (-iWidth)>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth++; }
91   zBuf[*pnUsed] = 0;
92 }
93 static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){
94   int i, j, k, c;
95   int nUsed = 0;
96   const char *z;
97   char zTemp[50];
98   str[0] = 0;
99   for(i=j=0; (c = zFormat[i])!=0; i++){
100     if( c=='%' ){
101       int iWidth = 0;
102       lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
103       c = zFormat[++i];
104       if( ISDIGIT(c) || (c=='-' && ISDIGIT(zFormat[i+1])) ){
105         if( c=='-' ) i++;
106         while( ISDIGIT(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0';
107         if( c=='-' ) iWidth = -iWidth;
108         c = zFormat[i];
109       }
110       if( c=='d' ){
111         int v = va_arg(ap, int);
112         if( v<0 ){
113           lemon_addtext(str, &nUsed, "-", 1, iWidth);
114           v = -v;
115         }else if( v==0 ){
116           lemon_addtext(str, &nUsed, "0", 1, iWidth);
117         }
118         k = 0;
119         while( v>0 ){
120           k++;
121           zTemp[sizeof(zTemp)-k] = (v%10) + '0';
122           v /= 10;
123         }
124         lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k, iWidth);
125       }else if( c=='s' ){
126         z = va_arg(ap, const char*);
127         lemon_addtext(str, &nUsed, z, -1, iWidth);
128       }else if( c=='.' && memcmp(&zFormat[i], ".*s", 3)==0 ){
129         i += 2;
130         k = va_arg(ap, int);
131         z = va_arg(ap, const char*);
132         lemon_addtext(str, &nUsed, z, k, iWidth);
133       }else if( c=='%' ){
134         lemon_addtext(str, &nUsed, "%", 1, 0);
135       }else{
136         fprintf(stderr, "illegal format\n");
137         exit(1);
138       }
139       j = i+1;
140     }
141   }
142   lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
143   return nUsed;
144 }
145 static int lemon_sprintf(char *str, const char *format, ...){
146   va_list ap;
147   int rc;
148   va_start(ap, format);
149   rc = lemon_vsprintf(str, format, ap);
150   va_end(ap);
151   return rc;
152 }
153 static void lemon_strcpy(char *dest, const char *src){
154   while( (*(dest++) = *(src++))!=0 ){}
155 }
156 static void lemon_strcat(char *dest, const char *src){
157   while( *dest ) dest++;
158   lemon_strcpy(dest, src);
159 }
160 
161 
162 /* a few forward declarations... */
163 struct rule;
164 struct lemon;
165 struct action;
166 
167 static struct action *Action_new(void);
168 static struct action *Action_sort(struct action *);
169 
170 /********** From the file "build.h" ************************************/
171 void FindRulePrecedences();
172 void FindFirstSets();
173 void FindStates();
174 void FindLinks();
175 void FindFollowSets();
176 void FindActions();
177 
178 /********* From the file "configlist.h" *********************************/
179 void Configlist_init(void);
180 struct config *Configlist_add(struct rule *, int);
181 struct config *Configlist_addbasis(struct rule *, int);
182 void Configlist_closure(struct lemon *);
183 void Configlist_sort(void);
184 void Configlist_sortbasis(void);
185 struct config *Configlist_return(void);
186 struct config *Configlist_basis(void);
187 void Configlist_eat(struct config *);
188 void Configlist_reset(void);
189 
190 /********* From the file "error.h" ***************************************/
191 void ErrorMsg(const char *, int,const char *, ...);
192 
193 /****** From the file "option.h" ******************************************/
194 enum option_type { OPT_FLAG=1,  OPT_INT,  OPT_DBL,  OPT_STR,
195          OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR};
196 struct s_options {
197   enum option_type type;
198   const char *label;
199   char *arg;
200   const char *message;
201 };
202 int    OptInit(char**,struct s_options*,FILE*);
203 int    OptNArgs(void);
204 char  *OptArg(int);
205 void   OptErr(int);
206 void   OptPrint(void);
207 
208 /******** From the file "parse.h" *****************************************/
209 void Parse(struct lemon *lemp);
210 
211 /********* From the file "plink.h" ***************************************/
212 struct plink *Plink_new(void);
213 void Plink_add(struct plink **, struct config *);
214 void Plink_copy(struct plink **, struct plink *);
215 void Plink_delete(struct plink *);
216 
217 /********** From the file "report.h" *************************************/
218 void Reprint(struct lemon *);
219 void ReportOutput(struct lemon *);
220 void ReportTable(struct lemon *, int);
221 void ReportHeader(struct lemon *);
222 void CompressTables(struct lemon *);
223 void ResortStates(struct lemon *);
224 
225 /********** From the file "set.h" ****************************************/
226 void  SetSize(int);             /* All sets will be of size N */
227 char *SetNew(void);               /* A new set for element 0..N */
228 void  SetFree(char*);             /* Deallocate a set */
229 int SetAdd(char*,int);            /* Add element to a set */
230 int SetUnion(char *,char *);    /* A <- A U B, thru element N */
231 #define SetFind(X,Y) (X[Y])       /* True if Y is in set X */
232 
233 /********** From the file "struct.h" *************************************/
234 /*
235 ** Principal data structures for the LEMON parser generator.
236 */
237 
238 typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean;
239 
240 /* Symbols (terminals and nonterminals) of the grammar are stored
241 ** in the following: */
242 enum symbol_type {
243   TERMINAL,
244   NONTERMINAL,
245   MULTITERMINAL
246 };
247 enum e_assoc {
248     LEFT,
249     RIGHT,
250     NONE,
251     UNK
252 };
253 struct symbol {
254   const char *name;        /* Name of the symbol */
255   int index;               /* Index number for this symbol */
256   enum symbol_type type;   /* Symbols are all either TERMINALS or NTs */
257   struct rule *rule;       /* Linked list of rules of this (if an NT) */
258   struct symbol *fallback; /* fallback token in case this token doesn't parse */
259   int prec;                /* Precedence if defined (-1 otherwise) */
260   enum e_assoc assoc;      /* Associativity if precedence is defined */
261   char *firstset;          /* First-set for all rules of this symbol */
262   Boolean lambda;          /* True if NT and can generate an empty string */
263   int useCnt;              /* Number of times used */
264   char *destructor;        /* Code which executes whenever this symbol is
265                            ** popped from the stack during error processing */
266   int destLineno;          /* Line number for start of destructor */
267   char *datatype;          /* The data type of information held by this
268                            ** object. Only used if type==NONTERMINAL */
269   int dtnum;               /* The data type number.  In the parser, the value
270                            ** stack is a union.  The .yy%d element of this
271                            ** union is the correct data type for this object */
272   /* The following fields are used by MULTITERMINALs only */
273   int nsubsym;             /* Number of constituent symbols in the MULTI */
274   struct symbol **subsym;  /* Array of constituent symbols */
275 };
276 
277 /* Each production rule in the grammar is stored in the following
278 ** structure.  */
279 struct rule {
280   struct symbol *lhs;      /* Left-hand side of the rule */
281   const char *lhsalias;    /* Alias for the LHS (NULL if none) */
282   int lhsStart;            /* True if left-hand side is the start symbol */
283   int ruleline;            /* Line number for the rule */
284   int nrhs;                /* Number of RHS symbols */
285   struct symbol **rhs;     /* The RHS symbols */
286   const char **rhsalias;   /* An alias for each RHS symbol (NULL if none) */
287   int line;                /* Line number at which code begins */
288   const char *code;        /* The code executed when this rule is reduced */
289   const char *codePrefix;  /* Setup code before code[] above */
290   const char *codeSuffix;  /* Breakdown code after code[] above */
291   struct symbol *precsym;  /* Precedence symbol for this rule */
292   int index;               /* An index number for this rule */
293   Boolean canReduce;       /* True if this rule is ever reduced */
294   struct rule *nextlhs;    /* Next rule with the same LHS */
295   struct rule *next;       /* Next rule in the global list */
296 };
297 
298 /* A configuration is a production rule of the grammar together with
299 ** a mark (dot) showing how much of that rule has been processed so far.
300 ** Configurations also contain a follow-set which is a list of terminal
301 ** symbols which are allowed to immediately follow the end of the rule.
302 ** Every configuration is recorded as an instance of the following: */
303 enum cfgstatus {
304   COMPLETE,
305   INCOMPLETE
306 };
307 struct config {
308   struct rule *rp;         /* The rule upon which the configuration is based */
309   int dot;                 /* The parse point */
310   char *fws;               /* Follow-set for this configuration only */
311   struct plink *fplp;      /* Follow-set forward propagation links */
312   struct plink *bplp;      /* Follow-set backwards propagation links */
313   struct state *stp;       /* Pointer to state which contains this */
314   enum cfgstatus status;   /* used during followset and shift computations */
315   struct config *next;     /* Next configuration in the state */
316   struct config *bp;       /* The next basis configuration */
317 };
318 
319 enum e_action {
320   SHIFT,
321   ACCEPT,
322   REDUCE,
323   ERROR,
324   SSCONFLICT,              /* A shift/shift conflict */
325   SRCONFLICT,              /* Was a reduce, but part of a conflict */
326   RRCONFLICT,              /* Was a reduce, but part of a conflict */
327   SH_RESOLVED,             /* Was a shift.  Precedence resolved conflict */
328   RD_RESOLVED,             /* Was reduce.  Precedence resolved conflict */
329   NOT_USED,                /* Deleted by compression */
330   SHIFTREDUCE              /* Shift first, then reduce */
331 };
332 
333 /* Every shift or reduce operation is stored as one of the following */
334 struct action {
335   struct symbol *sp;       /* The look-ahead symbol */
336   enum e_action type;
337   union {
338     struct state *stp;     /* The new state, if a shift */
339     struct rule *rp;       /* The rule, if a reduce */
340   } x;
341   struct action *next;     /* Next action for this state */
342   struct action *collide;  /* Next action with the same hash */
343 };
344 
345 /* Each state of the generated parser's finite state machine
346 ** is encoded as an instance of the following structure. */
347 struct state {
348   struct config *bp;       /* The basis configurations for this state */
349   struct config *cfp;      /* All configurations in this set */
350   int statenum;            /* Sequential number for this state */
351   struct action *ap;       /* Array of actions for this state */
352   int nTknAct, nNtAct;     /* Number of actions on terminals and nonterminals */
353   int iTknOfst, iNtOfst;   /* yy_action[] offset for terminals and nonterms */
354   int iDfltReduce;         /* Default action is to REDUCE by this rule */
355   struct rule *pDfltReduce;/* The default REDUCE rule. */
356   int autoReduce;          /* True if this is an auto-reduce state */
357 };
358 #define NO_OFFSET (-2147483647)
359 
360 /* A followset propagation link indicates that the contents of one
361 ** configuration followset should be propagated to another whenever
362 ** the first changes. */
363 struct plink {
364   struct config *cfp;      /* The configuration to which linked */
365   struct plink *next;      /* The next propagate link */
366 };
367 
368 /* The state vector for the entire parser generator is recorded as
369 ** follows.  (LEMON uses no global variables and makes little use of
370 ** static variables.  Fields in the following structure can be thought
371 ** of as begin global variables in the program.) */
372 struct lemon {
373   struct state **sorted;   /* Table of states sorted by state number */
374   struct rule *rule;       /* List of all rules */
375   int nstate;              /* Number of states */
376   int nxstate;             /* nstate with tail degenerate states removed */
377   int nrule;               /* Number of rules */
378   int nsymbol;             /* Number of terminal and nonterminal symbols */
379   int nterminal;           /* Number of terminal symbols */
380   struct symbol **symbols; /* Sorted array of pointers to symbols */
381   int errorcnt;            /* Number of errors */
382   struct symbol *errsym;   /* The error symbol */
383   struct symbol *wildcard; /* Token that matches anything */
384   char *name;              /* Name of the generated parser */
385   char *arg;               /* Declaration of the 3th argument to parser */
386   char *tokentype;         /* Type of terminal symbols in the parser stack */
387   char *vartype;           /* The default type of non-terminal symbols */
388   char *start;             /* Name of the start symbol for the grammar */
389   char *stacksize;         /* Size of the parser stack */
390   char *include;           /* Code to put at the start of the C file */
391   char *error;             /* Code to execute when an error is seen */
392   char *overflow;          /* Code to execute on a stack overflow */
393   char *failure;           /* Code to execute on parser failure */
394   char *accept;            /* Code to execute when the parser excepts */
395   char *extracode;         /* Code appended to the generated file */
396   char *tokendest;         /* Code to execute to destroy token data */
397   char *vardest;           /* Code for the default non-terminal destructor */
398   char *filename;          /* Name of the input file */
399   char *outname;           /* Name of the current output file */
400   char *tokenprefix;       /* A prefix added to token names in the .h file */
401   int nconflict;           /* Number of parsing conflicts */
402   int nactiontab;          /* Number of entries in the yy_action[] table */
403   int tablesize;           /* Total table size of all tables in bytes */
404   int basisflag;           /* Print only basis configurations */
405   int has_fallback;        /* True if any %fallback is seen in the grammar */
406   int nolinenosflag;       /* True if #line statements should not be printed */
407   char *argv0;             /* Name of the program */
408 };
409 
410 #define MemoryCheck(X) if((X)==0){ \
411   extern void memory_error(); \
412   memory_error(); \
413 }
414 
415 /**************** From the file "table.h" *********************************/
416 /*
417 ** All code in this file has been automatically generated
418 ** from a specification in the file
419 **              "table.q"
420 ** by the associative array code building program "aagen".
421 ** Do not edit this file!  Instead, edit the specification
422 ** file, then rerun aagen.
423 */
424 /*
425 ** Code for processing tables in the LEMON parser generator.
426 */
427 /* Routines for handling a strings */
428 
429 const char *Strsafe(const char *);
430 
431 void Strsafe_init(void);
432 int Strsafe_insert(const char *);
433 const char *Strsafe_find(const char *);
434 
435 /* Routines for handling symbols of the grammar */
436 
437 struct symbol *Symbol_new(const char *);
438 int Symbolcmpp(const void *, const void *);
439 void Symbol_init(void);
440 int Symbol_insert(struct symbol *, const char *);
441 struct symbol *Symbol_find(const char *);
442 struct symbol *Symbol_Nth(int);
443 int Symbol_count(void);
444 struct symbol **Symbol_arrayof(void);
445 
446 /* Routines to manage the state table */
447 
448 int Configcmp(const char *, const char *);
449 struct state *State_new(void);
450 void State_init(void);
451 int State_insert(struct state *, struct config *);
452 struct state *State_find(struct config *);
453 struct state **State_arrayof(/*  */);
454 
455 /* Routines used for efficiency in Configlist_add */
456 
457 void Configtable_init(void);
458 int Configtable_insert(struct config *);
459 struct config *Configtable_find(struct config *);
460 void Configtable_clear(int(*)(struct config *));
461 
462 /****************** From the file "action.c" *******************************/
463 /*
464 ** Routines processing parser actions in the LEMON parser generator.
465 */
466 
467 /* Allocate a new parser action */
468 static struct action *Action_new(void){
469   static struct action *freelist = 0;
470   struct action *newaction;
471 
472   if( freelist==0 ){
473     int i;
474     int amt = 100;
475     freelist = (struct action *)calloc(amt, sizeof(struct action));
476     if( freelist==0 ){
477       fprintf(stderr,"Unable to allocate memory for a new parser action.");
478       exit(1);
479     }
480     for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
481     freelist[amt-1].next = 0;
482   }
483   newaction = freelist;
484   freelist = freelist->next;
485   return newaction;
486 }
487 
488 /* Compare two actions for sorting purposes.  Return negative, zero, or
489 ** positive if the first action is less than, equal to, or greater than
490 ** the first
491 */
492 static int actioncmp(
493   struct action *ap1,
494   struct action *ap2
495 ){
496   int rc;
497   rc = ap1->sp->index - ap2->sp->index;
498   if( rc==0 ){
499     rc = (int)ap1->type - (int)ap2->type;
500   }
501   if( rc==0 && (ap1->type==REDUCE || ap1->type==SHIFTREDUCE) ){
502     rc = ap1->x.rp->index - ap2->x.rp->index;
503   }
504   if( rc==0 ){
505     rc = (int) (ap2 - ap1);
506   }
507   return rc;
508 }
509 
510 /* Sort parser actions */
511 static struct action *Action_sort(
512   struct action *ap
513 ){
514   ap = (struct action *)msort((char *)ap,(char **)&ap->next,
515                               (int(*)(const char*,const char*))actioncmp);
516   return ap;
517 }
518 
519 void Action_add(
520   struct action **app,
521   enum e_action type,
522   struct symbol *sp,
523   char *arg
524 ){
525   struct action *newaction;
526   newaction = Action_new();
527   newaction->next = *app;
528   *app = newaction;
529   newaction->type = type;
530   newaction->sp = sp;
531   if( type==SHIFT ){
532     newaction->x.stp = (struct state *)arg;
533   }else{
534     newaction->x.rp = (struct rule *)arg;
535   }
536 }
537 /********************** New code to implement the "acttab" module ***********/
538 /*
539 ** This module implements routines use to construct the yy_action[] table.
540 */
541 
542 /*
543 ** The state of the yy_action table under construction is an instance of
544 ** the following structure.
545 **
546 ** The yy_action table maps the pair (state_number, lookahead) into an
547 ** action_number.  The table is an array of integers pairs.  The state_number
548 ** determines an initial offset into the yy_action array.  The lookahead
549 ** value is then added to this initial offset to get an index X into the
550 ** yy_action array. If the aAction[X].lookahead equals the value of the
551 ** of the lookahead input, then the value of the action_number output is
552 ** aAction[X].action.  If the lookaheads do not match then the
553 ** default action for the state_number is returned.
554 **
555 ** All actions associated with a single state_number are first entered
556 ** into aLookahead[] using multiple calls to acttab_action().  Then the
557 ** actions for that single state_number are placed into the aAction[]
558 ** array with a single call to acttab_insert().  The acttab_insert() call
559 ** also resets the aLookahead[] array in preparation for the next
560 ** state number.
561 */
562 struct lookahead_action {
563   int lookahead;             /* Value of the lookahead token */
564   int action;                /* Action to take on the given lookahead */
565 };
566 typedef struct acttab acttab;
567 struct acttab {
568   int nAction;                 /* Number of used slots in aAction[] */
569   int nActionAlloc;            /* Slots allocated for aAction[] */
570   struct lookahead_action
571     *aAction,                  /* The yy_action[] table under construction */
572     *aLookahead;               /* A single new transaction set */
573   int mnLookahead;             /* Minimum aLookahead[].lookahead */
574   int mnAction;                /* Action associated with mnLookahead */
575   int mxLookahead;             /* Maximum aLookahead[].lookahead */
576   int nLookahead;              /* Used slots in aLookahead[] */
577   int nLookaheadAlloc;         /* Slots allocated in aLookahead[] */
578 };
579 
580 /* Return the number of entries in the yy_action table */
581 #define acttab_size(X) ((X)->nAction)
582 
583 /* The value for the N-th entry in yy_action */
584 #define acttab_yyaction(X,N)  ((X)->aAction[N].action)
585 
586 /* The value for the N-th entry in yy_lookahead */
587 #define acttab_yylookahead(X,N)  ((X)->aAction[N].lookahead)
588 
589 /* Free all memory associated with the given acttab */
590 void acttab_free(acttab *p){
591   free( p->aAction );
592   free( p->aLookahead );
593   free( p );
594 }
595 
596 /* Allocate a new acttab structure */
597 acttab *acttab_alloc(void){
598   acttab *p = (acttab *) calloc( 1, sizeof(*p) );
599   if( p==0 ){
600     fprintf(stderr,"Unable to allocate memory for a new acttab.");
601     exit(1);
602   }
603   memset(p, 0, sizeof(*p));
604   return p;
605 }
606 
607 /* Add a new action to the current transaction set.
608 **
609 ** This routine is called once for each lookahead for a particular
610 ** state.
611 */
612 void acttab_action(acttab *p, int lookahead, int action){
613   if( p->nLookahead>=p->nLookaheadAlloc ){
614     p->nLookaheadAlloc += 25;
615     p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead,
616                              sizeof(p->aLookahead[0])*p->nLookaheadAlloc );
617     if( p->aLookahead==0 ){
618       fprintf(stderr,"malloc failed\n");
619       exit(1);
620     }
621   }
622   if( p->nLookahead==0 ){
623     p->mxLookahead = lookahead;
624     p->mnLookahead = lookahead;
625     p->mnAction = action;
626   }else{
627     if( p->mxLookahead<lookahead ) p->mxLookahead = lookahead;
628     if( p->mnLookahead>lookahead ){
629       p->mnLookahead = lookahead;
630       p->mnAction = action;
631     }
632   }
633   p->aLookahead[p->nLookahead].lookahead = lookahead;
634   p->aLookahead[p->nLookahead].action = action;
635   p->nLookahead++;
636 }
637 
638 /*
639 ** Add the transaction set built up with prior calls to acttab_action()
640 ** into the current action table.  Then reset the transaction set back
641 ** to an empty set in preparation for a new round of acttab_action() calls.
642 **
643 ** Return the offset into the action table of the new transaction.
644 */
645 int acttab_insert(acttab *p){
646   int i, j, k, n;
647   assert( p->nLookahead>0 );
648 
649   /* Make sure we have enough space to hold the expanded action table
650   ** in the worst case.  The worst case occurs if the transaction set
651   ** must be appended to the current action table
652   */
653   n = p->mxLookahead + 1;
654   if( p->nAction + n >= p->nActionAlloc ){
655     int oldAlloc = p->nActionAlloc;
656     p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20;
657     p->aAction = (struct lookahead_action *) realloc( p->aAction,
658                           sizeof(p->aAction[0])*p->nActionAlloc);
659     if( p->aAction==0 ){
660       fprintf(stderr,"malloc failed\n");
661       exit(1);
662     }
663     for(i=oldAlloc; i<p->nActionAlloc; i++){
664       p->aAction[i].lookahead = -1;
665       p->aAction[i].action = -1;
666     }
667   }
668 
669   /* Scan the existing action table looking for an offset that is a
670   ** duplicate of the current transaction set.  Fall out of the loop
671   ** if and when the duplicate is found.
672   **
673   ** i is the index in p->aAction[] where p->mnLookahead is inserted.
674   */
675   for(i=p->nAction-1; i>=0; i--){
676     if( p->aAction[i].lookahead==p->mnLookahead ){
677       /* All lookaheads and actions in the aLookahead[] transaction
678       ** must match against the candidate aAction[i] entry. */
679       if( p->aAction[i].action!=p->mnAction ) continue;
680       for(j=0; j<p->nLookahead; j++){
681         k = p->aLookahead[j].lookahead - p->mnLookahead + i;
682         if( k<0 || k>=p->nAction ) break;
683         if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break;
684         if( p->aLookahead[j].action!=p->aAction[k].action ) break;
685       }
686       if( j<p->nLookahead ) continue;
687 
688       /* No possible lookahead value that is not in the aLookahead[]
689       ** transaction is allowed to match aAction[i] */
690       n = 0;
691       for(j=0; j<p->nAction; j++){
692         if( p->aAction[j].lookahead<0 ) continue;
693         if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++;
694       }
695       if( n==p->nLookahead ){
696         break;  /* An exact match is found at offset i */
697       }
698     }
699   }
700 
701   /* If no existing offsets exactly match the current transaction, find an
702   ** an empty offset in the aAction[] table in which we can add the
703   ** aLookahead[] transaction.
704   */
705   if( i<0 ){
706     /* Look for holes in the aAction[] table that fit the current
707     ** aLookahead[] transaction.  Leave i set to the offset of the hole.
708     ** If no holes are found, i is left at p->nAction, which means the
709     ** transaction will be appended. */
710     for(i=0; i<p->nActionAlloc - p->mxLookahead; i++){
711       if( p->aAction[i].lookahead<0 ){
712         for(j=0; j<p->nLookahead; j++){
713           k = p->aLookahead[j].lookahead - p->mnLookahead + i;
714           if( k<0 ) break;
715           if( p->aAction[k].lookahead>=0 ) break;
716         }
717         if( j<p->nLookahead ) continue;
718         for(j=0; j<p->nAction; j++){
719           if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
720         }
721         if( j==p->nAction ){
722           break;  /* Fits in empty slots */
723         }
724       }
725     }
726   }
727   /* Insert transaction set at index i. */
728   for(j=0; j<p->nLookahead; j++){
729     k = p->aLookahead[j].lookahead - p->mnLookahead + i;
730     p->aAction[k] = p->aLookahead[j];
731     if( k>=p->nAction ) p->nAction = k+1;
732   }
733   p->nLookahead = 0;
734 
735   /* Return the offset that is added to the lookahead in order to get the
736   ** index into yy_action of the action */
737   return i - p->mnLookahead;
738 }
739 
740 /********************** From the file "build.c" *****************************/
741 /*
742 ** Routines to construction the finite state machine for the LEMON
743 ** parser generator.
744 */
745 
746 /* Find a precedence symbol of every rule in the grammar.
747 **
748 ** Those rules which have a precedence symbol coded in the input
749 ** grammar using the "[symbol]" construct will already have the
750 ** rp->precsym field filled.  Other rules take as their precedence
751 ** symbol the first RHS symbol with a defined precedence.  If there
752 ** are not RHS symbols with a defined precedence, the precedence
753 ** symbol field is left blank.
754 */
755 void FindRulePrecedences(struct lemon *xp)
756 {
757   struct rule *rp;
758   for(rp=xp->rule; rp; rp=rp->next){
759     if( rp->precsym==0 ){
760       int i, j;
761       for(i=0; i<rp->nrhs && rp->precsym==0; i++){
762         struct symbol *sp = rp->rhs[i];
763         if( sp->type==MULTITERMINAL ){
764           for(j=0; j<sp->nsubsym; j++){
765             if( sp->subsym[j]->prec>=0 ){
766               rp->precsym = sp->subsym[j];
767               break;
768             }
769           }
770         }else if( sp->prec>=0 ){
771           rp->precsym = rp->rhs[i];
772         }
773       }
774     }
775   }
776   return;
777 }
778 
779 /* Find all nonterminals which will generate the empty string.
780 ** Then go back and compute the first sets of every nonterminal.
781 ** The first set is the set of all terminal symbols which can begin
782 ** a string generated by that nonterminal.
783 */
784 void FindFirstSets(struct lemon *lemp)
785 {
786   int i, j;
787   struct rule *rp;
788   int progress;
789 
790   for(i=0; i<lemp->nsymbol; i++){
791     lemp->symbols[i]->lambda = LEMON_FALSE;
792   }
793   for(i=lemp->nterminal; i<lemp->nsymbol; i++){
794     lemp->symbols[i]->firstset = SetNew();
795   }
796 
797   /* First compute all lambdas */
798   do{
799     progress = 0;
800     for(rp=lemp->rule; rp; rp=rp->next){
801       if( rp->lhs->lambda ) continue;
802       for(i=0; i<rp->nrhs; i++){
803         struct symbol *sp = rp->rhs[i];
804         assert( sp->type==NONTERMINAL || sp->lambda==LEMON_FALSE );
805         if( sp->lambda==LEMON_FALSE ) break;
806       }
807       if( i==rp->nrhs ){
808         rp->lhs->lambda = LEMON_TRUE;
809         progress = 1;
810       }
811     }
812   }while( progress );
813 
814   /* Now compute all first sets */
815   do{
816     struct symbol *s1, *s2;
817     progress = 0;
818     for(rp=lemp->rule; rp; rp=rp->next){
819       s1 = rp->lhs;
820       for(i=0; i<rp->nrhs; i++){
821         s2 = rp->rhs[i];
822         if( s2->type==TERMINAL ){
823           progress += SetAdd(s1->firstset,s2->index);
824           break;
825         }else if( s2->type==MULTITERMINAL ){
826           for(j=0; j<s2->nsubsym; j++){
827             progress += SetAdd(s1->firstset,s2->subsym[j]->index);
828           }
829           break;
830         }else if( s1==s2 ){
831           if( s1->lambda==LEMON_FALSE ) break;
832         }else{
833           progress += SetUnion(s1->firstset,s2->firstset);
834           if( s2->lambda==LEMON_FALSE ) break;
835         }
836       }
837     }
838   }while( progress );
839   return;
840 }
841 
842 /* Compute all LR(0) states for the grammar.  Links
843 ** are added to between some states so that the LR(1) follow sets
844 ** can be computed later.
845 */
846 PRIVATE struct state *getstate(struct lemon *);  /* forward reference */
847 void FindStates(struct lemon *lemp)
848 {
849   struct symbol *sp;
850   struct rule *rp;
851 
852   Configlist_init();
853 
854   /* Find the start symbol */
855   if( lemp->start ){
856     sp = Symbol_find(lemp->start);
857     if( sp==0 ){
858       ErrorMsg(lemp->filename,0,
859 "The specified start symbol \"%s\" is not \
860 in a nonterminal of the grammar.  \"%s\" will be used as the start \
861 symbol instead.",lemp->start,lemp->rule->lhs->name);
862       lemp->errorcnt++;
863       sp = lemp->rule->lhs;
864     }
865   }else{
866     sp = lemp->rule->lhs;
867   }
868 
869   /* Make sure the start symbol doesn't occur on the right-hand side of
870   ** any rule.  Report an error if it does.  (YACC would generate a new
871   ** start symbol in this case.) */
872   for(rp=lemp->rule; rp; rp=rp->next){
873     int i;
874     for(i=0; i<rp->nrhs; i++){
875       if( rp->rhs[i]==sp ){   /* FIX ME:  Deal with multiterminals */
876         ErrorMsg(lemp->filename,0,
877 "The start symbol \"%s\" occurs on the \
878 right-hand side of a rule. This will result in a parser which \
879 does not work properly.",sp->name);
880         lemp->errorcnt++;
881       }
882     }
883   }
884 
885   /* The basis configuration set for the first state
886   ** is all rules which have the start symbol as their
887   ** left-hand side */
888   for(rp=sp->rule; rp; rp=rp->nextlhs){
889     struct config *newcfp;
890     rp->lhsStart = 1;
891     newcfp = Configlist_addbasis(rp,0);
892     SetAdd(newcfp->fws,0);
893   }
894 
895   /* Compute the first state.  All other states will be
896   ** computed automatically during the computation of the first one.
897   ** The returned pointer to the first state is not used. */
898   (void)getstate(lemp);
899   return;
900 }
901 
902 /* Return a pointer to a state which is described by the configuration
903 ** list which has been built from calls to Configlist_add.
904 */
905 PRIVATE void buildshifts(struct lemon *, struct state *); /* Forwd ref */
906 PRIVATE struct state *getstate(struct lemon *lemp)
907 {
908   struct config *cfp, *bp;
909   struct state *stp;
910 
911   /* Extract the sorted basis of the new state.  The basis was constructed
912   ** by prior calls to "Configlist_addbasis()". */
913   Configlist_sortbasis();
914   bp = Configlist_basis();
915 
916   /* Get a state with the same basis */
917   stp = State_find(bp);
918   if( stp ){
919     /* A state with the same basis already exists!  Copy all the follow-set
920     ** propagation links from the state under construction into the
921     ** preexisting state, then return a pointer to the preexisting state */
922     struct config *x, *y;
923     for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){
924       Plink_copy(&y->bplp,x->bplp);
925       Plink_delete(x->fplp);
926       x->fplp = x->bplp = 0;
927     }
928     cfp = Configlist_return();
929     Configlist_eat(cfp);
930   }else{
931     /* This really is a new state.  Construct all the details */
932     Configlist_closure(lemp);    /* Compute the configuration closure */
933     Configlist_sort();           /* Sort the configuration closure */
934     cfp = Configlist_return();   /* Get a pointer to the config list */
935     stp = State_new();           /* A new state structure */
936     MemoryCheck(stp);
937     stp->bp = bp;                /* Remember the configuration basis */
938     stp->cfp = cfp;              /* Remember the configuration closure */
939     stp->statenum = lemp->nstate++; /* Every state gets a sequence number */
940     stp->ap = 0;                 /* No actions, yet. */
941     State_insert(stp,stp->bp);   /* Add to the state table */
942     buildshifts(lemp,stp);       /* Recursively compute successor states */
943   }
944   return stp;
945 }
946 
947 /*
948 ** Return true if two symbols are the same.
949 */
950 int same_symbol(struct symbol *a, struct symbol *b)
951 {
952   int i;
953   if( a==b ) return 1;
954   if( a->type!=MULTITERMINAL ) return 0;
955   if( b->type!=MULTITERMINAL ) return 0;
956   if( a->nsubsym!=b->nsubsym ) return 0;
957   for(i=0; i<a->nsubsym; i++){
958     if( a->subsym[i]!=b->subsym[i] ) return 0;
959   }
960   return 1;
961 }
962 
963 /* Construct all successor states to the given state.  A "successor"
964 ** state is any state which can be reached by a shift action.
965 */
966 PRIVATE void buildshifts(struct lemon *lemp, struct state *stp)
967 {
968   struct config *cfp;  /* For looping thru the config closure of "stp" */
969   struct config *bcfp; /* For the inner loop on config closure of "stp" */
970   struct config *newcfg;  /* */
971   struct symbol *sp;   /* Symbol following the dot in configuration "cfp" */
972   struct symbol *bsp;  /* Symbol following the dot in configuration "bcfp" */
973   struct state *newstp; /* A pointer to a successor state */
974 
975   /* Each configuration becomes complete after it contibutes to a successor
976   ** state.  Initially, all configurations are incomplete */
977   for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE;
978 
979   /* Loop through all configurations of the state "stp" */
980   for(cfp=stp->cfp; cfp; cfp=cfp->next){
981     if( cfp->status==COMPLETE ) continue;    /* Already used by inner loop */
982     if( cfp->dot>=cfp->rp->nrhs ) continue;  /* Can't shift this config */
983     Configlist_reset();                      /* Reset the new config set */
984     sp = cfp->rp->rhs[cfp->dot];             /* Symbol after the dot */
985 
986     /* For every configuration in the state "stp" which has the symbol "sp"
987     ** following its dot, add the same configuration to the basis set under
988     ** construction but with the dot shifted one symbol to the right. */
989     for(bcfp=cfp; bcfp; bcfp=bcfp->next){
990       if( bcfp->status==COMPLETE ) continue;    /* Already used */
991       if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */
992       bsp = bcfp->rp->rhs[bcfp->dot];           /* Get symbol after dot */
993       if( !same_symbol(bsp,sp) ) continue;      /* Must be same as for "cfp" */
994       bcfp->status = COMPLETE;                  /* Mark this config as used */
995       newcfg = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
996       Plink_add(&newcfg->bplp,bcfp);
997     }
998 
999     /* Get a pointer to the state described by the basis configuration set
1000     ** constructed in the preceding loop */
1001     newstp = getstate(lemp);
1002 
1003     /* The state "newstp" is reached from the state "stp" by a shift action
1004     ** on the symbol "sp" */
1005     if( sp->type==MULTITERMINAL ){
1006       int i;
1007       for(i=0; i<sp->nsubsym; i++){
1008         Action_add(&stp->ap,SHIFT,sp->subsym[i],(char*)newstp);
1009       }
1010     }else{
1011       Action_add(&stp->ap,SHIFT,sp,(char *)newstp);
1012     }
1013   }
1014 }
1015 
1016 /*
1017 ** Construct the propagation links
1018 */
1019 void FindLinks(struct lemon *lemp)
1020 {
1021   int i;
1022   struct config *cfp, *other;
1023   struct state *stp;
1024   struct plink *plp;
1025 
1026   /* Housekeeping detail:
1027   ** Add to every propagate link a pointer back to the state to
1028   ** which the link is attached. */
1029   for(i=0; i<lemp->nstate; i++){
1030     stp = lemp->sorted[i];
1031     for(cfp=stp->cfp; cfp; cfp=cfp->next){
1032       cfp->stp = stp;
1033     }
1034   }
1035 
1036   /* Convert all backlinks into forward links.  Only the forward
1037   ** links are used in the follow-set computation. */
1038   for(i=0; i<lemp->nstate; i++){
1039     stp = lemp->sorted[i];
1040     for(cfp=stp->cfp; cfp; cfp=cfp->next){
1041       for(plp=cfp->bplp; plp; plp=plp->next){
1042         other = plp->cfp;
1043         Plink_add(&other->fplp,cfp);
1044       }
1045     }
1046   }
1047 }
1048 
1049 /* Compute all followsets.
1050 **
1051 ** A followset is the set of all symbols which can come immediately
1052 ** after a configuration.
1053 */
1054 void FindFollowSets(struct lemon *lemp)
1055 {
1056   int i;
1057   struct config *cfp;
1058   struct plink *plp;
1059   int progress;
1060   int change;
1061 
1062   for(i=0; i<lemp->nstate; i++){
1063     for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
1064       cfp->status = INCOMPLETE;
1065     }
1066   }
1067 
1068   do{
1069     progress = 0;
1070     for(i=0; i<lemp->nstate; i++){
1071       for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
1072         if( cfp->status==COMPLETE ) continue;
1073         for(plp=cfp->fplp; plp; plp=plp->next){
1074           change = SetUnion(plp->cfp->fws,cfp->fws);
1075           if( change ){
1076             plp->cfp->status = INCOMPLETE;
1077             progress = 1;
1078           }
1079         }
1080         cfp->status = COMPLETE;
1081       }
1082     }
1083   }while( progress );
1084 }
1085 
1086 static int resolve_conflict(struct action *,struct action *);
1087 
1088 /* Compute the reduce actions, and resolve conflicts.
1089 */
1090 void FindActions(struct lemon *lemp)
1091 {
1092   int i,j;
1093   struct config *cfp;
1094   struct state *stp;
1095   struct symbol *sp;
1096   struct rule *rp;
1097 
1098   /* Add all of the reduce actions
1099   ** A reduce action is added for each element of the followset of
1100   ** a configuration which has its dot at the extreme right.
1101   */
1102   for(i=0; i<lemp->nstate; i++){   /* Loop over all states */
1103     stp = lemp->sorted[i];
1104     for(cfp=stp->cfp; cfp; cfp=cfp->next){  /* Loop over all configurations */
1105       if( cfp->rp->nrhs==cfp->dot ){        /* Is dot at extreme right? */
1106         for(j=0; j<lemp->nterminal; j++){
1107           if( SetFind(cfp->fws,j) ){
1108             /* Add a reduce action to the state "stp" which will reduce by the
1109             ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */
1110             Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
1111           }
1112         }
1113       }
1114     }
1115   }
1116 
1117   /* Add the accepting token */
1118   if( lemp->start ){
1119     sp = Symbol_find(lemp->start);
1120     if( sp==0 ) sp = lemp->rule->lhs;
1121   }else{
1122     sp = lemp->rule->lhs;
1123   }
1124   /* Add to the first state (which is always the starting state of the
1125   ** finite state machine) an action to ACCEPT if the lookahead is the
1126   ** start nonterminal.  */
1127   Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0);
1128 
1129   /* Resolve conflicts */
1130   for(i=0; i<lemp->nstate; i++){
1131     struct action *ap, *nap;
1132     stp = lemp->sorted[i];
1133     /* assert( stp->ap ); */
1134     stp->ap = Action_sort(stp->ap);
1135     for(ap=stp->ap; ap && ap->next; ap=ap->next){
1136       for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
1137          /* The two actions "ap" and "nap" have the same lookahead.
1138          ** Figure out which one should be used */
1139          lemp->nconflict += resolve_conflict(ap,nap);
1140       }
1141     }
1142   }
1143 
1144   /* Report an error for each rule that can never be reduced. */
1145   for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE;
1146   for(i=0; i<lemp->nstate; i++){
1147     struct action *ap;
1148     for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
1149       if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE;
1150     }
1151   }
1152   for(rp=lemp->rule; rp; rp=rp->next){
1153     if( rp->canReduce ) continue;
1154     ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n");
1155     lemp->errorcnt++;
1156   }
1157 }
1158 
1159 /* Resolve a conflict between the two given actions.  If the
1160 ** conflict can't be resolved, return non-zero.
1161 **
1162 ** NO LONGER TRUE:
1163 **   To resolve a conflict, first look to see if either action
1164 **   is on an error rule.  In that case, take the action which
1165 **   is not associated with the error rule.  If neither or both
1166 **   actions are associated with an error rule, then try to
1167 **   use precedence to resolve the conflict.
1168 **
1169 ** If either action is a SHIFT, then it must be apx.  This
1170 ** function won't work if apx->type==REDUCE and apy->type==SHIFT.
1171 */
1172 static int resolve_conflict(
1173   struct action *apx,
1174   struct action *apy
1175 ){
1176   struct symbol *spx, *spy;
1177   int errcnt = 0;
1178   assert( apx->sp==apy->sp );  /* Otherwise there would be no conflict */
1179   if( apx->type==SHIFT && apy->type==SHIFT ){
1180     apy->type = SSCONFLICT;
1181     errcnt++;
1182   }
1183   if( apx->type==SHIFT && apy->type==REDUCE ){
1184     spx = apx->sp;
1185     spy = apy->x.rp->precsym;
1186     if( spy==0 || spx->prec<0 || spy->prec<0 ){
1187       /* Not enough precedence information. */
1188       apy->type = SRCONFLICT;
1189       errcnt++;
1190     }else if( spx->prec>spy->prec ){    /* higher precedence wins */
1191       apy->type = RD_RESOLVED;
1192     }else if( spx->prec<spy->prec ){
1193       apx->type = SH_RESOLVED;
1194     }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */
1195       apy->type = RD_RESOLVED;                             /* associativity */
1196     }else if( spx->prec==spy->prec && spx->assoc==LEFT ){  /* to break tie */
1197       apx->type = SH_RESOLVED;
1198     }else{
1199       assert( spx->prec==spy->prec && spx->assoc==NONE );
1200       apx->type = ERROR;
1201     }
1202   }else if( apx->type==REDUCE && apy->type==REDUCE ){
1203     spx = apx->x.rp->precsym;
1204     spy = apy->x.rp->precsym;
1205     if( spx==0 || spy==0 || spx->prec<0 ||
1206     spy->prec<0 || spx->prec==spy->prec ){
1207       apy->type = RRCONFLICT;
1208       errcnt++;
1209     }else if( spx->prec>spy->prec ){
1210       apy->type = RD_RESOLVED;
1211     }else if( spx->prec<spy->prec ){
1212       apx->type = RD_RESOLVED;
1213     }
1214   }else{
1215     assert(
1216       apx->type==SH_RESOLVED ||
1217       apx->type==RD_RESOLVED ||
1218       apx->type==SSCONFLICT ||
1219       apx->type==SRCONFLICT ||
1220       apx->type==RRCONFLICT ||
1221       apy->type==SH_RESOLVED ||
1222       apy->type==RD_RESOLVED ||
1223       apy->type==SSCONFLICT ||
1224       apy->type==SRCONFLICT ||
1225       apy->type==RRCONFLICT
1226     );
1227     /* The REDUCE/SHIFT case cannot happen because SHIFTs come before
1228     ** REDUCEs on the list.  If we reach this point it must be because
1229     ** the parser conflict had already been resolved. */
1230   }
1231   return errcnt;
1232 }
1233 /********************* From the file "configlist.c" *************************/
1234 /*
1235 ** Routines to processing a configuration list and building a state
1236 ** in the LEMON parser generator.
1237 */
1238 
1239 static struct config *freelist = 0;      /* List of free configurations */
1240 static struct config *current = 0;       /* Top of list of configurations */
1241 static struct config **currentend = 0;   /* Last on list of configs */
1242 static struct config *basis = 0;         /* Top of list of basis configs */
1243 static struct config **basisend = 0;     /* End of list of basis configs */
1244 
1245 /* Return a pointer to a new configuration */
1246 PRIVATE struct config *newconfig(){
1247   struct config *newcfg;
1248   if( freelist==0 ){
1249     int i;
1250     int amt = 3;
1251     freelist = (struct config *)calloc( amt, sizeof(struct config) );
1252     if( freelist==0 ){
1253       fprintf(stderr,"Unable to allocate memory for a new configuration.");
1254       exit(1);
1255     }
1256     for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
1257     freelist[amt-1].next = 0;
1258   }
1259   newcfg = freelist;
1260   freelist = freelist->next;
1261   return newcfg;
1262 }
1263 
1264 /* The configuration "old" is no longer used */
1265 PRIVATE void deleteconfig(struct config *old)
1266 {
1267   old->next = freelist;
1268   freelist = old;
1269 }
1270 
1271 /* Initialized the configuration list builder */
1272 void Configlist_init(){
1273   current = 0;
1274   currentend = &current;
1275   basis = 0;
1276   basisend = &basis;
1277   Configtable_init();
1278   return;
1279 }
1280 
1281 /* Initialized the configuration list builder */
1282 void Configlist_reset(){
1283   current = 0;
1284   currentend = &current;
1285   basis = 0;
1286   basisend = &basis;
1287   Configtable_clear(0);
1288   return;
1289 }
1290 
1291 /* Add another configuration to the configuration list */
1292 struct config *Configlist_add(
1293   struct rule *rp,    /* The rule */
1294   int dot             /* Index into the RHS of the rule where the dot goes */
1295 ){
1296   struct config *cfp, model;
1297 
1298   assert( currentend!=0 );
1299   model.rp = rp;
1300   model.dot = dot;
1301   cfp = Configtable_find(&model);
1302   if( cfp==0 ){
1303     cfp = newconfig();
1304     cfp->rp = rp;
1305     cfp->dot = dot;
1306     cfp->fws = SetNew();
1307     cfp->stp = 0;
1308     cfp->fplp = cfp->bplp = 0;
1309     cfp->next = 0;
1310     cfp->bp = 0;
1311     *currentend = cfp;
1312     currentend = &cfp->next;
1313     Configtable_insert(cfp);
1314   }
1315   return cfp;
1316 }
1317 
1318 /* Add a basis configuration to the configuration list */
1319 struct config *Configlist_addbasis(struct rule *rp, int dot)
1320 {
1321   struct config *cfp, model;
1322 
1323   assert( basisend!=0 );
1324   assert( currentend!=0 );
1325   model.rp = rp;
1326   model.dot = dot;
1327   cfp = Configtable_find(&model);
1328   if( cfp==0 ){
1329     cfp = newconfig();
1330     cfp->rp = rp;
1331     cfp->dot = dot;
1332     cfp->fws = SetNew();
1333     cfp->stp = 0;
1334     cfp->fplp = cfp->bplp = 0;
1335     cfp->next = 0;
1336     cfp->bp = 0;
1337     *currentend = cfp;
1338     currentend = &cfp->next;
1339     *basisend = cfp;
1340     basisend = &cfp->bp;
1341     Configtable_insert(cfp);
1342   }
1343   return cfp;
1344 }
1345 
1346 /* Compute the closure of the configuration list */
1347 void Configlist_closure(struct lemon *lemp)
1348 {
1349   struct config *cfp, *newcfp;
1350   struct rule *rp, *newrp;
1351   struct symbol *sp, *xsp;
1352   int i, dot;
1353 
1354   assert( currentend!=0 );
1355   for(cfp=current; cfp; cfp=cfp->next){
1356     rp = cfp->rp;
1357     dot = cfp->dot;
1358     if( dot>=rp->nrhs ) continue;
1359     sp = rp->rhs[dot];
1360     if( sp->type==NONTERMINAL ){
1361       if( sp->rule==0 && sp!=lemp->errsym ){
1362         ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.",
1363           sp->name);
1364         lemp->errorcnt++;
1365       }
1366       for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){
1367         newcfp = Configlist_add(newrp,0);
1368         for(i=dot+1; i<rp->nrhs; i++){
1369           xsp = rp->rhs[i];
1370           if( xsp->type==TERMINAL ){
1371             SetAdd(newcfp->fws,xsp->index);
1372             break;
1373           }else if( xsp->type==MULTITERMINAL ){
1374             int k;
1375             for(k=0; k<xsp->nsubsym; k++){
1376               SetAdd(newcfp->fws, xsp->subsym[k]->index);
1377             }
1378             break;
1379           }else{
1380             SetUnion(newcfp->fws,xsp->firstset);
1381             if( xsp->lambda==LEMON_FALSE ) break;
1382           }
1383         }
1384         if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
1385       }
1386     }
1387   }
1388   return;
1389 }
1390 
1391 /* Sort the configuration list */
1392 void Configlist_sort(){
1393   current = (struct config*)msort((char*)current,(char**)&(current->next),
1394                                   Configcmp);
1395   currentend = 0;
1396   return;
1397 }
1398 
1399 /* Sort the basis configuration list */
1400 void Configlist_sortbasis(){
1401   basis = (struct config*)msort((char*)current,(char**)&(current->bp),
1402                                 Configcmp);
1403   basisend = 0;
1404   return;
1405 }
1406 
1407 /* Return a pointer to the head of the configuration list and
1408 ** reset the list */
1409 struct config *Configlist_return(){
1410   struct config *old;
1411   old = current;
1412   current = 0;
1413   currentend = 0;
1414   return old;
1415 }
1416 
1417 /* Return a pointer to the head of the configuration list and
1418 ** reset the list */
1419 struct config *Configlist_basis(){
1420   struct config *old;
1421   old = basis;
1422   basis = 0;
1423   basisend = 0;
1424   return old;
1425 }
1426 
1427 /* Free all elements of the given configuration list */
1428 void Configlist_eat(struct config *cfp)
1429 {
1430   struct config *nextcfp;
1431   for(; cfp; cfp=nextcfp){
1432     nextcfp = cfp->next;
1433     assert( cfp->fplp==0 );
1434     assert( cfp->bplp==0 );
1435     if( cfp->fws ) SetFree(cfp->fws);
1436     deleteconfig(cfp);
1437   }
1438   return;
1439 }
1440 /***************** From the file "error.c" *********************************/
1441 /*
1442 ** Code for printing error message.
1443 */
1444 
1445 void ErrorMsg(const char *filename, int lineno, const char *format, ...){
1446   va_list ap;
1447   fprintf(stderr, "%s:%d: ", filename, lineno);
1448   va_start(ap, format);
1449   vfprintf(stderr,format,ap);
1450   va_end(ap);
1451   fprintf(stderr, "\n");
1452 }
1453 /**************** From the file "main.c" ************************************/
1454 /*
1455 ** Main program file for the LEMON parser generator.
1456 */
1457 
1458 /* Report an out-of-memory condition and abort.  This function
1459 ** is used mostly by the "MemoryCheck" macro in struct.h
1460 */
1461 void memory_error(){
1462   fprintf(stderr,"Out of memory.  Aborting...\n");
1463   exit(1);
1464 }
1465 
1466 static int nDefine = 0;      /* Number of -D options on the command line */
1467 static char **azDefine = 0;  /* Name of the -D macros */
1468 
1469 /* This routine is called with the argument to each -D command-line option.
1470 ** Add the macro defined to the azDefine array.
1471 */
1472 static void handle_D_option(char *z){
1473   char **paz;
1474   nDefine++;
1475   azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine);
1476   if( azDefine==0 ){
1477     fprintf(stderr,"out of memory\n");
1478     exit(1);
1479   }
1480   paz = &azDefine[nDefine-1];
1481   *paz = (char *) malloc( lemonStrlen(z)+1 );
1482   if( *paz==0 ){
1483     fprintf(stderr,"out of memory\n");
1484     exit(1);
1485   }
1486   lemon_strcpy(*paz, z);
1487   for(z=*paz; *z && *z!='='; z++){}
1488   *z = 0;
1489 }
1490 
1491 static char *user_templatename = NULL;
1492 static void handle_T_option(char *z){
1493   user_templatename = (char *) malloc( lemonStrlen(z)+1 );
1494   if( user_templatename==0 ){
1495     memory_error();
1496   }
1497   lemon_strcpy(user_templatename, z);
1498 }
1499 
1500 /* forward reference */
1501 static const char *minimum_size_type(int lwr, int upr, int *pnByte);
1502 
1503 /* Print a single line of the "Parser Stats" output
1504 */
1505 static void stats_line(const char *zLabel, int iValue){
1506   int nLabel = lemonStrlen(zLabel);
1507   printf("  %s%.*s %5d\n", zLabel,
1508          35-nLabel, "................................",
1509          iValue);
1510 }
1511 
1512 /* The main program.  Parse the command line and do it... */
1513 int main(int argc, char **argv)
1514 {
1515   static int version = 0;
1516   static int rpflag = 0;
1517   static int basisflag = 0;
1518   static int compress = 0;
1519   static int quiet = 0;
1520   static int statistics = 0;
1521   static int mhflag = 0;
1522   static int nolinenosflag = 0;
1523   static int noResort = 0;
1524   static struct s_options options[] = {
1525     {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},
1526     {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},
1527     {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
1528     {OPT_FSTR, "f", 0, "Ignored.  (Placeholder for -f compiler options.)"},
1529     {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
1530     {OPT_FSTR, "I", 0, "Ignored.  (Placeholder for '-I' compiler options.)"},
1531     {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."},
1532     {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."},
1533     {OPT_FSTR, "O", 0, "Ignored.  (Placeholder for '-O' compiler options.)"},
1534     {OPT_FLAG, "p", (char*)&showPrecedenceConflict,
1535                     "Show conflicts resolved by precedence rules"},
1536     {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."},
1537     {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"},
1538     {OPT_FLAG, "s", (char*)&statistics,
1539                                    "Print parser stats to standard output."},
1540     {OPT_FLAG, "x", (char*)&version, "Print the version number."},
1541     {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
1542     {OPT_FSTR, "W", 0, "Ignored.  (Placeholder for '-W' compiler options.)"},
1543     {OPT_FLAG,0,0,0}
1544   };
1545   int i;
1546   int exitcode;
1547   struct lemon lem;
1548 
1549   OptInit(argv,options,stderr);
1550   if( version ){
1551      printf("Lemon version 1.0\n");
1552      exit(0);
1553   }
1554   if( OptNArgs()!=1 ){
1555     fprintf(stderr,"Exactly one filename argument is required.\n");
1556     exit(1);
1557   }
1558   memset(&lem, 0, sizeof(lem));
1559   lem.errorcnt = 0;
1560 
1561   /* Initialize the machine */
1562   Strsafe_init();
1563   Symbol_init();
1564   State_init();
1565   lem.argv0 = argv[0];
1566   lem.filename = OptArg(0);
1567   lem.basisflag = basisflag;
1568   lem.nolinenosflag = nolinenosflag;
1569   Symbol_new("$");
1570   lem.errsym = Symbol_new("error");
1571   lem.errsym->useCnt = 0;
1572 
1573   /* Parse the input file */
1574   Parse(&lem);
1575   if( lem.errorcnt ) exit(lem.errorcnt);
1576   if( lem.nrule==0 ){
1577     fprintf(stderr,"Empty grammar.\n");
1578     exit(1);
1579   }
1580 
1581   /* Count and index the symbols of the grammar */
1582   Symbol_new("{default}");
1583   lem.nsymbol = Symbol_count();
1584   lem.symbols = Symbol_arrayof();
1585   for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1586   qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp);
1587   for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1588   while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; }
1589   assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 );
1590   lem.nsymbol = i - 1;
1591   for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++);
1592   lem.nterminal = i;
1593 
1594   /* Generate a reprint of the grammar, if requested on the command line */
1595   if( rpflag ){
1596     Reprint(&lem);
1597   }else{
1598     /* Initialize the size for all follow and first sets */
1599     SetSize(lem.nterminal+1);
1600 
1601     /* Find the precedence for every production rule (that has one) */
1602     FindRulePrecedences(&lem);
1603 
1604     /* Compute the lambda-nonterminals and the first-sets for every
1605     ** nonterminal */
1606     FindFirstSets(&lem);
1607 
1608     /* Compute all LR(0) states.  Also record follow-set propagation
1609     ** links so that the follow-set can be computed later */
1610     lem.nstate = 0;
1611     FindStates(&lem);
1612     lem.sorted = State_arrayof();
1613 
1614     /* Tie up loose ends on the propagation links */
1615     FindLinks(&lem);
1616 
1617     /* Compute the follow set of every reducible configuration */
1618     FindFollowSets(&lem);
1619 
1620     /* Compute the action tables */
1621     FindActions(&lem);
1622 
1623     /* Compress the action tables */
1624     if( compress==0 ) CompressTables(&lem);
1625 
1626     /* Reorder and renumber the states so that states with fewer choices
1627     ** occur at the end.  This is an optimization that helps make the
1628     ** generated parser tables smaller. */
1629     if( noResort==0 ) ResortStates(&lem);
1630 
1631     /* Generate a report of the parser generated.  (the "y.output" file) */
1632     if( !quiet ) ReportOutput(&lem);
1633 
1634     /* Generate the source code for the parser */
1635     ReportTable(&lem, mhflag);
1636 
1637     /* Produce a header file for use by the scanner.  (This step is
1638     ** omitted if the "-m" option is used because makeheaders will
1639     ** generate the file for us.) */
1640     if( !mhflag ) ReportHeader(&lem);
1641   }
1642   if( statistics ){
1643     printf("Parser statistics:\n");
1644     stats_line("terminal symbols", lem.nterminal);
1645     stats_line("non-terminal symbols", lem.nsymbol - lem.nterminal);
1646     stats_line("total symbols", lem.nsymbol);
1647     stats_line("rules", lem.nrule);
1648     stats_line("states", lem.nxstate);
1649     stats_line("conflicts", lem.nconflict);
1650     stats_line("action table entries", lem.nactiontab);
1651     stats_line("total table size (bytes)", lem.tablesize);
1652   }
1653   if( lem.nconflict > 0 ){
1654     fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
1655   }
1656 
1657   /* return 0 on success, 1 on failure. */
1658   exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0;
1659   exit(exitcode);
1660   return (exitcode);
1661 }
1662 /******************** From the file "msort.c" *******************************/
1663 /*
1664 ** A generic merge-sort program.
1665 **
1666 ** USAGE:
1667 ** Let "ptr" be a pointer to some structure which is at the head of
1668 ** a null-terminated list.  Then to sort the list call:
1669 **
1670 **     ptr = msort(ptr,&(ptr->next),cmpfnc);
1671 **
1672 ** In the above, "cmpfnc" is a pointer to a function which compares
1673 ** two instances of the structure and returns an integer, as in
1674 ** strcmp.  The second argument is a pointer to the pointer to the
1675 ** second element of the linked list.  This address is used to compute
1676 ** the offset to the "next" field within the structure.  The offset to
1677 ** the "next" field must be constant for all structures in the list.
1678 **
1679 ** The function returns a new pointer which is the head of the list
1680 ** after sorting.
1681 **
1682 ** ALGORITHM:
1683 ** Merge-sort.
1684 */
1685 
1686 /*
1687 ** Return a pointer to the next structure in the linked list.
1688 */
1689 #define NEXT(A) (*(char**)(((char*)A)+offset))
1690 
1691 /*
1692 ** Inputs:
1693 **   a:       A sorted, null-terminated linked list.  (May be null).
1694 **   b:       A sorted, null-terminated linked list.  (May be null).
1695 **   cmp:     A pointer to the comparison function.
1696 **   offset:  Offset in the structure to the "next" field.
1697 **
1698 ** Return Value:
1699 **   A pointer to the head of a sorted list containing the elements
1700 **   of both a and b.
1701 **
1702 ** Side effects:
1703 **   The "next" pointers for elements in the lists a and b are
1704 **   changed.
1705 */
1706 static char *merge(
1707   char *a,
1708   char *b,
1709   int (*cmp)(const char*,const char*),
1710   int offset
1711 ){
1712   char *ptr, *head;
1713 
1714   if( a==0 ){
1715     head = b;
1716   }else if( b==0 ){
1717     head = a;
1718   }else{
1719     if( (*cmp)(a,b)<=0 ){
1720       ptr = a;
1721       a = NEXT(a);
1722     }else{
1723       ptr = b;
1724       b = NEXT(b);
1725     }
1726     head = ptr;
1727     while( a && b ){
1728       if( (*cmp)(a,b)<=0 ){
1729         NEXT(ptr) = a;
1730         ptr = a;
1731         a = NEXT(a);
1732       }else{
1733         NEXT(ptr) = b;
1734         ptr = b;
1735         b = NEXT(b);
1736       }
1737     }
1738     if( a ) NEXT(ptr) = a;
1739     else    NEXT(ptr) = b;
1740   }
1741   return head;
1742 }
1743 
1744 /*
1745 ** Inputs:
1746 **   list:      Pointer to a singly-linked list of structures.
1747 **   next:      Pointer to pointer to the second element of the list.
1748 **   cmp:       A comparison function.
1749 **
1750 ** Return Value:
1751 **   A pointer to the head of a sorted list containing the elements
1752 **   orginally in list.
1753 **
1754 ** Side effects:
1755 **   The "next" pointers for elements in list are changed.
1756 */
1757 #define LISTSIZE 30
1758 static char *msort(
1759   char *list,
1760   char **next,
1761   int (*cmp)(const char*,const char*)
1762 ){
1763   unsigned long offset;
1764   char *ep;
1765   char *set[LISTSIZE];
1766   int i;
1767   offset = (unsigned long)((char*)next - (char*)list);
1768   for(i=0; i<LISTSIZE; i++) set[i] = 0;
1769   while( list ){
1770     ep = list;
1771     list = NEXT(list);
1772     NEXT(ep) = 0;
1773     for(i=0; i<LISTSIZE-1 && set[i]!=0; i++){
1774       ep = merge(ep,set[i],cmp,offset);
1775       set[i] = 0;
1776     }
1777     set[i] = ep;
1778   }
1779   ep = 0;
1780   for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset);
1781   return ep;
1782 }
1783 /************************ From the file "option.c" **************************/
1784 static char **argv;
1785 static struct s_options *op;
1786 static FILE *errstream;
1787 
1788 #define ISOPT(X) ((X)[0]=='-'||(X)[0]=='+'||strchr((X),'=')!=0)
1789 
1790 /*
1791 ** Print the command line with a carrot pointing to the k-th character
1792 ** of the n-th field.
1793 */
1794 static void errline(int n, int k, FILE *err)
1795 {
1796   int spcnt, i;
1797   if( argv[0] ) fprintf(err,"%s",argv[0]);
1798   spcnt = lemonStrlen(argv[0]) + 1;
1799   for(i=1; i<n && argv[i]; i++){
1800     fprintf(err," %s",argv[i]);
1801     spcnt += lemonStrlen(argv[i])+1;
1802   }
1803   spcnt += k;
1804   for(; argv[i]; i++) fprintf(err," %s",argv[i]);
1805   if( spcnt<20 ){
1806     fprintf(err,"\n%*s^-- here\n",spcnt,"");
1807   }else{
1808     fprintf(err,"\n%*shere --^\n",spcnt-7,"");
1809   }
1810 }
1811 
1812 /*
1813 ** Return the index of the N-th non-switch argument.  Return -1
1814 ** if N is out of range.
1815 */
1816 static int argindex(int n)
1817 {
1818   int i;
1819   int dashdash = 0;
1820   if( argv!=0 && *argv!=0 ){
1821     for(i=1; argv[i]; i++){
1822       if( dashdash || !ISOPT(argv[i]) ){
1823         if( n==0 ) return i;
1824         n--;
1825       }
1826       if( strcmp(argv[i],"--")==0 ) dashdash = 1;
1827     }
1828   }
1829   return -1;
1830 }
1831 
1832 static char emsg[] = "Command line syntax error: ";
1833 
1834 /*
1835 ** Process a flag command line argument.
1836 */
1837 static int handleflags(int i, FILE *err)
1838 {
1839   int v;
1840   int errcnt = 0;
1841   int j;
1842   for(j=0; op[j].label; j++){
1843     if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break;
1844   }
1845   v = argv[i][0]=='-' ? 1 : 0;
1846   if( op[j].label==0 ){
1847     if( err ){
1848       fprintf(err,"%sundefined option.\n",emsg);
1849       errline(i,1,err);
1850     }
1851     errcnt++;
1852   }else if( op[j].arg==0 ){
1853     /* Ignore this option */
1854   }else if( op[j].type==OPT_FLAG ){
1855     *((int*)op[j].arg) = v;
1856   }else if( op[j].type==OPT_FFLAG ){
1857     (*(void(*)(int))(op[j].arg))(v);
1858   }else if( op[j].type==OPT_FSTR ){
1859     (*(void(*)(char *))(op[j].arg))(&argv[i][2]);
1860   }else{
1861     if( err ){
1862       fprintf(err,"%smissing argument on switch.\n",emsg);
1863       errline(i,1,err);
1864     }
1865     errcnt++;
1866   }
1867   return errcnt;
1868 }
1869 
1870 /*
1871 ** Process a command line switch which has an argument.
1872 */
1873 static int handleswitch(int i, FILE *err)
1874 {
1875   int lv = 0;
1876   double dv = 0.0;
1877   char *sv = 0, *end;
1878   char *cp;
1879   int j;
1880   int errcnt = 0;
1881   cp = strchr(argv[i],'=');
1882   assert( cp!=0 );
1883   *cp = 0;
1884   for(j=0; op[j].label; j++){
1885     if( strcmp(argv[i],op[j].label)==0 ) break;
1886   }
1887   *cp = '=';
1888   if( op[j].label==0 ){
1889     if( err ){
1890       fprintf(err,"%sundefined option.\n",emsg);
1891       errline(i,0,err);
1892     }
1893     errcnt++;
1894   }else{
1895     cp++;
1896     switch( op[j].type ){
1897       case OPT_FLAG:
1898       case OPT_FFLAG:
1899         if( err ){
1900           fprintf(err,"%soption requires an argument.\n",emsg);
1901           errline(i,0,err);
1902         }
1903         errcnt++;
1904         break;
1905       case OPT_DBL:
1906       case OPT_FDBL:
1907         dv = strtod(cp,&end);
1908         if( *end ){
1909           if( err ){
1910             fprintf(err,
1911                "%sillegal character in floating-point argument.\n",emsg);
1912             errline(i,(int)((char*)end-(char*)argv[i]),err);
1913           }
1914           errcnt++;
1915         }
1916         break;
1917       case OPT_INT:
1918       case OPT_FINT:
1919         lv = strtol(cp,&end,0);
1920         if( *end ){
1921           if( err ){
1922             fprintf(err,"%sillegal character in integer argument.\n",emsg);
1923             errline(i,(int)((char*)end-(char*)argv[i]),err);
1924           }
1925           errcnt++;
1926         }
1927         break;
1928       case OPT_STR:
1929       case OPT_FSTR:
1930         sv = cp;
1931         break;
1932     }
1933     switch( op[j].type ){
1934       case OPT_FLAG:
1935       case OPT_FFLAG:
1936         break;
1937       case OPT_DBL:
1938         *(double*)(op[j].arg) = dv;
1939         break;
1940       case OPT_FDBL:
1941         (*(void(*)(double))(op[j].arg))(dv);
1942         break;
1943       case OPT_INT:
1944         *(int*)(op[j].arg) = lv;
1945         break;
1946       case OPT_FINT:
1947         (*(void(*)(int))(op[j].arg))((int)lv);
1948         break;
1949       case OPT_STR:
1950         *(char**)(op[j].arg) = sv;
1951         break;
1952       case OPT_FSTR:
1953         (*(void(*)(char *))(op[j].arg))(sv);
1954         break;
1955     }
1956   }
1957   return errcnt;
1958 }
1959 
1960 int OptInit(char **a, struct s_options *o, FILE *err)
1961 {
1962   int errcnt = 0;
1963   argv = a;
1964   op = o;
1965   errstream = err;
1966   if( argv && *argv && op ){
1967     int i;
1968     for(i=1; argv[i]; i++){
1969       if( argv[i][0]=='+' || argv[i][0]=='-' ){
1970         errcnt += handleflags(i,err);
1971       }else if( strchr(argv[i],'=') ){
1972         errcnt += handleswitch(i,err);
1973       }
1974     }
1975   }
1976   if( errcnt>0 ){
1977     fprintf(err,"Valid command line options for \"%s\" are:\n",*a);
1978     OptPrint();
1979     exit(1);
1980   }
1981   return 0;
1982 }
1983 
1984 int OptNArgs(){
1985   int cnt = 0;
1986   int dashdash = 0;
1987   int i;
1988   if( argv!=0 && argv[0]!=0 ){
1989     for(i=1; argv[i]; i++){
1990       if( dashdash || !ISOPT(argv[i]) ) cnt++;
1991       if( strcmp(argv[i],"--")==0 ) dashdash = 1;
1992     }
1993   }
1994   return cnt;
1995 }
1996 
1997 char *OptArg(int n)
1998 {
1999   int i;
2000   i = argindex(n);
2001   return i>=0 ? argv[i] : 0;
2002 }
2003 
2004 void OptErr(int n)
2005 {
2006   int i;
2007   i = argindex(n);
2008   if( i>=0 ) errline(i,0,errstream);
2009 }
2010 
2011 void OptPrint(){
2012   int i;
2013   int max, len;
2014   max = 0;
2015   for(i=0; op[i].label; i++){
2016     len = lemonStrlen(op[i].label) + 1;
2017     switch( op[i].type ){
2018       case OPT_FLAG:
2019       case OPT_FFLAG:
2020         break;
2021       case OPT_INT:
2022       case OPT_FINT:
2023         len += 9;       /* length of "<integer>" */
2024         break;
2025       case OPT_DBL:
2026       case OPT_FDBL:
2027         len += 6;       /* length of "<real>" */
2028         break;
2029       case OPT_STR:
2030       case OPT_FSTR:
2031         len += 8;       /* length of "<string>" */
2032         break;
2033     }
2034     if( len>max ) max = len;
2035   }
2036   for(i=0; op[i].label; i++){
2037     switch( op[i].type ){
2038       case OPT_FLAG:
2039       case OPT_FFLAG:
2040         fprintf(errstream,"  -%-*s  %s\n",max,op[i].label,op[i].message);
2041         break;
2042       case OPT_INT:
2043       case OPT_FINT:
2044         fprintf(errstream,"  -%s<integer>%*s  %s\n",op[i].label,
2045           (int)(max-lemonStrlen(op[i].label)-9),"",op[i].message);
2046         break;
2047       case OPT_DBL:
2048       case OPT_FDBL:
2049         fprintf(errstream,"  -%s<real>%*s  %s\n",op[i].label,
2050           (int)(max-lemonStrlen(op[i].label)-6),"",op[i].message);
2051         break;
2052       case OPT_STR:
2053       case OPT_FSTR:
2054         fprintf(errstream,"  -%s<string>%*s  %s\n",op[i].label,
2055           (int)(max-lemonStrlen(op[i].label)-8),"",op[i].message);
2056         break;
2057     }
2058   }
2059 }
2060 /*********************** From the file "parse.c" ****************************/
2061 /*
2062 ** Input file parser for the LEMON parser generator.
2063 */
2064 
2065 /* The state of the parser */
2066 enum e_state {
2067   INITIALIZE,
2068   WAITING_FOR_DECL_OR_RULE,
2069   WAITING_FOR_DECL_KEYWORD,
2070   WAITING_FOR_DECL_ARG,
2071   WAITING_FOR_PRECEDENCE_SYMBOL,
2072   WAITING_FOR_ARROW,
2073   IN_RHS,
2074   LHS_ALIAS_1,
2075   LHS_ALIAS_2,
2076   LHS_ALIAS_3,
2077   RHS_ALIAS_1,
2078   RHS_ALIAS_2,
2079   PRECEDENCE_MARK_1,
2080   PRECEDENCE_MARK_2,
2081   RESYNC_AFTER_RULE_ERROR,
2082   RESYNC_AFTER_DECL_ERROR,
2083   WAITING_FOR_DESTRUCTOR_SYMBOL,
2084   WAITING_FOR_DATATYPE_SYMBOL,
2085   WAITING_FOR_FALLBACK_ID,
2086   WAITING_FOR_WILDCARD_ID,
2087   WAITING_FOR_CLASS_ID,
2088   WAITING_FOR_CLASS_TOKEN
2089 };
2090 struct pstate {
2091   char *filename;       /* Name of the input file */
2092   int tokenlineno;      /* Linenumber at which current token starts */
2093   int errorcnt;         /* Number of errors so far */
2094   char *tokenstart;     /* Text of current token */
2095   struct lemon *gp;     /* Global state vector */
2096   enum e_state state;        /* The state of the parser */
2097   struct symbol *fallback;   /* The fallback token */
2098   struct symbol *tkclass;    /* Token class symbol */
2099   struct symbol *lhs;        /* Left-hand side of current rule */
2100   const char *lhsalias;      /* Alias for the LHS */
2101   int nrhs;                  /* Number of right-hand side symbols seen */
2102   struct symbol *rhs[MAXRHS];  /* RHS symbols */
2103   const char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */
2104   struct rule *prevrule;     /* Previous rule parsed */
2105   const char *declkeyword;   /* Keyword of a declaration */
2106   char **declargslot;        /* Where the declaration argument should be put */
2107   int insertLineMacro;       /* Add #line before declaration insert */
2108   int *decllinenoslot;       /* Where to write declaration line number */
2109   enum e_assoc declassoc;    /* Assign this association to decl arguments */
2110   int preccounter;           /* Assign this precedence to decl arguments */
2111   struct rule *firstrule;    /* Pointer to first rule in the grammar */
2112   struct rule *lastrule;     /* Pointer to the most recently parsed rule */
2113 };
2114 
2115 /* Parse a single token */
2116 static void parseonetoken(struct pstate *psp)
2117 {
2118   const char *x;
2119   x = Strsafe(psp->tokenstart);     /* Save the token permanently */
2120 #if 0
2121   printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno,
2122     x,psp->state);
2123 #endif
2124   switch( psp->state ){
2125     case INITIALIZE:
2126       psp->prevrule = 0;
2127       psp->preccounter = 0;
2128       psp->firstrule = psp->lastrule = 0;
2129       psp->gp->nrule = 0;
2130       /* Fall thru to next case */
2131     case WAITING_FOR_DECL_OR_RULE:
2132       if( x[0]=='%' ){
2133         psp->state = WAITING_FOR_DECL_KEYWORD;
2134       }else if( ISLOWER(x[0]) ){
2135         psp->lhs = Symbol_new(x);
2136         psp->nrhs = 0;
2137         psp->lhsalias = 0;
2138         psp->state = WAITING_FOR_ARROW;
2139       }else if( x[0]=='{' ){
2140         if( psp->prevrule==0 ){
2141           ErrorMsg(psp->filename,psp->tokenlineno,
2142 "There is no prior rule upon which to attach the code \
2143 fragment which begins on this line.");
2144           psp->errorcnt++;
2145         }else if( psp->prevrule->code!=0 ){
2146           ErrorMsg(psp->filename,psp->tokenlineno,
2147 "Code fragment beginning on this line is not the first \
2148 to follow the previous rule.");
2149           psp->errorcnt++;
2150         }else{
2151           psp->prevrule->line = psp->tokenlineno;
2152           psp->prevrule->code = &x[1];
2153         }
2154       }else if( x[0]=='[' ){
2155         psp->state = PRECEDENCE_MARK_1;
2156       }else{
2157         ErrorMsg(psp->filename,psp->tokenlineno,
2158           "Token \"%s\" should be either \"%%\" or a nonterminal name.",
2159           x);
2160         psp->errorcnt++;
2161       }
2162       break;
2163     case PRECEDENCE_MARK_1:
2164       if( !ISUPPER(x[0]) ){
2165         ErrorMsg(psp->filename,psp->tokenlineno,
2166           "The precedence symbol must be a terminal.");
2167         psp->errorcnt++;
2168       }else if( psp->prevrule==0 ){
2169         ErrorMsg(psp->filename,psp->tokenlineno,
2170           "There is no prior rule to assign precedence \"[%s]\".",x);
2171         psp->errorcnt++;
2172       }else if( psp->prevrule->precsym!=0 ){
2173         ErrorMsg(psp->filename,psp->tokenlineno,
2174 "Precedence mark on this line is not the first \
2175 to follow the previous rule.");
2176         psp->errorcnt++;
2177       }else{
2178         psp->prevrule->precsym = Symbol_new(x);
2179       }
2180       psp->state = PRECEDENCE_MARK_2;
2181       break;
2182     case PRECEDENCE_MARK_2:
2183       if( x[0]!=']' ){
2184         ErrorMsg(psp->filename,psp->tokenlineno,
2185           "Missing \"]\" on precedence mark.");
2186         psp->errorcnt++;
2187       }
2188       psp->state = WAITING_FOR_DECL_OR_RULE;
2189       break;
2190     case WAITING_FOR_ARROW:
2191       if( x[0]==':' && x[1]==':' && x[2]=='=' ){
2192         psp->state = IN_RHS;
2193       }else if( x[0]=='(' ){
2194         psp->state = LHS_ALIAS_1;
2195       }else{
2196         ErrorMsg(psp->filename,psp->tokenlineno,
2197           "Expected to see a \":\" following the LHS symbol \"%s\".",
2198           psp->lhs->name);
2199         psp->errorcnt++;
2200         psp->state = RESYNC_AFTER_RULE_ERROR;
2201       }
2202       break;
2203     case LHS_ALIAS_1:
2204       if( ISALPHA(x[0]) ){
2205         psp->lhsalias = x;
2206         psp->state = LHS_ALIAS_2;
2207       }else{
2208         ErrorMsg(psp->filename,psp->tokenlineno,
2209           "\"%s\" is not a valid alias for the LHS \"%s\"\n",
2210           x,psp->lhs->name);
2211         psp->errorcnt++;
2212         psp->state = RESYNC_AFTER_RULE_ERROR;
2213       }
2214       break;
2215     case LHS_ALIAS_2:
2216       if( x[0]==')' ){
2217         psp->state = LHS_ALIAS_3;
2218       }else{
2219         ErrorMsg(psp->filename,psp->tokenlineno,
2220           "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias);
2221         psp->errorcnt++;
2222         psp->state = RESYNC_AFTER_RULE_ERROR;
2223       }
2224       break;
2225     case LHS_ALIAS_3:
2226       if( x[0]==':' && x[1]==':' && x[2]=='=' ){
2227         psp->state = IN_RHS;
2228       }else{
2229         ErrorMsg(psp->filename,psp->tokenlineno,
2230           "Missing \"->\" following: \"%s(%s)\".",
2231            psp->lhs->name,psp->lhsalias);
2232         psp->errorcnt++;
2233         psp->state = RESYNC_AFTER_RULE_ERROR;
2234       }
2235       break;
2236     case IN_RHS:
2237       if( x[0]=='.' ){
2238         struct rule *rp;
2239         rp = (struct rule *)calloc( sizeof(struct rule) +
2240              sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1);
2241         if( rp==0 ){
2242           ErrorMsg(psp->filename,psp->tokenlineno,
2243             "Can't allocate enough memory for this rule.");
2244           psp->errorcnt++;
2245           psp->prevrule = 0;
2246         }else{
2247           int i;
2248           rp->ruleline = psp->tokenlineno;
2249           rp->rhs = (struct symbol**)&rp[1];
2250           rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
2251           for(i=0; i<psp->nrhs; i++){
2252             rp->rhs[i] = psp->rhs[i];
2253             rp->rhsalias[i] = psp->alias[i];
2254           }
2255           rp->lhs = psp->lhs;
2256           rp->lhsalias = psp->lhsalias;
2257           rp->nrhs = psp->nrhs;
2258           rp->code = 0;
2259           rp->precsym = 0;
2260           rp->index = psp->gp->nrule++;
2261           rp->nextlhs = rp->lhs->rule;
2262           rp->lhs->rule = rp;
2263           rp->next = 0;
2264           if( psp->firstrule==0 ){
2265             psp->firstrule = psp->lastrule = rp;
2266           }else{
2267             psp->lastrule->next = rp;
2268             psp->lastrule = rp;
2269           }
2270           psp->prevrule = rp;
2271         }
2272         psp->state = WAITING_FOR_DECL_OR_RULE;
2273       }else if( ISALPHA(x[0]) ){
2274         if( psp->nrhs>=MAXRHS ){
2275           ErrorMsg(psp->filename,psp->tokenlineno,
2276             "Too many symbols on RHS of rule beginning at \"%s\".",
2277             x);
2278           psp->errorcnt++;
2279           psp->state = RESYNC_AFTER_RULE_ERROR;
2280         }else{
2281           psp->rhs[psp->nrhs] = Symbol_new(x);
2282           psp->alias[psp->nrhs] = 0;
2283           psp->nrhs++;
2284         }
2285       }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){
2286         struct symbol *msp = psp->rhs[psp->nrhs-1];
2287         if( msp->type!=MULTITERMINAL ){
2288           struct symbol *origsp = msp;
2289           msp = (struct symbol *) calloc(1,sizeof(*msp));
2290           memset(msp, 0, sizeof(*msp));
2291           msp->type = MULTITERMINAL;
2292           msp->nsubsym = 1;
2293           msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*));
2294           msp->subsym[0] = origsp;
2295           msp->name = origsp->name;
2296           psp->rhs[psp->nrhs-1] = msp;
2297         }
2298         msp->nsubsym++;
2299         msp->subsym = (struct symbol **) realloc(msp->subsym,
2300           sizeof(struct symbol*)*msp->nsubsym);
2301         msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]);
2302         if( ISLOWER(x[1]) || ISLOWER(msp->subsym[0]->name[0]) ){
2303           ErrorMsg(psp->filename,psp->tokenlineno,
2304             "Cannot form a compound containing a non-terminal");
2305           psp->errorcnt++;
2306         }
2307       }else if( x[0]=='(' && psp->nrhs>0 ){
2308         psp->state = RHS_ALIAS_1;
2309       }else{
2310         ErrorMsg(psp->filename,psp->tokenlineno,
2311           "Illegal character on RHS of rule: \"%s\".",x);
2312         psp->errorcnt++;
2313         psp->state = RESYNC_AFTER_RULE_ERROR;
2314       }
2315       break;
2316     case RHS_ALIAS_1:
2317       if( ISALPHA(x[0]) ){
2318         psp->alias[psp->nrhs-1] = x;
2319         psp->state = RHS_ALIAS_2;
2320       }else{
2321         ErrorMsg(psp->filename,psp->tokenlineno,
2322           "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n",
2323           x,psp->rhs[psp->nrhs-1]->name);
2324         psp->errorcnt++;
2325         psp->state = RESYNC_AFTER_RULE_ERROR;
2326       }
2327       break;
2328     case RHS_ALIAS_2:
2329       if( x[0]==')' ){
2330         psp->state = IN_RHS;
2331       }else{
2332         ErrorMsg(psp->filename,psp->tokenlineno,
2333           "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias);
2334         psp->errorcnt++;
2335         psp->state = RESYNC_AFTER_RULE_ERROR;
2336       }
2337       break;
2338     case WAITING_FOR_DECL_KEYWORD:
2339       if( ISALPHA(x[0]) ){
2340         psp->declkeyword = x;
2341         psp->declargslot = 0;
2342         psp->decllinenoslot = 0;
2343         psp->insertLineMacro = 1;
2344         psp->state = WAITING_FOR_DECL_ARG;
2345         if( strcmp(x,"name")==0 ){
2346           psp->declargslot = &(psp->gp->name);
2347           psp->insertLineMacro = 0;
2348         }else if( strcmp(x,"include")==0 ){
2349           psp->declargslot = &(psp->gp->include);
2350         }else if( strcmp(x,"code")==0 ){
2351           psp->declargslot = &(psp->gp->extracode);
2352         }else if( strcmp(x,"token_destructor")==0 ){
2353           psp->declargslot = &psp->gp->tokendest;
2354         }else if( strcmp(x,"default_destructor")==0 ){
2355           psp->declargslot = &psp->gp->vardest;
2356         }else if( strcmp(x,"token_prefix")==0 ){
2357           psp->declargslot = &psp->gp->tokenprefix;
2358           psp->insertLineMacro = 0;
2359         }else if( strcmp(x,"syntax_error")==0 ){
2360           psp->declargslot = &(psp->gp->error);
2361         }else if( strcmp(x,"parse_accept")==0 ){
2362           psp->declargslot = &(psp->gp->accept);
2363         }else if( strcmp(x,"parse_failure")==0 ){
2364           psp->declargslot = &(psp->gp->failure);
2365         }else if( strcmp(x,"stack_overflow")==0 ){
2366           psp->declargslot = &(psp->gp->overflow);
2367         }else if( strcmp(x,"extra_argument")==0 ){
2368           psp->declargslot = &(psp->gp->arg);
2369           psp->insertLineMacro = 0;
2370         }else if( strcmp(x,"token_type")==0 ){
2371           psp->declargslot = &(psp->gp->tokentype);
2372           psp->insertLineMacro = 0;
2373         }else if( strcmp(x,"default_type")==0 ){
2374           psp->declargslot = &(psp->gp->vartype);
2375           psp->insertLineMacro = 0;
2376         }else if( strcmp(x,"stack_size")==0 ){
2377           psp->declargslot = &(psp->gp->stacksize);
2378           psp->insertLineMacro = 0;
2379         }else if( strcmp(x,"start_symbol")==0 ){
2380           psp->declargslot = &(psp->gp->start);
2381           psp->insertLineMacro = 0;
2382         }else if( strcmp(x,"left")==0 ){
2383           psp->preccounter++;
2384           psp->declassoc = LEFT;
2385           psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
2386         }else if( strcmp(x,"right")==0 ){
2387           psp->preccounter++;
2388           psp->declassoc = RIGHT;
2389           psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
2390         }else if( strcmp(x,"nonassoc")==0 ){
2391           psp->preccounter++;
2392           psp->declassoc = NONE;
2393           psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
2394         }else if( strcmp(x,"destructor")==0 ){
2395           psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL;
2396         }else if( strcmp(x,"type")==0 ){
2397           psp->state = WAITING_FOR_DATATYPE_SYMBOL;
2398         }else if( strcmp(x,"fallback")==0 ){
2399           psp->fallback = 0;
2400           psp->state = WAITING_FOR_FALLBACK_ID;
2401         }else if( strcmp(x,"wildcard")==0 ){
2402           psp->state = WAITING_FOR_WILDCARD_ID;
2403         }else if( strcmp(x,"token_class")==0 ){
2404           psp->state = WAITING_FOR_CLASS_ID;
2405         }else{
2406           ErrorMsg(psp->filename,psp->tokenlineno,
2407             "Unknown declaration keyword: \"%%%s\".",x);
2408           psp->errorcnt++;
2409           psp->state = RESYNC_AFTER_DECL_ERROR;
2410         }
2411       }else{
2412         ErrorMsg(psp->filename,psp->tokenlineno,
2413           "Illegal declaration keyword: \"%s\".",x);
2414         psp->errorcnt++;
2415         psp->state = RESYNC_AFTER_DECL_ERROR;
2416       }
2417       break;
2418     case WAITING_FOR_DESTRUCTOR_SYMBOL:
2419       if( !ISALPHA(x[0]) ){
2420         ErrorMsg(psp->filename,psp->tokenlineno,
2421           "Symbol name missing after %%destructor keyword");
2422         psp->errorcnt++;
2423         psp->state = RESYNC_AFTER_DECL_ERROR;
2424       }else{
2425         struct symbol *sp = Symbol_new(x);
2426         psp->declargslot = &sp->destructor;
2427         psp->decllinenoslot = &sp->destLineno;
2428         psp->insertLineMacro = 1;
2429         psp->state = WAITING_FOR_DECL_ARG;
2430       }
2431       break;
2432     case WAITING_FOR_DATATYPE_SYMBOL:
2433       if( !ISALPHA(x[0]) ){
2434         ErrorMsg(psp->filename,psp->tokenlineno,
2435           "Symbol name missing after %%type keyword");
2436         psp->errorcnt++;
2437         psp->state = RESYNC_AFTER_DECL_ERROR;
2438       }else{
2439         struct symbol *sp = Symbol_find(x);
2440         if((sp) && (sp->datatype)){
2441           ErrorMsg(psp->filename,psp->tokenlineno,
2442             "Symbol %%type \"%s\" already defined", x);
2443           psp->errorcnt++;
2444           psp->state = RESYNC_AFTER_DECL_ERROR;
2445         }else{
2446           if (!sp){
2447             sp = Symbol_new(x);
2448           }
2449           psp->declargslot = &sp->datatype;
2450           psp->insertLineMacro = 0;
2451           psp->state = WAITING_FOR_DECL_ARG;
2452         }
2453       }
2454       break;
2455     case WAITING_FOR_PRECEDENCE_SYMBOL:
2456       if( x[0]=='.' ){
2457         psp->state = WAITING_FOR_DECL_OR_RULE;
2458       }else if( ISUPPER(x[0]) ){
2459         struct symbol *sp;
2460         sp = Symbol_new(x);
2461         if( sp->prec>=0 ){
2462           ErrorMsg(psp->filename,psp->tokenlineno,
2463             "Symbol \"%s\" has already be given a precedence.",x);
2464           psp->errorcnt++;
2465         }else{
2466           sp->prec = psp->preccounter;
2467           sp->assoc = psp->declassoc;
2468         }
2469       }else{
2470         ErrorMsg(psp->filename,psp->tokenlineno,
2471           "Can't assign a precedence to \"%s\".",x);
2472         psp->errorcnt++;
2473       }
2474       break;
2475     case WAITING_FOR_DECL_ARG:
2476       if( x[0]=='{' || x[0]=='\"' || ISALNUM(x[0]) ){
2477         const char *zOld, *zNew;
2478         char *zBuf, *z;
2479         int nOld, n, nLine = 0, nNew, nBack;
2480         int addLineMacro;
2481         char zLine[50];
2482         zNew = x;
2483         if( zNew[0]=='"' || zNew[0]=='{' ) zNew++;
2484         nNew = lemonStrlen(zNew);
2485         if( *psp->declargslot ){
2486           zOld = *psp->declargslot;
2487         }else{
2488           zOld = "";
2489         }
2490         nOld = lemonStrlen(zOld);
2491         n = nOld + nNew + 20;
2492         addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro &&
2493                         (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0);
2494         if( addLineMacro ){
2495           for(z=psp->filename, nBack=0; *z; z++){
2496             if( *z=='\\' ) nBack++;
2497           }
2498           lemon_sprintf(zLine, "#line %d ", psp->tokenlineno);
2499           nLine = lemonStrlen(zLine);
2500           n += nLine + lemonStrlen(psp->filename) + nBack;
2501         }
2502         *psp->declargslot = (char *) realloc(*psp->declargslot, n);
2503         zBuf = *psp->declargslot + nOld;
2504         if( addLineMacro ){
2505           if( nOld && zBuf[-1]!='\n' ){
2506             *(zBuf++) = '\n';
2507           }
2508           memcpy(zBuf, zLine, nLine);
2509           zBuf += nLine;
2510           *(zBuf++) = '"';
2511           for(z=psp->filename; *z; z++){
2512             if( *z=='\\' ){
2513               *(zBuf++) = '\\';
2514             }
2515             *(zBuf++) = *z;
2516           }
2517           *(zBuf++) = '"';
2518           *(zBuf++) = '\n';
2519         }
2520         if( psp->decllinenoslot && psp->decllinenoslot[0]==0 ){
2521           psp->decllinenoslot[0] = psp->tokenlineno;
2522         }
2523         memcpy(zBuf, zNew, nNew);
2524         zBuf += nNew;
2525         *zBuf = 0;
2526         psp->state = WAITING_FOR_DECL_OR_RULE;
2527       }else{
2528         ErrorMsg(psp->filename,psp->tokenlineno,
2529           "Illegal argument to %%%s: %s",psp->declkeyword,x);
2530         psp->errorcnt++;
2531         psp->state = RESYNC_AFTER_DECL_ERROR;
2532       }
2533       break;
2534     case WAITING_FOR_FALLBACK_ID:
2535       if( x[0]=='.' ){
2536         psp->state = WAITING_FOR_DECL_OR_RULE;
2537       }else if( !ISUPPER(x[0]) ){
2538         ErrorMsg(psp->filename, psp->tokenlineno,
2539           "%%fallback argument \"%s\" should be a token", x);
2540         psp->errorcnt++;
2541       }else{
2542         struct symbol *sp = Symbol_new(x);
2543         if( psp->fallback==0 ){
2544           psp->fallback = sp;
2545         }else if( sp->fallback ){
2546           ErrorMsg(psp->filename, psp->tokenlineno,
2547             "More than one fallback assigned to token %s", x);
2548           psp->errorcnt++;
2549         }else{
2550           sp->fallback = psp->fallback;
2551           psp->gp->has_fallback = 1;
2552         }
2553       }
2554       break;
2555     case WAITING_FOR_WILDCARD_ID:
2556       if( x[0]=='.' ){
2557         psp->state = WAITING_FOR_DECL_OR_RULE;
2558       }else if( !ISUPPER(x[0]) ){
2559         ErrorMsg(psp->filename, psp->tokenlineno,
2560           "%%wildcard argument \"%s\" should be a token", x);
2561         psp->errorcnt++;
2562       }else{
2563         struct symbol *sp = Symbol_new(x);
2564         if( psp->gp->wildcard==0 ){
2565           psp->gp->wildcard = sp;
2566         }else{
2567           ErrorMsg(psp->filename, psp->tokenlineno,
2568             "Extra wildcard to token: %s", x);
2569           psp->errorcnt++;
2570         }
2571       }
2572       break;
2573     case WAITING_FOR_CLASS_ID:
2574       if( !ISLOWER(x[0]) ){
2575         ErrorMsg(psp->filename, psp->tokenlineno,
2576           "%%token_class must be followed by an identifier: ", x);
2577         psp->errorcnt++;
2578         psp->state = RESYNC_AFTER_DECL_ERROR;
2579      }else if( Symbol_find(x) ){
2580         ErrorMsg(psp->filename, psp->tokenlineno,
2581           "Symbol \"%s\" already used", x);
2582         psp->errorcnt++;
2583         psp->state = RESYNC_AFTER_DECL_ERROR;
2584       }else{
2585         psp->tkclass = Symbol_new(x);
2586         psp->tkclass->type = MULTITERMINAL;
2587         psp->state = WAITING_FOR_CLASS_TOKEN;
2588       }
2589       break;
2590     case WAITING_FOR_CLASS_TOKEN:
2591       if( x[0]=='.' ){
2592         psp->state = WAITING_FOR_DECL_OR_RULE;
2593       }else if( ISUPPER(x[0]) || ((x[0]=='|' || x[0]=='/') && ISUPPER(x[1])) ){
2594         struct symbol *msp = psp->tkclass;
2595         msp->nsubsym++;
2596         msp->subsym = (struct symbol **) realloc(msp->subsym,
2597           sizeof(struct symbol*)*msp->nsubsym);
2598         if( !ISUPPER(x[0]) ) x++;
2599         msp->subsym[msp->nsubsym-1] = Symbol_new(x);
2600       }else{
2601         ErrorMsg(psp->filename, psp->tokenlineno,
2602           "%%token_class argument \"%s\" should be a token", x);
2603         psp->errorcnt++;
2604         psp->state = RESYNC_AFTER_DECL_ERROR;
2605       }
2606       break;
2607     case RESYNC_AFTER_RULE_ERROR:
2608 /*      if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
2609 **      break; */
2610     case RESYNC_AFTER_DECL_ERROR:
2611       if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
2612       if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD;
2613       break;
2614   }
2615 }
2616 
2617 /* Run the preprocessor over the input file text.  The global variables
2618 ** azDefine[0] through azDefine[nDefine-1] contains the names of all defined
2619 ** macros.  This routine looks for "%ifdef" and "%ifndef" and "%endif" and
2620 ** comments them out.  Text in between is also commented out as appropriate.
2621 */
2622 static void preprocess_input(char *z){
2623   int i, j, k, n;
2624   int exclude = 0;
2625   int start = 0;
2626   int lineno = 1;
2627   int start_lineno = 1;
2628   for(i=0; z[i]; i++){
2629     if( z[i]=='\n' ) lineno++;
2630     if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue;
2631     if( strncmp(&z[i],"%endif",6)==0 && ISSPACE(z[i+6]) ){
2632       if( exclude ){
2633         exclude--;
2634         if( exclude==0 ){
2635           for(j=start; j<i; j++) if( z[j]!='\n' ) z[j] = ' ';
2636         }
2637       }
2638       for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' ';
2639     }else if( (strncmp(&z[i],"%ifdef",6)==0 && ISSPACE(z[i+6]))
2640           || (strncmp(&z[i],"%ifndef",7)==0 && ISSPACE(z[i+7])) ){
2641       if( exclude ){
2642         exclude++;
2643       }else{
2644         for(j=i+7; ISSPACE(z[j]); j++){}
2645         for(n=0; z[j+n] && !ISSPACE(z[j+n]); n++){}
2646         exclude = 1;
2647         for(k=0; k<nDefine; k++){
2648           if( strncmp(azDefine[k],&z[j],n)==0 && lemonStrlen(azDefine[k])==n ){
2649             exclude = 0;
2650             break;
2651           }
2652         }
2653         if( z[i+3]=='n' ) exclude = !exclude;
2654         if( exclude ){
2655           start = i;
2656           start_lineno = lineno;
2657         }
2658       }
2659       for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' ';
2660     }
2661   }
2662   if( exclude ){
2663     fprintf(stderr,"unterminated %%ifdef starting on line %d\n", start_lineno);
2664     exit(1);
2665   }
2666 }
2667 
2668 /* In spite of its name, this function is really a scanner.  It read
2669 ** in the entire input file (all at once) then tokenizes it.  Each
2670 ** token is passed to the function "parseonetoken" which builds all
2671 ** the appropriate data structures in the global state vector "gp".
2672 */
2673 void Parse(struct lemon *gp)
2674 {
2675   struct pstate ps;
2676   FILE *fp;
2677   char *filebuf;
2678   unsigned int filesize;
2679   int lineno;
2680   int c;
2681   char *cp, *nextcp;
2682   int startline = 0;
2683 
2684   memset(&ps, '\0', sizeof(ps));
2685   ps.gp = gp;
2686   ps.filename = gp->filename;
2687   ps.errorcnt = 0;
2688   ps.state = INITIALIZE;
2689 
2690   /* Begin by reading the input file */
2691   fp = fopen(ps.filename,"rb");
2692   if( fp==0 ){
2693     ErrorMsg(ps.filename,0,"Can't open this file for reading.");
2694     gp->errorcnt++;
2695     return;
2696   }
2697   fseek(fp,0,2);
2698   filesize = ftell(fp);
2699   rewind(fp);
2700   filebuf = (char *)malloc( filesize+1 );
2701   if( filesize>100000000 || filebuf==0 ){
2702     ErrorMsg(ps.filename,0,"Input file too large.");
2703     gp->errorcnt++;
2704     fclose(fp);
2705     return;
2706   }
2707   if( fread(filebuf,1,filesize,fp)!=filesize ){
2708     ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.",
2709       filesize);
2710     free(filebuf);
2711     gp->errorcnt++;
2712     fclose(fp);
2713     return;
2714   }
2715   fclose(fp);
2716   filebuf[filesize] = 0;
2717 
2718   /* Make an initial pass through the file to handle %ifdef and %ifndef */
2719   preprocess_input(filebuf);
2720 
2721   /* Now scan the text of the input file */
2722   lineno = 1;
2723   for(cp=filebuf; (c= *cp)!=0; ){
2724     if( c=='\n' ) lineno++;              /* Keep track of the line number */
2725     if( ISSPACE(c) ){ cp++; continue; }  /* Skip all white space */
2726     if( c=='/' && cp[1]=='/' ){          /* Skip C++ style comments */
2727       cp+=2;
2728       while( (c= *cp)!=0 && c!='\n' ) cp++;
2729       continue;
2730     }
2731     if( c=='/' && cp[1]=='*' ){          /* Skip C style comments */
2732       cp+=2;
2733       while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){
2734         if( c=='\n' ) lineno++;
2735         cp++;
2736       }
2737       if( c ) cp++;
2738       continue;
2739     }
2740     ps.tokenstart = cp;                /* Mark the beginning of the token */
2741     ps.tokenlineno = lineno;           /* Linenumber on which token begins */
2742     if( c=='\"' ){                     /* String literals */
2743       cp++;
2744       while( (c= *cp)!=0 && c!='\"' ){
2745         if( c=='\n' ) lineno++;
2746         cp++;
2747       }
2748       if( c==0 ){
2749         ErrorMsg(ps.filename,startline,
2750 "String starting on this line is not terminated before the end of the file.");
2751         ps.errorcnt++;
2752         nextcp = cp;
2753       }else{
2754         nextcp = cp+1;
2755       }
2756     }else if( c=='{' ){               /* A block of C code */
2757       int level;
2758       cp++;
2759       for(level=1; (c= *cp)!=0 && (level>1 || c!='}'); cp++){
2760         if( c=='\n' ) lineno++;
2761         else if( c=='{' ) level++;
2762         else if( c=='}' ) level--;
2763         else if( c=='/' && cp[1]=='*' ){  /* Skip comments */
2764           int prevc;
2765           cp = &cp[2];
2766           prevc = 0;
2767           while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){
2768             if( c=='\n' ) lineno++;
2769             prevc = c;
2770             cp++;
2771           }
2772         }else if( c=='/' && cp[1]=='/' ){  /* Skip C++ style comments too */
2773           cp = &cp[2];
2774           while( (c= *cp)!=0 && c!='\n' ) cp++;
2775           if( c ) lineno++;
2776         }else if( c=='\'' || c=='\"' ){    /* String a character literals */
2777           int startchar, prevc;
2778           startchar = c;
2779           prevc = 0;
2780           for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){
2781             if( c=='\n' ) lineno++;
2782             if( prevc=='\\' ) prevc = 0;
2783             else              prevc = c;
2784           }
2785         }
2786       }
2787       if( c==0 ){
2788         ErrorMsg(ps.filename,ps.tokenlineno,
2789 "C code starting on this line is not terminated before the end of the file.");
2790         ps.errorcnt++;
2791         nextcp = cp;
2792       }else{
2793         nextcp = cp+1;
2794       }
2795     }else if( ISALNUM(c) ){          /* Identifiers */
2796       while( (c= *cp)!=0 && (ISALNUM(c) || c=='_') ) cp++;
2797       nextcp = cp;
2798     }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */
2799       cp += 3;
2800       nextcp = cp;
2801     }else if( (c=='/' || c=='|') && ISALPHA(cp[1]) ){
2802       cp += 2;
2803       while( (c = *cp)!=0 && (ISALNUM(c) || c=='_') ) cp++;
2804       nextcp = cp;
2805     }else{                          /* All other (one character) operators */
2806       cp++;
2807       nextcp = cp;
2808     }
2809     c = *cp;
2810     *cp = 0;                        /* Null terminate the token */
2811     parseonetoken(&ps);             /* Parse the token */
2812     *cp = (char)c;                  /* Restore the buffer */
2813     cp = nextcp;
2814   }
2815   free(filebuf);                    /* Release the buffer after parsing */
2816   gp->rule = ps.firstrule;
2817   gp->errorcnt = ps.errorcnt;
2818 }
2819 /*************************** From the file "plink.c" *********************/
2820 /*
2821 ** Routines processing configuration follow-set propagation links
2822 ** in the LEMON parser generator.
2823 */
2824 static struct plink *plink_freelist = 0;
2825 
2826 /* Allocate a new plink */
2827 struct plink *Plink_new(){
2828   struct plink *newlink;
2829 
2830   if( plink_freelist==0 ){
2831     int i;
2832     int amt = 100;
2833     plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) );
2834     if( plink_freelist==0 ){
2835       fprintf(stderr,
2836       "Unable to allocate memory for a new follow-set propagation link.\n");
2837       exit(1);
2838     }
2839     for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1];
2840     plink_freelist[amt-1].next = 0;
2841   }
2842   newlink = plink_freelist;
2843   plink_freelist = plink_freelist->next;
2844   return newlink;
2845 }
2846 
2847 /* Add a plink to a plink list */
2848 void Plink_add(struct plink **plpp, struct config *cfp)
2849 {
2850   struct plink *newlink;
2851   newlink = Plink_new();
2852   newlink->next = *plpp;
2853   *plpp = newlink;
2854   newlink->cfp = cfp;
2855 }
2856 
2857 /* Transfer every plink on the list "from" to the list "to" */
2858 void Plink_copy(struct plink **to, struct plink *from)
2859 {
2860   struct plink *nextpl;
2861   while( from ){
2862     nextpl = from->next;
2863     from->next = *to;
2864     *to = from;
2865     from = nextpl;
2866   }
2867 }
2868 
2869 /* Delete every plink on the list */
2870 void Plink_delete(struct plink *plp)
2871 {
2872   struct plink *nextpl;
2873 
2874   while( plp ){
2875     nextpl = plp->next;
2876     plp->next = plink_freelist;
2877     plink_freelist = plp;
2878     plp = nextpl;
2879   }
2880 }
2881 /*********************** From the file "report.c" **************************/
2882 /*
2883 ** Procedures for generating reports and tables in the LEMON parser generator.
2884 */
2885 
2886 /* Generate a filename with the given suffix.  Space to hold the
2887 ** name comes from malloc() and must be freed by the calling
2888 ** function.
2889 */
2890 PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
2891 {
2892   char *name;
2893   char *cp;
2894 
2895   name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 );
2896   if( name==0 ){
2897     fprintf(stderr,"Can't allocate space for a filename.\n");
2898     exit(1);
2899   }
2900   lemon_strcpy(name,lemp->filename);
2901   cp = strrchr(name,'.');
2902   if( cp ) *cp = 0;
2903   lemon_strcat(name,suffix);
2904   return name;
2905 }
2906 
2907 /* Open a file with a name based on the name of the input file,
2908 ** but with a different (specified) suffix, and return a pointer
2909 ** to the stream */
2910 PRIVATE FILE *file_open(
2911   struct lemon *lemp,
2912   const char *suffix,
2913   const char *mode
2914 ){
2915   FILE *fp;
2916 
2917   if( lemp->outname ) free(lemp->outname);
2918   lemp->outname = file_makename(lemp, suffix);
2919   fp = fopen(lemp->outname,mode);
2920   if( fp==0 && *mode=='w' ){
2921     fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname);
2922     lemp->errorcnt++;
2923     return 0;
2924   }
2925   return fp;
2926 }
2927 
2928 /* Duplicate the input file without comments and without actions
2929 ** on rules */
2930 void Reprint(struct lemon *lemp)
2931 {
2932   struct rule *rp;
2933   struct symbol *sp;
2934   int i, j, maxlen, len, ncolumns, skip;
2935   printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename);
2936   maxlen = 10;
2937   for(i=0; i<lemp->nsymbol; i++){
2938     sp = lemp->symbols[i];
2939     len = lemonStrlen(sp->name);
2940     if( len>maxlen ) maxlen = len;
2941   }
2942   ncolumns = 76/(maxlen+5);
2943   if( ncolumns<1 ) ncolumns = 1;
2944   skip = (lemp->nsymbol + ncolumns - 1)/ncolumns;
2945   for(i=0; i<skip; i++){
2946     printf("//");
2947     for(j=i; j<lemp->nsymbol; j+=skip){
2948       sp = lemp->symbols[j];
2949       assert( sp->index==j );
2950       printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name);
2951     }
2952     printf("\n");
2953   }
2954   for(rp=lemp->rule; rp; rp=rp->next){
2955     printf("%s",rp->lhs->name);
2956     /*    if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */
2957     printf(" ::=");
2958     for(i=0; i<rp->nrhs; i++){
2959       sp = rp->rhs[i];
2960       if( sp->type==MULTITERMINAL ){
2961         printf(" %s", sp->subsym[0]->name);
2962         for(j=1; j<sp->nsubsym; j++){
2963           printf("|%s", sp->subsym[j]->name);
2964         }
2965       }else{
2966         printf(" %s", sp->name);
2967       }
2968       /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */
2969     }
2970     printf(".");
2971     if( rp->precsym ) printf(" [%s]",rp->precsym->name);
2972     /* if( rp->code ) printf("\n    %s",rp->code); */
2973     printf("\n");
2974   }
2975 }
2976 
2977 /* Print a single rule.
2978 */
2979 void RulePrint(FILE *fp, struct rule *rp, int iCursor){
2980   struct symbol *sp;
2981   int i, j;
2982   fprintf(fp,"%s ::=",rp->lhs->name);
2983   for(i=0; i<=rp->nrhs; i++){
2984     if( i==iCursor ) fprintf(fp," *");
2985     if( i==rp->nrhs ) break;
2986     sp = rp->rhs[i];
2987     if( sp->type==MULTITERMINAL ){
2988       fprintf(fp," %s", sp->subsym[0]->name);
2989       for(j=1; j<sp->nsubsym; j++){
2990         fprintf(fp,"|%s",sp->subsym[j]->name);
2991       }
2992     }else{
2993       fprintf(fp," %s", sp->name);
2994     }
2995   }
2996 }
2997 
2998 /* Print the rule for a configuration.
2999 */
3000 void ConfigPrint(FILE *fp, struct config *cfp){
3001   RulePrint(fp, cfp->rp, cfp->dot);
3002 }
3003 
3004 /* #define TEST */
3005 #if 0
3006 /* Print a set */
3007 PRIVATE void SetPrint(out,set,lemp)
3008 FILE *out;
3009 char *set;
3010 struct lemon *lemp;
3011 {
3012   int i;
3013   char *spacer;
3014   spacer = "";
3015   fprintf(out,"%12s[","");
3016   for(i=0; i<lemp->nterminal; i++){
3017     if( SetFind(set,i) ){
3018       fprintf(out,"%s%s",spacer,lemp->symbols[i]->name);
3019       spacer = " ";
3020     }
3021   }
3022   fprintf(out,"]\n");
3023 }
3024 
3025 /* Print a plink chain */
3026 PRIVATE void PlinkPrint(out,plp,tag)
3027 FILE *out;
3028 struct plink *plp;
3029 char *tag;
3030 {
3031   while( plp ){
3032     fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->statenum);
3033     ConfigPrint(out,plp->cfp);
3034     fprintf(out,"\n");
3035     plp = plp->next;
3036   }
3037 }
3038 #endif
3039 
3040 /* Print an action to the given file descriptor.  Return FALSE if
3041 ** nothing was actually printed.
3042 */
3043 int PrintAction(
3044   struct action *ap,          /* The action to print */
3045   FILE *fp,                   /* Print the action here */
3046   int indent                  /* Indent by this amount */
3047 ){
3048   int result = 1;
3049   switch( ap->type ){
3050     case SHIFT: {
3051       struct state *stp = ap->x.stp;
3052       fprintf(fp,"%*s shift        %-7d",indent,ap->sp->name,stp->statenum);
3053       break;
3054     }
3055     case REDUCE: {
3056       struct rule *rp = ap->x.rp;
3057       fprintf(fp,"%*s reduce       %-7d",indent,ap->sp->name,rp->index);
3058       RulePrint(fp, rp, -1);
3059       break;
3060     }
3061     case SHIFTREDUCE: {
3062       struct rule *rp = ap->x.rp;
3063       fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->index);
3064       RulePrint(fp, rp, -1);
3065       break;
3066     }
3067     case ACCEPT:
3068       fprintf(fp,"%*s accept",indent,ap->sp->name);
3069       break;
3070     case ERROR:
3071       fprintf(fp,"%*s error",indent,ap->sp->name);
3072       break;
3073     case SRCONFLICT:
3074     case RRCONFLICT:
3075       fprintf(fp,"%*s reduce       %-7d ** Parsing conflict **",
3076         indent,ap->sp->name,ap->x.rp->index);
3077       break;
3078     case SSCONFLICT:
3079       fprintf(fp,"%*s shift        %-7d ** Parsing conflict **",
3080         indent,ap->sp->name,ap->x.stp->statenum);
3081       break;
3082     case SH_RESOLVED:
3083       if( showPrecedenceConflict ){
3084         fprintf(fp,"%*s shift        %-7d -- dropped by precedence",
3085                 indent,ap->sp->name,ap->x.stp->statenum);
3086       }else{
3087         result = 0;
3088       }
3089       break;
3090     case RD_RESOLVED:
3091       if( showPrecedenceConflict ){
3092         fprintf(fp,"%*s reduce %-7d -- dropped by precedence",
3093                 indent,ap->sp->name,ap->x.rp->index);
3094       }else{
3095         result = 0;
3096       }
3097       break;
3098     case NOT_USED:
3099       result = 0;
3100       break;
3101   }
3102   return result;
3103 }
3104 
3105 /* Generate the "*.out" log file */
3106 void ReportOutput(struct lemon *lemp)
3107 {
3108   int i;
3109   struct state *stp;
3110   struct config *cfp;
3111   struct action *ap;
3112   FILE *fp;
3113 
3114   fp = file_open(lemp,".out","wb");
3115   if( fp==0 ) return;
3116   for(i=0; i<lemp->nxstate; i++){
3117     stp = lemp->sorted[i];
3118     fprintf(fp,"State %d:\n",stp->statenum);
3119     if( lemp->basisflag ) cfp=stp->bp;
3120     else                  cfp=stp->cfp;
3121     while( cfp ){
3122       char buf[20];
3123       if( cfp->dot==cfp->rp->nrhs ){
3124         lemon_sprintf(buf,"(%d)",cfp->rp->index);
3125         fprintf(fp,"    %5s ",buf);
3126       }else{
3127         fprintf(fp,"          ");
3128       }
3129       ConfigPrint(fp,cfp);
3130       fprintf(fp,"\n");
3131 #if 0
3132       SetPrint(fp,cfp->fws,lemp);
3133       PlinkPrint(fp,cfp->fplp,"To  ");
3134       PlinkPrint(fp,cfp->bplp,"From");
3135 #endif
3136       if( lemp->basisflag ) cfp=cfp->bp;
3137       else                  cfp=cfp->next;
3138     }
3139     fprintf(fp,"\n");
3140     for(ap=stp->ap; ap; ap=ap->next){
3141       if( PrintAction(ap,fp,30) ) fprintf(fp,"\n");
3142     }
3143     fprintf(fp,"\n");
3144   }
3145   fprintf(fp, "----------------------------------------------------\n");
3146   fprintf(fp, "Symbols:\n");
3147   for(i=0; i<lemp->nsymbol; i++){
3148     int j;
3149     struct symbol *sp;
3150 
3151     sp = lemp->symbols[i];
3152     fprintf(fp, "  %3d: %s", i, sp->name);
3153     if( sp->type==NONTERMINAL ){
3154       fprintf(fp, ":");
3155       if( sp->lambda ){
3156         fprintf(fp, " <lambda>");
3157       }
3158       for(j=0; j<lemp->nterminal; j++){
3159         if( sp->firstset && SetFind(sp->firstset, j) ){
3160           fprintf(fp, " %s", lemp->symbols[j]->name);
3161         }
3162       }
3163     }
3164     fprintf(fp, "\n");
3165   }
3166   fclose(fp);
3167   return;
3168 }
3169 
3170 /* Search for the file "name" which is in the same directory as
3171 ** the exacutable */
3172 PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
3173 {
3174   const char *pathlist;
3175   char *pathbufptr;
3176   char *pathbuf;
3177   char *path,*cp;
3178   char c;
3179 
3180 #ifdef __WIN32__
3181   cp = strrchr(argv0,'\\');
3182 #else
3183   cp = strrchr(argv0,'/');
3184 #endif
3185   if( cp ){
3186     c = *cp;
3187     *cp = 0;
3188     path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
3189     if( path ) lemon_sprintf(path,"%s/%s",argv0,name);
3190     *cp = c;
3191   }else{
3192     pathlist = getenv("PATH");
3193     if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
3194     pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 );
3195     path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
3196     if( (pathbuf != 0) && (path!=0) ){
3197       pathbufptr = pathbuf;
3198       lemon_strcpy(pathbuf, pathlist);
3199       while( *pathbuf ){
3200         cp = strchr(pathbuf,':');
3201         if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)];
3202         c = *cp;
3203         *cp = 0;
3204         lemon_sprintf(path,"%s/%s",pathbuf,name);
3205         *cp = c;
3206         if( c==0 ) pathbuf[0] = 0;
3207         else pathbuf = &cp[1];
3208         if( access(path,modemask)==0 ) break;
3209       }
3210       free(pathbufptr);
3211     }
3212   }
3213   return path;
3214 }
3215 
3216 /* Given an action, compute the integer value for that action
3217 ** which is to be put in the action table of the generated machine.
3218 ** Return negative if no action should be generated.
3219 */
3220 PRIVATE int compute_action(struct lemon *lemp, struct action *ap)
3221 {
3222   int act;
3223   switch( ap->type ){
3224     case SHIFT:  act = ap->x.stp->statenum;                        break;
3225     case SHIFTREDUCE: act = ap->x.rp->index + lemp->nstate;        break;
3226     case REDUCE: act = ap->x.rp->index + lemp->nstate+lemp->nrule; break;
3227     case ERROR:  act = lemp->nstate + lemp->nrule*2;               break;
3228     case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1;           break;
3229     default:     act = -1; break;
3230   }
3231   return act;
3232 }
3233 
3234 #define LINESIZE 1000
3235 /* The next cluster of routines are for reading the template file
3236 ** and writing the results to the generated parser */
3237 /* The first function transfers data from "in" to "out" until
3238 ** a line is seen which begins with "%%".  The line number is
3239 ** tracked.
3240 **
3241 ** if name!=0, then any word that begin with "Parse" is changed to
3242 ** begin with *name instead.
3243 */
3244 PRIVATE void tplt_xfer(char *name, FILE *in, FILE *out, int *lineno)
3245 {
3246   int i, iStart;
3247   char line[LINESIZE];
3248   while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){
3249     (*lineno)++;
3250     iStart = 0;
3251     if( name ){
3252       for(i=0; line[i]; i++){
3253         if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0
3254           && (i==0 || !ISALPHA(line[i-1]))
3255         ){
3256           if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]);
3257           fprintf(out,"%s",name);
3258           i += 4;
3259           iStart = i+1;
3260         }
3261       }
3262     }
3263     fprintf(out,"%s",&line[iStart]);
3264   }
3265 }
3266 
3267 /* The next function finds the template file and opens it, returning
3268 ** a pointer to the opened file. */
3269 PRIVATE FILE *tplt_open(struct lemon *lemp)
3270 {
3271   static char templatename[] = "lempar.c";
3272   char buf[1000];
3273   FILE *in;
3274   char *tpltname;
3275   char *cp;
3276 
3277   /* first, see if user specified a template filename on the command line. */
3278   if (user_templatename != 0) {
3279     if( access(user_templatename,004)==-1 ){
3280       fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
3281         user_templatename);
3282       lemp->errorcnt++;
3283       return 0;
3284     }
3285     in = fopen(user_templatename,"rb");
3286     if( in==0 ){
3287       fprintf(stderr,"Can't open the template file \"%s\".\n",
3288               user_templatename);
3289       lemp->errorcnt++;
3290       return 0;
3291     }
3292     return in;
3293   }
3294 
3295   cp = strrchr(lemp->filename,'.');
3296   if( cp ){
3297     lemon_sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename);
3298   }else{
3299     lemon_sprintf(buf,"%s.lt",lemp->filename);
3300   }
3301   if( access(buf,004)==0 ){
3302     tpltname = buf;
3303   }else if( access(templatename,004)==0 ){
3304     tpltname = templatename;
3305   }else{
3306     tpltname = pathsearch(lemp->argv0,templatename,0);
3307   }
3308   if( tpltname==0 ){
3309     fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
3310     templatename);
3311     lemp->errorcnt++;
3312     return 0;
3313   }
3314   in = fopen(tpltname,"rb");
3315   if( in==0 ){
3316     fprintf(stderr,"Can't open the template file \"%s\".\n",templatename);
3317     lemp->errorcnt++;
3318     return 0;
3319   }
3320   return in;
3321 }
3322 
3323 /* Print a #line directive line to the output file. */
3324 PRIVATE void tplt_linedir(FILE *out, int lineno, char *filename)
3325 {
3326   fprintf(out,"#line %d \"",lineno);
3327   while( *filename ){
3328     if( *filename == '\\' ) putc('\\',out);
3329     putc(*filename,out);
3330     filename++;
3331   }
3332   fprintf(out,"\"\n");
3333 }
3334 
3335 /* Print a string to the file and keep the linenumber up to date */
3336 PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, int *lineno)
3337 {
3338   if( str==0 ) return;
3339   while( *str ){
3340     putc(*str,out);
3341     if( *str=='\n' ) (*lineno)++;
3342     str++;
3343   }
3344   if( str[-1]!='\n' ){
3345     putc('\n',out);
3346     (*lineno)++;
3347   }
3348   if (!lemp->nolinenosflag) {
3349     (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
3350   }
3351   return;
3352 }
3353 
3354 /*
3355 ** The following routine emits code for the destructor for the
3356 ** symbol sp
3357 */
3358 void emit_destructor_code(
3359   FILE *out,
3360   struct symbol *sp,
3361   struct lemon *lemp,
3362   int *lineno
3363 ){
3364  char *cp = 0;
3365 
3366  if( sp->type==TERMINAL ){
3367    cp = lemp->tokendest;
3368    if( cp==0 ) return;
3369    fprintf(out,"{\n"); (*lineno)++;
3370  }else if( sp->destructor ){
3371    cp = sp->destructor;
3372    fprintf(out,"{\n"); (*lineno)++;
3373    if( !lemp->nolinenosflag ){
3374      (*lineno)++;
3375      tplt_linedir(out,sp->destLineno,lemp->filename);
3376    }
3377  }else if( lemp->vardest ){
3378    cp = lemp->vardest;
3379    if( cp==0 ) return;
3380    fprintf(out,"{\n"); (*lineno)++;
3381  }else{
3382    assert( 0 );  /* Cannot happen */
3383  }
3384  for(; *cp; cp++){
3385    if( *cp=='$' && cp[1]=='$' ){
3386      fprintf(out,"(yypminor->yy%d)",sp->dtnum);
3387      cp++;
3388      continue;
3389    }
3390    if( *cp=='\n' ) (*lineno)++;
3391    fputc(*cp,out);
3392  }
3393  fprintf(out,"\n"); (*lineno)++;
3394  if (!lemp->nolinenosflag) {
3395    (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
3396  }
3397  fprintf(out,"}\n"); (*lineno)++;
3398  return;
3399 }
3400 
3401 /*
3402 ** Return TRUE (non-zero) if the given symbol has a destructor.
3403 */
3404 int has_destructor(struct symbol *sp, struct lemon *lemp)
3405 {
3406   int ret;
3407   if( sp->type==TERMINAL ){
3408     ret = lemp->tokendest!=0;
3409   }else{
3410     ret = lemp->vardest!=0 || sp->destructor!=0;
3411   }
3412   return ret;
3413 }
3414 
3415 /*
3416 ** Append text to a dynamically allocated string.  If zText is 0 then
3417 ** reset the string to be empty again.  Always return the complete text
3418 ** of the string (which is overwritten with each call).
3419 **
3420 ** n bytes of zText are stored.  If n==0 then all of zText up to the first
3421 ** \000 terminator is stored.  zText can contain up to two instances of
3422 ** %d.  The values of p1 and p2 are written into the first and second
3423 ** %d.
3424 **
3425 ** If n==-1, then the previous character is overwritten.
3426 */
3427 PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
3428   static char empty[1] = { 0 };
3429   static char *z = 0;
3430   static int alloced = 0;
3431   static int used = 0;
3432   int c;
3433   char zInt[40];
3434   if( zText==0 ){
3435     if( used==0 && z!=0 ) z[0] = 0;
3436     used = 0;
3437     return z;
3438   }
3439   if( n<=0 ){
3440     if( n<0 ){
3441       used += n;
3442       assert( used>=0 );
3443     }
3444     n = lemonStrlen(zText);
3445   }
3446   if( (int) (n+sizeof(zInt)*2+used) >= alloced ){
3447     alloced = n + sizeof(zInt)*2 + used + 200;
3448     z = (char *) realloc(z,  alloced);
3449   }
3450   if( z==0 ) return empty;
3451   while( n-- > 0 ){
3452     c = *(zText++);
3453     if( c=='%' && n>0 && zText[0]=='d' ){
3454       lemon_sprintf(zInt, "%d", p1);
3455       p1 = p2;
3456       lemon_strcpy(&z[used], zInt);
3457       used += lemonStrlen(&z[used]);
3458       zText++;
3459       n--;
3460     }else{
3461       z[used++] = (char)c;
3462     }
3463   }
3464   z[used] = 0;
3465   return z;
3466 }
3467 
3468 /*
3469 ** zCode is a string that is the action associated with a rule.  Expand
3470 ** the symbols in this string so that the refer to elements of the parser
3471 ** stack.
3472 **
3473 ** Return 1 if the expanded code requires that "yylhsminor" local variable
3474 ** to be defined.
3475 */
3476 PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
3477   char *cp, *xp;
3478   int i;
3479   int rc = 0;            /* True if yylhsminor is used */
3480   int dontUseRhs0 = 0;   /* If true, use of left-most RHS label is illegal */
3481   const char *zSkip = 0; /* The zOvwrt comment within rp->code, or NULL */
3482   char lhsused = 0;      /* True if the LHS element has been used */
3483   char lhsdirect;        /* True if LHS writes directly into stack */
3484   char used[MAXRHS];     /* True for each RHS element which is used */
3485   char zLhs[50];         /* Convert the LHS symbol into this string */
3486   char zOvwrt[900];      /* Comment that to allow LHS to overwrite RHS */
3487 
3488   for(i=0; i<rp->nrhs; i++) used[i] = 0;
3489   lhsused = 0;
3490 
3491   if( rp->code==0 ){
3492     static char newlinestr[2] = { '\n', '\0' };
3493     rp->code = newlinestr;
3494     rp->line = rp->ruleline;
3495   }
3496 
3497 
3498   if( rp->lhsalias==0 ){
3499     /* There is no LHS value symbol. */
3500     lhsdirect = 1;
3501   }else if( rp->nrhs==0 ){
3502     /* If there are no RHS symbols, then writing directly to the LHS is ok */
3503     lhsdirect = 1;
3504   }else if( rp->rhsalias[0]==0 ){
3505     /* The left-most RHS symbol has not value.  LHS direct is ok.  But
3506     ** we have to call the distructor on the RHS symbol first. */
3507     lhsdirect = 1;
3508     if( has_destructor(rp->rhs[0],lemp) ){
3509       append_str(0,0,0,0);
3510       append_str("  yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
3511                  rp->rhs[0]->index,1-rp->nrhs);
3512       rp->codePrefix = Strsafe(append_str(0,0,0,0));
3513     }
3514   }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
3515     /* The LHS symbol and the left-most RHS symbol are the same, so
3516     ** direct writing is allowed */
3517     lhsdirect = 1;
3518     lhsused = 1;
3519     used[0] = 1;
3520     if( rp->lhs->dtnum!=rp->rhs[0]->dtnum ){
3521       ErrorMsg(lemp->filename,rp->ruleline,
3522         "%s(%s) and %s(%s) share the same label but have "
3523         "different datatypes.",
3524         rp->lhs->name, rp->lhsalias, rp->rhs[0]->name, rp->rhsalias[0]);
3525       lemp->errorcnt++;
3526     }
3527   }else{
3528     lemon_sprintf(zOvwrt, "/*%s-overwrites-%s*/",
3529                   rp->lhsalias, rp->rhsalias[0]);
3530     zSkip = strstr(rp->code, zOvwrt);
3531     if( zSkip!=0 ){
3532       /* The code contains a special comment that indicates that it is safe
3533       ** for the LHS label to overwrite left-most RHS label. */
3534       lhsdirect = 1;
3535     }else{
3536       lhsdirect = 0;
3537     }
3538   }
3539   if( lhsdirect ){
3540     sprintf(zLhs, "yymsp[%d].minor.yy%d",1-rp->nrhs,rp->lhs->dtnum);
3541   }else{
3542     rc = 1;
3543     sprintf(zLhs, "yylhsminor.yy%d",rp->lhs->dtnum);
3544   }
3545 
3546   append_str(0,0,0,0);
3547 
3548   /* This const cast is wrong but harmless, if we're careful. */
3549   for(cp=(char *)rp->code; *cp; cp++){
3550     if( cp==zSkip ){
3551       append_str(zOvwrt,0,0,0);
3552       cp += lemonStrlen(zOvwrt)-1;
3553       dontUseRhs0 = 1;
3554       continue;
3555     }
3556     if( ISALPHA(*cp) && (cp==rp->code || (!ISALNUM(cp[-1]) && cp[-1]!='_')) ){
3557       char saved;
3558       for(xp= &cp[1]; ISALNUM(*xp) || *xp=='_'; xp++);
3559       saved = *xp;
3560       *xp = 0;
3561       if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
3562         append_str(zLhs,0,0,0);
3563         cp = xp;
3564         lhsused = 1;
3565       }else{
3566         for(i=0; i<rp->nrhs; i++){
3567           if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){
3568             if( i==0 && dontUseRhs0 ){
3569               ErrorMsg(lemp->filename,rp->ruleline,
3570                  "Label %s used after '%s'.",
3571                  rp->rhsalias[0], zOvwrt);
3572               lemp->errorcnt++;
3573             }else if( cp!=rp->code && cp[-1]=='@' ){
3574               /* If the argument is of the form @X then substituted
3575               ** the token number of X, not the value of X */
3576               append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0);
3577             }else{
3578               struct symbol *sp = rp->rhs[i];
3579               int dtnum;
3580               if( sp->type==MULTITERMINAL ){
3581                 dtnum = sp->subsym[0]->dtnum;
3582               }else{
3583                 dtnum = sp->dtnum;
3584               }
3585               append_str("yymsp[%d].minor.yy%d",0,i-rp->nrhs+1, dtnum);
3586             }
3587             cp = xp;
3588             used[i] = 1;
3589             break;
3590           }
3591         }
3592       }
3593       *xp = saved;
3594     }
3595     append_str(cp, 1, 0, 0);
3596   } /* End loop */
3597 
3598   /* Main code generation completed */
3599   cp = append_str(0,0,0,0);
3600   if( cp && cp[0] ) rp->code = Strsafe(cp);
3601   append_str(0,0,0,0);
3602 
3603   /* Check to make sure the LHS has been used */
3604   if( rp->lhsalias && !lhsused ){
3605     ErrorMsg(lemp->filename,rp->ruleline,
3606       "Label \"%s\" for \"%s(%s)\" is never used.",
3607         rp->lhsalias,rp->lhs->name,rp->lhsalias);
3608     lemp->errorcnt++;
3609   }
3610 
3611   /* Generate destructor code for RHS minor values which are not referenced.
3612   ** Generate error messages for unused labels and duplicate labels.
3613   */
3614   for(i=0; i<rp->nrhs; i++){
3615     if( rp->rhsalias[i] ){
3616       if( i>0 ){
3617         int j;
3618         if( rp->lhsalias && strcmp(rp->lhsalias,rp->rhsalias[i])==0 ){
3619           ErrorMsg(lemp->filename,rp->ruleline,
3620             "%s(%s) has the same label as the LHS but is not the left-most "
3621             "symbol on the RHS.",
3622             rp->rhs[i]->name, rp->rhsalias);
3623           lemp->errorcnt++;
3624         }
3625         for(j=0; j<i; j++){
3626           if( rp->rhsalias[j] && strcmp(rp->rhsalias[j],rp->rhsalias[i])==0 ){
3627             ErrorMsg(lemp->filename,rp->ruleline,
3628               "Label %s used for multiple symbols on the RHS of a rule.",
3629               rp->rhsalias[i]);
3630             lemp->errorcnt++;
3631             break;
3632           }
3633         }
3634       }
3635       if( !used[i] ){
3636         ErrorMsg(lemp->filename,rp->ruleline,
3637           "Label %s for \"%s(%s)\" is never used.",
3638           rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
3639         lemp->errorcnt++;
3640       }
3641     }else if( i>0 && has_destructor(rp->rhs[i],lemp) ){
3642       append_str("  yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
3643          rp->rhs[i]->index,i-rp->nrhs+1);
3644     }
3645   }
3646 
3647   /* If unable to write LHS values directly into the stack, write the
3648   ** saved LHS value now. */
3649   if( lhsdirect==0 ){
3650     append_str("  yymsp[%d].minor.yy%d = ", 0, 1-rp->nrhs, rp->lhs->dtnum);
3651     append_str(zLhs, 0, 0, 0);
3652     append_str(";\n", 0, 0, 0);
3653   }
3654 
3655   /* Suffix code generation complete */
3656   cp = append_str(0,0,0,0);
3657   if( cp ) rp->codeSuffix = Strsafe(cp);
3658 
3659   return rc;
3660 }
3661 
3662 /*
3663 ** Generate code which executes when the rule "rp" is reduced.  Write
3664 ** the code to "out".  Make sure lineno stays up-to-date.
3665 */
3666 PRIVATE void emit_code(
3667   FILE *out,
3668   struct rule *rp,
3669   struct lemon *lemp,
3670   int *lineno
3671 ){
3672  const char *cp;
3673 
3674  /* Setup code prior to the #line directive */
3675  if( rp->codePrefix && rp->codePrefix[0] ){
3676    fprintf(out, "{%s", rp->codePrefix);
3677    for(cp=rp->codePrefix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3678  }
3679 
3680  /* Generate code to do the reduce action */
3681  if( rp->code ){
3682    if( !lemp->nolinenosflag ){
3683      (*lineno)++;
3684      tplt_linedir(out,rp->line,lemp->filename);
3685    }
3686    fprintf(out,"{%s",rp->code);
3687    for(cp=rp->code; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3688    fprintf(out,"}\n"); (*lineno)++;
3689    if( !lemp->nolinenosflag ){
3690      (*lineno)++;
3691      tplt_linedir(out,*lineno,lemp->outname);
3692    }
3693  }
3694 
3695  /* Generate breakdown code that occurs after the #line directive */
3696  if( rp->codeSuffix && rp->codeSuffix[0] ){
3697    fprintf(out, "%s", rp->codeSuffix);
3698    for(cp=rp->codeSuffix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3699  }
3700 
3701  if( rp->codePrefix ){
3702    fprintf(out, "}\n"); (*lineno)++;
3703  }
3704 
3705  return;
3706 }
3707 
3708 /*
3709 ** Print the definition of the union used for the parser's data stack.
3710 ** This union contains fields for every possible data type for tokens
3711 ** and nonterminals.  In the process of computing and printing this
3712 ** union, also set the ".dtnum" field of every terminal and nonterminal
3713 ** symbol.
3714 */
3715 void print_stack_union(
3716   FILE *out,                  /* The output stream */
3717   struct lemon *lemp,         /* The main info structure for this parser */
3718   int *plineno,               /* Pointer to the line number */
3719   int mhflag                  /* True if generating makeheaders output */
3720 ){
3721   int lineno = *plineno;    /* The line number of the output */
3722   char **types;             /* A hash table of datatypes */
3723   int arraysize;            /* Size of the "types" array */
3724   int maxdtlength;          /* Maximum length of any ".datatype" field. */
3725   char *stddt;              /* Standardized name for a datatype */
3726   int i,j;                  /* Loop counters */
3727   unsigned hash;            /* For hashing the name of a type */
3728   const char *name;         /* Name of the parser */
3729 
3730   /* Allocate and initialize types[] and allocate stddt[] */
3731   arraysize = lemp->nsymbol * 2;
3732   types = (char**)calloc( arraysize, sizeof(char*) );
3733   if( types==0 ){
3734     fprintf(stderr,"Out of memory.\n");
3735     exit(1);
3736   }
3737   for(i=0; i<arraysize; i++) types[i] = 0;
3738   maxdtlength = 0;
3739   if( lemp->vartype ){
3740     maxdtlength = lemonStrlen(lemp->vartype);
3741   }
3742   for(i=0; i<lemp->nsymbol; i++){
3743     int len;
3744     struct symbol *sp = lemp->symbols[i];
3745     if( sp->datatype==0 ) continue;
3746     len = lemonStrlen(sp->datatype);
3747     if( len>maxdtlength ) maxdtlength = len;
3748   }
3749   stddt = (char*)malloc( maxdtlength*2 + 1 );
3750   if( stddt==0 ){
3751     fprintf(stderr,"Out of memory.\n");
3752     exit(1);
3753   }
3754 
3755   /* Build a hash table of datatypes. The ".dtnum" field of each symbol
3756   ** is filled in with the hash index plus 1.  A ".dtnum" value of 0 is
3757   ** used for terminal symbols.  If there is no %default_type defined then
3758   ** 0 is also used as the .dtnum value for nonterminals which do not specify
3759   ** a datatype using the %type directive.
3760   */
3761   for(i=0; i<lemp->nsymbol; i++){
3762     struct symbol *sp = lemp->symbols[i];
3763     char *cp;
3764     if( sp==lemp->errsym ){
3765       sp->dtnum = arraysize+1;
3766       continue;
3767     }
3768     if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){
3769       sp->dtnum = 0;
3770       continue;
3771     }
3772     cp = sp->datatype;
3773     if( cp==0 ) cp = lemp->vartype;
3774     j = 0;
3775     while( ISSPACE(*cp) ) cp++;
3776     while( *cp ) stddt[j++] = *cp++;
3777     while( j>0 && ISSPACE(stddt[j-1]) ) j--;
3778     stddt[j] = 0;
3779     if( lemp->tokentype && strcmp(stddt, lemp->tokentype)==0 ){
3780       sp->dtnum = 0;
3781       continue;
3782     }
3783     hash = 0;
3784     for(j=0; stddt[j]; j++){
3785       hash = hash*53 + stddt[j];
3786     }
3787     hash = (hash & 0x7fffffff)%arraysize;
3788     while( types[hash] ){
3789       if( strcmp(types[hash],stddt)==0 ){
3790         sp->dtnum = hash + 1;
3791         break;
3792       }
3793       hash++;
3794       if( hash>=(unsigned)arraysize ) hash = 0;
3795     }
3796     if( types[hash]==0 ){
3797       sp->dtnum = hash + 1;
3798       types[hash] = (char*)malloc( lemonStrlen(stddt)+1 );
3799       if( types[hash]==0 ){
3800         fprintf(stderr,"Out of memory.\n");
3801         exit(1);
3802       }
3803       lemon_strcpy(types[hash],stddt);
3804     }
3805   }
3806 
3807   /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */
3808   name = lemp->name ? lemp->name : "Parse";
3809   lineno = *plineno;
3810   if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; }
3811   fprintf(out,"#define %sTOKENTYPE %s\n",name,
3812     lemp->tokentype?lemp->tokentype:"void*");  lineno++;
3813   if( mhflag ){ fprintf(out,"#endif\n"); lineno++; }
3814   fprintf(out,"typedef union {\n"); lineno++;
3815   fprintf(out,"  int yyinit;\n"); lineno++;
3816   fprintf(out,"  %sTOKENTYPE yy0;\n",name); lineno++;
3817   for(i=0; i<arraysize; i++){
3818     if( types[i]==0 ) continue;
3819     fprintf(out,"  %s yy%d;\n",types[i],i+1); lineno++;
3820     free(types[i]);
3821   }
3822   if( lemp->errsym->useCnt ){
3823     fprintf(out,"  int yy%d;\n",lemp->errsym->dtnum); lineno++;
3824   }
3825   free(stddt);
3826   free(types);
3827   fprintf(out,"} YYMINORTYPE;\n"); lineno++;
3828   *plineno = lineno;
3829 }
3830 
3831 /*
3832 ** Return the name of a C datatype able to represent values between
3833 ** lwr and upr, inclusive.  If pnByte!=NULL then also write the sizeof
3834 ** for that type (1, 2, or 4) into *pnByte.
3835 */
3836 static const char *minimum_size_type(int lwr, int upr, int *pnByte){
3837   const char *zType = "int";
3838   int nByte = 4;
3839   if( lwr>=0 ){
3840     if( upr<=255 ){
3841       zType = "unsigned char";
3842       nByte = 1;
3843     }else if( upr<65535 ){
3844       zType = "unsigned short int";
3845       nByte = 2;
3846     }else{
3847       zType = "unsigned int";
3848       nByte = 4;
3849     }
3850   }else if( lwr>=-127 && upr<=127 ){
3851     zType = "signed char";
3852     nByte = 1;
3853   }else if( lwr>=-32767 && upr<32767 ){
3854     zType = "short";
3855     nByte = 2;
3856   }
3857   if( pnByte ) *pnByte = nByte;
3858   return zType;
3859 }
3860 
3861 /*
3862 ** Each state contains a set of token transaction and a set of
3863 ** nonterminal transactions.  Each of these sets makes an instance
3864 ** of the following structure.  An array of these structures is used
3865 ** to order the creation of entries in the yy_action[] table.
3866 */
3867 struct axset {
3868   struct state *stp;   /* A pointer to a state */
3869   int isTkn;           /* True to use tokens.  False for non-terminals */
3870   int nAction;         /* Number of actions */
3871   int iOrder;          /* Original order of action sets */
3872 };
3873 
3874 /*
3875 ** Compare to axset structures for sorting purposes
3876 */
3877 static int axset_compare(const void *a, const void *b){
3878   struct axset *p1 = (struct axset*)a;
3879   struct axset *p2 = (struct axset*)b;
3880   int c;
3881   c = p2->nAction - p1->nAction;
3882   if( c==0 ){
3883     c = p1->iOrder - p2->iOrder;
3884   }
3885   assert( c!=0 || p1==p2 );
3886   return c;
3887 }
3888 
3889 /*
3890 ** Write text on "out" that describes the rule "rp".
3891 */
3892 static void writeRuleText(FILE *out, struct rule *rp){
3893   int j;
3894   fprintf(out,"%s ::=", rp->lhs->name);
3895   for(j=0; j<rp->nrhs; j++){
3896     struct symbol *sp = rp->rhs[j];
3897     if( sp->type!=MULTITERMINAL ){
3898       fprintf(out," %s", sp->name);
3899     }else{
3900       int k;
3901       fprintf(out," %s", sp->subsym[0]->name);
3902       for(k=1; k<sp->nsubsym; k++){
3903         fprintf(out,"|%s",sp->subsym[k]->name);
3904       }
3905     }
3906   }
3907 }
3908 
3909 
3910 /* Generate C source code for the parser */
3911 void ReportTable(
3912   struct lemon *lemp,
3913   int mhflag     /* Output in makeheaders format if true */
3914 ){
3915   FILE *out, *in;
3916   char line[LINESIZE];
3917   int  lineno;
3918   struct state *stp;
3919   struct action *ap;
3920   struct rule *rp;
3921   struct acttab *pActtab;
3922   int i, j, n, sz;
3923   int szActionType;     /* sizeof(YYACTIONTYPE) */
3924   int szCodeType;       /* sizeof(YYCODETYPE)   */
3925   const char *name;
3926   int mnTknOfst, mxTknOfst;
3927   int mnNtOfst, mxNtOfst;
3928   struct axset *ax;
3929 
3930   in = tplt_open(lemp);
3931   if( in==0 ) return;
3932   out = file_open(lemp,".c","wb");
3933   if( out==0 ){
3934     fclose(in);
3935     return;
3936   }
3937   lineno = 1;
3938   tplt_xfer(lemp->name,in,out,&lineno);
3939 
3940   /* Generate the include code, if any */
3941   tplt_print(out,lemp,lemp->include,&lineno);
3942   if( mhflag ){
3943     char *incName = file_makename(lemp, ".h");
3944     fprintf(out,"#include \"%s\"\n", incName); lineno++;
3945     free(incName);
3946   }
3947   tplt_xfer(lemp->name,in,out,&lineno);
3948 
3949   /* Generate #defines for all tokens */
3950   if( mhflag ){
3951     const char *prefix;
3952     fprintf(out,"#if INTERFACE\n"); lineno++;
3953     if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
3954     else                    prefix = "";
3955     for(i=1; i<lemp->nterminal; i++){
3956       fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
3957       lineno++;
3958     }
3959     fprintf(out,"#endif\n"); lineno++;
3960   }
3961   tplt_xfer(lemp->name,in,out,&lineno);
3962 
3963   /* Generate the defines */
3964   fprintf(out,"#define YYCODETYPE %s\n",
3965     minimum_size_type(0, lemp->nsymbol+1, &szCodeType)); lineno++;
3966   fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1);  lineno++;
3967   fprintf(out,"#define YYACTIONTYPE %s\n",
3968     minimum_size_type(0,lemp->nstate+lemp->nrule*2+5,&szActionType)); lineno++;
3969   if( lemp->wildcard ){
3970     fprintf(out,"#define YYWILDCARD %d\n",
3971        lemp->wildcard->index); lineno++;
3972   }
3973   print_stack_union(out,lemp,&lineno,mhflag);
3974   fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++;
3975   if( lemp->stacksize ){
3976     fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize);  lineno++;
3977   }else{
3978     fprintf(out,"#define YYSTACKDEPTH 100\n");  lineno++;
3979   }
3980   fprintf(out, "#endif\n"); lineno++;
3981   if( mhflag ){
3982     fprintf(out,"#if INTERFACE\n"); lineno++;
3983   }
3984   name = lemp->name ? lemp->name : "Parse";
3985   if( lemp->arg && lemp->arg[0] ){
3986     i = lemonStrlen(lemp->arg);
3987     while( i>=1 && ISSPACE(lemp->arg[i-1]) ) i--;
3988     while( i>=1 && (ISALNUM(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;
3989     fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg);  lineno++;
3990     fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg);  lineno++;
3991     fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n",
3992                  name,lemp->arg,&lemp->arg[i]);  lineno++;
3993     fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n",
3994                  name,&lemp->arg[i],&lemp->arg[i]);  lineno++;
3995   }else{
3996     fprintf(out,"#define %sARG_SDECL\n",name);  lineno++;
3997     fprintf(out,"#define %sARG_PDECL\n",name);  lineno++;
3998     fprintf(out,"#define %sARG_FETCH\n",name); lineno++;
3999     fprintf(out,"#define %sARG_STORE\n",name); lineno++;
4000   }
4001   if( mhflag ){
4002     fprintf(out,"#endif\n"); lineno++;
4003   }
4004   if( lemp->errsym->useCnt ){
4005     fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
4006     fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
4007   }
4008   if( lemp->has_fallback ){
4009     fprintf(out,"#define YYFALLBACK 1\n");  lineno++;
4010   }
4011 
4012   /* Compute the action table, but do not output it yet.  The action
4013   ** table must be computed before generating the YYNSTATE macro because
4014   ** we need to know how many states can be eliminated.
4015   */
4016   ax = (struct axset *) calloc(lemp->nxstate*2, sizeof(ax[0]));
4017   if( ax==0 ){
4018     fprintf(stderr,"malloc failed\n");
4019     exit(1);
4020   }
4021   for(i=0; i<lemp->nxstate; i++){
4022     stp = lemp->sorted[i];
4023     ax[i*2].stp = stp;
4024     ax[i*2].isTkn = 1;
4025     ax[i*2].nAction = stp->nTknAct;
4026     ax[i*2+1].stp = stp;
4027     ax[i*2+1].isTkn = 0;
4028     ax[i*2+1].nAction = stp->nNtAct;
4029   }
4030   mxTknOfst = mnTknOfst = 0;
4031   mxNtOfst = mnNtOfst = 0;
4032   /* In an effort to minimize the action table size, use the heuristic
4033   ** of placing the largest action sets first */
4034   for(i=0; i<lemp->nxstate*2; i++) ax[i].iOrder = i;
4035   qsort(ax, lemp->nxstate*2, sizeof(ax[0]), axset_compare);
4036   pActtab = acttab_alloc();
4037   for(i=0; i<lemp->nxstate*2 && ax[i].nAction>0; i++){
4038     stp = ax[i].stp;
4039     if( ax[i].isTkn ){
4040       for(ap=stp->ap; ap; ap=ap->next){
4041         int action;
4042         if( ap->sp->index>=lemp->nterminal ) continue;
4043         action = compute_action(lemp, ap);
4044         if( action<0 ) continue;
4045         acttab_action(pActtab, ap->sp->index, action);
4046       }
4047       stp->iTknOfst = acttab_insert(pActtab);
4048       if( stp->iTknOfst<mnTknOfst ) mnTknOfst = stp->iTknOfst;
4049       if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst;
4050     }else{
4051       for(ap=stp->ap; ap; ap=ap->next){
4052         int action;
4053         if( ap->sp->index<lemp->nterminal ) continue;
4054         if( ap->sp->index==lemp->nsymbol ) continue;
4055         action = compute_action(lemp, ap);
4056         if( action<0 ) continue;
4057         acttab_action(pActtab, ap->sp->index, action);
4058       }
4059       stp->iNtOfst = acttab_insert(pActtab);
4060       if( stp->iNtOfst<mnNtOfst ) mnNtOfst = stp->iNtOfst;
4061       if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst;
4062     }
4063 #if 0  /* Uncomment for a trace of how the yy_action[] table fills out */
4064     { int jj, nn;
4065       for(jj=nn=0; jj<pActtab->nAction; jj++){
4066         if( pActtab->aAction[jj].action<0 ) nn++;
4067       }
4068       printf("%4d: State %3d %s n: %2d size: %5d freespace: %d\n",
4069              i, stp->statenum, ax[i].isTkn ? "Token" : "Var  ",
4070              ax[i].nAction, pActtab->nAction, nn);
4071     }
4072 #endif
4073   }
4074   free(ax);
4075 
4076   /* Finish rendering the constants now that the action table has
4077   ** been computed */
4078   fprintf(out,"#define YYNSTATE             %d\n",lemp->nxstate);  lineno++;
4079   fprintf(out,"#define YYNRULE              %d\n",lemp->nrule);  lineno++;
4080   fprintf(out,"#define YY_MAX_SHIFT         %d\n",lemp->nxstate-1); lineno++;
4081   fprintf(out,"#define YY_MIN_SHIFTREDUCE   %d\n",lemp->nstate); lineno++;
4082   i = lemp->nstate + lemp->nrule;
4083   fprintf(out,"#define YY_MAX_SHIFTREDUCE   %d\n", i-1); lineno++;
4084   fprintf(out,"#define YY_MIN_REDUCE        %d\n", i); lineno++;
4085   i = lemp->nstate + lemp->nrule*2;
4086   fprintf(out,"#define YY_MAX_REDUCE        %d\n", i-1); lineno++;
4087   fprintf(out,"#define YY_ERROR_ACTION      %d\n", i); lineno++;
4088   fprintf(out,"#define YY_ACCEPT_ACTION     %d\n", i+1); lineno++;
4089   fprintf(out,"#define YY_NO_ACTION         %d\n", i+2); lineno++;
4090   tplt_xfer(lemp->name,in,out,&lineno);
4091 
4092   /* Now output the action table and its associates:
4093   **
4094   **  yy_action[]        A single table containing all actions.
4095   **  yy_lookahead[]     A table containing the lookahead for each entry in
4096   **                     yy_action.  Used to detect hash collisions.
4097   **  yy_shift_ofst[]    For each state, the offset into yy_action for
4098   **                     shifting terminals.
4099   **  yy_reduce_ofst[]   For each state, the offset into yy_action for
4100   **                     shifting non-terminals after a reduce.
4101   **  yy_default[]       Default action for each state.
4102   */
4103 
4104   /* Output the yy_action table */
4105   lemp->nactiontab = n = acttab_size(pActtab);
4106   lemp->tablesize += n*szActionType;
4107   fprintf(out,"#define YY_ACTTAB_COUNT (%d)\n", n); lineno++;
4108   fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++;
4109   for(i=j=0; i<n; i++){
4110     int action = acttab_yyaction(pActtab, i);
4111     if( action<0 ) action = lemp->nstate + lemp->nrule + 2;
4112     if( j==0 ) fprintf(out," /* %5d */ ", i);
4113     fprintf(out, " %4d,", action);
4114     if( j==9 || i==n-1 ){
4115       fprintf(out, "\n"); lineno++;
4116       j = 0;
4117     }else{
4118       j++;
4119     }
4120   }
4121   fprintf(out, "};\n"); lineno++;
4122 
4123   /* Output the yy_lookahead table */
4124   lemp->tablesize += n*szCodeType;
4125   fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++;
4126   for(i=j=0; i<n; i++){
4127     int la = acttab_yylookahead(pActtab, i);
4128     if( la<0 ) la = lemp->nsymbol;
4129     if( j==0 ) fprintf(out," /* %5d */ ", i);
4130     fprintf(out, " %4d,", la);
4131     if( j==9 || i==n-1 ){
4132       fprintf(out, "\n"); lineno++;
4133       j = 0;
4134     }else{
4135       j++;
4136     }
4137   }
4138   fprintf(out, "};\n"); lineno++;
4139 
4140   /* Output the yy_shift_ofst[] table */
4141   fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
4142   n = lemp->nxstate;
4143   while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
4144   fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++;
4145   fprintf(out, "#define YY_SHIFT_MIN   (%d)\n", mnTknOfst); lineno++;
4146   fprintf(out, "#define YY_SHIFT_MAX   (%d)\n", mxTknOfst); lineno++;
4147   fprintf(out, "static const %s yy_shift_ofst[] = {\n",
4148           minimum_size_type(mnTknOfst-1, mxTknOfst, &sz)); lineno++;
4149   lemp->tablesize += n*sz;
4150   for(i=j=0; i<n; i++){
4151     int ofst;
4152     stp = lemp->sorted[i];
4153     ofst = stp->iTknOfst;
4154     if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1;
4155     if( j==0 ) fprintf(out," /* %5d */ ", i);
4156     fprintf(out, " %4d,", ofst);
4157     if( j==9 || i==n-1 ){
4158       fprintf(out, "\n"); lineno++;
4159       j = 0;
4160     }else{
4161       j++;
4162     }
4163   }
4164   fprintf(out, "};\n"); lineno++;
4165 
4166   /* Output the yy_reduce_ofst[] table */
4167   fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
4168   n = lemp->nxstate;
4169   while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--;
4170   fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++;
4171   fprintf(out, "#define YY_REDUCE_MIN   (%d)\n", mnNtOfst); lineno++;
4172   fprintf(out, "#define YY_REDUCE_MAX   (%d)\n", mxNtOfst); lineno++;
4173   fprintf(out, "static const %s yy_reduce_ofst[] = {\n",
4174           minimum_size_type(mnNtOfst-1, mxNtOfst, &sz)); lineno++;
4175   lemp->tablesize += n*sz;
4176   for(i=j=0; i<n; i++){
4177     int ofst;
4178     stp = lemp->sorted[i];
4179     ofst = stp->iNtOfst;
4180     if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1;
4181     if( j==0 ) fprintf(out," /* %5d */ ", i);
4182     fprintf(out, " %4d,", ofst);
4183     if( j==9 || i==n-1 ){
4184       fprintf(out, "\n"); lineno++;
4185       j = 0;
4186     }else{
4187       j++;
4188     }
4189   }
4190   fprintf(out, "};\n"); lineno++;
4191 
4192   /* Output the default action table */
4193   fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++;
4194   n = lemp->nxstate;
4195   lemp->tablesize += n*szActionType;
4196   for(i=j=0; i<n; i++){
4197     stp = lemp->sorted[i];
4198     if( j==0 ) fprintf(out," /* %5d */ ", i);
4199     fprintf(out, " %4d,", stp->iDfltReduce+lemp->nstate+lemp->nrule);
4200     if( j==9 || i==n-1 ){
4201       fprintf(out, "\n"); lineno++;
4202       j = 0;
4203     }else{
4204       j++;
4205     }
4206   }
4207   fprintf(out, "};\n"); lineno++;
4208   tplt_xfer(lemp->name,in,out,&lineno);
4209 
4210   /* Generate the table of fallback tokens.
4211   */
4212   if( lemp->has_fallback ){
4213     int mx = lemp->nterminal - 1;
4214     while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; }
4215     lemp->tablesize += (mx+1)*szCodeType;
4216     for(i=0; i<=mx; i++){
4217       struct symbol *p = lemp->symbols[i];
4218       if( p->fallback==0 ){
4219         fprintf(out, "    0,  /* %10s => nothing */\n", p->name);
4220       }else{
4221         fprintf(out, "  %3d,  /* %10s => %s */\n", p->fallback->index,
4222           p->name, p->fallback->name);
4223       }
4224       lineno++;
4225     }
4226   }
4227   tplt_xfer(lemp->name, in, out, &lineno);
4228 
4229   /* Generate a table containing the symbolic name of every symbol
4230   */
4231   for(i=0; i<lemp->nsymbol; i++){
4232     lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name);
4233     fprintf(out,"  %-15s",line);
4234     if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; }
4235   }
4236   if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; }
4237   tplt_xfer(lemp->name,in,out,&lineno);
4238 
4239   /* Generate a table containing a text string that describes every
4240   ** rule in the rule set of the grammar.  This information is used
4241   ** when tracing REDUCE actions.
4242   */
4243   for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
4244     assert( rp->index==i );
4245     fprintf(out," /* %3d */ \"", i);
4246     writeRuleText(out, rp);
4247     fprintf(out,"\",\n"); lineno++;
4248   }
4249   tplt_xfer(lemp->name,in,out,&lineno);
4250 
4251   /* Generate code which executes every time a symbol is popped from
4252   ** the stack while processing errors or while destroying the parser.
4253   ** (In other words, generate the %destructor actions)
4254   */
4255   if( lemp->tokendest ){
4256     int once = 1;
4257     for(i=0; i<lemp->nsymbol; i++){
4258       struct symbol *sp = lemp->symbols[i];
4259       if( sp==0 || sp->type!=TERMINAL ) continue;
4260       if( once ){
4261         fprintf(out, "      /* TERMINAL Destructor */\n"); lineno++;
4262         once = 0;
4263       }
4264       fprintf(out,"    case %d: /* %s */\n", sp->index, sp->name); lineno++;
4265     }
4266     for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++);
4267     if( i<lemp->nsymbol ){
4268       emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
4269       fprintf(out,"      break;\n"); lineno++;
4270     }
4271   }
4272   if( lemp->vardest ){
4273     struct symbol *dflt_sp = 0;
4274     int once = 1;
4275     for(i=0; i<lemp->nsymbol; i++){
4276       struct symbol *sp = lemp->symbols[i];
4277       if( sp==0 || sp->type==TERMINAL ||
4278           sp->index<=0 || sp->destructor!=0 ) continue;
4279       if( once ){
4280         fprintf(out, "      /* Default NON-TERMINAL Destructor */\n"); lineno++;
4281         once = 0;
4282       }
4283       fprintf(out,"    case %d: /* %s */\n", sp->index, sp->name); lineno++;
4284       dflt_sp = sp;
4285     }
4286     if( dflt_sp!=0 ){
4287       emit_destructor_code(out,dflt_sp,lemp,&lineno);
4288     }
4289     fprintf(out,"      break;\n"); lineno++;
4290   }
4291   for(i=0; i<lemp->nsymbol; i++){
4292     struct symbol *sp = lemp->symbols[i];
4293     if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
4294     fprintf(out,"    case %d: /* %s */\n", sp->index, sp->name); lineno++;
4295 
4296     /* Combine duplicate destructors into a single case */
4297     for(j=i+1; j<lemp->nsymbol; j++){
4298       struct symbol *sp2 = lemp->symbols[j];
4299       if( sp2 && sp2->type!=TERMINAL && sp2->destructor
4300           && sp2->dtnum==sp->dtnum
4301           && strcmp(sp->destructor,sp2->destructor)==0 ){
4302          fprintf(out,"    case %d: /* %s */\n",
4303                  sp2->index, sp2->name); lineno++;
4304          sp2->destructor = 0;
4305       }
4306     }
4307 
4308     emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
4309     fprintf(out,"      break;\n"); lineno++;
4310   }
4311   tplt_xfer(lemp->name,in,out,&lineno);
4312 
4313   /* Generate code which executes whenever the parser stack overflows */
4314   tplt_print(out,lemp,lemp->overflow,&lineno);
4315   tplt_xfer(lemp->name,in,out,&lineno);
4316 
4317   /* Generate the table of rule information
4318   **
4319   ** Note: This code depends on the fact that rules are number
4320   ** sequentually beginning with 0.
4321   */
4322   for(rp=lemp->rule; rp; rp=rp->next){
4323     fprintf(out,"  { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++;
4324   }
4325   tplt_xfer(lemp->name,in,out,&lineno);
4326 
4327   /* Generate code which execution during each REDUCE action */
4328   i = 0;
4329   for(rp=lemp->rule; rp; rp=rp->next){
4330     i += translate_code(lemp, rp);
4331   }
4332   if( i ){
4333     fprintf(out,"        YYMINORTYPE yylhsminor;\n"); lineno++;
4334   }
4335   /* First output rules other than the default: rule */
4336   for(rp=lemp->rule; rp; rp=rp->next){
4337     struct rule *rp2;               /* Other rules with the same action */
4338     if( rp->code==0 ) continue;
4339     if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */
4340     fprintf(out,"      case %d: /* ", rp->index);
4341     writeRuleText(out, rp);
4342     fprintf(out, " */\n"); lineno++;
4343     for(rp2=rp->next; rp2; rp2=rp2->next){
4344       if( rp2->code==rp->code ){
4345         fprintf(out,"      case %d: /* ", rp2->index);
4346         writeRuleText(out, rp2);
4347         fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++;
4348         rp2->code = 0;
4349       }
4350     }
4351     emit_code(out,rp,lemp,&lineno);
4352     fprintf(out,"        break;\n"); lineno++;
4353     rp->code = 0;
4354   }
4355   /* Finally, output the default: rule.  We choose as the default: all
4356   ** empty actions. */
4357   fprintf(out,"      default:\n"); lineno++;
4358   for(rp=lemp->rule; rp; rp=rp->next){
4359     if( rp->code==0 ) continue;
4360     assert( rp->code[0]=='\n' && rp->code[1]==0 );
4361     fprintf(out,"      /* (%d) ", rp->index);
4362     writeRuleText(out, rp);
4363     fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++;
4364   }
4365   fprintf(out,"        break;\n"); lineno++;
4366   tplt_xfer(lemp->name,in,out,&lineno);
4367 
4368   /* Generate code which executes if a parse fails */
4369   tplt_print(out,lemp,lemp->failure,&lineno);
4370   tplt_xfer(lemp->name,in,out,&lineno);
4371 
4372   /* Generate code which executes when a syntax error occurs */
4373   tplt_print(out,lemp,lemp->error,&lineno);
4374   tplt_xfer(lemp->name,in,out,&lineno);
4375 
4376   /* Generate code which executes when the parser accepts its input */
4377   tplt_print(out,lemp,lemp->accept,&lineno);
4378   tplt_xfer(lemp->name,in,out,&lineno);
4379 
4380   /* Append any addition code the user desires */
4381   tplt_print(out,lemp,lemp->extracode,&lineno);
4382 
4383   fclose(in);
4384   fclose(out);
4385   return;
4386 }
4387 
4388 /* Generate a header file for the parser */
4389 void ReportHeader(struct lemon *lemp)
4390 {
4391   FILE *out, *in;
4392   const char *prefix;
4393   char line[LINESIZE];
4394   char pattern[LINESIZE];
4395   int i;
4396 
4397   if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
4398   else                    prefix = "";
4399   in = file_open(lemp,".h","rb");
4400   if( in ){
4401     int nextChar;
4402     for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){
4403       lemon_sprintf(pattern,"#define %s%-30s %3d\n",
4404                     prefix,lemp->symbols[i]->name,i);
4405       if( strcmp(line,pattern) ) break;
4406     }
4407     nextChar = fgetc(in);
4408     fclose(in);
4409     if( i==lemp->nterminal && nextChar==EOF ){
4410       /* No change in the file.  Don't rewrite it. */
4411       return;
4412     }
4413   }
4414   out = file_open(lemp,".h","wb");
4415   if( out ){
4416     for(i=1; i<lemp->nterminal; i++){
4417       fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i);
4418     }
4419     fclose(out);
4420   }
4421   return;
4422 }
4423 
4424 /* Reduce the size of the action tables, if possible, by making use
4425 ** of defaults.
4426 **
4427 ** In this version, we take the most frequent REDUCE action and make
4428 ** it the default.  Except, there is no default if the wildcard token
4429 ** is a possible look-ahead.
4430 */
4431 void CompressTables(struct lemon *lemp)
4432 {
4433   struct state *stp;
4434   struct action *ap, *ap2;
4435   struct rule *rp, *rp2, *rbest;
4436   int nbest, n;
4437   int i;
4438   int usesWildcard;
4439 
4440   for(i=0; i<lemp->nstate; i++){
4441     stp = lemp->sorted[i];
4442     nbest = 0;
4443     rbest = 0;
4444     usesWildcard = 0;
4445 
4446     for(ap=stp->ap; ap; ap=ap->next){
4447       if( ap->type==SHIFT && ap->sp==lemp->wildcard ){
4448         usesWildcard = 1;
4449       }
4450       if( ap->type!=REDUCE ) continue;
4451       rp = ap->x.rp;
4452       if( rp->lhsStart ) continue;
4453       if( rp==rbest ) continue;
4454       n = 1;
4455       for(ap2=ap->next; ap2; ap2=ap2->next){
4456         if( ap2->type!=REDUCE ) continue;
4457         rp2 = ap2->x.rp;
4458         if( rp2==rbest ) continue;
4459         if( rp2==rp ) n++;
4460       }
4461       if( n>nbest ){
4462         nbest = n;
4463         rbest = rp;
4464       }
4465     }
4466 
4467     /* Do not make a default if the number of rules to default
4468     ** is not at least 1 or if the wildcard token is a possible
4469     ** lookahead.
4470     */
4471     if( nbest<1 || usesWildcard ) continue;
4472 
4473 
4474     /* Combine matching REDUCE actions into a single default */
4475     for(ap=stp->ap; ap; ap=ap->next){
4476       if( ap->type==REDUCE && ap->x.rp==rbest ) break;
4477     }
4478     assert( ap );
4479     ap->sp = Symbol_new("{default}");
4480     for(ap=ap->next; ap; ap=ap->next){
4481       if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED;
4482     }
4483     stp->ap = Action_sort(stp->ap);
4484 
4485     for(ap=stp->ap; ap; ap=ap->next){
4486       if( ap->type==SHIFT ) break;
4487       if( ap->type==REDUCE && ap->x.rp!=rbest ) break;
4488     }
4489     if( ap==0 ){
4490       stp->autoReduce = 1;
4491       stp->pDfltReduce = rbest;
4492     }
4493   }
4494 
4495   /* Make a second pass over all states and actions.  Convert
4496   ** every action that is a SHIFT to an autoReduce state into
4497   ** a SHIFTREDUCE action.
4498   */
4499   for(i=0; i<lemp->nstate; i++){
4500     stp = lemp->sorted[i];
4501     for(ap=stp->ap; ap; ap=ap->next){
4502       struct state *pNextState;
4503       if( ap->type!=SHIFT ) continue;
4504       pNextState = ap->x.stp;
4505       if( pNextState->autoReduce && pNextState->pDfltReduce!=0 ){
4506         ap->type = SHIFTREDUCE;
4507         ap->x.rp = pNextState->pDfltReduce;
4508       }
4509     }
4510   }
4511 }
4512 
4513 
4514 /*
4515 ** Compare two states for sorting purposes.  The smaller state is the
4516 ** one with the most non-terminal actions.  If they have the same number
4517 ** of non-terminal actions, then the smaller is the one with the most
4518 ** token actions.
4519 */
4520 static int stateResortCompare(const void *a, const void *b){
4521   const struct state *pA = *(const struct state**)a;
4522   const struct state *pB = *(const struct state**)b;
4523   int n;
4524 
4525   n = pB->nNtAct - pA->nNtAct;
4526   if( n==0 ){
4527     n = pB->nTknAct - pA->nTknAct;
4528     if( n==0 ){
4529       n = pB->statenum - pA->statenum;
4530     }
4531   }
4532   assert( n!=0 );
4533   return n;
4534 }
4535 
4536 
4537 /*
4538 ** Renumber and resort states so that states with fewer choices
4539 ** occur at the end.  Except, keep state 0 as the first state.
4540 */
4541 void ResortStates(struct lemon *lemp)
4542 {
4543   int i;
4544   struct state *stp;
4545   struct action *ap;
4546 
4547   for(i=0; i<lemp->nstate; i++){
4548     stp = lemp->sorted[i];
4549     stp->nTknAct = stp->nNtAct = 0;
4550     stp->iDfltReduce = lemp->nrule;  /* Init dflt action to "syntax error" */
4551     stp->iTknOfst = NO_OFFSET;
4552     stp->iNtOfst = NO_OFFSET;
4553     for(ap=stp->ap; ap; ap=ap->next){
4554       int iAction = compute_action(lemp,ap);
4555       if( iAction>=0 ){
4556         if( ap->sp->index<lemp->nterminal ){
4557           stp->nTknAct++;
4558         }else if( ap->sp->index<lemp->nsymbol ){
4559           stp->nNtAct++;
4560         }else{
4561           assert( stp->autoReduce==0 || stp->pDfltReduce==ap->x.rp );
4562           stp->iDfltReduce = iAction - lemp->nstate - lemp->nrule;
4563         }
4564       }
4565     }
4566   }
4567   qsort(&lemp->sorted[1], lemp->nstate-1, sizeof(lemp->sorted[0]),
4568         stateResortCompare);
4569   for(i=0; i<lemp->nstate; i++){
4570     lemp->sorted[i]->statenum = i;
4571   }
4572   lemp->nxstate = lemp->nstate;
4573   while( lemp->nxstate>1 && lemp->sorted[lemp->nxstate-1]->autoReduce ){
4574     lemp->nxstate--;
4575   }
4576 }
4577 
4578 
4579 /***************** From the file "set.c" ************************************/
4580 /*
4581 ** Set manipulation routines for the LEMON parser generator.
4582 */
4583 
4584 static int size = 0;
4585 
4586 /* Set the set size */
4587 void SetSize(int n)
4588 {
4589   size = n+1;
4590 }
4591 
4592 /* Allocate a new set */
4593 char *SetNew(){
4594   char *s;
4595   s = (char*)calloc( size, 1);
4596   if( s==0 ){
4597     extern void memory_error();
4598     memory_error();
4599   }
4600   return s;
4601 }
4602 
4603 /* Deallocate a set */
4604 void SetFree(char *s)
4605 {
4606   free(s);
4607 }
4608 
4609 /* Add a new element to the set.  Return TRUE if the element was added
4610 ** and FALSE if it was already there. */
4611 int SetAdd(char *s, int e)
4612 {
4613   int rv;
4614   assert( e>=0 && e<size );
4615   rv = s[e];
4616   s[e] = 1;
4617   return !rv;
4618 }
4619 
4620 /* Add every element of s2 to s1.  Return TRUE if s1 changes. */
4621 int SetUnion(char *s1, char *s2)
4622 {
4623   int i, progress;
4624   progress = 0;
4625   for(i=0; i<size; i++){
4626     if( s2[i]==0 ) continue;
4627     if( s1[i]==0 ){
4628       progress = 1;
4629       s1[i] = 1;
4630     }
4631   }
4632   return progress;
4633 }
4634 /********************** From the file "table.c" ****************************/
4635 /*
4636 ** All code in this file has been automatically generated
4637 ** from a specification in the file
4638 **              "table.q"
4639 ** by the associative array code building program "aagen".
4640 ** Do not edit this file!  Instead, edit the specification
4641 ** file, then rerun aagen.
4642 */
4643 /*
4644 ** Code for processing tables in the LEMON parser generator.
4645 */
4646 
4647 PRIVATE unsigned strhash(const char *x)
4648 {
4649   unsigned h = 0;
4650   while( *x ) h = h*13 + *(x++);
4651   return h;
4652 }
4653 
4654 /* Works like strdup, sort of.  Save a string in malloced memory, but
4655 ** keep strings in a table so that the same string is not in more
4656 ** than one place.
4657 */
4658 const char *Strsafe(const char *y)
4659 {
4660   const char *z;
4661   char *cpy;
4662 
4663   if( y==0 ) return 0;
4664   z = Strsafe_find(y);
4665   if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
4666     lemon_strcpy(cpy,y);
4667     z = cpy;
4668     Strsafe_insert(z);
4669   }
4670   MemoryCheck(z);
4671   return z;
4672 }
4673 
4674 /* There is one instance of the following structure for each
4675 ** associative array of type "x1".
4676 */
4677 struct s_x1 {
4678   int size;               /* The number of available slots. */
4679                           /*   Must be a power of 2 greater than or */
4680                           /*   equal to 1 */
4681   int count;              /* Number of currently slots filled */
4682   struct s_x1node *tbl;  /* The data stored here */
4683   struct s_x1node **ht;  /* Hash table for lookups */
4684 };
4685 
4686 /* There is one instance of this structure for every data element
4687 ** in an associative array of type "x1".
4688 */
4689 typedef struct s_x1node {
4690   const char *data;        /* The data */
4691   struct s_x1node *next;   /* Next entry with the same hash */
4692   struct s_x1node **from;  /* Previous link */
4693 } x1node;
4694 
4695 /* There is only one instance of the array, which is the following */
4696 static struct s_x1 *x1a;
4697 
4698 /* Allocate a new associative array */
4699 void Strsafe_init(){
4700   if( x1a ) return;
4701   x1a = (struct s_x1*)malloc( sizeof(struct s_x1) );
4702   if( x1a ){
4703     x1a->size = 1024;
4704     x1a->count = 0;
4705     x1a->tbl = (x1node*)calloc(1024, sizeof(x1node) + sizeof(x1node*));
4706     if( x1a->tbl==0 ){
4707       free(x1a);
4708       x1a = 0;
4709     }else{
4710       int i;
4711       x1a->ht = (x1node**)&(x1a->tbl[1024]);
4712       for(i=0; i<1024; i++) x1a->ht[i] = 0;
4713     }
4714   }
4715 }
4716 /* Insert a new record into the array.  Return TRUE if successful.
4717 ** Prior data with the same key is NOT overwritten */
4718 int Strsafe_insert(const char *data)
4719 {
4720   x1node *np;
4721   unsigned h;
4722   unsigned ph;
4723 
4724   if( x1a==0 ) return 0;
4725   ph = strhash(data);
4726   h = ph & (x1a->size-1);
4727   np = x1a->ht[h];
4728   while( np ){
4729     if( strcmp(np->data,data)==0 ){
4730       /* An existing entry with the same key is found. */
4731       /* Fail because overwrite is not allows. */
4732       return 0;
4733     }
4734     np = np->next;
4735   }
4736   if( x1a->count>=x1a->size ){
4737     /* Need to make the hash table bigger */
4738     int i,arrSize;
4739     struct s_x1 array;
4740     array.size = arrSize = x1a->size*2;
4741     array.count = x1a->count;
4742     array.tbl = (x1node*)calloc(arrSize, sizeof(x1node) + sizeof(x1node*));
4743     if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
4744     array.ht = (x1node**)&(array.tbl[arrSize]);
4745     for(i=0; i<arrSize; i++) array.ht[i] = 0;
4746     for(i=0; i<x1a->count; i++){
4747       x1node *oldnp, *newnp;
4748       oldnp = &(x1a->tbl[i]);
4749       h = strhash(oldnp->data) & (arrSize-1);
4750       newnp = &(array.tbl[i]);
4751       if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
4752       newnp->next = array.ht[h];
4753       newnp->data = oldnp->data;
4754       newnp->from = &(array.ht[h]);
4755       array.ht[h] = newnp;
4756     }
4757     free(x1a->tbl);
4758     *x1a = array;
4759   }
4760   /* Insert the new data */
4761   h = ph & (x1a->size-1);
4762   np = &(x1a->tbl[x1a->count++]);
4763   np->data = data;
4764   if( x1a->ht[h] ) x1a->ht[h]->from = &(np->next);
4765   np->next = x1a->ht[h];
4766   x1a->ht[h] = np;
4767   np->from = &(x1a->ht[h]);
4768   return 1;
4769 }
4770 
4771 /* Return a pointer to data assigned to the given key.  Return NULL
4772 ** if no such key. */
4773 const char *Strsafe_find(const char *key)
4774 {
4775   unsigned h;
4776   x1node *np;
4777 
4778   if( x1a==0 ) return 0;
4779   h = strhash(key) & (x1a->size-1);
4780   np = x1a->ht[h];
4781   while( np ){
4782     if( strcmp(np->data,key)==0 ) break;
4783     np = np->next;
4784   }
4785   return np ? np->data : 0;
4786 }
4787 
4788 /* Return a pointer to the (terminal or nonterminal) symbol "x".
4789 ** Create a new symbol if this is the first time "x" has been seen.
4790 */
4791 struct symbol *Symbol_new(const char *x)
4792 {
4793   struct symbol *sp;
4794 
4795   sp = Symbol_find(x);
4796   if( sp==0 ){
4797     sp = (struct symbol *)calloc(1, sizeof(struct symbol) );
4798     MemoryCheck(sp);
4799     sp->name = Strsafe(x);
4800     sp->type = ISUPPER(*x) ? TERMINAL : NONTERMINAL;
4801     sp->rule = 0;
4802     sp->fallback = 0;
4803     sp->prec = -1;
4804     sp->assoc = UNK;
4805     sp->firstset = 0;
4806     sp->lambda = LEMON_FALSE;
4807     sp->destructor = 0;
4808     sp->destLineno = 0;
4809     sp->datatype = 0;
4810     sp->useCnt = 0;
4811     Symbol_insert(sp,sp->name);
4812   }
4813   sp->useCnt++;
4814   return sp;
4815 }
4816 
4817 /* Compare two symbols for sorting purposes.  Return negative,
4818 ** zero, or positive if a is less then, equal to, or greater
4819 ** than b.
4820 **
4821 ** Symbols that begin with upper case letters (terminals or tokens)
4822 ** must sort before symbols that begin with lower case letters
4823 ** (non-terminals).  And MULTITERMINAL symbols (created using the
4824 ** %token_class directive) must sort at the very end. Other than
4825 ** that, the order does not matter.
4826 **
4827 ** We find experimentally that leaving the symbols in their original
4828 ** order (the order they appeared in the grammar file) gives the
4829 ** smallest parser tables in SQLite.
4830 */
4831 int Symbolcmpp(const void *_a, const void *_b)
4832 {
4833   const struct symbol *a = *(const struct symbol **) _a;
4834   const struct symbol *b = *(const struct symbol **) _b;
4835   int i1 = a->type==MULTITERMINAL ? 3 : a->name[0]>'Z' ? 2 : 1;
4836   int i2 = b->type==MULTITERMINAL ? 3 : b->name[0]>'Z' ? 2 : 1;
4837   return i1==i2 ? a->index - b->index : i1 - i2;
4838 }
4839 
4840 /* There is one instance of the following structure for each
4841 ** associative array of type "x2".
4842 */
4843 struct s_x2 {
4844   int size;               /* The number of available slots. */
4845                           /*   Must be a power of 2 greater than or */
4846                           /*   equal to 1 */
4847   int count;              /* Number of currently slots filled */
4848   struct s_x2node *tbl;  /* The data stored here */
4849   struct s_x2node **ht;  /* Hash table for lookups */
4850 };
4851 
4852 /* There is one instance of this structure for every data element
4853 ** in an associative array of type "x2".
4854 */
4855 typedef struct s_x2node {
4856   struct symbol *data;     /* The data */
4857   const char *key;         /* The key */
4858   struct s_x2node *next;   /* Next entry with the same hash */
4859   struct s_x2node **from;  /* Previous link */
4860 } x2node;
4861 
4862 /* There is only one instance of the array, which is the following */
4863 static struct s_x2 *x2a;
4864 
4865 /* Allocate a new associative array */
4866 void Symbol_init(){
4867   if( x2a ) return;
4868   x2a = (struct s_x2*)malloc( sizeof(struct s_x2) );
4869   if( x2a ){
4870     x2a->size = 128;
4871     x2a->count = 0;
4872     x2a->tbl = (x2node*)calloc(128, sizeof(x2node) + sizeof(x2node*));
4873     if( x2a->tbl==0 ){
4874       free(x2a);
4875       x2a = 0;
4876     }else{
4877       int i;
4878       x2a->ht = (x2node**)&(x2a->tbl[128]);
4879       for(i=0; i<128; i++) x2a->ht[i] = 0;
4880     }
4881   }
4882 }
4883 /* Insert a new record into the array.  Return TRUE if successful.
4884 ** Prior data with the same key is NOT overwritten */
4885 int Symbol_insert(struct symbol *data, const char *key)
4886 {
4887   x2node *np;
4888   unsigned h;
4889   unsigned ph;
4890 
4891   if( x2a==0 ) return 0;
4892   ph = strhash(key);
4893   h = ph & (x2a->size-1);
4894   np = x2a->ht[h];
4895   while( np ){
4896     if( strcmp(np->key,key)==0 ){
4897       /* An existing entry with the same key is found. */
4898       /* Fail because overwrite is not allows. */
4899       return 0;
4900     }
4901     np = np->next;
4902   }
4903   if( x2a->count>=x2a->size ){
4904     /* Need to make the hash table bigger */
4905     int i,arrSize;
4906     struct s_x2 array;
4907     array.size = arrSize = x2a->size*2;
4908     array.count = x2a->count;
4909     array.tbl = (x2node*)calloc(arrSize, sizeof(x2node) + sizeof(x2node*));
4910     if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
4911     array.ht = (x2node**)&(array.tbl[arrSize]);
4912     for(i=0; i<arrSize; i++) array.ht[i] = 0;
4913     for(i=0; i<x2a->count; i++){
4914       x2node *oldnp, *newnp;
4915       oldnp = &(x2a->tbl[i]);
4916       h = strhash(oldnp->key) & (arrSize-1);
4917       newnp = &(array.tbl[i]);
4918       if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
4919       newnp->next = array.ht[h];
4920       newnp->key = oldnp->key;
4921       newnp->data = oldnp->data;
4922       newnp->from = &(array.ht[h]);
4923       array.ht[h] = newnp;
4924     }
4925     free(x2a->tbl);
4926     *x2a = array;
4927   }
4928   /* Insert the new data */
4929   h = ph & (x2a->size-1);
4930   np = &(x2a->tbl[x2a->count++]);
4931   np->key = key;
4932   np->data = data;
4933   if( x2a->ht[h] ) x2a->ht[h]->from = &(np->next);
4934   np->next = x2a->ht[h];
4935   x2a->ht[h] = np;
4936   np->from = &(x2a->ht[h]);
4937   return 1;
4938 }
4939 
4940 /* Return a pointer to data assigned to the given key.  Return NULL
4941 ** if no such key. */
4942 struct symbol *Symbol_find(const char *key)
4943 {
4944   unsigned h;
4945   x2node *np;
4946 
4947   if( x2a==0 ) return 0;
4948   h = strhash(key) & (x2a->size-1);
4949   np = x2a->ht[h];
4950   while( np ){
4951     if( strcmp(np->key,key)==0 ) break;
4952     np = np->next;
4953   }
4954   return np ? np->data : 0;
4955 }
4956 
4957 /* Return the n-th data.  Return NULL if n is out of range. */
4958 struct symbol *Symbol_Nth(int n)
4959 {
4960   struct symbol *data;
4961   if( x2a && n>0 && n<=x2a->count ){
4962     data = x2a->tbl[n-1].data;
4963   }else{
4964     data = 0;
4965   }
4966   return data;
4967 }
4968 
4969 /* Return the size of the array */
4970 int Symbol_count()
4971 {
4972   return x2a ? x2a->count : 0;
4973 }
4974 
4975 /* Return an array of pointers to all data in the table.
4976 ** The array is obtained from malloc.  Return NULL if memory allocation
4977 ** problems, or if the array is empty. */
4978 struct symbol **Symbol_arrayof()
4979 {
4980   struct symbol **array;
4981   int i,arrSize;
4982   if( x2a==0 ) return 0;
4983   arrSize = x2a->count;
4984   array = (struct symbol **)calloc(arrSize, sizeof(struct symbol *));
4985   if( array ){
4986     for(i=0; i<arrSize; i++) array[i] = x2a->tbl[i].data;
4987   }
4988   return array;
4989 }
4990 
4991 /* Compare two configurations */
4992 int Configcmp(const char *_a,const char *_b)
4993 {
4994   const struct config *a = (struct config *) _a;
4995   const struct config *b = (struct config *) _b;
4996   int x;
4997   x = a->rp->index - b->rp->index;
4998   if( x==0 ) x = a->dot - b->dot;
4999   return x;
5000 }
5001 
5002 /* Compare two states */
5003 PRIVATE int statecmp(struct config *a, struct config *b)
5004 {
5005   int rc;
5006   for(rc=0; rc==0 && a && b;  a=a->bp, b=b->bp){
5007     rc = a->rp->index - b->rp->index;
5008     if( rc==0 ) rc = a->dot - b->dot;
5009   }
5010   if( rc==0 ){
5011     if( a ) rc = 1;
5012     if( b ) rc = -1;
5013   }
5014   return rc;
5015 }
5016 
5017 /* Hash a state */
5018 PRIVATE unsigned statehash(struct config *a)
5019 {
5020   unsigned h=0;
5021   while( a ){
5022     h = h*571 + a->rp->index*37 + a->dot;
5023     a = a->bp;
5024   }
5025   return h;
5026 }
5027 
5028 /* Allocate a new state structure */
5029 struct state *State_new()
5030 {
5031   struct state *newstate;
5032   newstate = (struct state *)calloc(1, sizeof(struct state) );
5033   MemoryCheck(newstate);
5034   return newstate;
5035 }
5036 
5037 /* There is one instance of the following structure for each
5038 ** associative array of type "x3".
5039 */
5040 struct s_x3 {
5041   int size;               /* The number of available slots. */
5042                           /*   Must be a power of 2 greater than or */
5043                           /*   equal to 1 */
5044   int count;              /* Number of currently slots filled */
5045   struct s_x3node *tbl;  /* The data stored here */
5046   struct s_x3node **ht;  /* Hash table for lookups */
5047 };
5048 
5049 /* There is one instance of this structure for every data element
5050 ** in an associative array of type "x3".
5051 */
5052 typedef struct s_x3node {
5053   struct state *data;                  /* The data */
5054   struct config *key;                   /* The key */
5055   struct s_x3node *next;   /* Next entry with the same hash */
5056   struct s_x3node **from;  /* Previous link */
5057 } x3node;
5058 
5059 /* There is only one instance of the array, which is the following */
5060 static struct s_x3 *x3a;
5061 
5062 /* Allocate a new associative array */
5063 void State_init(){
5064   if( x3a ) return;
5065   x3a = (struct s_x3*)malloc( sizeof(struct s_x3) );
5066   if( x3a ){
5067     x3a->size = 128;
5068     x3a->count = 0;
5069     x3a->tbl = (x3node*)calloc(128, sizeof(x3node) + sizeof(x3node*));
5070     if( x3a->tbl==0 ){
5071       free(x3a);
5072       x3a = 0;
5073     }else{
5074       int i;
5075       x3a->ht = (x3node**)&(x3a->tbl[128]);
5076       for(i=0; i<128; i++) x3a->ht[i] = 0;
5077     }
5078   }
5079 }
5080 /* Insert a new record into the array.  Return TRUE if successful.
5081 ** Prior data with the same key is NOT overwritten */
5082 int State_insert(struct state *data, struct config *key)
5083 {
5084   x3node *np;
5085   unsigned h;
5086   unsigned ph;
5087 
5088   if( x3a==0 ) return 0;
5089   ph = statehash(key);
5090   h = ph & (x3a->size-1);
5091   np = x3a->ht[h];
5092   while( np ){
5093     if( statecmp(np->key,key)==0 ){
5094       /* An existing entry with the same key is found. */
5095       /* Fail because overwrite is not allows. */
5096       return 0;
5097     }
5098     np = np->next;
5099   }
5100   if( x3a->count>=x3a->size ){
5101     /* Need to make the hash table bigger */
5102     int i,arrSize;
5103     struct s_x3 array;
5104     array.size = arrSize = x3a->size*2;
5105     array.count = x3a->count;
5106     array.tbl = (x3node*)calloc(arrSize, sizeof(x3node) + sizeof(x3node*));
5107     if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
5108     array.ht = (x3node**)&(array.tbl[arrSize]);
5109     for(i=0; i<arrSize; i++) array.ht[i] = 0;
5110     for(i=0; i<x3a->count; i++){
5111       x3node *oldnp, *newnp;
5112       oldnp = &(x3a->tbl[i]);
5113       h = statehash(oldnp->key) & (arrSize-1);
5114       newnp = &(array.tbl[i]);
5115       if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
5116       newnp->next = array.ht[h];
5117       newnp->key = oldnp->key;
5118       newnp->data = oldnp->data;
5119       newnp->from = &(array.ht[h]);
5120       array.ht[h] = newnp;
5121     }
5122     free(x3a->tbl);
5123     *x3a = array;
5124   }
5125   /* Insert the new data */
5126   h = ph & (x3a->size-1);
5127   np = &(x3a->tbl[x3a->count++]);
5128   np->key = key;
5129   np->data = data;
5130   if( x3a->ht[h] ) x3a->ht[h]->from = &(np->next);
5131   np->next = x3a->ht[h];
5132   x3a->ht[h] = np;
5133   np->from = &(x3a->ht[h]);
5134   return 1;
5135 }
5136 
5137 /* Return a pointer to data assigned to the given key.  Return NULL
5138 ** if no such key. */
5139 struct state *State_find(struct config *key)
5140 {
5141   unsigned h;
5142   x3node *np;
5143 
5144   if( x3a==0 ) return 0;
5145   h = statehash(key) & (x3a->size-1);
5146   np = x3a->ht[h];
5147   while( np ){
5148     if( statecmp(np->key,key)==0 ) break;
5149     np = np->next;
5150   }
5151   return np ? np->data : 0;
5152 }
5153 
5154 /* Return an array of pointers to all data in the table.
5155 ** The array is obtained from malloc.  Return NULL if memory allocation
5156 ** problems, or if the array is empty. */
5157 struct state **State_arrayof()
5158 {
5159   struct state **array;
5160   int i,arrSize;
5161   if( x3a==0 ) return 0;
5162   arrSize = x3a->count;
5163   array = (struct state **)calloc(arrSize, sizeof(struct state *));
5164   if( array ){
5165     for(i=0; i<arrSize; i++) array[i] = x3a->tbl[i].data;
5166   }
5167   return array;
5168 }
5169 
5170 /* Hash a configuration */
5171 PRIVATE unsigned confighash(struct config *a)
5172 {
5173   unsigned h=0;
5174   h = h*571 + a->rp->index*37 + a->dot;
5175   return h;
5176 }
5177 
5178 /* There is one instance of the following structure for each
5179 ** associative array of type "x4".
5180 */
5181 struct s_x4 {
5182   int size;               /* The number of available slots. */
5183                           /*   Must be a power of 2 greater than or */
5184                           /*   equal to 1 */
5185   int count;              /* Number of currently slots filled */
5186   struct s_x4node *tbl;  /* The data stored here */
5187   struct s_x4node **ht;  /* Hash table for lookups */
5188 };
5189 
5190 /* There is one instance of this structure for every data element
5191 ** in an associative array of type "x4".
5192 */
5193 typedef struct s_x4node {
5194   struct config *data;                  /* The data */
5195   struct s_x4node *next;   /* Next entry with the same hash */
5196   struct s_x4node **from;  /* Previous link */
5197 } x4node;
5198 
5199 /* There is only one instance of the array, which is the following */
5200 static struct s_x4 *x4a;
5201 
5202 /* Allocate a new associative array */
5203 void Configtable_init(){
5204   if( x4a ) return;
5205   x4a = (struct s_x4*)malloc( sizeof(struct s_x4) );
5206   if( x4a ){
5207     x4a->size = 64;
5208     x4a->count = 0;
5209     x4a->tbl = (x4node*)calloc(64, sizeof(x4node) + sizeof(x4node*));
5210     if( x4a->tbl==0 ){
5211       free(x4a);
5212       x4a = 0;
5213     }else{
5214       int i;
5215       x4a->ht = (x4node**)&(x4a->tbl[64]);
5216       for(i=0; i<64; i++) x4a->ht[i] = 0;
5217     }
5218   }
5219 }
5220 /* Insert a new record into the array.  Return TRUE if successful.
5221 ** Prior data with the same key is NOT overwritten */
5222 int Configtable_insert(struct config *data)
5223 {
5224   x4node *np;
5225   unsigned h;
5226   unsigned ph;
5227 
5228   if( x4a==0 ) return 0;
5229   ph = confighash(data);
5230   h = ph & (x4a->size-1);
5231   np = x4a->ht[h];
5232   while( np ){
5233     if( Configcmp((const char *) np->data,(const char *) data)==0 ){
5234       /* An existing entry with the same key is found. */
5235       /* Fail because overwrite is not allows. */
5236       return 0;
5237     }
5238     np = np->next;
5239   }
5240   if( x4a->count>=x4a->size ){
5241     /* Need to make the hash table bigger */
5242     int i,arrSize;
5243     struct s_x4 array;
5244     array.size = arrSize = x4a->size*2;
5245     array.count = x4a->count;
5246     array.tbl = (x4node*)calloc(arrSize, sizeof(x4node) + sizeof(x4node*));
5247     if( array.tbl==0 ) return 0;  /* Fail due to malloc failure */
5248     array.ht = (x4node**)&(array.tbl[arrSize]);
5249     for(i=0; i<arrSize; i++) array.ht[i] = 0;
5250     for(i=0; i<x4a->count; i++){
5251       x4node *oldnp, *newnp;
5252       oldnp = &(x4a->tbl[i]);
5253       h = confighash(oldnp->data) & (arrSize-1);
5254       newnp = &(array.tbl[i]);
5255       if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
5256       newnp->next = array.ht[h];
5257       newnp->data = oldnp->data;
5258       newnp->from = &(array.ht[h]);
5259       array.ht[h] = newnp;
5260     }
5261     free(x4a->tbl);
5262     *x4a = array;
5263   }
5264   /* Insert the new data */
5265   h = ph & (x4a->size-1);
5266   np = &(x4a->tbl[x4a->count++]);
5267   np->data = data;
5268   if( x4a->ht[h] ) x4a->ht[h]->from = &(np->next);
5269   np->next = x4a->ht[h];
5270   x4a->ht[h] = np;
5271   np->from = &(x4a->ht[h]);
5272   return 1;
5273 }
5274 
5275 /* Return a pointer to data assigned to the given key.  Return NULL
5276 ** if no such key. */
5277 struct config *Configtable_find(struct config *key)
5278 {
5279   int h;
5280   x4node *np;
5281 
5282   if( x4a==0 ) return 0;
5283   h = confighash(key) & (x4a->size-1);
5284   np = x4a->ht[h];
5285   while( np ){
5286     if( Configcmp((const char *) np->data,(const char *) key)==0 ) break;
5287     np = np->next;
5288   }
5289   return np ? np->data : 0;
5290 }
5291 
5292 /* Remove all data from the table.  Pass each data to the function "f"
5293 ** as it is removed.  ("f" may be null to avoid this step.) */
5294 void Configtable_clear(int(*f)(struct config *))
5295 {
5296   int i;
5297   if( x4a==0 || x4a->count==0 ) return;
5298   if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data);
5299   for(i=0; i<x4a->size; i++) x4a->ht[i] = 0;
5300   x4a->count = 0;
5301   return;
5302 }
5303