Commit MetaInfo

Revision84945d6486e0b86808762635b18aad52798ebc37 (tree)
Time2019-11-25 05:54:18
AuthorJoshua Surace <doomjoshuaboy@gmai...>
CommiterJoshua Surace

Log Message

Merged lemon tool to the latest .

Change Summary

Incremental Difference

diff -r ada484f0688e -r 84945d6486e0 tools/lemon/lemon.c
--- a/tools/lemon/lemon.c Sun Oct 20 21:34:48 2019 +0200
+++ b/tools/lemon/lemon.c Mon Nov 25 07:54:18 2019 +1100
@@ -6,9 +6,9 @@
66 **
77 ** The author of this program disclaims copyright.
88 **
9-** This file is based on version 1.43 of lemon.c from the SQLite
10-** source tree, with modifications to make it work nicer when run
11-** by Developer Studio.
9+** This file is based on version 1.69 of lemon.c from the SQLite
10+** CVS, with modifications to make it work nicer when run
11+** from Developer Studio.
1212 */
1313 #include <stdio.h>
1414 #include <stdarg.h>
@@ -17,6 +17,14 @@
1717 #include <stdlib.h>
1818 #include <assert.h>
1919
20+#define ISSPACE(X) isspace((unsigned char)(X))
21+#define ISDIGIT(X) isdigit((unsigned char)(X))
22+#define ISALNUM(X) isalnum((unsigned char)(X))
23+#define ISALPHA(X) isalpha((unsigned char)(X))
24+#define ISUPPER(X) isupper((unsigned char)(X))
25+#define ISLOWER(X) islower((unsigned char)(X))
26+
27+
2028 #ifndef __WIN32__
2129 # if defined(_WIN32) || defined(WIN32)
2230 # define __WIN32__
@@ -24,7 +32,13 @@
2432 #endif
2533
2634 #ifdef __WIN32__
27-extern int access();
35+#ifdef __cplusplus
36+extern "C" {
37+#endif
38+extern int access(char *path, int mode);
39+#ifdef __cplusplus
40+}
41+#endif
2842 #else
2943 #include <unistd.h>
3044 #endif
@@ -38,8 +52,21 @@
3852 #define MAXRHS 1000
3953 #endif
4054
55+static int showPrecedenceConflict = 0;
4156 static void *msort(void *list, void *next, int (*cmp)());
4257
58+/*
59+** Compilers are getting increasingly pedantic about type conversions
60+** as C evolves ever closer to Ada.... To work around the latest problems
61+** we have to define the following variant of strlen().
62+*/
63+#define lemonStrlen(X) ((int)strlen(X))
64+
65+/* a few forward declarations... */
66+struct rule;
67+struct lemon;
68+struct action;
69+
4370 /******** From the file "action.h" *************************************/
4471 static struct action *Action_new(void);
4572 static struct action *Action_sort(struct action *);
@@ -53,59 +80,58 @@
5380 void FindActions();
5481
5582 /********* From the file "configlist.h" *********************************/
56-void Configlist_init(/* void */);
57-struct config *Configlist_add(/* struct rule *, int */);
58-struct config *Configlist_addbasis(/* struct rule *, int */);
59-void Configlist_closure(/* void */);
60-void Configlist_sort(/* void */);
61-void Configlist_sortbasis(/* void */);
62-struct config *Configlist_return(/* void */);
63-struct config *Configlist_basis(/* void */);
64-void Configlist_eat(/* struct config * */);
65-void Configlist_reset(/* void */);
83+void Configlist_init(void);
84+struct config *Configlist_add(struct rule *, int);
85+struct config *Configlist_addbasis(struct rule *, int);
86+void Configlist_closure(struct lemon *);
87+void Configlist_sort(void);
88+void Configlist_sortbasis(void);
89+struct config *Configlist_return(void);
90+struct config *Configlist_basis(void);
91+void Configlist_eat(struct config *);
92+void Configlist_reset(void);
6693
6794 /********* From the file "error.h" ***************************************/
6895 void ErrorMsg(const char *, int,const char *, ...);
6996
7097 /****** From the file "option.h" ******************************************/
98+enum option_type { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR,
99+ OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR};
71100 struct s_options {
72- enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR,
73- OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type;
74- char *label;
101+ enum option_type type;
102+ const char *label;
75103 char *arg;
76- char *message;
104+ const char *message;
77105 };
78-int OptInit(/* char**,struct s_options*,FILE* */);
79-int OptNArgs(/* void */);
80-char *OptArg(/* int */);
81-void OptErr(/* int */);
82-void OptPrint(/* void */);
106+int OptInit(char**,struct s_options*,FILE*);
107+int OptNArgs(void);
108+char *OptArg(int);
109+void OptErr(int);
110+void OptPrint(void);
83111
84112 /******** From the file "parse.h" *****************************************/
85-void Parse(/* struct lemon *lemp */);
113+void Parse(struct lemon *lemp);
86114
87115 /********* From the file "plink.h" ***************************************/
88-struct plink *Plink_new(/* void */);
89-void Plink_add(/* struct plink **, struct config * */);
90-void Plink_copy(/* struct plink **, struct plink * */);
91-void Plink_delete(/* struct plink * */);
116+struct plink *Plink_new(void);
117+void Plink_add(struct plink **, struct config *);
118+void Plink_copy(struct plink **, struct plink *);
119+void Plink_delete(struct plink *);
92120
93121 /********** From the file "report.h" *************************************/
94-void Reprint(/* struct lemon * */);
95-void ReportOutput(/* struct lemon * */);
96-void ReportTable(/* struct lemon * */);
97-void ReportHeader(/* struct lemon * */);
98-void CompressTables(/* struct lemon * */);
99-void ResortStates(/* struct lemon * */);
122+void Reprint(struct lemon *);
123+void ReportOutput(struct lemon *);
124+void ReportTable(struct lemon *, int);
125+void ReportHeader(struct lemon *);
126+void CompressTables(struct lemon *);
127+void ResortStates(struct lemon *);
100128
101129 /********** From the file "set.h" ****************************************/
102-void SetSize(/* int N */); /* All sets will be of size N */
103-char *SetNew(/* void */); /* A new set for element 0..N */
104-void SetFree(/* char* */); /* Deallocate a set */
105-
106-int SetAdd(/* char*,int */); /* Add element to a set */
107-int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */
108-
130+void SetSize(int); /* All sets will be of size N */
131+char *SetNew(void); /* A new set for element 0..N */
132+void SetFree(char*); /* Deallocate a set */
133+int SetAdd(char*,int); /* Add element to a set */
134+int SetUnion(char *,char *); /* A <- A U B, thru element N */
109135 #define SetFind(X,Y) (X[Y]) /* True if Y is in set X */
110136
111137 /********** From the file "struct.h" *************************************/
@@ -117,29 +143,32 @@
117143
118144 /* Symbols (terminals and nonterminals) of the grammar are stored
119145 ** in the following: */
120-struct symbol {
121- char *name; /* Name of the symbol */
122- int index; /* Index number for this symbol */
123- enum {
124- TERMINAL,
125- NONTERMINAL,
126- MULTITERMINAL
127- } type; /* Symbols are all either TERMINALS or NTs */
128- struct rule *rule; /* Linked list of rules of this (if an NT) */
129- struct symbol *fallback; /* fallback token in case this token doesn't parse */
130- int prec; /* Precedence if defined (-1 otherwise) */
131- enum e_assoc {
146+enum symbol_type {
147+ TERMINAL,
148+ NONTERMINAL,
149+ MULTITERMINAL
150+};
151+enum e_assoc {
132152 LEFT,
133153 RIGHT,
134154 NONE,
135155 UNK
136- } assoc; /* Associativity if predecence is defined */
156+};
157+struct symbol {
158+ const char *name; /* Name of the symbol */
159+ int index; /* Index number for this symbol */
160+ enum symbol_type type; /* Symbols are all either TERMINALS or NTs */
161+ struct rule *rule; /* Linked list of rules of this (if an NT) */
162+ struct symbol *fallback; /* fallback token in case this token doesn't parse */
163+ int prec; /* Precedence if defined (-1 otherwise) */
164+ enum e_assoc assoc; /* Associativity if precedence is defined */
137165 char *firstset; /* First-set for all rules of this symbol */
138166 Boolean lambda; /* True if NT and can generate an empty string */
139167 int useCnt; /* Number of times used */
140168 char *destructor; /* Code which executes whenever this symbol is
141169 ** popped from the stack during error processing */
142- int destructorln; /* Line number of destructor code */
170+ int destLineno; /* Line number for start of destructor. Set to
171+ ** -1 for duplicate destructors. */
143172 char *datatype; /* The data type of information held by this
144173 ** object. Only used if type==NONTERMINAL */
145174 int dtnum; /* The data type number. In the parser, the value
@@ -154,17 +183,25 @@
154183 ** structure. */
155184 struct rule {
156185 struct symbol *lhs; /* Left-hand side of the rule */
157- char *lhsalias; /* Alias for the LHS (NULL if none) */
186+ const char *lhsalias; /* Alias for the LHS (NULL if none) */
158187 int lhsStart; /* True if left-hand side is the start symbol */
159188 int ruleline; /* Line number for the rule */
160189 int nrhs; /* Number of RHS symbols */
161190 struct symbol **rhs; /* The RHS symbols */
162- char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
191+ const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
163192 int line; /* Line number at which code begins */
164- char *code; /* The code executed when this rule is reduced */
193+ const char *code; /* The code executed when this rule is reduced */
194+ const char *codePrefix; /* Setup code before code[] above */
195+ const char *codeSuffix; /* Breakdown code after code[] above */
196+ int noCode; /* True if this rule has no associated C code */
197+ int codeEmitted; /* True if the code has been emitted already */
165198 struct symbol *precsym; /* Precedence symbol for this rule */
166199 int index; /* An index number for this rule */
200+ int iRule; /* Rule number as used in the generated tables */
167201 Boolean canReduce; /* True if this rule is ever reduced */
202+#if 0
203+ Boolean doesReduce; /* Reduce actions occur after optimization */
204+#endif
168205 struct rule *nextlhs; /* Next rule with the same LHS */
169206 struct rule *next; /* Next rule in the global list */
170207 };
@@ -174,6 +211,10 @@
174211 ** Configurations also contain a follow-set which is a list of terminal
175212 ** symbols which are allowed to immediately follow the end of the rule.
176213 ** Every configuration is recorded as an instance of the following: */
214+enum cfgstatus {
215+ COMPLETE,
216+ INCOMPLETE
217+};
177218 struct config {
178219 struct rule *rp; /* The rule upon which the configuration is based */
179220 int dot; /* The parse point */
@@ -181,33 +222,34 @@
181222 struct plink *fplp; /* Follow-set forward propagation links */
182223 struct plink *bplp; /* Follow-set backwards propagation links */
183224 struct state *stp; /* Pointer to state which contains this */
184- enum {
185- COMPLETE, /* The status is used during followset and */
186- INCOMPLETE /* shift computations */
187- } status;
225+ enum cfgstatus status; /* used during followset and shift computations */
188226 struct config *next; /* Next configuration in the state */
189227 struct config *bp; /* The next basis configuration */
190228 };
191229
230+enum e_action {
231+ SHIFT,
232+ ACCEPT,
233+ REDUCE,
234+ ERROR,
235+ SSCONFLICT, /* A shift/shift conflict */
236+ SRCONFLICT, /* Was a reduce, but part of a conflict */
237+ RRCONFLICT, /* Was a reduce, but part of a conflict */
238+ SH_RESOLVED, /* Was a shift. Precedence resolved conflict */
239+ RD_RESOLVED, /* Was reduce. Precedence resolved conflict */
240+ NOT_USED, /* Deleted by compression */
241+ SHIFTREDUCE /* Shift first, then reduce */
242+};
243+
192244 /* Every shift or reduce operation is stored as one of the following */
193245 struct action {
194246 struct symbol *sp; /* The look-ahead symbol */
195- enum e_action {
196- SHIFT,
197- ACCEPT,
198- REDUCE,
199- ERROR,
200- SSCONFLICT, /* A shift/shift conflict */
201- SRCONFLICT, /* Was a reduce, but part of a conflict */
202- RRCONFLICT, /* Was a reduce, but part of a conflict */
203- SH_RESOLVED, /* Was a shift. Precedence resolved conflict */
204- RD_RESOLVED, /* Was reduce. Precedence resolved conflict */
205- NOT_USED /* Deleted by compression */
206- } type;
247+ enum e_action type;
207248 union {
208249 struct state *stp; /* The new state, if a shift */
209250 struct rule *rp; /* The rule, if a reduce */
210251 } x;
252+ struct symbol *spOpt; /* SHIFTREDUCE optimization to this symbol */
211253 struct action *next; /* Next action for this state */
212254 struct action *collide; /* Next action with the same hash */
213255 };
@@ -217,11 +259,13 @@
217259 struct state {
218260 struct config *bp; /* The basis configurations for this state */
219261 struct config *cfp; /* All configurations in this set */
220- int statenum; /* Sequencial number for this state */
221- struct action *ap; /* Array of actions for this state */
262+ int statenum; /* Sequential number for this state */
263+ struct action *ap; /* List of actions for this state */
222264 int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */
223265 int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */
224- int iDflt; /* Default action */
266+ int iDfltReduce; /* Default action is to REDUCE by this rule */
267+ struct rule *pDfltReduce;/* The default REDUCE rule. */
268+ int autoReduce; /* True if this is an auto-reduce state */
225269 };
226270 #define NO_OFFSET (-2147483647)
227271
@@ -236,11 +280,13 @@
236280 /* The state vector for the entire parser generator is recorded as
237281 ** follows. (LEMON uses no global variables and makes little use of
238282 ** static variables. Fields in the following structure can be thought
239-** of as begin global variables in the program.) */
283+** of as being global variables in the program.) */
240284 struct lemon {
241285 struct state **sorted; /* Table of states sorted by state number */
242286 struct rule *rule; /* List of all rules */
287+ struct rule *startRule; /* First rule */
243288 int nstate; /* Number of states */
289+ int nxstate; /* nstate with tail degenerate states removed */
244290 int nrule; /* Number of rules */
245291 int nsymbol; /* Number of terminal and nonterminal symbols */
246292 int nterminal; /* Number of terminal symbols */
@@ -255,28 +301,23 @@
255301 char *start; /* Name of the start symbol for the grammar */
256302 char *stacksize; /* Size of the parser stack */
257303 char *include; /* Code to put at the start of the C file */
258- int includeln; /* Line number for start of include code */
259304 char *error; /* Code to execute when an error is seen */
260- int errorln; /* Line number for start of error code */
261305 char *overflow; /* Code to execute on a stack overflow */
262- int overflowln; /* Line number for start of overflow code */
263306 char *failure; /* Code to execute on parser failure */
264- int failureln; /* Line number for start of failure code */
265307 char *accept; /* Code to execute when the parser excepts */
266- int acceptln; /* Line number for the start of accept code */
267308 char *extracode; /* Code appended to the generated file */
268- int extracodeln; /* Line number for the start of the extra code */
269309 char *tokendest; /* Code to execute to destroy token data */
270- int tokendestln; /* Line number for token destroyer code */
271310 char *vardest; /* Code for the default non-terminal destructor */
272- int vardestln; /* Line number for default non-term destructor code*/
273311 char *filename; /* Name of the input file */
312+ char *outbasefilename; /* Name of the input file, with the output dir's path */
274313 char *outname; /* Name of the current output file */
275314 char *tokenprefix; /* A prefix added to token names in the .h file */
276315 int nconflict; /* Number of parsing conflicts */
277- int tablesize; /* Size of the parse tables */
316+ int nactiontab; /* Number of entries in the yy_action[] table */
317+ int tablesize; /* Total table size of all tables in bytes */
278318 int basisflag; /* Print only basis configurations */
279- int has_fallback; /* True if any %fallback is seen in the grammer */
319+ int has_fallback; /* True if any %fallback is seen in the grammar */
320+ int nolinenosflag; /* True if #line statements should not be printed */
280321 char *argv0; /* Name of the program */
281322 };
282323
@@ -297,41 +338,41 @@
297338 /*
298339 ** Code for processing tables in the LEMON parser generator.
299340 */
300-
301341 /* Routines for handling a strings */
302342
303-char *Strsafe();
304-
305-void Strsafe_init(/* void */);
306-int Strsafe_insert(/* char * */);
307-char *Strsafe_find(/* char * */);
343+const char *Strsafe(const char *);
344+
345+void Strsafe_init(void);
346+int Strsafe_insert(const char *);
347+const char *Strsafe_find(const char *);
308348
309349 /* Routines for handling symbols of the grammar */
310350
311-struct symbol *Symbol_new();
312-int Symbolcmpp(/* struct symbol **, struct symbol ** */);
313-void Symbol_init(/* void */);
314-int Symbol_insert(/* struct symbol *, char * */);
315-struct symbol *Symbol_find(/* char * */);
316-struct symbol *Symbol_Nth(/* int */);
317-int Symbol_count(/* */);
318-struct symbol **Symbol_arrayof(/* */);
351+struct symbol *Symbol_new(const char *);
352+int Symbolcmpp(const void *, const void *);
353+void Symbol_init(void);
354+int Symbol_insert(struct symbol *, const char *);
355+struct symbol *Symbol_find(const char *);
356+struct symbol *Symbol_Nth(int);
357+int Symbol_count(void);
358+struct symbol **Symbol_arrayof(void);
319359
320360 /* Routines to manage the state table */
321361
322-int Configcmp(/* struct config *, struct config * */);
323-struct state *State_new();
324-void State_init(/* void */);
325-int State_insert(/* struct state *, struct config * */);
326-struct state *State_find(/* struct config * */);
362+int Configcmp(const char *, const char *);
363+struct state *State_new(void);
364+void State_init(void);
365+int State_insert(struct state *, struct config *);
366+struct state *State_find(struct config *);
327367 struct state **State_arrayof(/* */);
328368
329369 /* Routines used for efficiency in Configlist_add */
330370
331-void Configtable_init(/* void */);
332-int Configtable_insert(/* struct config * */);
333-struct config *Configtable_find(/* struct config * */);
334-void Configtable_clear(/* int(*)(struct config *) */);
371+void Configtable_init(void);
372+int Configtable_insert(struct config *);
373+struct config *Configtable_find(struct config *);
374+void Configtable_clear(int(*)(struct config *));
375+
335376 /****************** From the file "action.c" *******************************/
336377 /*
337378 ** Routines processing parser actions in the LEMON parser generator.
@@ -340,7 +381,7 @@
340381 /* Allocate a new parser action */
341382 static struct action *Action_new(void){
342383 static struct action *freelist = 0;
343- struct action *new;
384+ struct action *newaction;
344385
345386 if( freelist==0 ){
346387 int i;
@@ -353,9 +394,9 @@
353394 for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
354395 freelist[amt-1].next = 0;
355396 }
356- new = freelist;
397+ newaction = freelist;
357398 freelist = freelist->next;
358- return new;
399+ return newaction;
359400 }
360401
361402 /* Compare two actions for sorting purposes. Return negative, zero, or
@@ -371,9 +412,12 @@
371412 if( rc==0 ){
372413 rc = (int)ap1->type - (int)ap2->type;
373414 }
374- if( rc==0 && ap1->type==REDUCE ){
415+ if( rc==0 && (ap1->type==REDUCE || ap1->type==SHIFTREDUCE) ){
375416 rc = ap1->x.rp->index - ap2->x.rp->index;
376417 }
418+ if( rc==0 ){
419+ rc = ap2 - ap1;
420+ }
377421 return rc;
378422 }
379423
@@ -384,22 +428,23 @@
384428 return ap;
385429 }
386430
387-void Action_add(app,type,sp,arg)
388-struct action **app;
389-enum e_action type;
390-struct symbol *sp;
391-char *arg;
392-{
393- struct action *new;
394- new = Action_new();
395- new->next = *app;
396- *app = new;
397- new->type = type;
398- new->sp = sp;
431+void Action_add(
432+ struct action **app,
433+ enum e_action type,
434+ struct symbol *sp,
435+ char *arg
436+){
437+ struct action *newaction;
438+ newaction = Action_new();
439+ newaction->next = *app;
440+ *app = newaction;
441+ newaction->type = type;
442+ newaction->sp = sp;
443+ newaction->spOpt = 0;
399444 if( type==SHIFT ){
400- new->x.stp = (struct state *)arg;
445+ newaction->x.stp = (struct state *)arg;
401446 }else{
402- new->x.rp = (struct rule *)arg;
447+ newaction->x.rp = (struct rule *)arg;
403448 }
404449 }
405450 /********************** New code to implement the "acttab" module ***********/
@@ -409,16 +454,34 @@
409454
410455 /*
411456 ** The state of the yy_action table under construction is an instance of
412-** the following structure
457+** the following structure.
458+**
459+** The yy_action table maps the pair (state_number, lookahead) into an
460+** action_number. The table is an array of integers pairs. The state_number
461+** determines an initial offset into the yy_action array. The lookahead
462+** value is then added to this initial offset to get an index X into the
463+** yy_action array. If the aAction[X].lookahead equals the value of the
464+** of the lookahead input, then the value of the action_number output is
465+** aAction[X].action. If the lookaheads do not match then the
466+** default action for the state_number is returned.
467+**
468+** All actions associated with a single state_number are first entered
469+** into aLookahead[] using multiple calls to acttab_action(). Then the
470+** actions for that single state_number are placed into the aAction[]
471+** array with a single call to acttab_insert(). The acttab_insert() call
472+** also resets the aLookahead[] array in preparation for the next
473+** state number.
413474 */
475+struct lookahead_action {
476+ int lookahead; /* Value of the lookahead token */
477+ int action; /* Action to take on the given lookahead */
478+};
414479 typedef struct acttab acttab;
415480 struct acttab {
416481 int nAction; /* Number of used slots in aAction[] */
417482 int nActionAlloc; /* Slots allocated for aAction[] */
418- struct {
419- int lookahead; /* Value of the lookahead token */
420- int action; /* Action to take on the given lookahead */
421- } *aAction, /* The yy_action[] table under construction */
483+ struct lookahead_action
484+ *aAction, /* The yy_action[] table under construction */
422485 *aLookahead; /* A single new transaction set */
423486 int mnLookahead; /* Minimum aLookahead[].lookahead */
424487 int mnAction; /* Action associated with mnLookahead */
@@ -437,7 +500,8 @@
437500 #define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead)
438501
439502 /* Free all memory associated with the given acttab */
440-void acttab_free(acttab *p){
503+void acttab_free(acttab **pp){
504+ acttab *p = *pp;
441505 free( p->aAction );
442506 free( p->aLookahead );
443507 free( p );
@@ -445,7 +509,7 @@
445509
446510 /* Allocate a new acttab structure */
447511 acttab *acttab_alloc(void){
448- acttab *p = calloc( 1, sizeof(*p) );
512+ acttab *p = (acttab *) calloc( 1, sizeof(*p) );
449513 if( p==0 ){
450514 fprintf(stderr,"Unable to allocate memory for a new acttab.");
451515 exit(1);
@@ -454,12 +518,15 @@
454518 return p;
455519 }
456520
457-/* Add a new action to the current transaction set
521+/* Add a new action to the current transaction set.
522+**
523+** This routine is called once for each lookahead for a particular
524+** state.
458525 */
459526 void acttab_action(acttab *p, int lookahead, int action){
460527 if( p->nLookahead>=p->nLookaheadAlloc ){
461528 p->nLookaheadAlloc += 25;
462- p->aLookahead = realloc( p->aLookahead,
529+ p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead,
463530 sizeof(p->aLookahead[0])*p->nLookaheadAlloc );
464531 if( p->aLookahead==0 ){
465532 fprintf(stderr,"malloc failed\n");
@@ -501,7 +568,7 @@
501568 if( p->nAction + n >= p->nActionAlloc ){
502569 int oldAlloc = p->nActionAlloc;
503570 p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20;
504- p->aAction = realloc( p->aAction,
571+ p->aAction = (struct lookahead_action *) realloc( p->aAction,
505572 sizeof(p->aAction[0])*p->nActionAlloc);
506573 if( p->aAction==0 ){
507574 fprintf(stderr,"malloc failed\n");
@@ -513,28 +580,16 @@
513580 }
514581 }
515582
516- /* Scan the existing action table looking for an offset where we can
517- ** insert the current transaction set. Fall out of the loop when that
518- ** offset is found. In the worst case, we fall out of the loop when
519- ** i reaches p->nAction, which means we append the new transaction set.
583+ /* Scan the existing action table looking for an offset that is a
584+ ** duplicate of the current transaction set. Fall out of the loop
585+ ** if and when the duplicate is found.
520586 **
521587 ** i is the index in p->aAction[] where p->mnLookahead is inserted.
522588 */
523- for(i=0; i<p->nAction+p->mnLookahead; i++){
524- if( p->aAction[i].lookahead<0 ){
525- for(j=0; j<p->nLookahead; j++){
526- k = p->aLookahead[j].lookahead - p->mnLookahead + i;
527- if( k<0 ) break;
528- if( p->aAction[k].lookahead>=0 ) break;
529- }
530- if( j<p->nLookahead ) continue;
531- for(j=0; j<p->nAction; j++){
532- if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
533- }
534- if( j==p->nAction ){
535- break; /* Fits in empty slots */
536- }
537- }else if( p->aAction[i].lookahead==p->mnLookahead ){
589+ for(i=p->nAction-1; i>=0; i--){
590+ if( p->aAction[i].lookahead==p->mnLookahead ){
591+ /* All lookaheads and actions in the aLookahead[] transaction
592+ ** must match against the candidate aAction[i] entry. */
538593 if( p->aAction[i].action!=p->mnAction ) continue;
539594 for(j=0; j<p->nLookahead; j++){
540595 k = p->aLookahead[j].lookahead - p->mnLookahead + i;
@@ -543,13 +598,43 @@
543598 if( p->aLookahead[j].action!=p->aAction[k].action ) break;
544599 }
545600 if( j<p->nLookahead ) continue;
601+
602+ /* No possible lookahead value that is not in the aLookahead[]
603+ ** transaction is allowed to match aAction[i] */
546604 n = 0;
547605 for(j=0; j<p->nAction; j++){
548606 if( p->aAction[j].lookahead<0 ) continue;
549607 if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++;
550608 }
551609 if( n==p->nLookahead ){
552- break; /* Same as a prior transaction set */
610+ break; /* An exact match is found at offset i */
611+ }
612+ }
613+ }
614+
615+ /* If no existing offsets exactly match the current transaction, find an
616+ ** an empty offset in the aAction[] table in which we can add the
617+ ** aLookahead[] transaction.
618+ */
619+ if( i<0 ){
620+ /* Look for holes in the aAction[] table that fit the current
621+ ** aLookahead[] transaction. Leave i set to the offset of the hole.
622+ ** If no holes are found, i is left at p->nAction, which means the
623+ ** transaction will be appended. */
624+ for(i=0; i<p->nActionAlloc - p->mxLookahead; i++){
625+ if( p->aAction[i].lookahead<0 ){
626+ for(j=0; j<p->nLookahead; j++){
627+ k = p->aLookahead[j].lookahead - p->mnLookahead + i;
628+ if( k<0 ) break;
629+ if( p->aAction[k].lookahead>=0 ) break;
630+ }
631+ if( j<p->nLookahead ) continue;
632+ for(j=0; j<p->nAction; j++){
633+ if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
634+ }
635+ if( j==p->nAction ){
636+ break; /* Fits in empty slots */
637+ }
553638 }
554639 }
555640 }
@@ -581,8 +666,7 @@
581666 ** are not RHS symbols with a defined precedence, the precedence
582667 ** symbol field is left blank.
583668 */
584-void FindRulePrecedences(xp)
585-struct lemon *xp;
669+void FindRulePrecedences(struct lemon *xp)
586670 {
587671 struct rule *rp;
588672 for(rp=xp->rule; rp; rp=rp->next){
@@ -611,8 +695,7 @@
611695 ** The first set is the set of all terminal symbols which can begin
612696 ** a string generated by that nonterminal.
613697 */
614-void FindFirstSets(lemp)
615-struct lemon *lemp;
698+void FindFirstSets(struct lemon *lemp)
616699 {
617700 int i, j;
618701 struct rule *rp;
@@ -632,7 +715,8 @@
632715 if( rp->lhs->lambda ) continue;
633716 for(i=0; i<rp->nrhs; i++){
634717 struct symbol *sp = rp->rhs[i];
635- if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break;
718+ assert( sp->type==NONTERMINAL || sp->lambda==LEMON_FALSE );
719+ if( sp->lambda==LEMON_FALSE ) break;
636720 }
637721 if( i==rp->nrhs ){
638722 rp->lhs->lambda = LEMON_TRUE;
@@ -673,9 +757,8 @@
673757 ** are added to between some states so that the LR(1) follow sets
674758 ** can be computed later.
675759 */
676-PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */
677-void FindStates(lemp)
678-struct lemon *lemp;
760+PRIVATE struct state *getstate(struct lemon *); /* forward reference */
761+void FindStates(struct lemon *lemp)
679762 {
680763 struct symbol *sp;
681764 struct rule *rp;
@@ -689,12 +772,12 @@
689772 ErrorMsg(lemp->filename,0,
690773 "The specified start symbol \"%s\" is not \
691774 in a nonterminal of the grammar. \"%s\" will be used as the start \
692-symbol instead.",lemp->start,lemp->rule->lhs->name);
775+symbol instead.",lemp->start,lemp->startRule->lhs->name);
693776 lemp->errorcnt++;
694- sp = lemp->rule->lhs;
777+ sp = lemp->startRule->lhs;
695778 }
696779 }else{
697- sp = lemp->rule->lhs;
780+ sp = lemp->startRule->lhs;
698781 }
699782
700783 /* Make sure the start symbol doesn't occur on the right-hand side of
@@ -733,9 +816,8 @@
733816 /* Return a pointer to a state which is described by the configuration
734817 ** list which has been built from calls to Configlist_add.
735818 */
736-PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */
737-PRIVATE struct state *getstate(lemp)
738-struct lemon *lemp;
819+PRIVATE void buildshifts(struct lemon *, struct state *); /* Forwd ref */
820+PRIVATE struct state *getstate(struct lemon *lemp)
739821 {
740822 struct config *cfp, *bp;
741823 struct state *stp;
@@ -779,9 +861,7 @@
779861 /*
780862 ** Return true if two symbols are the same.
781863 */
782-int same_symbol(a,b)
783-struct symbol *a;
784-struct symbol *b;
864+int same_symbol(struct symbol *a, struct symbol *b)
785865 {
786866 int i;
787867 if( a==b ) return 1;
@@ -797,13 +877,11 @@
797877 /* Construct all successor states to the given state. A "successor"
798878 ** state is any state which can be reached by a shift action.
799879 */
800-PRIVATE void buildshifts(lemp,stp)
801-struct lemon *lemp;
802-struct state *stp; /* The state from which successors are computed */
880+PRIVATE void buildshifts(struct lemon *lemp, struct state *stp)
803881 {
804882 struct config *cfp; /* For looping thru the config closure of "stp" */
805883 struct config *bcfp; /* For the inner loop on config closure of "stp" */
806- struct config *new; /* */
884+ struct config *newcfg; /* */
807885 struct symbol *sp; /* Symbol following the dot in configuration "cfp" */
808886 struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */
809887 struct state *newstp; /* A pointer to a successor state */
@@ -828,8 +906,8 @@
828906 bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */
829907 if( !same_symbol(bsp,sp) ) continue; /* Must be same as for "cfp" */
830908 bcfp->status = COMPLETE; /* Mark this config as used */
831- new = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
832- Plink_add(&new->bplp,bcfp);
909+ newcfg = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
910+ Plink_add(&newcfg->bplp,bcfp);
833911 }
834912
835913 /* Get a pointer to the state described by the basis configuration set
@@ -852,8 +930,7 @@
852930 /*
853931 ** Construct the propagation links
854932 */
855-void FindLinks(lemp)
856-struct lemon *lemp;
933+void FindLinks(struct lemon *lemp)
857934 {
858935 int i;
859936 struct config *cfp, *other;
@@ -888,8 +965,7 @@
888965 ** A followset is the set of all symbols which can come immediately
889966 ** after a configuration.
890967 */
891-void FindFollowSets(lemp)
892-struct lemon *lemp;
968+void FindFollowSets(struct lemon *lemp)
893969 {
894970 int i;
895971 struct config *cfp;
@@ -921,12 +997,11 @@
921997 }while( progress );
922998 }
923999
924-static int resolve_conflict();
1000+static int resolve_conflict(struct action *,struct action *);
9251001
9261002 /* Compute the reduce actions, and resolve conflicts.
9271003 */
928-void FindActions(lemp)
929-struct lemon *lemp;
1004+void FindActions(struct lemon *lemp)
9301005 {
9311006 int i,j;
9321007 struct config *cfp;
@@ -956,9 +1031,9 @@
9561031 /* Add the accepting token */
9571032 if( lemp->start ){
9581033 sp = Symbol_find(lemp->start);
959- if( sp==0 ) sp = lemp->rule->lhs;
1034+ if( sp==0 ) sp = lemp->startRule->lhs;
9601035 }else{
961- sp = lemp->rule->lhs;
1036+ sp = lemp->startRule->lhs;
9621037 }
9631038 /* Add to the first state (which is always the starting state of the
9641039 ** finite state machine) an action to ACCEPT if the lookahead is the
@@ -976,7 +1051,7 @@
9761051 for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
9771052 /* The two actions "ap" and "nap" have the same lookahead.
9781053 ** Figure out which one should be used */
979- lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym);
1054+ lemp->nconflict += resolve_conflict(ap,nap);
9801055 }
9811056 }
9821057 }
@@ -997,7 +1072,7 @@
9971072 }
9981073
9991074 /* Resolve a conflict between the two given actions. If the
1000-** conflict can't be resolve, return non-zero.
1075+** conflict can't be resolved, return non-zero.
10011076 **
10021077 ** NO LONGER TRUE:
10031078 ** To resolve a conflict, first look to see if either action
@@ -1009,11 +1084,10 @@
10091084 ** If either action is a SHIFT, then it must be apx. This
10101085 ** function won't work if apx->type==REDUCE and apy->type==SHIFT.
10111086 */
1012-static int resolve_conflict(apx,apy,errsym)
1013-struct action *apx;
1014-struct action *apy;
1015-struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
1016-{
1087+static int resolve_conflict(
1088+ struct action *apx,
1089+ struct action *apy
1090+){
10171091 struct symbol *spx, *spy;
10181092 int errcnt = 0;
10191093 assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */
@@ -1028,7 +1102,7 @@
10281102 /* Not enough precedence information. */
10291103 apy->type = SRCONFLICT;
10301104 errcnt++;
1031- }else if( spx->prec>spy->prec ){ /* Lower precedence wins */
1105+ }else if( spx->prec>spy->prec ){ /* higher precedence wins */
10321106 apy->type = RD_RESOLVED;
10331107 }else if( spx->prec<spy->prec ){
10341108 apx->type = SH_RESOLVED;
@@ -1038,8 +1112,7 @@
10381112 apx->type = SH_RESOLVED;
10391113 }else{
10401114 assert( spx->prec==spy->prec && spx->assoc==NONE );
1041- apy->type = SRCONFLICT;
1042- errcnt++;
1115+ apy->type = ERROR;
10431116 }
10441117 }else if( apx->type==REDUCE && apy->type==REDUCE ){
10451118 spx = apx->x.rp->precsym;
@@ -1086,7 +1159,7 @@
10861159
10871160 /* Return a pointer to a new configuration */
10881161 PRIVATE struct config *newconfig(){
1089- struct config *new;
1162+ struct config *newcfg;
10901163 if( freelist==0 ){
10911164 int i;
10921165 int amt = 3;
@@ -1098,14 +1171,13 @@
10981171 for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
10991172 freelist[amt-1].next = 0;
11001173 }
1101- new = freelist;
1174+ newcfg = freelist;
11021175 freelist = freelist->next;
1103- return new;
1176+ return newcfg;
11041177 }
11051178
11061179 /* The configuration "old" is no longer used */
1107-PRIVATE void deleteconfig(old)
1108-struct config *old;
1180+PRIVATE void deleteconfig(struct config *old)
11091181 {
11101182 old->next = freelist;
11111183 freelist = old;
@@ -1132,10 +1204,10 @@
11321204 }
11331205
11341206 /* Add another configuration to the configuration list */
1135-struct config *Configlist_add(rp,dot)
1136-struct rule *rp; /* The rule */
1137-int dot; /* Index into the RHS of the rule where the dot goes */
1138-{
1207+struct config *Configlist_add(
1208+ struct rule *rp, /* The rule */
1209+ int dot /* Index into the RHS of the rule where the dot goes */
1210+){
11391211 struct config *cfp, model;
11401212
11411213 assert( currentend!=0 );
@@ -1159,9 +1231,7 @@
11591231 }
11601232
11611233 /* Add a basis configuration to the configuration list */
1162-struct config *Configlist_addbasis(rp,dot)
1163-struct rule *rp;
1164-int dot;
1234+struct config *Configlist_addbasis(struct rule *rp, int dot)
11651235 {
11661236 struct config *cfp, model;
11671237
@@ -1189,8 +1259,7 @@
11891259 }
11901260
11911261 /* Compute the closure of the configuration list */
1192-void Configlist_closure(lemp)
1193-struct lemon *lemp;
1262+void Configlist_closure(struct lemon *lemp)
11941263 {
11951264 struct config *cfp, *newcfp;
11961265 struct rule *rp, *newrp;
@@ -1236,14 +1305,16 @@
12361305
12371306 /* Sort the configuration list */
12381307 void Configlist_sort(){
1239- current = (struct config *)msort(current,&(current->next),Configcmp);
1308+ current = (struct config*)msort((char*)current,(char**)&(current->next),
1309+ Configcmp);
12401310 currentend = 0;
12411311 return;
12421312 }
12431313
12441314 /* Sort the basis configuration list */
12451315 void Configlist_sortbasis(){
1246- basis = (struct config *)msort(current,&(current->bp),Configcmp);
1316+ basis = (struct config *)msort((char*)current,(char**)&(current->bp),
1317+ Configcmp);
12471318 basisend = 0;
12481319 return;
12491320 }
@@ -1269,8 +1340,7 @@
12691340 }
12701341
12711342 /* Free all elements of the given configuration list */
1272-void Configlist_eat(cfp)
1273-struct config *cfp;
1343+void Configlist_eat(struct config *cfp)
12741344 {
12751345 struct config *nextcfp;
12761346 for(; cfp; cfp=nextcfp){
@@ -1287,84 +1357,26 @@
12871357 ** Code for printing error message.
12881358 */
12891359
1290-/* Find a good place to break "msg" so that its length is at least "min"
1291-** but no more than "max". Make the point as close to max as possible.
1292-*/
1293-static int findbreak(msg,min,max)
1294-char *msg;
1295-int min;
1296-int max;
1297-{
1298- int i,spot;
1299- char c;
1300- for(i=spot=min; i<=max; i++){
1301- c = msg[i];
1302- if( c=='\t' ) msg[i] = ' ';
1303- if( c=='\n' ){ msg[i] = ' '; spot = i; break; }
1304- if( c==0 ){ spot = i; break; }
1305- if( c=='-' && i<max-1 ) spot = i+1;
1306- if( c==' ' ) spot = i;
1307- }
1308- return spot;
1309-}
1310-
1311-/*
1312-** The error message is split across multiple lines if necessary. The
1313-** splits occur at a space, if there is a space available near the end
1314-** of the line.
1315-*/
1316-#define ERRMSGSIZE 10000 /* Hope this is big enough. No way to error check */
1317-#if _MSC_VER
1318-#define LINEWIDTH 10000 /* Max width of any output line */
1319-#else
1320-#define LINEWIDTH 79 /* Max width of any output line */
1321-#endif
1322-#define PREFIXLIMIT 3000 /* Max width of the prefix on each line */
13231360 void ErrorMsg(const char *filename, int lineno, const char *format, ...){
1324- char errmsg[ERRMSGSIZE];
1325- char prefix[PREFIXLIMIT+10];
1326- size_t errmsgsize;
1327- size_t prefixsize;
1328- size_t availablewidth;
13291361 va_list ap;
1330- int end, restart, base;
1331-
1332- va_start(ap, format);
1333- /* Prepare a prefix to be prepended to every output line */
1362+
13341363 #if _MSC_VER
13351364 if( lineno>0 ){
1336- sprintf(prefix,"%.*s(%d) : error : ",PREFIXLIMIT-10,filename,lineno);
1365+ fprintf(stderr,"%s(%d) : error : ",filename,lineno);
13371366 }else{
1338- sprintf(prefix,"%.*s : error : ",PREFIXLIMIT-10,filename);
1367+ fprintf(stderr,"%s : error : ",filename);
13391368 }
13401369 #else
13411370 if( lineno>0 ){
1342- sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno);
1371+ fprintf(stderr,"%s:%d: ",filename,lineno);
13431372 }else{
1344- sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename);
1373+ fprintf(stderr,"%s: ",filename);
13451374 }
13461375 #endif
1347- prefixsize = strlen(prefix);
1348- availablewidth = LINEWIDTH - prefixsize;
1349-
1350- /* Generate the error message */
1351- vsprintf(errmsg,format,ap);
1376+ va_start(ap, format);
1377+ vfprintf(stderr,format,ap);
13521378 va_end(ap);
1353- errmsgsize = strlen(errmsg);
1354- /* Remove trailing '\n's from the error message. */
1355- while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){
1356- errmsg[--errmsgsize] = 0;
1357- }
1358-
1359- /* Print the error message */
1360- base = 0;
1361- while( errmsg[base]!=0 ){
1362- end = restart = findbreak(&errmsg[base],0,availablewidth);
1363- restart += base;
1364- while( errmsg[restart]==' ' ) restart++;
1365- fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]);
1366- base = restart;
1367- }
1379+ fprintf(stderr, "\n");
13681380 }
13691381 /**************** From the file "main.c" ************************************/
13701382 /*
@@ -1388,13 +1400,13 @@
13881400 static void handle_D_option(char *z){
13891401 char **paz;
13901402 nDefine++;
1391- azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine);
1403+ azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine);
13921404 if( azDefine==0 ){
13931405 fprintf(stderr,"out of memory\n");
13941406 exit(1);
13951407 }
13961408 paz = &azDefine[nDefine-1];
1397- *paz = malloc( strlen(z)+1 );
1409+ *paz = (char *) malloc( lemonStrlen(z)+1 );
13981410 if( *paz==0 ){
13991411 fprintf(stderr,"out of memory\n");
14001412 exit(1);
@@ -1404,11 +1416,143 @@
14041416 *z = 0;
14051417 }
14061418
1419+static char *user_templatename = NULL;
1420+static void handle_T_option(char *z){
1421+ user_templatename = (char *) malloc( lemonStrlen(z)+1 );
1422+ if( user_templatename==0 ){
1423+ memory_error();
1424+ }
1425+ strcpy(user_templatename, z);
1426+}
1427+
1428+/* Routines for routing output to a different directory than the one
1429+** the source file resides in.
1430+*/
1431+static char *output_dir = NULL;
1432+
1433+static inline Boolean is_seperator(int c)
1434+{
1435+ if (c == '/')
1436+ return LEMON_TRUE;
1437+#if defined(_WIN32) || defined(DOS)
1438+ if (c == '\\' || c == ':')
1439+ return LEMON_TRUE;
1440+#endif
1441+ return LEMON_FALSE;
1442+}
1443+
1444+/* Returns the file part of a pathname.
1445+*/
1446+const char *file_base(const char *path)
1447+{
1448+ const char *src = path + strlen(path) - 1;
1449+ if( src >= path ){
1450+ // back up until a / or the start
1451+ while (src != path && !is_seperator(*(src - 1)))
1452+ src--;
1453+
1454+ // Check for files with drive specification but no path
1455+#if defined(_WIN32) || defined(DOS)
1456+ if( src == path && src[0] != 0 ){
1457+ if( src[1] == ':' )
1458+ src += 2;
1459+ }
1460+#endif
1461+ return src;
1462+ }
1463+ return NULL;
1464+}
1465+
1466+static char *stitch_outdir(char *path)
1467+{
1468+ if( output_dir ){
1469+ const char *base = file_base(path);
1470+ char *newpath = (char *) malloc( lemonStrlen(output_dir) + lemonStrlen(path) + 1 );
1471+ if( newpath==0 ){
1472+ memory_error();
1473+ }
1474+ strcpy(newpath, output_dir);
1475+ strcat(newpath, base);
1476+ return newpath;
1477+ }
1478+ return path;
1479+}
1480+
1481+static void handle_C_option(char *z){
1482+ int len = lemonStrlen(z);
1483+ output_dir = (char *) malloc( len+2 );
1484+ if( output_dir==0 ){
1485+ memory_error();
1486+ }
1487+ strcpy(output_dir, z);
1488+ if( !is_seperator(output_dir[len-1]) ){
1489+ output_dir[len] = '/';
1490+ output_dir[len+1] = '\0';
1491+ }
1492+}
1493+
1494+/* Merge together to lists of rules ordered by rule.iRule */
1495+static struct rule *Rule_merge(struct rule *pA, struct rule *pB){
1496+ struct rule *pFirst = 0;
1497+ struct rule **ppPrev = &pFirst;
1498+ while( pA && pB ){
1499+ if( pA->iRule<pB->iRule ){
1500+ *ppPrev = pA;
1501+ ppPrev = &pA->next;
1502+ pA = pA->next;
1503+ }else{
1504+ *ppPrev = pB;
1505+ ppPrev = &pB->next;
1506+ pB = pB->next;
1507+ }
1508+ }
1509+ if( pA ){
1510+ *ppPrev = pA;
1511+ }else{
1512+ *ppPrev = pB;
1513+ }
1514+ return pFirst;
1515+}
1516+
1517+/*
1518+** Sort a list of rules in order of increasing iRule value
1519+*/
1520+static struct rule *Rule_sort(struct rule *rp){
1521+ int i;
1522+ struct rule *pNext;
1523+ struct rule *x[32];
1524+ memset(x, 0, sizeof(x));
1525+ while( rp ){
1526+ pNext = rp->next;
1527+ rp->next = 0;
1528+ for(i=0; i<sizeof(x)/sizeof(x[0]) && x[i]; i++){
1529+ rp = Rule_merge(x[i], rp);
1530+ x[i] = 0;
1531+ }
1532+ x[i] = rp;
1533+ rp = pNext;
1534+ }
1535+ rp = 0;
1536+ for(i=0; i<sizeof(x)/sizeof(x[0]); i++){
1537+ rp = Rule_merge(x[i], rp);
1538+ }
1539+ return rp;
1540+}
1541+
1542+/* forward reference */
1543+static const char *minimum_size_type(int lwr, int upr, int *pnByte);
1544+
1545+/* Print a single line of the "Parser Stats" output
1546+*/
1547+static void stats_line(const char *zLabel, int iValue){
1548+ int nLabel = lemonStrlen(zLabel);
1549+ printf(" %s%.*s %5d\n", zLabel,
1550+ 35-nLabel, "................................",
1551+ iValue);
1552+}
14071553
14081554 /* The main program. Parse the command line and do it... */
1409-int main(argc,argv)
1410-int argc;
1411-char **argv;
1555+int main(int argc, char **argv)
14121556 {
14131557 static int version = 0;
14141558 static int rpflag = 0;
@@ -1417,20 +1561,33 @@
14171561 static int quiet = 0;
14181562 static int statistics = 0;
14191563 static int mhflag = 0;
1564+ static int nolinenosflag = 0;
1565+ static int noResort = 0;
14201566 static struct s_options options[] = {
14211567 {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},
14221568 {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},
1569+ {OPT_FSTR, "C", (char*)handle_C_option, "Write output files to a different directory."},
14231570 {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
1571+ {OPT_FSTR, "f", 0, "Ignored. (Placeholder for -f compiler options.)"},
14241572 {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
1425- {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file"},
1573+ {OPT_FSTR, "I", 0, "Ignored. (Placeholder for '-I' compiler options.)"},
1574+ {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."},
1575+ {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."},
1576+ {OPT_FSTR, "O", 0, "Ignored. (Placeholder for '-O' compiler options.)"},
1577+ {OPT_FLAG, "p", (char*)&showPrecedenceConflict,
1578+ "Show conflicts resolved by precedence rules"},
14261579 {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."},
1580+ {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"},
14271581 {OPT_FLAG, "s", (char*)&statistics,
14281582 "Print parser stats to standard output."},
14291583 {OPT_FLAG, "x", (char*)&version, "Print the version number."},
1584+ {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
1585+ {OPT_FSTR, "W", 0, "Ignored. (Placeholder for '-W' compiler options.)"},
14301586 {OPT_FLAG,0,0,0}
14311587 };
14321588 int i;
14331589 struct lemon lem;
1590+ struct rule *rp;
14341591
14351592 OptInit(argv,options,stderr);
14361593 if( version ){
@@ -1450,7 +1607,9 @@
14501607 State_init();
14511608 lem.argv0 = argv[0];
14521609 lem.filename = OptArg(0);
1610+ lem.outbasefilename = stitch_outdir(lem.filename);
14531611 lem.basisflag = basisflag;
1612+ lem.nolinenosflag = nolinenosflag;
14541613 Symbol_new("$");
14551614 lem.errsym = Symbol_new("error");
14561615 lem.errsym->useCnt = 0;
@@ -1464,16 +1623,31 @@
14641623 }
14651624
14661625 /* Count and index the symbols of the grammar */
1626+ Symbol_new("{default}");
14671627 lem.nsymbol = Symbol_count();
1468- Symbol_new("{default}");
14691628 lem.symbols = Symbol_arrayof();
1470- for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
1471- qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*),
1472- (int(*)(const void*, const void*))Symbolcmpp);
1473- for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
1474- for(i=1; isupper(lem.symbols[i]->name[0]); i++);
1629+ for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1630+ qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp);
1631+ for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1632+ while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; }
1633+ assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 );
1634+ lem.nsymbol = i - 1;
1635+ for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++);
14751636 lem.nterminal = i;
14761637
1638+ /* Assign sequential rule numbers. Start with 0. Put rules that have no
1639+ ** reduce action C-code associated with them last, so that the switch()
1640+ ** statement that selects reduction actions will have a smaller jump table.
1641+ */
1642+ for(i=0, rp=lem.rule; rp; rp=rp->next){
1643+ rp->iRule = rp->code ? i++ : -1;
1644+ }
1645+ for(rp=lem.rule; rp; rp=rp->next){
1646+ if( rp->iRule<0 ) rp->iRule = i++;
1647+ }
1648+ lem.startRule = lem.rule;
1649+ lem.rule = Rule_sort(lem.rule);
1650+
14771651 /* Generate a reprint of the grammar, if requested on the command line */
14781652 if( rpflag ){
14791653 Reprint(&lem);
@@ -1507,8 +1681,9 @@
15071681 if( compress==0 ) CompressTables(&lem);
15081682
15091683 /* Reorder and renumber the states so that states with fewer choices
1510- ** occur at the end. */
1511- ResortStates(&lem);
1684+ ** occur at the end. This is an optimization that helps make the
1685+ ** generated parser tables smaller. */
1686+ if( noResort==0 ) ResortStates(&lem);
15121687
15131688 /* Generate a report of the parser generated. (the "y.output" file) */
15141689 if( !quiet ) ReportOutput(&lem);
@@ -1522,10 +1697,15 @@
15221697 if( !mhflag ) ReportHeader(&lem);
15231698 }
15241699 if( statistics ){
1525- printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n",
1526- lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule);
1527- printf(" %d states, %d parser table entries, %d conflicts\n",
1528- lem.nstate, lem.tablesize, lem.nconflict);
1700+ printf("Parser statistics:\n");
1701+ stats_line("terminal symbols", lem.nterminal);
1702+ stats_line("non-terminal symbols", lem.nsymbol - lem.nterminal);
1703+ stats_line("total symbols", lem.nsymbol);
1704+ stats_line("rules", lem.nrule);
1705+ stats_line("states", lem.nxstate);
1706+ stats_line("conflicts", lem.nconflict);
1707+ stats_line("action table entries", lem.nactiontab);
1708+ stats_line("total table size (bytes)", lem.tablesize);
15291709 }
15301710 if( lem.nconflict ){
15311711 fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
@@ -1586,7 +1766,7 @@
15861766 }else if( b==0 ){
15871767 head = a;
15881768 }else{
1589- if( (*cmp)(a,b)<0 ){
1769+ if( (*cmp)(a,b)<=0 ){
15901770 ptr = a;
15911771 a = NEXT(a);
15921772 }else{
@@ -1595,7 +1775,7 @@
15951775 }
15961776 head = ptr;
15971777 while( a && b ){
1598- if( (*cmp)(a,b)<0 ){
1778+ if( (*cmp)(a,b)<=0 ){
15991779 NEXT(ptr) = a;
16001780 ptr = a;
16011781 a = NEXT(a);
@@ -1644,7 +1824,7 @@
16441824 set[i] = ep;
16451825 }
16461826 ep = 0;
1647- for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(ep,set[i],cmp,offset);
1827+ for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset);
16481828 return ep;
16491829 }
16501830 /************************ From the file "option.c" **************************/
@@ -1658,18 +1838,15 @@
16581838 ** Print the command line with a carrot pointing to the k-th character
16591839 ** of the n-th field.
16601840 */
1661-static void errline(n,k,err)
1662-int n;
1663-int k;
1664-FILE *err;
1841+static void errline(int n, int k, FILE *err)
16651842 {
16661843 int i;
16671844 size_t spcnt;
16681845 if( argv[0] ) fprintf(err,"%s",argv[0]);
1669- spcnt = strlen(argv[0]) + 1;
1846+ spcnt = lemonStrlen(argv[0]) + 1;
16701847 for(i=1; i<n && argv[i]; i++){
16711848 fprintf(err," %s",argv[i]);
1672- spcnt += strlen(argv[i])+1;
1849+ spcnt += lemonStrlen(argv[i])+1;
16731850 }
16741851 spcnt += k;
16751852 for(; argv[i]; i++) fprintf(err," %s",argv[i]);
@@ -1684,8 +1861,7 @@
16841861 ** Return the index of the N-th non-switch argument. Return -1
16851862 ** if N is out of range.
16861863 */
1687-static int argindex(n)
1688-int n;
1864+static int argindex(int n)
16891865 {
16901866 int i;
16911867 int dashdash = 0;
@@ -1706,15 +1882,13 @@
17061882 /*
17071883 ** Process a flag command line argument.
17081884 */
1709-static int handleflags(i,err)
1710-int i;
1711-FILE *err;
1885+static int handleflags(int i, FILE *err)
17121886 {
17131887 int v;
17141888 int errcnt = 0;
17151889 int j;
17161890 for(j=0; op[j].label; j++){
1717- if( strncmp(&argv[i][1],op[j].label,strlen(op[j].label))==0 ) break;
1891+ if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break;
17181892 }
17191893 v = argv[i][0]=='-' ? 1 : 0;
17201894 if( op[j].label==0 ){
@@ -1723,12 +1897,14 @@
17231897 errline(i,1,err);
17241898 }
17251899 errcnt++;
1900+ }else if( op[j].arg==0 ){
1901+ /* Ignore this option */
17261902 }else if( op[j].type==OPT_FLAG ){
17271903 *((int*)op[j].arg) = v;
17281904 }else if( op[j].type==OPT_FFLAG ){
1729- (*(void(*)())(op[j].arg))(v);
1905+ (*(void(*)(int))(op[j].arg))(v);
17301906 }else if( op[j].type==OPT_FSTR ){
1731- (*(void(*)())(op[j].arg))(&argv[i][2]);
1907+ (*(void(*)(char *))(op[j].arg))(&argv[i][2]);
17321908 }else{
17331909 if( err ){
17341910 fprintf(err,"%smissing argument on switch.\n",emsg);
@@ -1742,9 +1918,7 @@
17421918 /*
17431919 ** Process a command line switch which has an argument.
17441920 */
1745-static int handleswitch(i,err)
1746-int i;
1747-FILE *err;
1921+static int handleswitch(int i, FILE *err)
17481922 {
17491923 int lv = 0;
17501924 double dv = 0.0;
@@ -1781,7 +1955,8 @@
17811955 dv = strtod(cp,&end);
17821956 if( *end ){
17831957 if( err ){
1784- fprintf(err,"%sillegal character in floating-point argument.\n",emsg);
1958+ fprintf(err,
1959+ "%sillegal character in floating-point argument.\n",emsg);
17851960 errline(i,((size_t)end)-(size_t)argv[i],err);
17861961 }
17871962 errcnt++;
@@ -1811,29 +1986,26 @@
18111986 *(double*)(op[j].arg) = dv;
18121987 break;
18131988 case OPT_FDBL:
1814- (*(void(*)())(op[j].arg))(dv);
1989+ (*(void(*)(double))(op[j].arg))(dv);
18151990 break;
18161991 case OPT_INT:
18171992 *(int*)(op[j].arg) = lv;
18181993 break;
18191994 case OPT_FINT:
1820- (*(void(*)())(op[j].arg))((int)lv);
1995+ (*(void(*)(int))(op[j].arg))((int)lv);
18211996 break;
18221997 case OPT_STR:
18231998 *(char**)(op[j].arg) = sv;
18241999 break;
18252000 case OPT_FSTR:
1826- (*(void(*)())(op[j].arg))(sv);
2001+ (*(void(*)(char *))(op[j].arg))(sv);
18272002 break;
18282003 }
18292004 }
18302005 return errcnt;
18312006 }
18322007
1833-int OptInit(a,o,err)
1834-char **a;
1835-struct s_options *o;
1836-FILE *err;
2008+int OptInit(char **a, struct s_options *o, FILE *err)
18372009 {
18382010 int errcnt = 0;
18392011 argv = a;
@@ -1870,16 +2042,14 @@
18702042 return cnt;
18712043 }
18722044
1873-char *OptArg(n)
1874-int n;
2045+char *OptArg(int n)
18752046 {
18762047 int i;
18772048 i = argindex(n);
18782049 return i>=0 ? argv[i] : 0;
18792050 }
18802051
1881-void OptErr(n)
1882-int n;
2052+void OptErr(int n)
18832053 {
18842054 int i;
18852055 i = argindex(n);
@@ -1891,7 +2061,7 @@
18912061 size_t max, len;
18922062 max = 0;
18932063 for(i=0; op[i].label; i++){
1894- len = strlen(op[i].label) + 1;
2064+ len = lemonStrlen(op[i].label) + 1;
18952065 switch( op[i].type ){
18962066 case OPT_FLAG:
18972067 case OPT_FFLAG:
@@ -1919,18 +2089,18 @@
19192089 break;
19202090 case OPT_INT:
19212091 case OPT_FINT:
1922- fprintf(errstream," %s=<integer>%*s %s\n",op[i].label,
1923- (int)(max-strlen(op[i].label)-9),"",op[i].message);
2092+ fprintf(errstream," -%s<integer>%*s %s\n",op[i].label,
2093+ (int)(max-lemonStrlen(op[i].label)-9),"",op[i].message);
19242094 break;
19252095 case OPT_DBL:
19262096 case OPT_FDBL:
1927- fprintf(errstream," %s=<real>%*s %s\n",op[i].label,
1928- (int)(max-strlen(op[i].label)-6),"",op[i].message);
2097+ fprintf(errstream," -%s<real>%*s %s\n",op[i].label,
2098+ (int)(max-lemonStrlen(op[i].label)-6),"",op[i].message);
19292099 break;
19302100 case OPT_STR:
19312101 case OPT_FSTR:
1932- fprintf(errstream," %s=<string>%*s %s\n",op[i].label,
1933- (int)(max-strlen(op[i].label)-8),"",op[i].message);
2102+ fprintf(errstream," -%s<string>%*s %s\n",op[i].label,
2103+ (int)(max-lemonStrlen(op[i].label)-8),"",op[i].message);
19342104 break;
19352105 }
19362106 }
@@ -1941,44 +2111,49 @@
19412111 */
19422112
19432113 /* The state of the parser */
2114+enum e_state {
2115+ INITIALIZE,
2116+ WAITING_FOR_DECL_OR_RULE,
2117+ WAITING_FOR_DECL_KEYWORD,
2118+ WAITING_FOR_DECL_ARG,
2119+ WAITING_FOR_PRECEDENCE_SYMBOL,
2120+ WAITING_FOR_ARROW,
2121+ IN_RHS,
2122+ LHS_ALIAS_1,
2123+ LHS_ALIAS_2,
2124+ LHS_ALIAS_3,
2125+ RHS_ALIAS_1,
2126+ RHS_ALIAS_2,
2127+ PRECEDENCE_MARK_1,
2128+ PRECEDENCE_MARK_2,
2129+ RESYNC_AFTER_RULE_ERROR,
2130+ RESYNC_AFTER_DECL_ERROR,
2131+ WAITING_FOR_DESTRUCTOR_SYMBOL,
2132+ WAITING_FOR_DATATYPE_SYMBOL,
2133+ WAITING_FOR_FALLBACK_ID,
2134+ WAITING_FOR_WILDCARD_ID,
2135+ WAITING_FOR_CLASS_ID,
2136+ WAITING_FOR_CLASS_TOKEN
2137+};
19442138 struct pstate {
19452139 char *filename; /* Name of the input file */
19462140 int tokenlineno; /* Linenumber at which current token starts */
19472141 int errorcnt; /* Number of errors so far */
19482142 char *tokenstart; /* Text of current token */
19492143 struct lemon *gp; /* Global state vector */
1950- enum e_state {
1951- INITIALIZE,
1952- WAITING_FOR_DECL_OR_RULE,
1953- WAITING_FOR_DECL_KEYWORD,
1954- WAITING_FOR_DECL_ARG,
1955- WAITING_FOR_PRECEDENCE_SYMBOL,
1956- WAITING_FOR_ARROW,
1957- IN_RHS,
1958- LHS_ALIAS_1,
1959- LHS_ALIAS_2,
1960- LHS_ALIAS_3,
1961- RHS_ALIAS_1,
1962- RHS_ALIAS_2,
1963- PRECEDENCE_MARK_1,
1964- PRECEDENCE_MARK_2,
1965- RESYNC_AFTER_RULE_ERROR,
1966- RESYNC_AFTER_DECL_ERROR,
1967- WAITING_FOR_DESTRUCTOR_SYMBOL,
1968- WAITING_FOR_DATATYPE_SYMBOL,
1969- WAITING_FOR_FALLBACK_ID,
1970- WAITING_FOR_WILDCARD_ID
1971- } state; /* The state of the parser */
2144+ enum e_state state; /* The state of the parser */
19722145 struct symbol *fallback; /* The fallback token */
2146+ struct symbol *tkclass; /* Token class symbol */
19732147 struct symbol *lhs; /* Left-hand side of current rule */
1974- char *lhsalias; /* Alias for the LHS */
2148+ const char *lhsalias; /* Alias for the LHS */
19752149 int nrhs; /* Number of right-hand side symbols seen */
19762150 struct symbol *rhs[MAXRHS]; /* RHS symbols */
1977- char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */
2151+ const char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */
19782152 struct rule *prevrule; /* Previous rule parsed */
1979- char *declkeyword; /* Keyword of a declaration */
2153+ const char *declkeyword; /* Keyword of a declaration */
19802154 char **declargslot; /* Where the declaration argument should be put */
1981- int *decllnslot; /* Where the declaration linenumber is put */
2155+ int insertLineMacro; /* Add #line before declaration insert */
2156+ int *decllinenoslot; /* Where to write declaration line number */
19822157 enum e_assoc declassoc; /* Assign this association to decl arguments */
19832158 int preccounter; /* Assign this precedence to decl arguments */
19842159 struct rule *firstrule; /* Pointer to first rule in the grammar */
@@ -1986,10 +2161,9 @@
19862161 };
19872162
19882163 /* Parse a single token */
1989-static void parseonetoken(psp)
1990-struct pstate *psp;
2164+static void parseonetoken(struct pstate *psp)
19912165 {
1992- char *x;
2166+ const char *x;
19932167 x = Strsafe(psp->tokenstart); /* Save the token permanently */
19942168 #if 0
19952169 printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno,
@@ -2005,7 +2179,7 @@
20052179 case WAITING_FOR_DECL_OR_RULE:
20062180 if( x[0]=='%' ){
20072181 psp->state = WAITING_FOR_DECL_KEYWORD;
2008- }else if( islower(x[0]) ){
2182+ }else if( ISLOWER(x[0]) ){
20092183 psp->lhs = Symbol_new(x);
20102184 psp->nrhs = 0;
20112185 psp->lhsalias = 0;
@@ -2013,10 +2187,10 @@
20132187 }else if( x[0]=='{' ){
20142188 if( psp->prevrule==0 ){
20152189 ErrorMsg(psp->filename,psp->tokenlineno,
2016-"There is not prior rule opon which to attach the code \
2190+"There is no prior rule upon which to attach the code \
20172191 fragment which begins on this line.");
20182192 psp->errorcnt++;
2019- }else if( psp->prevrule->code!=0 ){
2193+ }else if( psp->prevrule->code!=0 ){
20202194 ErrorMsg(psp->filename,psp->tokenlineno,
20212195 "Code fragment beginning on this line is not the first \
20222196 to follow the previous rule.");
@@ -2024,7 +2198,8 @@
20242198 }else{
20252199 psp->prevrule->line = psp->tokenlineno;
20262200 psp->prevrule->code = &x[1];
2027- }
2201+ psp->prevrule->noCode = 0;
2202+ }
20282203 }else if( x[0]=='[' ){
20292204 psp->state = PRECEDENCE_MARK_1;
20302205 }else{
@@ -2035,7 +2210,7 @@
20352210 }
20362211 break;
20372212 case PRECEDENCE_MARK_1:
2038- if( !isupper(x[0]) ){
2213+ if( !ISUPPER(x[0]) ){
20392214 ErrorMsg(psp->filename,psp->tokenlineno,
20402215 "The precedence symbol must be a terminal.");
20412216 psp->errorcnt++;
@@ -2075,7 +2250,7 @@
20752250 }
20762251 break;
20772252 case LHS_ALIAS_1:
2078- if( isalpha(x[0]) ){
2253+ if( ISALPHA(x[0]) ){
20792254 psp->lhsalias = x;
20802255 psp->state = LHS_ALIAS_2;
20812256 }else{
@@ -2121,7 +2296,7 @@
21212296 int i;
21222297 rp->ruleline = psp->tokenlineno;
21232298 rp->rhs = (struct symbol**)&rp[1];
2124- rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]);
2299+ rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
21252300 for(i=0; i<psp->nrhs; i++){
21262301 rp->rhs[i] = psp->rhs[i];
21272302 rp->rhsalias[i] = psp->alias[i];
@@ -2130,6 +2305,7 @@
21302305 rp->lhsalias = psp->lhsalias;
21312306 rp->nrhs = psp->nrhs;
21322307 rp->code = 0;
2308+ rp->noCode = 1;
21332309 rp->precsym = 0;
21342310 rp->index = psp->gp->nrule++;
21352311 rp->nextlhs = rp->lhs->rule;
@@ -2140,11 +2316,11 @@
21402316 }else{
21412317 psp->lastrule->next = rp;
21422318 psp->lastrule = rp;
2143- }
2319+ }
21442320 psp->prevrule = rp;
2145- }
2321+ }
21462322 psp->state = WAITING_FOR_DECL_OR_RULE;
2147- }else if( isalpha(x[0]) ){
2323+ }else if( ISALPHA(x[0]) ){
21482324 if( psp->nrhs>=MAXRHS ){
21492325 ErrorMsg(psp->filename,psp->tokenlineno,
21502326 "Too many symbols on RHS of rule beginning at \"%s\".",
@@ -2160,18 +2336,19 @@
21602336 struct symbol *msp = psp->rhs[psp->nrhs-1];
21612337 if( msp->type!=MULTITERMINAL ){
21622338 struct symbol *origsp = msp;
2163- msp = calloc(1,sizeof(*msp));
2339+ msp = (struct symbol *) calloc(1,sizeof(*msp));
21642340 msp->type = MULTITERMINAL;
21652341 msp->nsubsym = 1;
2166- msp->subsym = calloc(1,sizeof(struct symbol*));
2342+ msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*));
21672343 msp->subsym[0] = origsp;
21682344 msp->name = origsp->name;
21692345 psp->rhs[psp->nrhs-1] = msp;
21702346 }
21712347 msp->nsubsym++;
2172- msp->subsym = realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym);
2348+ msp->subsym = (struct symbol **) realloc(msp->subsym,
2349+ sizeof(struct symbol*)*msp->nsubsym);
21732350 msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]);
2174- if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){
2351+ if( ISLOWER(x[1]) || ISLOWER(msp->subsym[0]->name[0]) ){
21752352 ErrorMsg(psp->filename,psp->tokenlineno,
21762353 "Cannot form a compound containing a non-terminal");
21772354 psp->errorcnt++;
@@ -2186,7 +2363,7 @@
21862363 }
21872364 break;
21882365 case RHS_ALIAS_1:
2189- if( isalpha(x[0]) ){
2366+ if( ISALPHA(x[0]) ){
21902367 psp->alias[psp->nrhs-1] = x;
21912368 psp->state = RHS_ALIAS_2;
21922369 }else{
@@ -2208,49 +2385,49 @@
22082385 }
22092386 break;
22102387 case WAITING_FOR_DECL_KEYWORD:
2211- if( isalpha(x[0]) ){
2388+ if( ISALPHA(x[0]) ){
22122389 psp->declkeyword = x;
22132390 psp->declargslot = 0;
2214- psp->decllnslot = 0;
2391+ psp->decllinenoslot = 0;
2392+ psp->insertLineMacro = 1;
22152393 psp->state = WAITING_FOR_DECL_ARG;
22162394 if( strcmp(x,"name")==0 ){
22172395 psp->declargslot = &(psp->gp->name);
2396+ psp->insertLineMacro = 0;
22182397 }else if( strcmp(x,"include")==0 ){
22192398 psp->declargslot = &(psp->gp->include);
2220- psp->decllnslot = &psp->gp->includeln;
22212399 }else if( strcmp(x,"code")==0 ){
22222400 psp->declargslot = &(psp->gp->extracode);
2223- psp->decllnslot = &psp->gp->extracodeln;
22242401 }else if( strcmp(x,"token_destructor")==0 ){
22252402 psp->declargslot = &psp->gp->tokendest;
2226- psp->decllnslot = &psp->gp->tokendestln;
22272403 }else if( strcmp(x,"default_destructor")==0 ){
22282404 psp->declargslot = &psp->gp->vardest;
2229- psp->decllnslot = &psp->gp->vardestln;
22302405 }else if( strcmp(x,"token_prefix")==0 ){
22312406 psp->declargslot = &psp->gp->tokenprefix;
2407+ psp->insertLineMacro = 0;
22322408 }else if( strcmp(x,"syntax_error")==0 ){
22332409 psp->declargslot = &(psp->gp->error);
2234- psp->decllnslot = &psp->gp->errorln;
22352410 }else if( strcmp(x,"parse_accept")==0 ){
22362411 psp->declargslot = &(psp->gp->accept);
2237- psp->decllnslot = &psp->gp->acceptln;
22382412 }else if( strcmp(x,"parse_failure")==0 ){
22392413 psp->declargslot = &(psp->gp->failure);
2240- psp->decllnslot = &psp->gp->failureln;
22412414 }else if( strcmp(x,"stack_overflow")==0 ){
22422415 psp->declargslot = &(psp->gp->overflow);
2243- psp->decllnslot = &psp->gp->overflowln;
22442416 }else if( strcmp(x,"extra_argument")==0 ){
22452417 psp->declargslot = &(psp->gp->arg);
2418+ psp->insertLineMacro = 0;
22462419 }else if( strcmp(x,"token_type")==0 ){
22472420 psp->declargslot = &(psp->gp->tokentype);
2421+ psp->insertLineMacro = 0;
22482422 }else if( strcmp(x,"default_type")==0 ){
22492423 psp->declargslot = &(psp->gp->vartype);
2424+ psp->insertLineMacro = 0;
22502425 }else if( strcmp(x,"stack_size")==0 ){
22512426 psp->declargslot = &(psp->gp->stacksize);
2427+ psp->insertLineMacro = 0;
22522428 }else if( strcmp(x,"start_symbol")==0 ){
22532429 psp->declargslot = &(psp->gp->start);
2430+ psp->insertLineMacro = 0;
22542431 }else if( strcmp(x,"left")==0 ){
22552432 psp->preccounter++;
22562433 psp->declassoc = LEFT;
@@ -2272,6 +2449,8 @@
22722449 psp->state = WAITING_FOR_FALLBACK_ID;
22732450 }else if( strcmp(x,"wildcard")==0 ){
22742451 psp->state = WAITING_FOR_WILDCARD_ID;
2452+ }else if( strcmp(x,"token_class")==0 ){
2453+ psp->state = WAITING_FOR_CLASS_ID;
22752454 }else{
22762455 ErrorMsg(psp->filename,psp->tokenlineno,
22772456 "Unknown declaration keyword: \"%%%s\".",x);
@@ -2286,7 +2465,7 @@
22862465 }
22872466 break;
22882467 case WAITING_FOR_DESTRUCTOR_SYMBOL:
2289- if( !isalpha(x[0]) ){
2468+ if( !ISALPHA(x[0]) ){
22902469 ErrorMsg(psp->filename,psp->tokenlineno,
22912470 "Symbol name missing after %%destructor keyword");
22922471 psp->errorcnt++;
@@ -2294,27 +2473,38 @@
22942473 }else{
22952474 struct symbol *sp = Symbol_new(x);
22962475 psp->declargslot = &sp->destructor;
2297- psp->decllnslot = &sp->destructorln;
2476+ psp->decllinenoslot = &sp->destLineno;
2477+ psp->insertLineMacro = 1;
22982478 psp->state = WAITING_FOR_DECL_ARG;
22992479 }
23002480 break;
23012481 case WAITING_FOR_DATATYPE_SYMBOL:
2302- if( !isalpha(x[0]) ){
2482+ if( !ISALPHA(x[0]) ){
23032483 ErrorMsg(psp->filename,psp->tokenlineno,
2304- "Symbol name missing after %%destructor keyword");
2484+ "Symbol name missing after %%type keyword");
23052485 psp->errorcnt++;
23062486 psp->state = RESYNC_AFTER_DECL_ERROR;
23072487 }else{
2308- struct symbol *sp = Symbol_new(x);
2309- psp->declargslot = &sp->datatype;
2310- psp->decllnslot = 0;
2311- psp->state = WAITING_FOR_DECL_ARG;
2488+ struct symbol *sp = Symbol_find(x);
2489+ if((sp) && (sp->datatype)){
2490+ ErrorMsg(psp->filename,psp->tokenlineno,
2491+ "Symbol %%type \"%s\" already defined", x);
2492+ psp->errorcnt++;
2493+ psp->state = RESYNC_AFTER_DECL_ERROR;
2494+ }else{
2495+ if (!sp){
2496+ sp = Symbol_new(x);
2497+ }
2498+ psp->declargslot = &sp->datatype;
2499+ psp->insertLineMacro = 0;
2500+ psp->state = WAITING_FOR_DECL_ARG;
2501+ }
23122502 }
23132503 break;
23142504 case WAITING_FOR_PRECEDENCE_SYMBOL:
23152505 if( x[0]=='.' ){
23162506 psp->state = WAITING_FOR_DECL_OR_RULE;
2317- }else if( isupper(x[0]) ){
2507+ }else if( ISUPPER(x[0]) ){
23182508 struct symbol *sp;
23192509 sp = Symbol_new(x);
23202510 if( sp->prec>=0 ){
@@ -2332,18 +2522,57 @@
23322522 }
23332523 break;
23342524 case WAITING_FOR_DECL_ARG:
2335- if( (x[0]=='{' || x[0]=='\"' || isalnum(x[0])) ){
2336- if( *(psp->declargslot)!=0 ){
2337- ErrorMsg(psp->filename,psp->tokenlineno,
2338- "The argument \"%s\" to declaration \"%%%s\" is not the first.",
2339- x[0]=='\"' ? &x[1] : x,psp->declkeyword);
2340- psp->errorcnt++;
2341- psp->state = RESYNC_AFTER_DECL_ERROR;
2342- }else{
2343- *(psp->declargslot) = (x[0]=='\"' || x[0]=='{') ? &x[1] : x;
2344- if( psp->decllnslot ) *psp->decllnslot = psp->tokenlineno;
2345- psp->state = WAITING_FOR_DECL_OR_RULE;
2346- }
2525+ if( x[0]=='{' || x[0]=='\"' || ISALNUM(x[0]) ){
2526+ const char *zOld, *zNew;
2527+ char *zBuf, *z;
2528+ int nOld, n, nLine, nNew, nBack;
2529+ int addLineMacro;
2530+ char zLine[50];
2531+ zNew = x;
2532+ if( zNew[0]=='"' || zNew[0]=='{' ) zNew++;
2533+ nNew = lemonStrlen(zNew);
2534+ if( *psp->declargslot ){
2535+ zOld = *psp->declargslot;
2536+ }else{
2537+ zOld = "";
2538+ }
2539+ nOld = lemonStrlen(zOld);
2540+ n = nOld + nNew + 20;
2541+ addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro &&
2542+ (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0);
2543+ if( addLineMacro ){
2544+ for(z=psp->filename, nBack=0; *z; z++){
2545+ if( *z=='\\' ) nBack++;
2546+ }
2547+ sprintf(zLine, "#line %d ", psp->tokenlineno);
2548+ nLine = lemonStrlen(zLine);
2549+ n += nLine + lemonStrlen(psp->filename) + nBack;
2550+ }
2551+ *psp->declargslot = (char *) realloc(*psp->declargslot, n);
2552+ zBuf = *psp->declargslot + nOld;
2553+ if( addLineMacro ){
2554+ if( nOld && zBuf[-1]!='\n' ){
2555+ *(zBuf++) = '\n';
2556+ }
2557+ memcpy(zBuf, zLine, nLine);
2558+ zBuf += nLine;
2559+ *(zBuf++) = '"';
2560+ for(z=psp->filename; *z; z++){
2561+ if( *z=='\\' ){
2562+ *(zBuf++) = '\\';
2563+ }
2564+ *(zBuf++) = *z;
2565+ }
2566+ *(zBuf++) = '"';
2567+ *(zBuf++) = '\n';
2568+ }
2569+ if( psp->decllinenoslot && psp->decllinenoslot[0]==0 ){
2570+ psp->decllinenoslot[0] = psp->tokenlineno;
2571+ }
2572+ memcpy(zBuf, zNew, nNew);
2573+ zBuf += nNew;
2574+ *zBuf = 0;
2575+ psp->state = WAITING_FOR_DECL_OR_RULE;
23472576 }else{
23482577 ErrorMsg(psp->filename,psp->tokenlineno,
23492578 "Illegal argument to %%%s: %s",psp->declkeyword,x);
@@ -2354,7 +2583,7 @@
23542583 case WAITING_FOR_FALLBACK_ID:
23552584 if( x[0]=='.' ){
23562585 psp->state = WAITING_FOR_DECL_OR_RULE;
2357- }else if( !isupper(x[0]) ){
2586+ }else if( !ISUPPER(x[0]) ){
23582587 ErrorMsg(psp->filename, psp->tokenlineno,
23592588 "%%fallback argument \"%s\" should be a token", x);
23602589 psp->errorcnt++;
@@ -2375,7 +2604,7 @@
23752604 case WAITING_FOR_WILDCARD_ID:
23762605 if( x[0]=='.' ){
23772606 psp->state = WAITING_FOR_DECL_OR_RULE;
2378- }else if( !isupper(x[0]) ){
2607+ }else if( !ISUPPER(x[0]) ){
23792608 ErrorMsg(psp->filename, psp->tokenlineno,
23802609 "%%wildcard argument \"%s\" should be a token", x);
23812610 psp->errorcnt++;
@@ -2390,6 +2619,40 @@
23902619 }
23912620 }
23922621 break;
2622+ case WAITING_FOR_CLASS_ID:
2623+ if( !ISLOWER(x[0]) ){
2624+ ErrorMsg(psp->filename, psp->tokenlineno,
2625+ "%%token_class must be followed by an identifier: ", x);
2626+ psp->errorcnt++;
2627+ psp->state = RESYNC_AFTER_DECL_ERROR;
2628+ }else if( Symbol_find(x) ){
2629+ ErrorMsg(psp->filename, psp->tokenlineno,
2630+ "Symbol \"%s\" already used", x);
2631+ psp->errorcnt++;
2632+ psp->state = RESYNC_AFTER_DECL_ERROR;
2633+ }else{
2634+ psp->tkclass = Symbol_new(x);
2635+ psp->tkclass->type = MULTITERMINAL;
2636+ psp->state = WAITING_FOR_CLASS_TOKEN;
2637+ }
2638+ break;
2639+ case WAITING_FOR_CLASS_TOKEN:
2640+ if( x[0]=='.' ){
2641+ psp->state = WAITING_FOR_DECL_OR_RULE;
2642+ }else if( ISUPPER(x[0]) || ((x[0]=='|' || x[0]=='/') && ISUPPER(x[1])) ){
2643+ struct symbol *msp = psp->tkclass;
2644+ msp->nsubsym++;
2645+ msp->subsym = (struct symbol **) realloc(msp->subsym,
2646+ sizeof(struct symbol*)*msp->nsubsym);
2647+ if( !ISUPPER(x[0]) ) x++;
2648+ msp->subsym[msp->nsubsym-1] = Symbol_new(x);
2649+ }else{
2650+ ErrorMsg(psp->filename, psp->tokenlineno,
2651+ "%%token_class argument \"%s\" should be a token", x);
2652+ psp->errorcnt++;
2653+ psp->state = RESYNC_AFTER_DECL_ERROR;
2654+ }
2655+ break;
23932656 case RESYNC_AFTER_RULE_ERROR:
23942657 /* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
23952658 ** break; */
@@ -2400,7 +2663,7 @@
24002663 }
24012664 }
24022665
2403-/* Run the proprocessor over the input file text. The global variables
2666+/* Run the preprocessor over the input file text. The global variables
24042667 ** azDefine[0] through azDefine[nDefine-1] contains the names of all defined
24052668 ** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and
24062669 ** comments them out. Text in between is also commented out as appropriate.
@@ -2414,7 +2677,7 @@
24142677 for(i=0; z[i]; i++){
24152678 if( z[i]=='\n' ) lineno++;
24162679 if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue;
2417- if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){
2680+ if( strncmp(&z[i],"%endif",6)==0 && ISSPACE(z[i+6]) ){
24182681 if( exclude ){
24192682 exclude--;
24202683 if( exclude==0 ){
@@ -2422,16 +2685,16 @@
24222685 }
24232686 }
24242687 for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' ';
2425- }else if( (strncmp(&z[i],"%ifdef",6)==0 && isspace(z[i+6]))
2426- || (strncmp(&z[i],"%ifndef",7)==0 && isspace(z[i+7])) ){
2688+ }else if( (strncmp(&z[i],"%ifdef",6)==0 && ISSPACE(z[i+6]))
2689+ || (strncmp(&z[i],"%ifndef",7)==0 && ISSPACE(z[i+7])) ){
24272690 if( exclude ){
24282691 exclude++;
24292692 }else{
2430- for(j=i+7; isspace(z[j]); j++){}
2431- for(n=0; z[j+n] && !isspace(z[j+n]); n++){}
2693+ for(j=i+7; ISSPACE(z[j]); j++){}
2694+ for(n=0; z[j+n] && !ISSPACE(z[j+n]); n++){}
24322695 exclude = 1;
24332696 for(k=0; k<nDefine; k++){
2434- if( strncmp(azDefine[k],&z[j],n)==0 && strlen(azDefine[k])==n ){
2697+ if( strncmp(azDefine[k],&z[j],n)==0 && lemonStrlen(azDefine[k])==n ){
24352698 exclude = 0;
24362699 break;
24372700 }
@@ -2473,8 +2736,7 @@
24732736 ** token is passed to the function "parseonetoken" which builds all
24742737 ** the appropriate data structures in the global state vector "gp".
24752738 */
2476-void Parse(gp)
2477-struct lemon *gp;
2739+void Parse(struct lemon *gp)
24782740 {
24792741 struct pstate ps;
24802742 FILE *fp;
@@ -2502,10 +2764,10 @@
25022764 filesize = ftell(fp);
25032765 rewind(fp);
25042766 filebuf = (char *)malloc( filesize+1 );
2505- if( filebuf==0 ){
2506- ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.",
2507- filesize+1);
2767+ if( filesize>100000000 || filebuf==0 ){
2768+ ErrorMsg(ps.filename,0,"Input file too large.");
25082769 gp->errorcnt++;
2770+ fclose(fp);
25092771 return;
25102772 }
25112773 if( fread(filebuf,1,filesize,fp)!=filesize ){
@@ -2513,6 +2775,7 @@
25132775 filesize);
25142776 free(filebuf);
25152777 gp->errorcnt++;
2778+ fclose(fp);
25162779 return;
25172780 }
25182781 fclose(fp);
@@ -2526,7 +2789,7 @@
25262789 lineno = 1;
25272790 for(cp=filebuf; (c= *cp)!=0; ){
25282791 if( c=='\n' ) lineno++; /* Keep track of the line number */
2529- if( isspace(c) ){ cp++; continue; } /* Skip all white space */
2792+ if( ISSPACE(c) ){ cp++; continue; } /* Skip all white space */
25302793 if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments */
25312794 cp+=2;
25322795 while( (c= *cp)!=0 && c!='\n' ) cp++;
@@ -2596,15 +2859,15 @@
25962859 }else{
25972860 nextcp = cp+1;
25982861 }
2599- }else if( isalnum(c) ){ /* Identifiers */
2600- while( (c= *cp)!=0 && (isalnum(c) || c=='_') ) cp++;
2862+ }else if( ISALNUM(c) ){ /* Identifiers */
2863+ while( (c= *cp)!=0 && (ISALNUM(c) || c=='_') ) cp++;
26012864 nextcp = cp;
26022865 }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */
26032866 cp += 3;
26042867 nextcp = cp;
2605- }else if( (c=='/' || c=='|') && isalpha(cp[1]) ){
2868+ }else if( (c=='/' || c=='|') && ISALPHA(cp[1]) ){
26062869 cp += 2;
2607- while( (c = *cp)!=0 && (isalnum(c) || c=='_') ) cp++;
2870+ while( (c = *cp)!=0 && (ISALNUM(c) || c=='_') ) cp++;
26082871 nextcp = cp;
26092872 }else{ /* All other (one character) operators */
26102873 cp++;
@@ -2629,7 +2892,7 @@
26292892
26302893 /* Allocate a new plink */
26312894 struct plink *Plink_new(){
2632- struct plink *new;
2895+ struct plink *newlink;
26332896
26342897 if( plink_freelist==0 ){
26352898 int i;
@@ -2643,27 +2906,23 @@
26432906 for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1];
26442907 plink_freelist[amt-1].next = 0;
26452908 }
2646- new = plink_freelist;
2909+ newlink = plink_freelist;
26472910 plink_freelist = plink_freelist->next;
2648- return new;
2911+ return newlink;
26492912 }
26502913
26512914 /* Add a plink to a plink list */
2652-void Plink_add(plpp,cfp)
2653-struct plink **plpp;
2654-struct config *cfp;
2915+void Plink_add(struct plink **plpp, struct config *cfp)
26552916 {
2656- struct plink *new;
2657- new = Plink_new();
2658- new->next = *plpp;
2659- *plpp = new;
2660- new->cfp = cfp;
2917+ struct plink *newlink;
2918+ newlink = Plink_new();
2919+ newlink->next = *plpp;
2920+ *plpp = newlink;
2921+ newlink->cfp = cfp;
26612922 }
26622923
26632924 /* Transfer every plink on the list "from" to the list "to" */
2664-void Plink_copy(to,from)
2665-struct plink **to;
2666-struct plink *from;
2925+void Plink_copy(struct plink **to, struct plink *from)
26672926 {
26682927 struct plink *nextpl;
26692928 while( from ){
@@ -2675,8 +2934,7 @@
26752934 }
26762935
26772936 /* Delete every plink on the list */
2678-void Plink_delete(plp)
2679-struct plink *plp;
2937+void Plink_delete(struct plink *plp)
26802938 {
26812939 struct plink *nextpl;
26822940
@@ -2696,19 +2954,17 @@
26962954 ** name comes from malloc() and must be freed by the calling
26972955 ** function.
26982956 */
2699-PRIVATE char *file_makename(lemp,suffix)
2700-struct lemon *lemp;
2701-char *suffix;
2957+PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
27022958 {
27032959 char *name;
27042960 char *cp;
27052961
2706- name = malloc( strlen(lemp->filename) + strlen(suffix) + 5 );
2962+ name = (char*)malloc( lemonStrlen(lemp->outbasefilename) + lemonStrlen(suffix) + 5 );
27072963 if( name==0 ){
27082964 fprintf(stderr,"Can't allocate space for a filename.\n");
27092965 exit(1);
27102966 }
2711- strcpy(name,lemp->filename);
2967+ strcpy(name,lemp->outbasefilename);
27122968 cp = strrchr(name,'.');
27132969 if( cp ) *cp = 0;
27142970 strcat(name,suffix);
@@ -2718,11 +2974,11 @@
27182974 /* Open a file with a name based on the name of the input file,
27192975 ** but with a different (specified) suffix, and return a pointer
27202976 ** to the stream */
2721-PRIVATE FILE *file_open(lemp,suffix,mode)
2722-struct lemon *lemp;
2723-char *suffix;
2724-char *mode;
2725-{
2977+PRIVATE FILE *file_open(
2978+ struct lemon *lemp,
2979+ const char *suffix,
2980+ const char *mode
2981+){
27262982 FILE *fp;
27272983
27282984 if( lemp->outname ) free(lemp->outname);
@@ -2738,8 +2994,7 @@
27382994
27392995 /* Duplicate the input file without comments and without actions
27402996 ** on rules */
2741-void Reprint(lemp)
2742-struct lemon *lemp;
2997+void Reprint(struct lemon *lemp)
27432998 {
27442999 struct rule *rp;
27453000 struct symbol *sp;
@@ -2748,7 +3003,7 @@
27483003 maxlen = 10;
27493004 for(i=0; i<lemp->nsymbol; i++){
27503005 sp = lemp->symbols[i];
2751- len = (int)strlen(sp->name);
3006+ len = lemonStrlen(sp->name);
27523007 if( len>maxlen ) maxlen = len;
27533008 }
27543009 ncolumns = 76/(maxlen+5);
@@ -2769,11 +3024,13 @@
27693024 printf(" ::=");
27703025 for(i=0; i<rp->nrhs; i++){
27713026 sp = rp->rhs[i];
2772- printf(" %s", sp->name);
27733027 if( sp->type==MULTITERMINAL ){
3028+ printf(" %s", sp->subsym[0]->name);
27743029 for(j=1; j<sp->nsubsym; j++){
27753030 printf("|%s", sp->subsym[j]->name);
27763031 }
3032+ }else{
3033+ printf(" %s", sp->name);
27773034 }
27783035 /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */
27793036 }
@@ -2784,28 +3041,33 @@
27843041 }
27853042 }
27863043
2787-void ConfigPrint(fp,cfp)
2788-FILE *fp;
2789-struct config *cfp;
2790-{
2791- struct rule *rp;
3044+/* Print a single rule.
3045+*/
3046+void RulePrint(FILE *fp, struct rule *rp, int iCursor){
27923047 struct symbol *sp;
27933048 int i, j;
2794- rp = cfp->rp;
27953049 fprintf(fp,"%s ::=",rp->lhs->name);
27963050 for(i=0; i<=rp->nrhs; i++){
2797- if( i==cfp->dot ) fprintf(fp," *");
3051+ if( i==iCursor ) fprintf(fp," *");
27983052 if( i==rp->nrhs ) break;
27993053 sp = rp->rhs[i];
2800- fprintf(fp," %s", sp->name);
28013054 if( sp->type==MULTITERMINAL ){
3055+ fprintf(fp," %s", sp->subsym[0]->name);
28023056 for(j=1; j<sp->nsubsym; j++){
28033057 fprintf(fp,"|%s",sp->subsym[j]->name);
28043058 }
3059+ }else{
3060+ fprintf(fp," %s", sp->name);
28053061 }
28063062 }
28073063 }
28083064
3065+/* Print the rule for a configuration.
3066+*/
3067+void ConfigPrint(FILE *fp, struct config *cfp){
3068+ RulePrint(fp, cfp->rp, cfp->dot);
3069+}
3070+
28093071 /* #define TEST */
28103072 #if 0
28113073 /* Print a set */
@@ -2845,15 +3107,30 @@
28453107 /* Print an action to the given file descriptor. Return FALSE if
28463108 ** nothing was actually printed.
28473109 */
2848-int PrintAction(struct action *ap, FILE *fp, int indent){
3110+int PrintAction(
3111+ struct action *ap, /* The action to print */
3112+ FILE *fp, /* Print the action here */
3113+ int indent /* Indent by this amount */
3114+){
28493115 int result = 1;
28503116 switch( ap->type ){
2851- case SHIFT:
2852- fprintf(fp,"%*s shift %d",indent,ap->sp->name,ap->x.stp->statenum);
3117+ case SHIFT: {
3118+ struct state *stp = ap->x.stp;
3119+ fprintf(fp,"%*s shift %-7d",indent,ap->sp->name,stp->statenum);
28533120 break;
2854- case REDUCE:
2855- fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index);
3121+ }
3122+ case REDUCE: {
3123+ struct rule *rp = ap->x.rp;
3124+ fprintf(fp,"%*s reduce %-7d",indent,ap->sp->name,rp->iRule);
3125+ RulePrint(fp, rp, -1);
28563126 break;
3127+ }
3128+ case SHIFTREDUCE: {
3129+ struct rule *rp = ap->x.rp;
3130+ fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->iRule);
3131+ RulePrint(fp, rp, -1);
3132+ break;
3133+ }
28573134 case ACCEPT:
28583135 fprintf(fp,"%*s accept",indent,ap->sp->name);
28593136 break;
@@ -2862,25 +3139,41 @@
28623139 break;
28633140 case SRCONFLICT:
28643141 case RRCONFLICT:
2865- fprintf(fp,"%*s reduce %-3d ** Parsing conflict **",
2866- indent,ap->sp->name,ap->x.rp->index);
3142+ fprintf(fp,"%*s reduce %-7d ** Parsing conflict **",
3143+ indent,ap->sp->name,ap->x.rp->iRule);
28673144 break;
28683145 case SSCONFLICT:
2869- fprintf(fp,"%*s shift %d ** Parsing conflict **",
3146+ fprintf(fp,"%*s shift %-7d ** Parsing conflict **",
28703147 indent,ap->sp->name,ap->x.stp->statenum);
28713148 break;
28723149 case SH_RESOLVED:
3150+ if( showPrecedenceConflict ){
3151+ fprintf(fp,"%*s shift %-7d -- dropped by precedence",
3152+ indent,ap->sp->name,ap->x.stp->statenum);
3153+ }else{
3154+ result = 0;
3155+ }
3156+ break;
28733157 case RD_RESOLVED:
3158+ if( showPrecedenceConflict ){
3159+ fprintf(fp,"%*s reduce %-7d -- dropped by precedence",
3160+ indent,ap->sp->name,ap->x.rp->iRule);
3161+ }else{
3162+ result = 0;
3163+ }
3164+ break;
28743165 case NOT_USED:
28753166 result = 0;
28763167 break;
28773168 }
3169+ if( result && ap->spOpt ){
3170+ fprintf(fp," /* because %s==%s */", ap->sp->name, ap->spOpt->name);
3171+ }
28783172 return result;
28793173 }
28803174
2881-/* Generate the "y.output" log file */
2882-void ReportOutput(lemp)
2883-struct lemon *lemp;
3175+/* Generate the "*.out" log file */
3176+void ReportOutput(struct lemon *lemp)
28843177 {
28853178 int i;
28863179 struct state *stp;
@@ -2890,7 +3183,7 @@
28903183
28913184 fp = file_open(lemp,".out","wb");
28923185 if( fp==0 ) return;
2893- for(i=0; i<lemp->nstate; i++){
3186+ for(i=0; i<lemp->nxstate; i++){
28943187 stp = lemp->sorted[i];
28953188 fprintf(fp,"State %d:\n",stp->statenum);
28963189 if( lemp->basisflag ) cfp=stp->bp;
@@ -2898,7 +3191,7 @@
28983191 while( cfp ){
28993192 char buf[20];
29003193 if( cfp->dot==cfp->rp->nrhs ){
2901- sprintf(buf,"(%d)",cfp->rp->index);
3194+ sprintf(buf,"(%d)",cfp->rp->iRule);
29023195 fprintf(fp," %5s ",buf);
29033196 }else{
29043197 fprintf(fp," ");
@@ -2946,17 +3239,16 @@
29463239
29473240 /* Search for the file "name" which is in the same directory as
29483241 ** the exacutable */
2949-PRIVATE char *pathsearch(argv0,name,modemask)
2950-char *argv0;
2951-char *name;
2952-int modemask;
3242+PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
29533243 {
2954- char *pathlist;
3244+ const char *pathlist;
3245+ char *pathbufptr;
3246+ char *pathbuf;
29553247 char *path,*cp;
29563248 char c;
29573249
29583250 #ifdef __WIN32__
2959- for (cp = argv0 + strlen(argv0); cp-- > argv0; )
3251+ for (cp = argv0 + lemonStrlen(argv0); cp-- > argv0; )
29603252 {
29613253 if( *cp == '\\' || *cp == '/' )
29623254 break;
@@ -2967,26 +3259,29 @@
29673259 if( cp ){
29683260 c = *cp;
29693261 *cp = 0;
2970- path = (char *)malloc( strlen(argv0) + strlen(name) + 2 );
3262+ path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
29713263 if( path ) sprintf(path,"%s/%s",argv0,name);
29723264 *cp = c;
29733265 }else{
2974- extern char *getenv();
29753266 pathlist = getenv("PATH");
29763267 if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
2977- path = (char *)malloc( strlen(pathlist)+strlen(name)+2 );
2978- if( path!=0 ){
2979- while( *pathlist ){
2980- cp = strchr(pathlist,':');
2981- if( cp==0 ) cp = &pathlist[strlen(pathlist)];
3268+ pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 );
3269+ path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
3270+ if( (pathbuf != 0) && (path!=0) ){
3271+ pathbufptr = pathbuf;
3272+ strcpy(pathbuf, pathlist);
3273+ while( *pathbuf ){
3274+ cp = strchr(pathbuf,':');
3275+ if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)];
29823276 c = *cp;
29833277 *cp = 0;
2984- sprintf(path,"%s/%s",pathlist,name);
3278+ sprintf(path,"%s/%s",pathbuf,name);
29853279 *cp = c;
2986- if( c==0 ) pathlist = "";
2987- else pathlist = &cp[1];
3280+ if( c==0 ) pathbuf[0] = 0;
3281+ else pathbuf = &cp[1];
29883282 if( access(path,modemask)==0 ) break;
29893283 }
3284+ free(pathbufptr);
29903285 }
29913286 }
29923287 return path;
@@ -2996,16 +3291,15 @@
29963291 ** which is to be put in the action table of the generated machine.
29973292 ** Return negative if no action should be generated.
29983293 */
2999-PRIVATE int compute_action(lemp,ap)
3000-struct lemon *lemp;
3001-struct action *ap;
3294+PRIVATE int compute_action(struct lemon *lemp, struct action *ap)
30023295 {
30033296 int act;
30043297 switch( ap->type ){
3005- case SHIFT: act = ap->x.stp->statenum; break;
3006- case REDUCE: act = ap->x.rp->index + lemp->nstate; break;
3007- case ERROR: act = lemp->nstate + lemp->nrule; break;
3008- case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break;
3298+ case SHIFT: act = ap->x.stp->statenum; break;
3299+ case SHIFTREDUCE: act = ap->x.rp->iRule + lemp->nstate; break;
3300+ case REDUCE: act = ap->x.rp->iRule + lemp->nstate+lemp->nrule; break;
3301+ case ERROR: act = lemp->nstate + lemp->nrule*2; break;
3302+ case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break;
30093303 default: act = -1; break;
30103304 }
30113305 return act;
@@ -3021,11 +3315,7 @@
30213315 ** if name!=0, then any word that begin with "Parse" is changed to
30223316 ** begin with *name instead.
30233317 */
3024-PRIVATE void tplt_xfer(name,in,out,lineno)
3025-char *name;
3026-FILE *in;
3027-FILE *out;
3028-int *lineno;
3318+PRIVATE void tplt_xfer(char *name, FILE *in, FILE *out, int *lineno)
30293319 {
30303320 int i, iStart;
30313321 char line[LINESIZE];
@@ -3035,7 +3325,7 @@
30353325 if( name ){
30363326 for(i=0; line[i]; i++){
30373327 if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0
3038- && (i==0 || !isalpha(line[i-1]))
3328+ && (i==0 || !ISALPHA(line[i-1]))
30393329 ){
30403330 if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]);
30413331 fprintf(out,"%s",name);
@@ -3050,14 +3340,32 @@
30503340
30513341 /* The next function finds the template file and opens it, returning
30523342 ** a pointer to the opened file. */
3053-PRIVATE FILE *tplt_open(lemp)
3054-struct lemon *lemp;
3343+PRIVATE FILE *tplt_open(struct lemon *lemp)
30553344 {
30563345 static char templatename[] = "lempar.c";
30573346 char buf[1000];
30583347 FILE *in;
30593348 char *tpltname;
30603349 char *cp;
3350+ Boolean tpltnameinbuf;
3351+
3352+ /* first, see if user specified a template filename on the command line. */
3353+ if (user_templatename != 0) {
3354+ if( access(user_templatename,004)==-1 ){
3355+ fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
3356+ user_templatename);
3357+ lemp->errorcnt++;
3358+ return 0;
3359+ }
3360+ in = fopen(user_templatename,"rb");
3361+ if( in==0 ){
3362+ fprintf(stderr,"Can't open the template file \"%s\".\n",
3363+ user_templatename);
3364+ lemp->errorcnt++;
3365+ return 0;
3366+ }
3367+ return in;
3368+ }
30613369
30623370 cp = strrchr(lemp->filename,'.');
30633371 if( cp ){
@@ -3067,10 +3375,13 @@
30673375 }
30683376 if( access(buf,004)==0 ){
30693377 tpltname = buf;
3378+ tpltnameinbuf = LEMON_TRUE;
30703379 }else if( access(templatename,004)==0 ){
30713380 tpltname = templatename;
3381+ tpltnameinbuf = LEMON_TRUE;
30723382 }else{
30733383 tpltname = pathsearch(lemp->argv0,templatename,0);
3384+ tpltnameinbuf = LEMON_FALSE;
30743385 }
30753386 if( tpltname==0 ){
30763387 fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
@@ -3081,17 +3392,16 @@
30813392 in = fopen(tpltname,"rb");
30823393 if( in==0 ){
30833394 fprintf(stderr,"Can't open the template file \"%s\".\n",templatename);
3395+ if (tpltnameinbuf == LEMON_FALSE) free(tpltname);
30843396 lemp->errorcnt++;
30853397 return 0;
30863398 }
3399+ if (tpltnameinbuf == LEMON_FALSE) free(tpltname);
30873400 return in;
30883401 }
30893402
30903403 /* Print a #line directive line to the output file. */
3091-PRIVATE void tplt_linedir(out,lineno,filename)
3092-FILE *out;
3093-int lineno;
3094-char *filename;
3404+PRIVATE void tplt_linedir(FILE *out, int lineno, char *filename)
30953405 {
30963406 fprintf(out,"#line %d \"",lineno);
30973407 while( *filename ){
@@ -3103,16 +3413,9 @@
31033413 }
31043414
31053415 /* Print a string to the file and keep the linenumber up to date */
3106-PRIVATE void tplt_print(out,lemp,str,strln,lineno)
3107-FILE *out;
3108-struct lemon *lemp;
3109-char *str;
3110-int strln;
3111-int *lineno;
3416+PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, int *lineno)
31123417 {
31133418 if( str==0 ) return;
3114- tplt_linedir(out,strln,lemp->filename);
3115- (*lineno)++;
31163419 while( *str ){
31173420 if( *str=='\n' ) (*lineno)++;
31183421 putc(*str,out);
@@ -3122,8 +3425,10 @@
31223425 putc('\n',out);
31233426 (*lineno)++;
31243427 }
3125- tplt_linedir(out,*lineno+1,lemp->outname);
3126- (*lineno)+=1;
3428+ if (!lemp->nolinenosflag) {
3429+ (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
3430+ }
3431+
31273432 return;
31283433 }
31293434
@@ -3131,29 +3436,29 @@
31313436 ** The following routine emits code for the destructor for the
31323437 ** symbol sp
31333438 */
3134-void emit_destructor_code(out,sp,lemp,lineno)
3135-FILE *out;
3136-struct symbol *sp;
3137-struct lemon *lemp;
3138-int *lineno;
3139-{
3439+void emit_destructor_code(
3440+ FILE *out,
3441+ struct symbol *sp,
3442+ struct lemon *lemp,
3443+ int *lineno
3444+){
31403445 char *cp = 0;
31413446
3142- int linecnt = 0;
31433447 if( sp->type==TERMINAL ){
31443448 cp = lemp->tokendest;
31453449 if( cp==0 ) return;
3146- tplt_linedir(out,lemp->tokendestln,lemp->filename);
3147- fprintf(out,"{");
3450+ fprintf(out,"{\n"); (*lineno)++;
31483451 }else if( sp->destructor ){
31493452 cp = sp->destructor;
3150- tplt_linedir(out,sp->destructorln,lemp->filename);
3151- fprintf(out,"{");
3453+ fprintf(out,"{\n"); (*lineno)++;
3454+ if( !lemp->nolinenosflag ){
3455+ (*lineno)++;
3456+ tplt_linedir(out,sp->destLineno,lemp->filename);
3457+ }
31523458 }else if( lemp->vardest ){
31533459 cp = lemp->vardest;
31543460 if( cp==0 ) return;
3155- tplt_linedir(out,lemp->vardestln,lemp->filename);
3156- fprintf(out,"{");
3461+ fprintf(out,"{\n"); (*lineno)++;
31573462 }else{
31583463 assert( 0 ); /* Cannot happen */
31593464 }
@@ -3163,21 +3468,21 @@
31633468 cp++;
31643469 continue;
31653470 }
3166- if( *cp=='\n' ) linecnt++;
3471+ if( *cp=='\n' ) (*lineno)++;
31673472 fputc(*cp,out);
31683473 }
3169- (*lineno) += 3 + linecnt;
3170- fprintf(out,"}\n");
3171- tplt_linedir(out,*lineno,lemp->outname);
3474+ fprintf(out,"\n"); (*lineno)++;
3475+ if (!lemp->nolinenosflag) {
3476+ (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
3477+ }
3478+ fprintf(out,"}\n"); (*lineno)++;
31723479 return;
31733480 }
31743481
31753482 /*
31763483 ** Return TRUE (non-zero) if the given symbol has a destructor.
31773484 */
3178-int has_destructor(sp, lemp)
3179-struct symbol *sp;
3180-struct lemon *lemp;
3485+int has_destructor(struct symbol *sp, struct lemon *lemp)
31813486 {
31823487 int ret;
31833488 if( sp->type==TERMINAL ){
@@ -3200,14 +3505,15 @@
32003505 **
32013506 ** If n==-1, then the previous character is overwritten.
32023507 */
3203-PRIVATE char *append_str(char *zText, int n, int p1, int p2, int bNoSubst){
3508+PRIVATE char *append_str(const char *zText, int n, int p1, int p2, int bNoSubst){
3509+ static char empty[1] = { 0 };
32043510 static char *z = 0;
32053511 static int alloced = 0;
32063512 static int used = 0;
32073513 int c;
32083514 char zInt[40];
3209-
32103515 if( zText==0 ){
3516+ if( used==0 && z!=0 ) z[0] = 0;
32113517 used = 0;
32123518 return z;
32133519 }
@@ -3216,20 +3522,20 @@
32163522 used += n;
32173523 assert( used>=0 );
32183524 }
3219- n = (int)strlen(zText);
3525+ n = lemonStrlen(zText);
32203526 }
32213527 if( n+sizeof(zInt)*2+used >= (size_t)alloced ){
32223528 alloced = n + sizeof(zInt)*2 + used + 200;
3223- z = realloc(z, alloced);
3224- }
3225- if( z==0 ) return "";
3529+ z = (char *) realloc(z, alloced);
3530+ }
3531+ if( z==0 ) return empty;
32263532 while( n-- > 0 ){
32273533 c = *(zText++);
32283534 if( !bNoSubst && c=='%' && n>0 && zText[0]=='d' ){
32293535 sprintf(zInt, "%d", p1);
32303536 p1 = p2;
32313537 strcpy(&z[used], zInt);
3232- used += (int)strlen(&z[used]);
3538+ used += lemonStrlen(&z[used]);
32333539 zText++;
32343540 n--;
32353541 }else{
@@ -3241,39 +3547,112 @@
32413547 }
32423548
32433549 /*
3244-** zCode is a string that is the action associated with a rule. Expand
3245-** the symbols in this string so that the refer to elements of the parser
3246-** stack.
3550+** Write and transform the rp->code string so that symbols are expanded.
3551+** Populate the rp->codePrefix and rp->codeSuffix strings, as appropriate.
3552+**
3553+** Return 1 if the expanded code requires that "yylhsminor" local variable
3554+** to be defined.
32473555 */
3248-PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
3556+PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
32493557 char *cp, *xp;
32503558 int i;
3251- char lhsused = 0; /* True if the LHS element has been used */
3252- char used[MAXRHS]; /* True for each RHS element which is used */
3559+ int rc = 0; /* True if yylhsminor is used */
3560+ int dontUseRhs0 = 0; /* If true, use of left-most RHS label is illegal */
3561+ const char *zSkip = 0; /* The zOvwrt comment within rp->code, or NULL */
3562+ char lhsused = 0; /* True if the LHS element has been used */
3563+ char lhsdirect; /* True if LHS writes directly into stack */
3564+ char used[MAXRHS]; /* True for each RHS element which is used */
3565+ char zLhs[50]; /* Convert the LHS symbol into this string */
3566+ char zOvwrt[900]; /* Comment that to allow LHS to overwrite RHS */
32533567
32543568 for(i=0; i<rp->nrhs; i++) used[i] = 0;
32553569 lhsused = 0;
32563570
32573571 if( rp->code==0 ){
3258- rp->code = "\n";
3259- rp->line = rp->ruleline;
3572+ static char newlinestr[2] = { '\n', '\0' };
3573+ rp->code = newlinestr;
3574+ rp->line = rp->ruleline;
3575+ rp->noCode = 1;
3576+ }else{
3577+ rp->noCode = 0;
3578+ }
3579+
3580+ if( rp->nrhs==0 ){
3581+ /* If there are no RHS symbols, then writing directly to the LHS is ok */
3582+ lhsdirect = 1;
3583+ }else if( rp->rhsalias[0]==0 ){
3584+ /* The left-most RHS symbol has not value. LHS direct is ok. But
3585+ ** we have to call the distructor on the RHS symbol first. */
3586+ lhsdirect = 1;
3587+ if( has_destructor(rp->rhs[0],lemp) ){
3588+ append_str(0,0,0,0,0);
3589+ append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
3590+ rp->rhs[0]->index,1-rp->nrhs,0);
3591+ rp->codePrefix = Strsafe(append_str(0,0,0,0,0));
3592+ rp->noCode = 0;
3593+ }
3594+ }else if( rp->lhsalias==0 ){
3595+ /* There is no LHS value symbol. */
3596+ lhsdirect = 1;
3597+ }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
3598+ /* The LHS symbol and the left-most RHS symbol are the same, so
3599+ ** direct writing is allowed */
3600+ lhsdirect = 1;
3601+ lhsused = 1;
3602+ used[0] = 1;
3603+ if( rp->lhs->dtnum!=rp->rhs[0]->dtnum ){
3604+ ErrorMsg(lemp->filename,rp->ruleline,
3605+ "%s(%s) and %s(%s) share the same label but have "
3606+ "different datatypes.",
3607+ rp->lhs->name, rp->lhsalias, rp->rhs[0]->name, rp->rhsalias[0]);
3608+ lemp->errorcnt++;
3609+ }
3610+ }else{
3611+ sprintf(zOvwrt, "/*%s-overwrites-%s*/", rp->lhsalias, rp->rhsalias[0]);
3612+ zSkip = strstr(rp->code, zOvwrt);
3613+ if( zSkip!=0 ){
3614+ /* The code contains a special comment that indicates that it is safe
3615+ ** for the LHS label to overwrite left-most RHS label. */
3616+ lhsdirect = 1;
3617+ }else{
3618+ lhsdirect = 0;
3619+ }
3620+ }
3621+ if( lhsdirect ){
3622+ sprintf(zLhs, "yymsp[%d].minor.yy%d",1-rp->nrhs,rp->lhs->dtnum);
3623+ }else{
3624+ rc = 1;
3625+ sprintf(zLhs, "yylhsminor.yy%d",rp->lhs->dtnum);
32603626 }
32613627
32623628 append_str(0,0,0,0,0);
3263- for(cp=rp->code; *cp; cp++){
3264- if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
3629+
3630+ /* This const cast is wrong but harmless, if we're careful. */
3631+ for(cp=(char *)rp->code; *cp; cp++){
3632+ if( cp==zSkip ){
3633+ append_str(zOvwrt,0,0,0,0);
3634+ cp += lemonStrlen(zOvwrt)-1;
3635+ dontUseRhs0 = 1;
3636+ continue;
3637+ }
3638+ if( ISALPHA(*cp) && (cp==rp->code || (!ISALNUM(cp[-1]) && cp[-1]!='_')) ){
32653639 char saved;
3266- for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
3640+ for(xp= &cp[1]; ISALNUM(*xp) || *xp=='_'; xp++);
32673641 saved = *xp;
32683642 *xp = 0;
32693643 if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
3270- append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0,0);
3644+ append_str(zLhs,0,0,0,0);
32713645 cp = xp;
32723646 lhsused = 1;
32733647 }else{
32743648 for(i=0; i<rp->nrhs; i++){
32753649 if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){
3276- if( cp!=rp->code && cp[-1]=='@' ){
3650+ if( i==0 && dontUseRhs0 ){
3651+ ErrorMsg(lemp->filename,rp->ruleline,
3652+ "Label %s used after '%s'.",
3653+ rp->rhsalias[0], zOvwrt);
3654+ lemp->errorcnt++;
3655+ }else if( cp!=rp->code && cp[-1]=='@' ){
32773656 /* If the argument is of the form @X then substituted
32783657 ** the token number of X, not the value of X */
32793658 append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0,0);
@@ -3298,6 +3677,11 @@
32983677 append_str(cp, 1, 0, 0, 1);
32993678 } /* End loop */
33003679
3680+ /* Main code generation completed */
3681+ cp = append_str(0,0,0,0,0);
3682+ if( cp && cp[0] ) rp->code = Strsafe(cp);
3683+ append_str(0,0,0,0,0);
3684+
33013685 /* Check to make sure the LHS has been used */
33023686 if( rp->lhsalias && !lhsused ){
33033687 ErrorMsg(lemp->filename,rp->ruleline,
@@ -3306,53 +3690,102 @@
33063690 lemp->errorcnt++;
33073691 }
33083692
3309- /* Generate destructor code for RHS symbols which are not used in the
3310- ** reduce code */
3693+ /* Generate destructor code for RHS minor values which are not referenced.
3694+ ** Generate error messages for unused labels and duplicate labels.
3695+ */
33113696 for(i=0; i<rp->nrhs; i++){
3312- if( rp->rhsalias[i] && !used[i] ){
3313- ErrorMsg(lemp->filename,rp->ruleline,
3314- "Label %s for \"%s(%s)\" is never used.",
3315- rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
3316- lemp->errorcnt++;
3317- }else if( rp->rhsalias[i]==0 ){
3318- if( has_destructor(rp->rhs[i],lemp) ){
3319- append_str(" yy_destructor(%d,&yymsp[%d].minor);\n", 0,
3320- rp->rhs[i]->index,i-rp->nrhs+1,0);
3321- }else{
3322- /* No destructor defined for this term */
3697+ if( rp->rhsalias[i] ){
3698+ if( i>0 ){
3699+ int j;
3700+ if( rp->lhsalias && strcmp(rp->lhsalias,rp->rhsalias[i])==0 ){
3701+ ErrorMsg(lemp->filename,rp->ruleline,
3702+ "%s(%s) has the same label as the LHS but is not the left-most "
3703+ "symbol on the RHS.",
3704+ rp->rhs[i]->name, rp->rhsalias);
3705+ lemp->errorcnt++;
3706+ }
3707+ for(j=0; j<i; j++){
3708+ if( rp->rhsalias[j] && strcmp(rp->rhsalias[j],rp->rhsalias[i])==0 ){
3709+ ErrorMsg(lemp->filename,rp->ruleline,
3710+ "Label %s used for multiple symbols on the RHS of a rule.",
3711+ rp->rhsalias[i]);
3712+ lemp->errorcnt++;
3713+ break;
3714+ }
3715+ }
33233716 }
3717+ if( !used[i] ){
3718+ ErrorMsg(lemp->filename,rp->ruleline,
3719+ "Label %s for \"%s(%s)\" is never used.",
3720+ rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
3721+ lemp->errorcnt++;
3722+ }
3723+ }else if( i>0 && has_destructor(rp->rhs[i],lemp) ){
3724+ append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
3725+ rp->rhs[i]->index,i-rp->nrhs+1,0);
33243726 }
33253727 }
3326- if( rp->code ){
3327- cp = append_str(0,0,0,0,0);
3328- rp->code = Strsafe(cp?cp:"");
3329- }
3728+
3729+ /* If unable to write LHS values directly into the stack, write the
3730+ ** saved LHS value now. */
3731+ if( lhsdirect==0 ){
3732+ append_str(" yymsp[%d].minor.yy%d = ", 0, 1-rp->nrhs, rp->lhs->dtnum, 0);
3733+ append_str(zLhs, 0, 0, 0, 0);
3734+ append_str(";\n", 0, 0, 0, 0);
3735+ }
3736+
3737+ /* Suffix code generation complete */
3738+ cp = append_str(0,0,0,0,0);
3739+ if( cp && cp[0] ){
3740+ rp->codeSuffix = Strsafe(cp);
3741+ rp->noCode = 0;
3742+ }
3743+
3744+ return rc;
33303745 }
33313746
33323747 /*
33333748 ** Generate code which executes when the rule "rp" is reduced. Write
33343749 ** the code to "out". Make sure lineno stays up-to-date.
33353750 */
3336-PRIVATE void emit_code(out,rp,lemp,lineno)
3337-FILE *out;
3338-struct rule *rp;
3339-struct lemon *lemp;
3340-int *lineno;
3341-{
3342- char *cp;
3343- int linecnt = 0;
3751+PRIVATE void emit_code(
3752+ FILE *out,
3753+ struct rule *rp,
3754+ struct lemon *lemp,
3755+ int *lineno
3756+){
3757+ const char *cp;
3758+
3759+ /* Setup code prior to the #line directive */
3760+ if( rp->codePrefix && rp->codePrefix[0] ){
3761+ fprintf(out, "{%s", rp->codePrefix);
3762+ for(cp=rp->codePrefix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3763+ }
33443764
33453765 /* Generate code to do the reduce action */
33463766 if( rp->code ){
3347- tplt_linedir(out,rp->line,lemp->filename);
3767+ if( !lemp->nolinenosflag ){
3768+ (*lineno)++;
3769+ tplt_linedir(out,rp->line,lemp->filename);
3770+ }
33483771 fprintf(out,"{%s",rp->code);
3349- for(cp=rp->code; *cp; cp++){
3350- if( *cp=='\n' ) linecnt++;
3351- } /* End loop */
3352- (*lineno) += 3 + linecnt;
3353- fprintf(out,"}\n");
3354- tplt_linedir(out,*lineno,lemp->outname);
3355- } /* End if( rp->code ) */
3772+ for(cp=rp->code; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3773+ fprintf(out,"}\n"); (*lineno)++;
3774+ if( !lemp->nolinenosflag ){
3775+ (*lineno)++;
3776+ tplt_linedir(out,*lineno,lemp->outname);
3777+ }
3778+ }
3779+
3780+ /* Generate breakdown code that occurs after the #line directive */
3781+ if( rp->codeSuffix && rp->codeSuffix[0] ){
3782+ fprintf(out, "%s", rp->codeSuffix);
3783+ for(cp=rp->codeSuffix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3784+ }
3785+
3786+ if( rp->codePrefix ){
3787+ fprintf(out, "}\n"); (*lineno)++;
3788+ }
33563789
33573790 return;
33583791 }
@@ -3364,33 +3797,37 @@
33643797 ** union, also set the ".dtnum" field of every terminal and nonterminal
33653798 ** symbol.
33663799 */
3367-void print_stack_union(out,lemp,plineno,mhflag)
3368-FILE *out; /* The output stream */
3369-struct lemon *lemp; /* The main info structure for this parser */
3370-int *plineno; /* Pointer to the line number */
3371-int mhflag; /* True if generating makeheaders output */
3372-{
3800+void print_stack_union(
3801+ FILE *out, /* The output stream */
3802+ struct lemon *lemp, /* The main info structure for this parser */
3803+ int *plineno, /* Pointer to the line number */
3804+ int mhflag /* True if generating makeheaders output */
3805+){
33733806 int lineno = *plineno; /* The line number of the output */
33743807 char **types; /* A hash table of datatypes */
33753808 int arraysize; /* Size of the "types" array */
33763809 int maxdtlength; /* Maximum length of any ".datatype" field. */
33773810 char *stddt; /* Standardized name for a datatype */
33783811 int i,j; /* Loop counters */
3379- int hash; /* For hashing the name of a type */
3380- char *name; /* Name of the parser */
3812+ unsigned hash; /* For hashing the name of a type */
3813+ const char *name; /* Name of the parser */
33813814
33823815 /* Allocate and initialize types[] and allocate stddt[] */
33833816 arraysize = lemp->nsymbol * 2;
33843817 types = (char**)calloc( arraysize, sizeof(char*) );
3818+ if( types==0 ){
3819+ fprintf(stderr,"Out of memory.\n");
3820+ exit(1);
3821+ }
33853822 maxdtlength = 0;
33863823 if( lemp->vartype ){
3387- maxdtlength = (int)strlen(lemp->vartype);
3824+ maxdtlength = lemonStrlen(lemp->vartype);
33883825 }
33893826 for(i=0; i<lemp->nsymbol; i++){
33903827 int len;
33913828 struct symbol *sp = lemp->symbols[i];
33923829 if( sp->datatype==0 ) continue;
3393- len = (int)strlen(sp->datatype);
3830+ len = lemonStrlen(sp->datatype);
33943831 if( len>maxdtlength ) maxdtlength = len;
33953832 }
33963833 stddt = (char*)malloc( maxdtlength*2 + 1 );
@@ -3419,10 +3856,14 @@
34193856 cp = sp->datatype;
34203857 if( cp==0 ) cp = lemp->vartype;
34213858 j = 0;
3422- while( isspace(*cp) ) cp++;
3859+ while( ISSPACE(*cp) ) cp++;
34233860 while( *cp ) stddt[j++] = *cp++;
3424- while( j>0 && isspace(stddt[j-1]) ) j--;
3861+ while( j>0 && ISSPACE(stddt[j-1]) ) j--;
34253862 stddt[j] = 0;
3863+ if( lemp->tokentype && strcmp(stddt, lemp->tokentype)==0 ){
3864+ sp->dtnum = 0;
3865+ continue;
3866+ }
34263867 hash = 0;
34273868 for(j=0; stddt[j]; j++){
34283869 hash = hash*53 + stddt[j];
@@ -3434,11 +3875,11 @@
34343875 break;
34353876 }
34363877 hash++;
3437- if( hash>=arraysize ) hash = 0;
3878+ if( hash>=(unsigned)arraysize ) hash = 0;
34383879 }
34393880 if( types[hash]==0 ){
34403881 sp->dtnum = hash + 1;
3441- types[hash] = (char*)malloc( strlen(stddt)+1 );
3882+ types[hash] = (char*)malloc( lemonStrlen(stddt)+1 );
34423883 if( types[hash]==0 ){
34433884 fprintf(stderr,"Out of memory.\n");
34443885 exit(1);
@@ -3455,6 +3896,7 @@
34553896 lemp->tokentype?lemp->tokentype:"void*"); lineno++;
34563897 if( mhflag ){ fprintf(out,"#endif\n"); lineno++; }
34573898 fprintf(out,"typedef union {\n"); lineno++;
3899+ fprintf(out," int yyinit;\n"); lineno++;
34583900 fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++;
34593901 for(i=0; i<arraysize; i++){
34603902 if( types[i]==0 ) continue;
@@ -3472,24 +3914,32 @@
34723914
34733915 /*
34743916 ** Return the name of a C datatype able to represent values between
3475-** lwr and upr, inclusive.
3917+** lwr and upr, inclusive. If pnByte!=NULL then also write the sizeof
3918+** for that type (1, 2, or 4) into *pnByte.
34763919 */
3477-static const char *minimum_size_type(int lwr, int upr){
3920+static const char *minimum_size_type(int lwr, int upr, int *pnByte){
3921+ const char *zType = "int";
3922+ int nByte = 4;
34783923 if( lwr>=0 ){
34793924 if( upr<=255 ){
3480- return "unsigned char";
3925+ zType = "unsigned char";
3926+ nByte = 1;
34813927 }else if( upr<65535 ){
3482- return "unsigned short int";
3928+ zType = "unsigned short int";
3929+ nByte = 2;
34833930 }else{
3484- return "unsigned int";
3931+ zType = "unsigned int";
3932+ nByte = 4;
34853933 }
34863934 }else if( lwr>=-127 && upr<=127 ){
3487- return "signed char";
3935+ zType = "signed char";
3936+ nByte = 1;
34883937 }else if( lwr>=-32767 && upr<32767 ){
3489- return "short";
3490- }else{
3491- return "int";
3492- }
3938+ zType = "short";
3939+ nByte = 2;
3940+ }
3941+ if( pnByte ) *pnByte = nByte;
3942+ return zType;
34933943 }
34943944
34953945 /*
@@ -3502,6 +3952,7 @@
35023952 struct state *stp; /* A pointer to a state */
35033953 int isTkn; /* True to use tokens. False for non-terminals */
35043954 int nAction; /* Number of actions */
3955+ int iOrder; /* Original order of action sets */
35053956 };
35063957
35073958 /*
@@ -3510,7 +3961,13 @@
35103961 static int axset_compare(const void *a, const void *b){
35113962 struct axset *p1 = (struct axset*)a;
35123963 struct axset *p2 = (struct axset*)b;
3513- return p2->nAction - p1->nAction;
3964+ int c;
3965+ c = p2->nAction - p1->nAction;
3966+ if( c==0 ){
3967+ c = p1->iOrder - p2->iOrder;
3968+ }
3969+ assert( c!=0 || p1==p2 );
3970+ return c;
35143971 }
35153972
35163973 /*
@@ -3521,9 +3978,11 @@
35213978 fprintf(out,"%s ::=", rp->lhs->name);
35223979 for(j=0; j<rp->nrhs; j++){
35233980 struct symbol *sp = rp->rhs[j];
3524- fprintf(out," %s", sp->name);
3525- if( sp->type==MULTITERMINAL ){
3981+ if( sp->type!=MULTITERMINAL ){
3982+ fprintf(out," %s", sp->name);
3983+ }else{
35263984 int k;
3985+ fprintf(out," %s", sp->subsym[0]->name);
35273986 for(k=1; k<sp->nsubsym; k++){
35283987 fprintf(out,"|%s",sp->subsym[k]->name);
35293988 }
@@ -3533,10 +3992,10 @@
35333992
35343993
35353994 /* Generate C source code for the parser */
3536-void ReportTable(lemp, mhflag)
3537-struct lemon *lemp;
3538-int mhflag; /* Output in makeheaders format if true */
3539-{
3995+void ReportTable(
3996+ struct lemon *lemp,
3997+ int mhflag /* Output in makeheaders format if true */
3998+){
35403999 FILE *out, *in;
35414000 char line[LINESIZE];
35424001 int lineno;
@@ -3544,8 +4003,10 @@
35444003 struct action *ap;
35454004 struct rule *rp;
35464005 struct acttab *pActtab;
3547- int i, j, n;
3548- char *name;
4006+ int i, j, n, sz;
4007+ int szActionType; /* sizeof(YYACTIONTYPE) */
4008+ int szCodeType; /* sizeof(YYCODETYPE) */
4009+ const char *name;
35494010 int mnTknOfst, mxTknOfst;
35504011 int mnNtOfst, mxNtOfst;
35514012 struct axset *ax;
@@ -3561,7 +4022,7 @@
35614022 tplt_xfer(lemp->name,in,out,&lineno);
35624023
35634024 /* Generate the include code, if any */
3564- tplt_print(out,lemp,lemp->include,lemp->includeln,&lineno);
4025+ tplt_print(out,lemp,lemp->include,&lineno);
35654026 if( mhflag ){
35664027 char *name = file_makename(lemp, ".h");
35674028 fprintf(out,"#include \"%s\"\n", name); lineno++;
@@ -3571,7 +4032,7 @@
35714032
35724033 /* Generate #defines for all tokens */
35734034 if( mhflag ){
3574- char *prefix;
4035+ const char *prefix;
35754036 fprintf(out,"#if INTERFACE\n"); lineno++;
35764037 if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
35774038 else prefix = "";
@@ -3585,10 +4046,10 @@
35854046
35864047 /* Generate the defines */
35874048 fprintf(out,"#define YYCODETYPE %s\n",
3588- minimum_size_type(0, lemp->nsymbol+5)); lineno++;
4049+ minimum_size_type(0, lemp->nsymbol+1, &szCodeType)); lineno++;
35894050 fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++;
35904051 fprintf(out,"#define YYACTIONTYPE %s\n",
3591- minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++;
4052+ minimum_size_type(0,lemp->nstate+lemp->nrule*2+5,&szActionType)); lineno++;
35924053 if( lemp->wildcard ){
35934054 fprintf(out,"#define YYWILDCARD %d\n",
35944055 lemp->wildcard->index); lineno++;
@@ -3607,9 +4068,9 @@
36074068 name = lemp->name ? lemp->name : "Parse";
36084069 if( lemp->arg && lemp->arg[0] ){
36094070 size_t i;
3610- i = strlen(lemp->arg);
3611- while( i>=1 && isspace(lemp->arg[i-1]) ) i--;
3612- while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;
4071+ i = lemonStrlen(lemp->arg);
4072+ while( i>=1 && ISSPACE(lemp->arg[i-1]) ) i--;
4073+ while( i>=1 && (ISALNUM(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;
36134074 fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++;
36144075 fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++;
36154076 fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n",
@@ -3625,36 +4086,24 @@
36254086 if( mhflag ){
36264087 fprintf(out,"#endif\n"); lineno++;
36274088 }
3628- fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++;
3629- fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++;
36304089 if( lemp->errsym->useCnt ){
3631- fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
3632- fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
4090+ fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
4091+ fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
36334092 }
36344093 if( lemp->has_fallback ){
36354094 fprintf(out,"#define YYFALLBACK 1\n"); lineno++;
36364095 }
3637- tplt_xfer(lemp->name,in,out,&lineno);
3638-
3639- /* Generate the action table and its associates:
3640- **
3641- ** yy_action[] A single table containing all actions.
3642- ** yy_lookahead[] A table containing the lookahead for each entry in
3643- ** yy_action. Used to detect hash collisions.
3644- ** yy_shift_ofst[] For each state, the offset into yy_action for
3645- ** shifting terminals.
3646- ** yy_reduce_ofst[] For each state, the offset into yy_action for
3647- ** shifting non-terminals after a reduce.
3648- ** yy_default[] Default action for each state.
4096+
4097+ /* Compute the action table, but do not output it yet. The action
4098+ ** table must be computed before generating the YYNSTATE macro because
4099+ ** we need to know how many states can be eliminated.
36494100 */
3650-
3651- /* Compute the actions on all states and count them up */
3652- ax = calloc(lemp->nstate*2 , sizeof(ax[0]));
4101+ ax = (struct axset *) calloc(lemp->nxstate*2 , sizeof(ax[0]));
36534102 if( ax==0 ){
36544103 fprintf(stderr,"malloc failed\n");
36554104 exit(1);
36564105 }
3657- for(i=0; i<lemp->nstate; i++){
4106+ for(i=0; i<lemp->nxstate; i++){
36584107 stp = lemp->sorted[i];
36594108 ax[i*2].stp = stp;
36604109 ax[i*2].isTkn = 1;
@@ -3665,14 +4114,12 @@
36654114 }
36664115 mxTknOfst = mnTknOfst = 0;
36674116 mxNtOfst = mnNtOfst = 0;
3668-
3669- /* Compute the action table. In order to try to keep the size of the
3670- ** action table to a minimum, the heuristic of placing the largest action
3671- ** sets first is used.
3672- */
3673- qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare);
4117+ /* In an effort to minimize the action table size, use the heuristic
4118+ ** of placing the largest action sets first */
4119+ for(i=0; i<lemp->nxstate*2; i++) ax[i].iOrder = i;
4120+ qsort(ax, lemp->nxstate*2, sizeof(ax[0]), axset_compare);
36744121 pActtab = acttab_alloc();
3675- for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){
4122+ for(i=0; i<lemp->nxstate*2 && ax[i].nAction>0; i++){
36764123 stp = ax[i].stp;
36774124 if( ax[i].isTkn ){
36784125 for(ap=stp->ap; ap; ap=ap->next){
@@ -3698,12 +4145,67 @@
36984145 if( stp->iNtOfst<mnNtOfst ) mnNtOfst = stp->iNtOfst;
36994146 if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst;
37004147 }
4148+#if 0 /* Uncomment for a trace of how the yy_action[] table fills out */
4149+ { int jj, nn;
4150+ for(jj=nn=0; jj<pActtab->nAction; jj++){
4151+ if( pActtab->aAction[jj].action<0 ) nn++;
4152+ }
4153+ printf("%4d: State %3d %s n: %2d size: %5d freespace: %d\n",
4154+ i, stp->statenum, ax[i].isTkn ? "Token" : "Var ",
4155+ ax[i].nAction, pActtab->nAction, nn);
4156+ }
4157+#endif
37014158 }
37024159 free(ax);
37034160
4161+#if 0
4162+ /* Mark rules that are actually used for reduce actions after all
4163+ ** optimizations have been applied
4164+ */
4165+ for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE;
4166+ for(i=0; i<lemp->nxstate; i++){
4167+ struct action *ap;
4168+ for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
4169+ if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){
4170+ ap->x.rp->doesReduce = i;
4171+ }
4172+ }
4173+ }
4174+#endif
4175+
4176+ /* Finish rendering the constants now that the action table has
4177+ ** been computed */
4178+ fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++;
4179+ fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++;
4180+ fprintf(out,"#define YY_MAX_SHIFT %d\n",lemp->nxstate-1); lineno++;
4181+ fprintf(out,"#define YY_MIN_SHIFTREDUCE %d\n",lemp->nstate); lineno++;
4182+ i = lemp->nstate + lemp->nrule;
4183+ fprintf(out,"#define YY_MAX_SHIFTREDUCE %d\n", i-1); lineno++;
4184+ fprintf(out,"#define YY_MIN_REDUCE %d\n", i); lineno++;
4185+ i = lemp->nstate + lemp->nrule*2;
4186+ fprintf(out,"#define YY_MAX_REDUCE %d\n", i-1); lineno++;
4187+ fprintf(out,"#define YY_ERROR_ACTION %d\n", i); lineno++;
4188+ fprintf(out,"#define YY_ACCEPT_ACTION %d\n", i+1); lineno++;
4189+ fprintf(out,"#define YY_NO_ACTION %d\n", i+2); lineno++;
4190+ tplt_xfer(lemp->name,in,out,&lineno);
4191+
4192+ /* Now output the action table and its associates:
4193+ **
4194+ ** yy_action[] A single table containing all actions.
4195+ ** yy_lookahead[] A table containing the lookahead for each entry in
4196+ ** yy_action. Used to detect hash collisions.
4197+ ** yy_shift_ofst[] For each state, the offset into yy_action for
4198+ ** shifting terminals.
4199+ ** yy_reduce_ofst[] For each state, the offset into yy_action for
4200+ ** shifting non-terminals after a reduce.
4201+ ** yy_default[] Default action for each state.
4202+ */
4203+
37044204 /* Output the yy_action table */
4205+ lemp->nactiontab = n = acttab_size(pActtab);
4206+ lemp->tablesize += n*szActionType;
4207+ fprintf(out,"#define YY_ACTTAB_COUNT (%d)\n", n); lineno++;
37054208 fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++;
3706- n = acttab_size(pActtab);
37074209 for(i=j=0; i<n; i++){
37084210 int action = acttab_yyaction(pActtab, i);
37094211 if( action<0 ) action = lemp->nstate + lemp->nrule + 2;
@@ -3719,6 +4221,7 @@
37194221 fprintf(out, "};\n"); lineno++;
37204222
37214223 /* Output the yy_lookahead table */
4224+ lemp->tablesize += n*szCodeType;
37224225 fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++;
37234226 for(i=j=0; i<n; i++){
37244227 int la = acttab_yylookahead(pActtab, i);
@@ -3735,17 +4238,21 @@
37354238 fprintf(out, "};\n"); lineno++;
37364239
37374240 /* Output the yy_shift_ofst[] table */
3738- fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
3739- n = lemp->nstate;
4241+ n = lemp->nxstate;
37404242 while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
3741- fprintf(out, "#define YY_SHIFT_MAX %d\n", n-1); lineno++;
4243+ fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", lemp->nactiontab); lineno++;
4244+ fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++;
4245+ fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++;
4246+ fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++;
37424247 fprintf(out, "static const %s yy_shift_ofst[] = {\n",
3743- minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++;
4248+ minimum_size_type(mnTknOfst, lemp->nterminal+lemp->nactiontab, &sz));
4249+ lineno++;
4250+ lemp->tablesize += n*sz;
37444251 for(i=j=0; i<n; i++){
37454252 int ofst;
37464253 stp = lemp->sorted[i];
37474254 ofst = stp->iTknOfst;
3748- if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1;
4255+ if( ofst==NO_OFFSET ) ofst = lemp->nactiontab;
37494256 if( j==0 ) fprintf(out," /* %5d */ ", i);
37504257 fprintf(out, " %4d,", ofst);
37514258 if( j==9 || i==n-1 ){
@@ -3759,11 +4266,14 @@
37594266
37604267 /* Output the yy_reduce_ofst[] table */
37614268 fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
3762- n = lemp->nstate;
4269+ n = lemp->nxstate;
37634270 while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--;
3764- fprintf(out, "#define YY_REDUCE_MAX %d\n", n-1); lineno++;
4271+ fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++;
4272+ fprintf(out, "#define YY_REDUCE_MIN (%d)\n", mnNtOfst); lineno++;
4273+ fprintf(out, "#define YY_REDUCE_MAX (%d)\n", mxNtOfst); lineno++;
37654274 fprintf(out, "static const %s yy_reduce_ofst[] = {\n",
3766- minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++;
4275+ minimum_size_type(mnNtOfst-1, mxNtOfst, &sz)); lineno++;
4276+ lemp->tablesize += n*sz;
37674277 for(i=j=0; i<n; i++){
37684278 int ofst;
37694279 stp = lemp->sorted[i];
@@ -3782,11 +4292,12 @@
37824292
37834293 /* Output the default action table */
37844294 fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++;
3785- n = lemp->nstate;
4295+ n = lemp->nxstate;
4296+ lemp->tablesize += n*szActionType;
37864297 for(i=j=0; i<n; i++){
37874298 stp = lemp->sorted[i];
37884299 if( j==0 ) fprintf(out," /* %5d */ ", i);
3789- fprintf(out, " %4d,", stp->iDflt);
4300+ fprintf(out, " %4d,", stp->iDfltReduce+lemp->nstate+lemp->nrule);
37904301 if( j==9 || i==n-1 ){
37914302 fprintf(out, "\n"); lineno++;
37924303 j = 0;
@@ -3800,7 +4311,10 @@
38004311 /* Generate the table of fallback tokens.
38014312 */
38024313 if( lemp->has_fallback ){
3803- for(i=0; i<lemp->nterminal; i++){
4314+ int mx = lemp->nterminal - 1;
4315+ while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; }
4316+ lemp->tablesize += (mx+1)*szCodeType;
4317+ for(i=0; i<=mx; i++){
38044318 struct symbol *p = lemp->symbols[i];
38054319 if( p->fallback==0 ){
38064320 fprintf(out, " 0, /* %10s => nothing */\n", p->name);
@@ -3824,11 +4338,11 @@
38244338 tplt_xfer(lemp->name,in,out,&lineno);
38254339
38264340 /* Generate a table containing a text string that describes every
3827- ** rule in the rule set of the grammer. This information is used
4341+ ** rule in the rule set of the grammar. This information is used
38284342 ** when tracing REDUCE actions.
38294343 */
38304344 for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
3831- assert( rp->index==i );
4345+ assert( rp->iRule==i );
38324346 fprintf(out," /* %3d */ \"", i);
38334347 writeRuleText(out, rp);
38344348 fprintf(out,"\",\n"); lineno++;
@@ -3840,11 +4354,15 @@
38404354 ** (In other words, generate the %destructor actions)
38414355 */
38424356 if( lemp->tokendest ){
4357+ int once = 1;
38434358 for(i=0; i<lemp->nsymbol; i++){
38444359 struct symbol *sp = lemp->symbols[i];
38454360 if( sp==0 || sp->type!=TERMINAL ) continue;
3846- fprintf(out," case %d: /* %s */\n",
3847- sp->index, sp->name); lineno++;
4361+ if( once ){
4362+ fprintf(out, " /* TERMINAL Destructor */\n"); lineno++;
4363+ once = 0;
4364+ }
4365+ fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++;
38484366 }
38494367 for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++);
38504368 if( i<lemp->nsymbol ){
@@ -3854,24 +4372,28 @@
38544372 }
38554373 if( lemp->vardest ){
38564374 struct symbol *dflt_sp = 0;
4375+ int once = 1;
38574376 for(i=0; i<lemp->nsymbol; i++){
38584377 struct symbol *sp = lemp->symbols[i];
38594378 if( sp==0 || sp->type==TERMINAL ||
38604379 sp->index<=0 || sp->destructor!=0 ) continue;
3861- fprintf(out," case %d: /* %s */\n",
3862- sp->index, sp->name); lineno++;
4380+ if( once ){
4381+ fprintf(out, " /* Default NON-TERMINAL Destructor */\n"); lineno++;
4382+ once = 0;
4383+ }
4384+ fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++;
38634385 dflt_sp = sp;
38644386 }
38654387 if( dflt_sp!=0 ){
38664388 emit_destructor_code(out,dflt_sp,lemp,&lineno);
3867- fprintf(out," break;\n"); lineno++;
38684389 }
4390+ fprintf(out," break;\n"); lineno++;
38694391 }
38704392 for(i=0; i<lemp->nsymbol; i++){
38714393 struct symbol *sp = lemp->symbols[i];
38724394 if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
3873- fprintf(out," case %d: /* %s */\n",
3874- sp->index, sp->name); lineno++;
4395+ if( sp->destLineno<0 ) continue; /* Already emitted */
4396+ fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++;
38754397
38764398 /* Combine duplicate destructors into a single case */
38774399 for(j=i+1; j<lemp->nsymbol; j++){
@@ -3881,7 +4403,7 @@
38814403 && strcmp(sp->destructor,sp2->destructor)==0 ){
38824404 fprintf(out," case %d: /* %s */\n",
38834405 sp2->index, sp2->name); lineno++;
3884- sp2->destructor = 0;
4406+ sp2->destLineno = -1; /* Avoid emitting this destructor again */
38854407 }
38864408 }
38874409
@@ -3891,7 +4413,7 @@
38914413 tplt_xfer(lemp->name,in,out,&lineno);
38924414
38934415 /* Generate code which executes whenever the parser stack overflows */
3894- tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno);
4416+ tplt_print(out,lemp,lemp->overflow,&lineno);
38954417 tplt_xfer(lemp->name,in,out,&lineno);
38964418
38974419 /* Generate the table of rule information
@@ -3905,54 +4427,85 @@
39054427 tplt_xfer(lemp->name,in,out,&lineno);
39064428
39074429 /* Generate code which executes during each REDUCE action */
3908- for(rp=lemp->rule; rp; rp=rp->next){
3909- translate_code(lemp, rp);
3910- }
4430+ i = 0;
39114431 for(rp=lemp->rule; rp; rp=rp->next){
3912- struct rule *rp2;
3913- if( rp->code==0 ) continue;
3914- fprintf(out," case %d: /* ",rp->index);
4432+ i += translate_code(lemp, rp);
4433+ }
4434+ if( i ){
4435+ fprintf(out," YYMINORTYPE yylhsminor;\n"); lineno++;
4436+ }
4437+ /* First output rules other than the default: rule */
4438+ for(rp=lemp->rule; rp; rp=rp->next){
4439+ struct rule *rp2; /* Other rules with the same action */
4440+ if( rp->codeEmitted ) continue;
4441+ if( rp->noCode ){
4442+ /* No C code actions, so this will be part of the "default:" rule */
4443+ continue;
4444+ }
4445+ fprintf(out," case %d: /* ",rp->iRule);
39154446 writeRuleText(out, rp);
3916- fprintf(out, " */\n"); lineno++;
4447+ fprintf(out," */\n"); lineno++;
39174448 for(rp2=rp->next; rp2; rp2=rp2->next){
3918- if( rp2->code==rp->code ){
3919- fprintf(out," case %d: /*",rp2->index);
4449+ if( rp2->code==rp->code && rp2->codePrefix==rp->codePrefix
4450+ && rp2->codeSuffix == rp->codeSuffix ){
4451+ fprintf(out," case %d: /*",rp2->iRule);
39204452 writeRuleText(out, rp2);
3921- fprintf(out," */\n"); lineno++;
3922- rp2->code = 0;
4453+ fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++;
4454+ rp2->codeEmitted = 1;
39234455 }
39244456 }
39254457 emit_code(out,rp,lemp,&lineno);
39264458 fprintf(out," break;\n"); lineno++;
3927- }
4459+ rp->codeEmitted = 1;
4460+ }
4461+ /* Finally, output the default: rule. We choose as the default: all
4462+ ** empty actions. */
4463+ fprintf(out," default:\n"); lineno++;
4464+ for(rp=lemp->rule; rp; rp=rp->next){
4465+ if( rp->codeEmitted ) continue;
4466+ assert( rp->noCode );
4467+ fprintf(out," /* (%d) ", rp->iRule);
4468+ writeRuleText(out, rp);
4469+#if 0
4470+ if( rp->doesReduce ){
4471+#endif
4472+ fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++;
4473+#if 0
4474+ }else{
4475+ fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n",
4476+ rp->iRule); lineno++;
4477+ }
4478+#endif
4479+ }
4480+ fprintf(out," break;\n"); lineno++;
39284481 tplt_xfer(lemp->name,in,out,&lineno);
39294482
39304483 /* Generate code which executes if a parse fails */
3931- tplt_print(out,lemp,lemp->failure,lemp->failureln,&lineno);
4484+ tplt_print(out,lemp,lemp->failure,&lineno);
39324485 tplt_xfer(lemp->name,in,out,&lineno);
39334486
39344487 /* Generate code which executes when a syntax error occurs */
3935- tplt_print(out,lemp,lemp->error,lemp->errorln,&lineno);
4488+ tplt_print(out,lemp,lemp->error,&lineno);
39364489 tplt_xfer(lemp->name,in,out,&lineno);
39374490
39384491 /* Generate code which executes when the parser accepts its input */
3939- tplt_print(out,lemp,lemp->accept,lemp->acceptln,&lineno);
4492+ tplt_print(out,lemp,lemp->accept,&lineno);
39404493 tplt_xfer(lemp->name,in,out,&lineno);
39414494
39424495 /* Append any addition code the user desires */
3943- tplt_print(out,lemp,lemp->extracode,lemp->extracodeln,&lineno);
3944-
4496+ tplt_print(out,lemp,lemp->extracode,&lineno);
4497+
4498+ acttab_free(&pActtab);
39454499 fclose(in);
39464500 fclose(out);
39474501 return;
39484502 }
39494503
39504504 /* Generate a header file for the parser */
3951-void ReportHeader(lemp)
3952-struct lemon *lemp;
4505+void ReportHeader(struct lemon *lemp)
39534506 {
39544507 FILE *out, *in;
3955- char *prefix;
4508+ const char *prefix;
39564509 char line[LINESIZE];
39574510 char pattern[LINESIZE];
39584511 int i;
@@ -3961,12 +4514,15 @@
39614514 else prefix = "";
39624515 in = file_open(lemp,".h","rb");
39634516 if( in ){
4517+ int nextChar;
39644518 for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){
3965- sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
4519+ sprintf(pattern,"#define %s%-30s %2d\n",
4520+ prefix,lemp->symbols[i]->name,i);
39664521 if( strcmp(line,pattern) ) break;
39674522 }
4523+ nextChar = fgetc(in);
39684524 fclose(in);
3969- if( i==lemp->nterminal ){
4525+ if( i==lemp->nterminal && nextChar==EOF ){
39704526 /* No change in the file. Don't rewrite it. */
39714527 /* (not the best idea if you use make tools that check the date! */
39724528 /*return;*/
@@ -3975,7 +4531,7 @@
39754531 out = file_open(lemp,".h","wb");
39764532 if( out ){
39774533 for(i=1; i<lemp->nterminal; i++){
3978- fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
4534+ fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i);
39794535 }
39804536 fclose(out);
39814537 }
@@ -3989,11 +4545,10 @@
39894545 ** it the default. Except, there is no default if the wildcard token
39904546 ** is a possible look-ahead.
39914547 */
3992-void CompressTables(lemp)
3993-struct lemon *lemp;
4548+void CompressTables(struct lemon *lemp)
39944549 {
39954550 struct state *stp;
3996- struct action *ap, *ap2;
4551+ struct action *ap, *ap2, *nextap;
39974552 struct rule *rp, *rp2, *rbest;
39984553 int nbest, n;
39994554 int i;
@@ -4028,7 +4583,7 @@
40284583
40294584 /* Do not make a default if the number of rules to default
40304585 ** is not at least 1 or if the wildcard token is a possbile
4031- ** lookahed.
4586+ ** lookahead.
40324587 */
40334588 if( nbest<1 || usesWildcard ) continue;
40344589
@@ -4043,6 +4598,62 @@
40434598 if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED;
40444599 }
40454600 stp->ap = Action_sort(stp->ap);
4601+
4602+ for(ap=stp->ap; ap; ap=ap->next){
4603+ if( ap->type==SHIFT ) break;
4604+ if( ap->type==REDUCE && ap->x.rp!=rbest ) break;
4605+ }
4606+ if( ap==0 ){
4607+ stp->autoReduce = 1;
4608+ stp->pDfltReduce = rbest;
4609+ }
4610+ }
4611+
4612+ /* Make a second pass over all states and actions. Convert
4613+ ** every action that is a SHIFT to an autoReduce state into
4614+ ** a SHIFTREDUCE action.
4615+ */
4616+ for(i=0; i<lemp->nstate; i++){
4617+ stp = lemp->sorted[i];
4618+ for(ap=stp->ap; ap; ap=ap->next){
4619+ struct state *pNextState;
4620+ if( ap->type!=SHIFT ) continue;
4621+ pNextState = ap->x.stp;
4622+ if( pNextState->autoReduce && pNextState->pDfltReduce!=0 ){
4623+ ap->type = SHIFTREDUCE;
4624+ ap->x.rp = pNextState->pDfltReduce;
4625+ }
4626+ }
4627+ }
4628+
4629+ /* If a SHIFTREDUCE action specifies a rule that has a single RHS term
4630+ ** (meaning that the SHIFTREDUCE will land back in the state where it
4631+ ** started) and if there is no C-code associated with the reduce action,
4632+ ** then we can go ahead and convert the action to be the same as the
4633+ ** action for the RHS of the rule.
4634+ */
4635+ for(i=0; i<lemp->nstate; i++){
4636+ stp = lemp->sorted[i];
4637+ for(ap=stp->ap; ap; ap=nextap){
4638+ nextap = ap->next;
4639+ if( ap->type!=SHIFTREDUCE ) continue;
4640+ rp = ap->x.rp;
4641+ if( rp->noCode==0 ) continue;
4642+ if( rp->nrhs!=1 ) continue;
4643+#if 1
4644+ /* Only apply this optimization to non-terminals. It would be OK to
4645+ ** apply it to terminal symbols too, but that makes the parser tables
4646+ ** larger. */
4647+ if( ap->sp->index<lemp->nterminal ) continue;
4648+#endif
4649+ /* If we reach this point, it means the optimization can be applied */
4650+ nextap = ap;
4651+ for(ap2=stp->ap; ap2 && (ap2==ap || ap2->sp!=rp->lhs); ap2=ap2->next){}
4652+ assert( ap2!=0 );
4653+ ap->spOpt = ap2->sp;
4654+ ap->type = ap2->type;
4655+ ap->x = ap2->x;
4656+ }
40464657 }
40474658 }
40484659
@@ -4061,7 +4672,11 @@
40614672 n = pB->nNtAct - pA->nNtAct;
40624673 if( n==0 ){
40634674 n = pB->nTknAct - pA->nTknAct;
4064- }
4675+ if( n==0 ){
4676+ n = pB->statenum - pA->statenum;
4677+ }
4678+ }
4679+ assert( n!=0 );
40654680 return n;
40664681 }
40674682
@@ -4070,8 +4685,7 @@
40704685 ** Renumber and resort states so that states with fewer choices
40714686 ** occur at the end. Except, keep state 0 as the first state.
40724687 */
4073-void ResortStates(lemp)
4074-struct lemon *lemp;
4688+void ResortStates(struct lemon *lemp)
40754689 {
40764690 int i;
40774691 struct state *stp;
@@ -4080,17 +4694,19 @@
40804694 for(i=0; i<lemp->nstate; i++){
40814695 stp = lemp->sorted[i];
40824696 stp->nTknAct = stp->nNtAct = 0;
4083- stp->iDflt = lemp->nstate + lemp->nrule;
4697+ stp->iDfltReduce = lemp->nrule; /* Init dflt action to "syntax error" */
40844698 stp->iTknOfst = NO_OFFSET;
40854699 stp->iNtOfst = NO_OFFSET;
40864700 for(ap=stp->ap; ap; ap=ap->next){
4087- if( compute_action(lemp,ap)>=0 ){
4701+ int iAction = compute_action(lemp,ap);
4702+ if( iAction>=0 ){
40884703 if( ap->sp->index<lemp->nterminal ){
40894704 stp->nTknAct++;
40904705 }else if( ap->sp->index<lemp->nsymbol ){
40914706 stp->nNtAct++;
40924707 }else{
4093- stp->iDflt = compute_action(lemp, ap);
4708+ assert( stp->autoReduce==0 || stp->pDfltReduce==ap->x.rp );
4709+ stp->iDfltReduce = iAction - lemp->nstate - lemp->nrule;
40944710 }
40954711 }
40964712 }
@@ -4100,6 +4716,10 @@
41004716 for(i=0; i<lemp->nstate; i++){
41014717 lemp->sorted[i]->statenum = i;
41024718 }
4719+ lemp->nxstate = lemp->nstate;
4720+ while( lemp->nxstate>1 && lemp->sorted[lemp->nxstate-1]->autoReduce ){
4721+ lemp->nxstate--;
4722+ }
41034723 }
41044724
41054725
@@ -4111,8 +4731,7 @@
41114731 static int size = 0;
41124732
41134733 /* Set the set size */
4114-void SetSize(n)
4115-int n;
4734+void SetSize(int n)
41164735 {
41174736 size = n+1;
41184737 }
@@ -4129,17 +4748,14 @@
41294748 }
41304749
41314750 /* Deallocate a set */
4132-void SetFree(s)
4133-char *s;
4751+void SetFree(char *s)
41344752 {
41354753 free(s);
41364754 }
41374755
41384756 /* Add a new element to the set. Return TRUE if the element was added
41394757 ** and FALSE if it was already there. */
4140-int SetAdd(s,e)
4141-char *s;
4142-int e;
4758+int SetAdd(char *s, int e)
41434759 {
41444760 int rv;
41454761 assert( e>=0 && e<size );
@@ -4149,9 +4765,7 @@
41494765 }
41504766
41514767 /* Add every element of s2 to s1. Return TRUE if s1 changes. */
4152-int SetUnion(s1,s2)
4153-char *s1;
4154-char *s2;
4768+int SetUnion(char *s1, char *s2)
41554769 {
41564770 int i, progress;
41574771 progress = 0;
@@ -4177,11 +4791,10 @@
41774791 ** Code for processing tables in the LEMON parser generator.
41784792 */
41794793
4180-PRIVATE int strhash(x)
4181-char *x;
4794+PRIVATE unsigned strhash(const char *x)
41824795 {
4183- int h = 0;
4184- while( *x) h = h*13 + *(x++);
4796+ unsigned h = 0;
4797+ while( *x ) h = h*13 + *(x++);
41854798 return h;
41864799 }
41874800
@@ -4189,15 +4802,16 @@
41894802 ** keep strings in a table so that the same string is not in more
41904803 ** than one place.
41914804 */
4192-char *Strsafe(y)
4193-char *y;
4805+const char *Strsafe(const char *y)
41944806 {
4195- char *z;
4807+ const char *z;
4808+ char *cpy;
41964809
41974810 if( y==0 ) return 0;
41984811 z = Strsafe_find(y);
4199- if( z==0 && (z=malloc( strlen(y)+1 ))!=0 ){
4200- strcpy(z,y);
4812+ if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
4813+ strcpy(cpy,y);
4814+ z = cpy;
42014815 Strsafe_insert(z);
42024816 }
42034817 MemoryCheck(z);
@@ -4220,7 +4834,7 @@
42204834 ** in an associative array of type "x1".
42214835 */
42224836 typedef struct s_x1node {
4223- char *data; /* The data */
4837+ const char *data; /* The data */
42244838 struct s_x1node *next; /* Next entry with the same hash */
42254839 struct s_x1node **from; /* Previous link */
42264840 } x1node;
@@ -4235,8 +4849,7 @@
42354849 if( x1a ){
42364850 x1a->size = 1024;
42374851 x1a->count = 0;
4238- x1a->tbl = (x1node*)malloc(
4239- (sizeof(x1node) + sizeof(x1node*))*1024 );
4852+ x1a->tbl = (x1node*)calloc(1024, sizeof(x1node) + sizeof(x1node*));
42404853 if( x1a->tbl==0 ){
42414854 free(x1a);
42424855 x1a = 0;
@@ -4249,12 +4862,11 @@
42494862 }
42504863 /* Insert a new record into the array. Return TRUE if successful.
42514864 ** Prior data with the same key is NOT overwritten */
4252-int Strsafe_insert(data)
4253-char *data;
4865+int Strsafe_insert(const char *data)
42544866 {
42554867 x1node *np;
4256- int h;
4257- int ph;
4868+ unsigned h;
4869+ unsigned ph;
42584870
42594871 if( x1a==0 ) return 0;
42604872 ph = strhash(data);
@@ -4274,8 +4886,7 @@
42744886 struct s_x1 array;
42754887 array.size = size = x1a->size*2;
42764888 array.count = x1a->count;
4277- array.tbl = (x1node*)malloc(
4278- (sizeof(x1node) + sizeof(x1node*))*size );
4889+ array.tbl = (x1node*)calloc(size, sizeof(x1node) + sizeof(x1node*));
42794890 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
42804891 array.ht = (x1node**)&(array.tbl[size]);
42814892 for(i=0; i<size; i++) array.ht[i] = 0;
@@ -4306,10 +4917,9 @@
43064917
43074918 /* Return a pointer to data assigned to the given key. Return NULL
43084919 ** if no such key. */
4309-char *Strsafe_find(key)
4310-char *key;
4920+const char *Strsafe_find(const char *key)
43114921 {
4312- int h;
4922+ unsigned h;
43134923 x1node *np;
43144924
43154925 if( x1a==0 ) return 0;
@@ -4325,8 +4935,7 @@
43254935 /* Return a pointer to the (terminal or nonterminal) symbol "x".
43264936 ** Create a new symbol if this is the first time "x" has been seen.
43274937 */
4328-struct symbol *Symbol_new(x)
4329-char *x;
4938+struct symbol *Symbol_new(const char *x)
43304939 {
43314940 struct symbol *sp;
43324941
@@ -4335,7 +4944,7 @@
43354944 sp = (struct symbol *)calloc(1, sizeof(struct symbol) );
43364945 MemoryCheck(sp);
43374946 sp->name = Strsafe(x);
4338- sp->type = isupper(*x) ? TERMINAL : NONTERMINAL;
4947+ sp->type = ISUPPER(*x) ? TERMINAL : NONTERMINAL;
43394948 sp->rule = 0;
43404949 sp->fallback = 0;
43414950 sp->prec = -1;
@@ -4343,6 +4952,7 @@
43434952 sp->firstset = 0;
43444953 sp->lambda = LEMON_FALSE;
43454954 sp->destructor = 0;
4955+ sp->destLineno = 0;
43464956 sp->datatype = 0;
43474957 sp->useCnt = 0;
43484958 Symbol_insert(sp,sp->name);
@@ -4351,20 +4961,27 @@
43514961 return sp;
43524962 }
43534963
4354-/* Compare two symbols for working purposes
4964+/* Compare two symbols for sorting purposes. Return negative,
4965+** zero, or positive if a is less then, equal to, or greater
4966+** than b.
43554967 **
43564968 ** Symbols that begin with upper case letters (terminals or tokens)
43574969 ** must sort before symbols that begin with lower case letters
4358-** (non-terminals). Other than that, the order does not matter.
4970+** (non-terminals). And MULTITERMINAL symbols (created using the
4971+** %token_class directive) must sort at the very end. Other than
4972+** that, the order does not matter.
43594973 **
43604974 ** We find experimentally that leaving the symbols in their original
43614975 ** order (the order they appeared in the grammar file) gives the
43624976 ** smallest parser tables in SQLite.
43634977 */
4364-int Symbolcmpp(struct symbol **a, struct symbol **b){
4365- int i1 = (**a).index + 10000000*((**a).name[0]>'Z');
4366- int i2 = (**b).index + 10000000*((**b).name[0]>'Z');
4367- return i1-i2;
4978+int Symbolcmpp(const void *_a, const void *_b)
4979+{
4980+ const struct symbol *a = *(const struct symbol **) _a;
4981+ const struct symbol *b = *(const struct symbol **) _b;
4982+ int i1 = a->type==MULTITERMINAL ? 3 : a->name[0]>'Z' ? 2 : 1;
4983+ int i2 = b->type==MULTITERMINAL ? 3 : b->name[0]>'Z' ? 2 : 1;
4984+ return i1==i2 ? a->index - b->index : i1 - i2;
43684985 }
43694986
43704987 /* There is one instance of the following structure for each
@@ -4383,8 +5000,8 @@
43835000 ** in an associative array of type "x2".
43845001 */
43855002 typedef struct s_x2node {
4386- struct symbol *data; /* The data */
4387- char *key; /* The key */
5003+ struct symbol *data; /* The data */
5004+ const char *key; /* The key */
43885005 struct s_x2node *next; /* Next entry with the same hash */
43895006 struct s_x2node **from; /* Previous link */
43905007 } x2node;
@@ -4399,8 +5016,7 @@
43995016 if( x2a ){
44005017 x2a->size = 128;
44015018 x2a->count = 0;
4402- x2a->tbl = (x2node*)malloc(
4403- (sizeof(x2node) + sizeof(x2node*))*128 );
5019+ x2a->tbl = (x2node*)calloc(128, sizeof(x2node) + sizeof(x2node*));
44045020 if( x2a->tbl==0 ){
44055021 free(x2a);
44065022 x2a = 0;
@@ -4413,13 +5029,11 @@
44135029 }
44145030 /* Insert a new record into the array. Return TRUE if successful.
44155031 ** Prior data with the same key is NOT overwritten */
4416-int Symbol_insert(data,key)
4417-struct symbol *data;
4418-char *key;
5032+int Symbol_insert(struct symbol *data, const char *key)
44195033 {
44205034 x2node *np;
4421- int h;
4422- int ph;
5035+ unsigned h;
5036+ unsigned ph;
44235037
44245038 if( x2a==0 ) return 0;
44255039 ph = strhash(key);
@@ -4439,8 +5053,7 @@
44395053 struct s_x2 array;
44405054 array.size = size = x2a->size*2;
44415055 array.count = x2a->count;
4442- array.tbl = (x2node*)malloc(
4443- (sizeof(x2node) + sizeof(x2node*))*size );
5056+ array.tbl = (x2node*)calloc(size, sizeof(x2node) + sizeof(x2node*));
44445057 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
44455058 array.ht = (x2node**)&(array.tbl[size]);
44465059 for(i=0; i<size; i++) array.ht[i] = 0;
@@ -4473,10 +5086,9 @@
44735086
44745087 /* Return a pointer to data assigned to the given key. Return NULL
44755088 ** if no such key. */
4476-struct symbol *Symbol_find(key)
4477-char *key;
5089+struct symbol *Symbol_find(const char *key)
44785090 {
4479- int h;
5091+ unsigned h;
44805092 x2node *np;
44815093
44825094 if( x2a==0 ) return 0;
@@ -4490,8 +5102,7 @@
44905102 }
44915103
44925104 /* Return the n-th data. Return NULL if n is out of range. */
4493-struct symbol *Symbol_Nth(n)
4494-int n;
5105+struct symbol *Symbol_Nth(int n)
44955106 {
44965107 struct symbol *data;
44975108 if( x2a && n>0 && n<=x2a->count ){
@@ -4525,10 +5136,10 @@
45255136 }
45265137
45275138 /* Compare two configurations */
4528-int Configcmp(a,b)
4529-struct config *a;
4530-struct config *b;
5139+int Configcmp(const char *_a,const char *_b)
45315140 {
5141+ const struct config *a = (struct config *) _a;
5142+ const struct config *b = (struct config *) _b;
45325143 int x;
45335144 x = a->rp->index - b->rp->index;
45345145 if( x==0 ) x = a->dot - b->dot;
@@ -4536,9 +5147,7 @@
45365147 }
45375148
45385149 /* Compare two states */
4539-PRIVATE int statecmp(a,b)
4540-struct config *a;
4541-struct config *b;
5150+PRIVATE int statecmp(struct config *a, struct config *b)
45425151 {
45435152 int rc;
45445153 for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){
@@ -4553,10 +5162,9 @@
45535162 }
45545163
45555164 /* Hash a state */
4556-PRIVATE int statehash(a)
4557-struct config *a;
5165+PRIVATE unsigned statehash(struct config *a)
45585166 {
4559- int h=0;
5167+ unsigned h=0;
45605168 while( a ){
45615169 h = h*571 + a->rp->index*37 + a->dot;
45625170 a = a->bp;
@@ -4567,10 +5175,10 @@
45675175 /* Allocate a new state structure */
45685176 struct state *State_new()
45695177 {
4570- struct state *new;
4571- new = (struct state *)calloc(1, sizeof(struct state) );
4572- MemoryCheck(new);
4573- return new;
5178+ struct state *newstate;
5179+ newstate = (struct state *)calloc(1, sizeof(struct state) );
5180+ MemoryCheck(newstate);
5181+ return newstate;
45745182 }
45755183
45765184 /* There is one instance of the following structure for each
@@ -4605,8 +5213,7 @@
46055213 if( x3a ){
46065214 x3a->size = 128;
46075215 x3a->count = 0;
4608- x3a->tbl = (x3node*)malloc(
4609- (sizeof(x3node) + sizeof(x3node*))*128 );
5216+ x3a->tbl = (x3node*)calloc(128, sizeof(x3node) + sizeof(x3node*));
46105217 if( x3a->tbl==0 ){
46115218 free(x3a);
46125219 x3a = 0;
@@ -4619,13 +5226,11 @@
46195226 }
46205227 /* Insert a new record into the array. Return TRUE if successful.
46215228 ** Prior data with the same key is NOT overwritten */
4622-int State_insert(data,key)
4623-struct state *data;
4624-struct config *key;
5229+int State_insert(struct state *data, struct config *key)
46255230 {
46265231 x3node *np;
4627- int h;
4628- int ph;
5232+ unsigned h;
5233+ unsigned ph;
46295234
46305235 if( x3a==0 ) return 0;
46315236 ph = statehash(key);
@@ -4645,8 +5250,7 @@
46455250 struct s_x3 array;
46465251 array.size = size = x3a->size*2;
46475252 array.count = x3a->count;
4648- array.tbl = (x3node*)malloc(
4649- (sizeof(x3node) + sizeof(x3node*))*size );
5253+ array.tbl = (x3node*)calloc(size, sizeof(x3node) + sizeof(x3node*));
46505254 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
46515255 array.ht = (x3node**)&(array.tbl[size]);
46525256 for(i=0; i<size; i++) array.ht[i] = 0;
@@ -4679,10 +5283,9 @@
46795283
46805284 /* Return a pointer to data assigned to the given key. Return NULL
46815285 ** if no such key. */
4682-struct state *State_find(key)
4683-struct config *key;
5286+struct state *State_find(struct config *key)
46845287 {
4685- int h;
5288+ unsigned h;
46865289 x3node *np;
46875290
46885291 if( x3a==0 ) return 0;
@@ -4704,7 +5307,7 @@
47045307 int i,size;
47055308 if( x3a==0 ) return 0;
47065309 size = x3a->count;
4707- array = (struct state **)malloc( sizeof(struct state *)*size );
5310+ array = (struct state **)calloc(size, sizeof(struct state *));
47085311 if( array ){
47095312 for(i=0; i<size; i++) array[i] = x3a->tbl[i].data;
47105313 }
@@ -4712,10 +5315,9 @@
47125315 }
47135316
47145317 /* Hash a configuration */
4715-PRIVATE int confighash(a)
4716-struct config *a;
5318+PRIVATE unsigned confighash(struct config *a)
47175319 {
4718- int h=0;
5320+ unsigned h=0;
47195321 h = h*571 + a->rp->index*37 + a->dot;
47205322 return h;
47215323 }
@@ -4751,8 +5353,7 @@
47515353 if( x4a ){
47525354 x4a->size = 64;
47535355 x4a->count = 0;
4754- x4a->tbl = (x4node*)malloc(
4755- (sizeof(x4node) + sizeof(x4node*))*64 );
5356+ x4a->tbl = (x4node*)calloc(64, sizeof(x4node) + sizeof(x4node*));
47565357 if( x4a->tbl==0 ){
47575358 free(x4a);
47585359 x4a = 0;
@@ -4765,19 +5366,18 @@
47655366 }
47665367 /* Insert a new record into the array. Return TRUE if successful.
47675368 ** Prior data with the same key is NOT overwritten */
4768-int Configtable_insert(data)
4769-struct config *data;
5369+int Configtable_insert(struct config *data)
47705370 {
47715371 x4node *np;
4772- int h;
4773- int ph;
5372+ unsigned h;
5373+ unsigned ph;
47745374
47755375 if( x4a==0 ) return 0;
47765376 ph = confighash(data);
47775377 h = ph & (x4a->size-1);
47785378 np = x4a->ht[h];
47795379 while( np ){
4780- if( Configcmp(np->data,data)==0 ){
5380+ if( Configcmp((const char *) np->data,(const char *) data)==0 ){
47815381 /* An existing entry with the same key is found. */
47825382 /* Fail because overwrite is not allows. */
47835383 return 0;
@@ -4790,8 +5390,7 @@
47905390 struct s_x4 array;
47915391 array.size = size = x4a->size*2;
47925392 array.count = x4a->count;
4793- array.tbl = (x4node*)malloc(
4794- (sizeof(x4node) + sizeof(x4node*))*size );
5393+ array.tbl = (x4node*)calloc(size, sizeof(x4node) + sizeof(x4node*));
47955394 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
47965395 array.ht = (x4node**)&(array.tbl[size]);
47975396 for(i=0; i<size; i++) array.ht[i] = 0;
@@ -4822,8 +5421,7 @@
48225421
48235422 /* Return a pointer to data assigned to the given key. Return NULL
48245423 ** if no such key. */
4825-struct config *Configtable_find(key)
4826-struct config *key;
5424+struct config *Configtable_find(struct config *key)
48275425 {
48285426 int h;
48295427 x4node *np;
@@ -4832,7 +5430,7 @@
48325430 h = confighash(key) & (x4a->size-1);
48335431 np = x4a->ht[h];
48345432 while( np ){
4835- if( Configcmp(np->data,key)==0 ) break;
5433+ if( Configcmp((const char *) np->data,(const char *) key)==0 ) break;
48365434 np = np->next;
48375435 }
48385436 return np ? np->data : 0;
@@ -4840,8 +5438,7 @@
48405438
48415439 /* Remove all data from the table. Pass each data to the function "f"
48425440 ** as it is removed. ("f" may be null to avoid this step.) */
4843-void Configtable_clear(f)
4844-int(*f)(/* struct config * */);
5441+void Configtable_clear(int(*f)(struct config *))
48455442 {
48465443 int i;
48475444 if( x4a==0 || x4a->count==0 ) return;
diff -r ada484f0688e -r 84945d6486e0 tools/lemon/lempar.c
--- a/tools/lemon/lempar.c Sun Oct 20 21:34:48 2019 +0200
+++ b/tools/lemon/lempar.c Mon Nov 25 07:54:18 2019 +1100
@@ -1,8 +1,27 @@
1-/* Driver template for the LEMON parser generator.
2-** The author disclaims copyright to this source code.
1+/*
2+** 2000-05-29
3+**
4+** The author disclaims copyright to this source code. In place of
5+** a legal notice, here is a blessing:
6+**
7+** May you do good and not evil.
8+** May you find forgiveness for yourself and forgive others.
9+** May you share freely, never taking more than you give.
10+**
11+*************************************************************************
12+** Driver template for the LEMON parser generator.
13+**
14+** The "lemon" program processes an LALR(1) input grammar file, then uses
15+** this template to construct a parser. The "lemon" program inserts text
16+** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the
17+** interstitial "-" characters) contained in this template is changed into
18+** the value of the %name directive from the grammar. Otherwise, the content
19+** of this template is copied straight through into the generate parser
20+** source file.
21+**
22+** The following is the concatenation of all %include directives from the
23+** input grammar file:
324 */
4-/* First off, code is included which follows the "include" declaration
5-** in the input file. */
625 #include <stdio.h>
726 #include <string.h>
827 #include <assert.h>
@@ -13,63 +32,84 @@
1332 #define CDECL
1433 #endif
1534
16-%%
17-/* Next is all token values, in a form suitable for use by makeheaders.
18-** This section will be null unless lemon is run with the -m switch.
19-*/
20-/*
21-** These constants (all generated automatically by the parser generator)
22-** specify the various kinds of tokens (terminals) that the parser
23-** understands.
24-**
25-** Each symbol here is a terminal symbol in the grammar.
26-*/
35+/************ Begin %include sections from the grammar ************************/
2736 %%
28-/* Make sure the INTERFACE macro is defined.
29-*/
30-#ifndef INTERFACE
31-# define INTERFACE 1
32-#endif
33-/* The next thing included is series of defines which control
37+/**************** End of %include directives **********************************/
38+/* These constants specify the various numeric values for terminal symbols
39+** in a format understandable to "makeheaders". This section is blank unless
40+** "lemon" is run with the "-m" command-line option.
41+***************** Begin makeheaders token definitions *************************/
42+%%
43+/**************** End makeheaders token definitions ***************************/
44+
45+/* The next section is a series of control #defines.
3446 ** various aspects of the generated parser.
35-** YYCODETYPE is the data type used for storing terminal
36-** and nonterminal numbers. "unsigned char" is
37-** used if there are fewer than 250 terminals
38-** and nonterminals. "int" is used otherwise.
39-** YYNOCODE is a number of type YYCODETYPE which corresponds
40-** to no legal terminal or nonterminal number. This
41-** number is used to fill in empty slots of the hash
42-** table.
47+** YYCODETYPE is the data type used to store the integer codes
48+** that represent terminal and non-terminal symbols.
49+** "unsigned char" is used if there are fewer than
50+** 256 symbols. Larger types otherwise.
51+** YYNOCODE is a number of type YYCODETYPE that is not used for
52+** any terminal or nonterminal symbol.
4353 ** YYFALLBACK If defined, this indicates that one or more tokens
44-** have fall-back values which should be used if the
45-** original value of the token will not parse.
46-** YYACTIONTYPE is the data type used for storing terminal
47-** and nonterminal numbers. "unsigned char" is
48-** used if there are fewer than 250 rules and
49-** states combined. "int" is used otherwise.
50-** ParseTOKENTYPE is the data type used for minor tokens given
51-** directly to the parser from the tokenizer.
52-** YYMINORTYPE is the data type used for all minor tokens.
54+** (also known as: "terminal symbols") have fall-back
55+** values which should be used if the original symbol
56+** would not parse. This permits keywords to sometimes
57+** be used as identifiers, for example.
58+** YYACTIONTYPE is the data type used for "action codes" - numbers
59+** that indicate what to do in response to the next
60+** token.
61+** ParseTOKENTYPE is the data type used for minor type for terminal
62+** symbols. Background: A "minor type" is a semantic
63+** value associated with a terminal or non-terminal
64+** symbols. For example, for an "ID" terminal symbol,
65+** the minor type might be the name of the identifier.
66+** Each non-terminal can have a different minor type.
67+** Terminal symbols all have the same minor type, though.
68+** This macros defines the minor type for terminal
69+** symbols.
70+** YYMINORTYPE is the data type used for all minor types.
5371 ** This is typically a union of many types, one of
5472 ** which is ParseTOKENTYPE. The entry in the union
55-** for base tokens is called "yy0".
73+** for terminal symbols is called "yy0".
5674 ** YYSTACKDEPTH is the maximum depth of the parser's stack. If
5775 ** zero the stack is dynamically sized using realloc()
5876 ** ParseARG_SDECL A static variable declaration for the %extra_argument
5977 ** ParseARG_PDECL A parameter declaration for the %extra_argument
6078 ** ParseARG_STORE Code to store %extra_argument into yypParser
6179 ** ParseARG_FETCH Code to extract %extra_argument from yypParser
62-** YYNSTATE the combined number of states.
63-** YYNRULE the number of rules in the grammar
6480 ** YYERRORSYMBOL is the code number of the error symbol. If not
6581 ** defined, then do no error processing.
82+** YYNSTATE the combined number of states.
83+** YYNRULE the number of rules in the grammar
84+** YY_MAX_SHIFT Maximum value for shift actions
85+** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
86+** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
87+** YY_MIN_REDUCE Maximum value for reduce actions
88+** YY_ERROR_ACTION The yy_action[] code for syntax error
89+** YY_ACCEPT_ACTION The yy_action[] code for accept
90+** YY_NO_ACTION The yy_action[] code for no-op
6691 */
92+#ifndef INTERFACE
93+# define INTERFACE 1
94+#endif
95+/************* Begin control #defines *****************************************/
6796 %%
68-#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
69-#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
70-#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
97+/************* End control #defines *******************************************/
7198
72-/* Next are that tables used to determine what action to take based on the
99+/* Define the yytestcase() macro to be a no-op if is not already defined
100+** otherwise.
101+**
102+** Applications can choose to define yytestcase() in the %include section
103+** to a macro that can assist in verifying code coverage. For production
104+** code the yytestcase() macro should be turned off. But it is useful
105+** for testing.
106+*/
107+#ifndef yytestcase
108+# define yytestcase(X)
109+#endif
110+
111+
112+/* Next are the tables used to determine what action to take based on the
73113 ** current state and lookahead token. These tables are used to implement
74114 ** functions that take a state number and lookahead value and return an
75115 ** action integer.
@@ -77,29 +117,37 @@
77117 ** Suppose the action integer is N. Then the action is determined as
78118 ** follows
79119 **
80-** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
120+** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
81121 ** token onto the stack and goto state N.
82122 **
83-** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
123+** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
124+** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
84125 **
85-** N == YYNSTATE+YYNRULE A syntax error has occurred.
126+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
127+** and YY_MAX_REDUCE
86128 **
87-** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
129+** N == YY_ERROR_ACTION A syntax error has occurred.
88130 **
89-** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
131+** N == YY_ACCEPT_ACTION The parser accepts its input.
132+**
133+** N == YY_NO_ACTION No such action. Denotes unused
90134 ** slots in the yy_action[] table.
91135 **
92136 ** The action table is constructed as a single large table named yy_action[].
93-** Given state S and lookahead X, the action is computed as
94-**
95-** yy_action[ yy_shift_ofst[S] + X ]
137+** Given state S and lookahead X, the action is computed as either:
96138 **
97-** If the index value yy_shift_ofst[S]+X is out of range or if the value
98-** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
99-** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
100-** and that yy_default[S] should be used instead.
139+** (A) N = yy_action[ yy_shift_ofst[S] + X ]
140+** (B) N = yy_default[S]
101141 **
102-** The formula above is for computing the action when the lookahead is
142+** The (A) formula is preferred. The B formula is used instead if:
143+** (1) The yy_shift_ofst[S]+X value is out of range, or
144+** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or
145+** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT.
146+** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that
147+** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
148+** Hence only tests (1) and (2) need to be evaluated.)
149+**
150+** The formulas above are for computing the action when the lookahead is
103151 ** a terminal symbol. If the lookahead is a non-terminal (as occurs after
104152 ** a reduce action) then the yy_reduce_ofst[] array is used in place of
105153 ** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
@@ -115,19 +163,24 @@
115163 ** yy_reduce_ofst[] For each state, the offset into yy_action for
116164 ** shifting non-terminals after a reduce.
117165 ** yy_default[] Default action for each state.
118-*/
166+**
167+*********** Begin parsing tables **********************************************/
119168 %%
120-#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
169+/********** End of lemon-generated parsing tables *****************************/
121170
122-/* The next table maps tokens into fallback tokens. If a construct
123-** like the following:
171+/* The next table maps tokens (terminal symbols) into fallback tokens.
172+** If a construct like the following:
124173 **
125174 ** %fallback ID X Y Z.
126175 **
127-** appears in the grammer, then ID becomes a fallback token for X, Y,
176+** appears in the grammar, then ID becomes a fallback token for X, Y,
128177 ** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
129178 ** but it does not parse, the type of the token is changed to ID and
130179 ** the parse is retried before an error is thrown.
180+**
181+** This feature can be used, for example, to cause some keywords in a language
182+** to revert to identifiers if they keyword does not apply in the context where
183+** it appears.
131184 */
132185 #ifdef YYFALLBACK
133186 static const YYCODETYPE yyFallback[] = {
@@ -146,25 +199,35 @@
146199 ** + The semantic value stored at this level of the stack. This is
147200 ** the information used by the action routines in the grammar.
148201 ** It is sometimes called the "minor" token.
202+**
203+** After the "shift" half of a SHIFTREDUCE action, the stateno field
204+** actually contains the reduce action for the second half of the
205+** SHIFTREDUCE.
149206 */
150207 struct yyStackEntry {
151- int stateno; /* The state-number */
152- int major; /* The major token value. This is the code
153- ** number for the token at this stack level */
154- YYMINORTYPE minor; /* The user-supplied minor token value. This
155- ** is the value of the token */
208+ YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
209+ YYCODETYPE major; /* The major token value. This is the code
210+ ** number for the token at this stack level */
211+ YYMINORTYPE minor; /* The user-supplied minor token value. This
212+ ** is the value of the token */
156213 };
157214 typedef struct yyStackEntry yyStackEntry;
158215
159216 /* The state of the parser is completely contained in an instance of
160217 ** the following structure */
161218 struct yyParser {
162- int yyidx; /* Index of top element in stack */
219+ yyStackEntry *yytos; /* Pointer to top element of the stack */
220+#ifdef YYTRACKMAXSTACKDEPTH
221+ int yyhwm; /* High-water mark of the stack */
222+#endif
223+#ifndef YYNOERRORRECOVERY
163224 int yyerrcnt; /* Shifts left before out of the error */
225+#endif
164226 ParseARG_SDECL /* A place to hold %extra_argument */
165227 #if YYSTACKDEPTH<=0
166228 int yystksz; /* Current side of the stack */
167229 yyStackEntry *yystack; /* The parser's stack */
230+ yyStackEntry yystk0; /* First stack entry */
168231 #else
169232 yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
170233 #endif
@@ -219,29 +282,50 @@
219282 };
220283 #endif /* NDEBUG */
221284
285+
222286 #if YYSTACKDEPTH<=0
223287 /*
224-** Try to increase the size of the parser stack.
288+** Try to increase the size of the parser stack. Return the number
289+** of errors. Return 0 on success.
225290 */
226-static void yyGrowStack(yyParser *p){
291+static int yyGrowStack(yyParser *p){
227292 int newSize;
293+ int idx;
228294 yyStackEntry *pNew;
229295
230296 newSize = p->yystksz*2 + 100;
231- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
297+ idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
298+ if( p->yystack==&p->yystk0 ){
299+ pNew = (yyStackEntry *)malloc(newSize*sizeof(pNew[0]));
300+ if( pNew ) pNew[0] = p->yystk0;
301+ }else{
302+ pNew = (yyStackEntry *)realloc(p->yystack, newSize*sizeof(pNew[0]));
303+ }
232304 if( pNew ){
233305 p->yystack = pNew;
234- p->yystksz = newSize;
306+ p->yytos = &p->yystack[idx];
235307 #ifndef NDEBUG
236308 if( yyTraceFILE ){
237- fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
238- yyTracePrompt, p->yystksz);
309+ fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
310+ yyTracePrompt, p->yystksz, newSize);
311+ fflush(yyTraceFILE);
239312 }
240313 #endif
314+ p->yystksz = newSize;
241315 }
316+ return pNew==0;
242317 }
243318 #endif
244319
320+/* Datatype of the argument to the memory allocated passed as the
321+** second argument to ParseAlloc() below. This can be changed by
322+** putting an appropriate #define in the %include section of the input
323+** grammar.
324+*/
325+#ifndef YYMALLOCARGTYPE
326+# define YYMALLOCARGTYPE size_t
327+#endif
328+
245329 /*
246330 ** This function allocates a new parser.
247331 ** The only argument is a pointer to a function which works like
@@ -254,24 +338,45 @@
254338 ** A pointer to a parser. This pointer is used in subsequent calls
255339 ** to Parse and ParseFree.
256340 */
257-void *ParseAlloc(void *(CDECL *mallocProc)(size_t)){
341+void *ParseAlloc(void *(CDECL *mallocProc)(YYMALLOCARGTYPE)){
258342 yyParser *pParser;
259- pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
343+ pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
260344 if( pParser ){
261- pParser->yyidx = -1;
345+#ifdef YYTRACKMAXSTACKDEPTH
346+ pParser->yyhwm = 0;
347+#endif
262348 #if YYSTACKDEPTH<=0
263- yyGrowStack(pParser);
349+ pParser->yytos = NULL;
350+ pParser->yystack = NULL;
351+ pParser->yystksz = 0;
352+ if( yyGrowStack(pParser) ){
353+ pParser->yystack = &pParser->yystk0;
354+ pParser->yystksz = 1;
355+ }
264356 #endif
357+#ifndef YYNOERRORRECOVERY
358+ pParser->yyerrcnt = -1;
359+#endif
360+ pParser->yytos = pParser->yystack;
361+ pParser->yystack[0].stateno = 0;
362+ pParser->yystack[0].major = 0;
265363 }
266364 return pParser;
267365 }
268366
269-/* The following function deletes the value associated with a
270-** symbol. The symbol can be either a terminal or nonterminal.
271-** "yymajor" is the symbol code, and "yypminor" is a pointer to
272-** the value.
367+/* The following function deletes the "minor type" or semantic value
368+** associated with a symbol. The symbol can be either a terminal
369+** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
370+** a pointer to the value to be deleted. The code used to do the
371+** deletions is derived from the %destructor and/or %token_destructor
372+** directives of the input grammar.
273373 */
274-static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
374+static void yy_destructor(
375+ yyParser *yypParser, /* The parser */
376+ YYCODETYPE yymajor, /* Type code for object to destroy */
377+ YYMINORTYPE *yypminor /* The object to be destroyed */
378+){
379+ ParseARG_FETCH;
275380 switch( yymajor ){
276381 /* Here is inserted the actions which take place when a
277382 ** terminal or non-terminal is destroyed. This can happen
@@ -280,10 +385,12 @@
280385 ** being destroyed before it is finished parsing.
281386 **
282387 ** Note: during a reduce, the only symbols destroyed are those
283- ** which appear on the RHS of the rule, but which are not used
388+ ** which appear on the RHS of the rule, but which are *not* used
284389 ** inside the C code.
285390 */
391+/********* Begin destructor definitions ***************************************/
286392 %%
393+/********* End destructor definitions *****************************************/
287394 default: break; /* If no destructor action specified: do nothing */
288395 }
289396 }
@@ -293,193 +400,232 @@
293400 **
294401 ** If there is a destructor routine associated with the token which
295402 ** is popped from the stack, then call it.
296-**
297-** Return the major token number for the symbol popped.
298403 */
299-static int yy_pop_parser_stack(yyParser *pParser){
300- YYCODETYPE yymajor;
301- yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
302-
303- if( pParser->yyidx<0 ) return 0;
404+static void yy_pop_parser_stack(yyParser *pParser){
405+ yyStackEntry *yytos;
406+ assert( pParser->yytos!=0 );
407+ assert( pParser->yytos > pParser->yystack );
408+ yytos = pParser->yytos--;
304409 #ifndef NDEBUG
305- if( yyTraceFILE && pParser->yyidx>=0 ){
410+ if( yyTraceFILE ){
306411 fprintf(yyTraceFILE,"%sPopping %s\n",
307412 yyTracePrompt,
308413 yyTokenName[yytos->major]);
414+ fflush(yyTraceFILE);
309415 }
310416 #endif
311- yymajor = yytos->major;
312- yy_destructor( yymajor, &yytos->minor);
313- pParser->yyidx--;
314- return yymajor;
417+ yy_destructor(pParser, yytos->major, &yytos->minor);
315418 }
316419
317420 /*
318-** Deallocate and destroy a parser. Destructors are all called for
421+** Deallocate and destroy a parser. Destructors are called for
319422 ** all stack elements before shutting the parser down.
320423 **
321-** Inputs:
322-** <ul>
323-** <li> A pointer to the parser. This should be a pointer
324-** obtained from ParseAlloc.
325-** <li> A pointer to a function used to reclaim memory obtained
326-** from malloc.
327-** </ul>
424+** If the YYPARSEFREENEVERNULL macro exists (for example because it
425+** is defined in a %include section of the input grammar) then it is
426+** assumed that the input pointer is never NULL.
328427 */
329428 void ParseFree(
330429 void *p, /* The parser to be deleted */
331430 void (CDECL *freeProc)(void*) /* Function used to reclaim memory */
332431 ){
333432 yyParser *pParser = (yyParser*)p;
433+#ifndef YYPARSEFREENEVERNULL
334434 if( pParser==0 ) return;
335- while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
435+#endif
436+ while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
336437 #if YYSTACKDEPTH<=0
337- free(pParser->yystack);
438+ if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
338439 #endif
339440 (*freeProc)((void*)pParser);
340441 }
341442
342443 /*
444+** Return the peak depth of the stack for a parser.
445+*/
446+#ifdef YYTRACKMAXSTACKDEPTH
447+int ParseStackPeak(void *p){
448+ yyParser *pParser = (yyParser*)p;
449+ return pParser->yyhwm;
450+}
451+#endif
452+
453+/*
343454 ** Find the appropriate action for a parser given the terminal
344455 ** look-ahead token iLookAhead.
345-**
346-** If the look-ahead token is YYNOCODE, then check to see if the action is
347-** independent of the look-ahead. If it is, return the action, otherwise
348-** return YY_NO_ACTION.
349456 */
350-static int yy_find_shift_action(
457+static unsigned int yy_find_shift_action(
351458 yyParser *pParser, /* The parser */
352459 YYCODETYPE iLookAhead /* The look-ahead token */
353460 ){
354461 int i;
355- int stateno = pParser->yystack[pParser->yyidx].stateno;
462+ int stateno = pParser->yytos->stateno;
356463
357- if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
358- return yy_default[stateno];
359- }
360- assert( iLookAhead!=YYNOCODE );
361- i += iLookAhead;
362- if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
363- if( iLookAhead>0 ){
464+ if( stateno>=YY_MIN_REDUCE ) return stateno;
465+ assert( stateno <= YY_SHIFT_COUNT );
466+ do{
467+ i = yy_shift_ofst[stateno];
468+ assert( iLookAhead!=YYNOCODE );
469+ i += iLookAhead;
470+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
364471 #ifdef YYFALLBACK
365- int iFallback; /* Fallback token */
472+ YYCODETYPE iFallback; /* Fallback token */
366473 if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
367474 && (iFallback = yyFallback[iLookAhead])!=0 ){
368475 #ifndef NDEBUG
369476 if( yyTraceFILE ){
370477 fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
371478 yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
479+ fflush(yyTraceFILE);
372480 }
373481 #endif
374- return yy_find_shift_action(pParser, iFallback);
482+ assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
483+ iLookAhead = iFallback;
484+ continue;
375485 }
376486 #endif
377487 #ifdef YYWILDCARD
378488 {
379489 int j = i - iLookAhead + YYWILDCARD;
380- if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){
490+ if(
491+#if YY_SHIFT_MIN+YYWILDCARD<0
492+ j>=0 &&
493+#endif
494+#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
495+ j<YY_ACTTAB_COUNT &&
496+#endif
497+ yy_lookahead[j]==YYWILDCARD && iLookAhead>0
498+ ){
381499 #ifndef NDEBUG
382500 if( yyTraceFILE ){
383501 fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
384- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
502+ yyTracePrompt, yyTokenName[iLookAhead],
503+ yyTokenName[YYWILDCARD]);
504+ fflush(yyTraceFILE);
385505 }
386506 #endif /* NDEBUG */
387507 return yy_action[j];
388508 }
389509 }
390510 #endif /* YYWILDCARD */
511+ return yy_default[stateno];
512+ }else{
513+ return yy_action[i];
391514 }
392- return yy_default[stateno];
393- }else{
394- return yy_action[i];
395- }
515+ }while(1);
396516 }
397517
398518 /*
399519 ** Find the appropriate action for a parser given the non-terminal
400520 ** look-ahead token iLookAhead.
401-**
402-** If the look-ahead token is YYNOCODE, then check to see if the action is
403-** independent of the look-ahead. If it is, return the action, otherwise
404-** return YY_NO_ACTION.
405521 */
406522 static int yy_find_reduce_action(
407523 int stateno, /* Current state number */
408524 YYCODETYPE iLookAhead /* The look-ahead token */
409525 ){
410526 int i;
411- if( stateno>YY_REDUCE_MAX ||
412- (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){
413- return yy_default[stateno];
527+#ifdef YYERRORSYMBOL
528+ if( stateno>YY_REDUCE_COUNT ){
529+ return yy_default[stateno];
414530 }
531+#else
532+ assert( stateno<=YY_REDUCE_COUNT );
533+#endif
534+ i = yy_reduce_ofst[stateno];
415535 assert( i!=YY_REDUCE_USE_DFLT );
416536 assert( iLookAhead!=YYNOCODE );
417537 i += iLookAhead;
418- if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
538+#ifdef YYERRORSYMBOL
539+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
419540 return yy_default[stateno];
420- }else{
421- return yy_action[i];
422541 }
542+#else
543+ assert( i>=0 && i<YY_ACTTAB_COUNT );
544+ assert( yy_lookahead[i]==iLookAhead );
545+#endif
423546 return yy_action[i];
424547 }
425548
426549 /*
427550 ** The following routine is called if the stack overflows.
428551 */
429-static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
552+static void yyStackOverflow(yyParser *yypParser){
430553 ParseARG_FETCH;
431- yypParser->yyidx--;
554+ yypParser->yytos--;
432555 #ifndef NDEBUG
433556 if( yyTraceFILE ){
434557 fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
558+ fflush(yyTraceFILE);
435559 }
436560 #endif
437- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
561+ while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
438562 /* Here code is inserted which will execute if the parser
439563 ** stack every overflows */
564+/******** Begin %stack_overflow code ******************************************/
440565 %%
566+/******** End %stack_overflow code ********************************************/
441567 ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
442568 }
443569
444570 /*
571+** Print tracing information for a SHIFT action
572+*/
573+#ifndef NDEBUG
574+static void yyTraceShift(yyParser *yypParser, int yyNewState){
575+ if( yyTraceFILE ){
576+ if( yyNewState<YYNSTATE ){
577+ fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
578+ yyTracePrompt,yyTokenName[yypParser->yytos->major],
579+ yyNewState);
580+ }else{
581+ fprintf(yyTraceFILE,"%sShift '%s'\n",
582+ yyTracePrompt,yyTokenName[yypParser->yytos->major]);
583+ }
584+ fflush(yyTraceFILE);
585+ }
586+}
587+#else
588+# define yyTraceShift(X,Y)
589+#endif
590+
591+/*
445592 ** Perform a shift action.
446593 */
447594 static void yy_shift(
448595 yyParser *yypParser, /* The parser to be shifted */
449596 int yyNewState, /* The new state to shift in */
450597 int yyMajor, /* The major token to shift in */
451- YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
598+ ParseTOKENTYPE yyMinor /* The minor token to shift in */
452599 ){
453600 yyStackEntry *yytos;
454- yypParser->yyidx++;
455-#if YYSTACKDEPTH>0
456- if( yypParser->yyidx>=YYSTACKDEPTH ){
457- yyStackOverflow(yypParser, yypMinor);
601+ yypParser->yytos++;
602+#ifdef YYTRACKMAXSTACKDEPTH
603+ if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
604+ yypParser->yyhwm++;
605+ assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
606+ }
607+#endif
608+#if YYSTACKDEPTH>0
609+ if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){
610+ yyStackOverflow(yypParser);
458611 return;
459612 }
460613 #else
461- if( yypParser->yyidx>=yypParser->yystksz ){
462- yyGrowStack(yypParser);
463- if( yypParser->yyidx>=yypParser->yystksz ){
464- yyStackOverflow(yypParser, yypMinor);
614+ if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
615+ if( yyGrowStack(yypParser) ){
616+ yyStackOverflow(yypParser);
465617 return;
466618 }
467619 }
468620 #endif
469- yytos = &yypParser->yystack[yypParser->yyidx];
470- yytos->stateno = yyNewState;
471- yytos->major = yyMajor;
472- yytos->minor = *yypMinor;
473-#ifndef NDEBUG
474- if( yyTraceFILE && yypParser->yyidx>0 ){
475- int i;
476- fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
477- fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
478- for(i=1; i<=yypParser->yyidx; i++)
479- fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]);
480- fprintf(yyTraceFILE,"\n");
621+ if( yyNewState > YY_MAX_SHIFT ){
622+ yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
481623 }
482-#endif
624+ yytos = yypParser->yytos;
625+ yytos->stateno = (YYACTIONTYPE)yyNewState;
626+ yytos->major = (YYCODETYPE)yyMajor;
627+ yytos->minor.yy0 = yyMinor;
628+ yyTraceShift(yypParser, yyNewState);
483629 }
484630
485631 /* The following table contains information about every rule that
@@ -500,39 +646,48 @@
500646 */
501647 static void yy_reduce(
502648 yyParser *yypParser, /* The parser */
503- int yyruleno /* Number of the rule by which to reduce */
649+ unsigned int yyruleno /* Number of the rule by which to reduce */
504650 ){
505651 int yygoto; /* The next state */
506652 int yyact; /* The next action */
507- YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
508653 yyStackEntry *yymsp; /* The top of the parser's stack */
509654 int yysize; /* Amount to pop the stack */
510655 ParseARG_FETCH;
511- yymsp = &yypParser->yystack[yypParser->yyidx];
656+ yymsp = yypParser->yytos;
512657 #ifndef NDEBUG
513- if( yyTraceFILE && yyruleno>=0
514- && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
515- fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
516- yyRuleName[yyruleno]);
658+ if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
659+ yysize = yyRuleInfo[yyruleno].nrhs;
660+ fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
661+ yyRuleName[yyruleno], yymsp[-yysize].stateno);
662+ fflush(yyTraceFILE);
517663 }
518664 #endif /* NDEBUG */
519665
520- /* Silence complaints from purify about yygotominor being uninitialized
521- ** in some cases when it is copied into the stack after the following
522- ** switch. yygotominor is uninitialized when a rule reduces that does
523- ** not set the value of its left-hand side nonterminal. Leaving the
524- ** value of the nonterminal uninitialized is utterly harmless as long
525- ** as the value is never used. So really the only thing this code
526- ** accomplishes is to quieten purify.
527- **
528- ** 2007-01-16: The wireshark project (www.wireshark.org) reports that
529- ** without this code, their parser segfaults. I'm not sure what there
530- ** parser is doing to make this happen. This is the second bug report
531- ** from wireshark this week. Clearly they are stressing Lemon in ways
532- ** that it has not been previously stressed... (SQLite ticket #2172)
533- */
534- memset(&yygotominor, 0, sizeof(yygotominor));
535-
666+ /* Check that the stack is large enough to grow by a single entry
667+ ** if the RHS of the rule is empty. This ensures that there is room
668+ ** enough on the stack to push the LHS value */
669+ if( yyRuleInfo[yyruleno].nrhs==0 ){
670+#ifdef YYTRACKMAXSTACKDEPTH
671+ if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
672+ yypParser->yyhwm++;
673+ assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack));
674+ }
675+#endif
676+#if YYSTACKDEPTH>0
677+ if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH-1] ){
678+ yyStackOverflow(yypParser);
679+ return;
680+ }
681+#else
682+ if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
683+ if( yyGrowStack(yypParser) ){
684+ yyStackOverflow(yypParser);
685+ return;
686+ }
687+ yymsp = yypParser->yytos;
688+ }
689+#endif
690+ }
536691
537692 switch( yyruleno ){
538693 /* Beginning here are the reduction cases. A typical example
@@ -543,31 +698,26 @@
543698 ** #line <lineno> <thisfile>
544699 ** break;
545700 */
701+/********** Begin reduce actions **********************************************/
546702 %%
703+/********** End reduce actions ************************************************/
547704 };
705+ assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
548706 yygoto = yyRuleInfo[yyruleno].lhs;
549707 yysize = yyRuleInfo[yyruleno].nrhs;
550- yypParser->yyidx -= yysize;
551- yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
552- if( yyact < YYNSTATE ){
553-#ifdef NDEBUG
554- /* If we are not debugging and the reduce action popped at least
555- ** one element off the stack, then we can push the new element back
556- ** onto the stack here, and skip the stack overflow test in yy_shift().
557- ** That gives a significant speed improvement. */
558- if( yysize ){
559- yypParser->yyidx++;
560- yymsp -= yysize-1;
561- yymsp->stateno = yyact;
562- yymsp->major = yygoto;
563- yymsp->minor = yygotominor;
564- }else
565-#endif
566- {
567- yy_shift(yypParser,yyact,yygoto,&yygotominor);
708+ yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
709+ if( yyact <= YY_MAX_SHIFTREDUCE ){
710+ if( yyact>YY_MAX_SHIFT ){
711+ yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
568712 }
713+ yymsp -= yysize-1;
714+ yypParser->yytos = yymsp;
715+ yymsp->stateno = (YYACTIONTYPE)yyact;
716+ yymsp->major = (YYCODETYPE)yygoto;
717+ yyTraceShift(yypParser, yyact);
569718 }else{
570- assert( yyact == YYNSTATE + YYNRULE + 1 );
719+ assert( yyact == YY_ACCEPT_ACTION );
720+ yypParser->yytos -= yysize;
571721 yy_accept(yypParser);
572722 }
573723 }
@@ -575,6 +725,7 @@
575725 /*
576726 ** The following code executes when the parse fails
577727 */
728+#ifndef YYNOERRORRECOVERY
578729 static void yy_parse_failed(
579730 yyParser *yypParser /* The parser */
580731 ){
@@ -582,14 +733,18 @@
582733 #ifndef NDEBUG
583734 if( yyTraceFILE ){
584735 fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
736+ fflush(yyTraceFILE);
585737 }
586738 #endif
587- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
739+ while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
588740 /* Here code is inserted which will be executed whenever the
589741 ** parser fails */
742+/************ Begin %parse_failure code ***************************************/
590743 %%
744+/************ End %parse_failure code *****************************************/
591745 ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
592746 }
747+#endif /* YYNOERRORRECOVERY */
593748
594749 /*
595750 ** The following code executes when a syntax error first occurs.
@@ -597,11 +752,13 @@
597752 static void yy_syntax_error(
598753 yyParser *yypParser, /* The parser */
599754 int yymajor, /* The major type of the error token */
600- YYMINORTYPE yyminor /* The minor type of the error token */
755+ ParseTOKENTYPE yyminor /* The minor type of the error token */
601756 ){
602757 ParseARG_FETCH;
603-#define TOKEN (yyminor.yy0)
758+#define TOKEN yyminor
759+/************ Begin %syntax_error code ****************************************/
604760 %%
761+/************ End %syntax_error code ******************************************/
605762 ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
606763 }
607764
@@ -615,12 +772,22 @@
615772 #ifndef NDEBUG
616773 if( yyTraceFILE ){
617774 fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
775+ fflush(yyTraceFILE);
618776 }
619777 #endif
620- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
778+#ifndef YYNOERRORRECOVERY
779+ yypParser->yyerrcnt = -1;
780+#endif
781+#if 0
782+ assert( yypParser->yytos==yypParser->yystack );
783+#else
784+ while (yypParser->yytos>yypParser->yystack) yy_pop_parser_stack(yypParser);
785+#endif
621786 /* Here code is inserted which will be executed whenever the
622787 ** parser accepts */
788+/*********** Begin %parse_accept code *****************************************/
623789 %%
790+/*********** End %parse_accept code *******************************************/
624791 ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
625792 }
626793
@@ -650,55 +817,49 @@
650817 ParseARG_PDECL /* Optional %extra_argument parameter */
651818 ){
652819 YYMINORTYPE yyminorunion;
653- int yyact; /* The parser action. */
820+ unsigned int yyact; /* The parser action. */
821+#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
654822 int yyendofinput; /* True if we are at the end of input */
823+#endif
655824 #ifdef YYERRORSYMBOL
656825 int yyerrorhit = 0; /* True if yymajor has invoked an error */
657826 #endif
658827 yyParser *yypParser; /* The parser */
659828
660- /* (re)initialize the parser, if necessary */
661829 yypParser = (yyParser*)yyp;
662- if( yypParser->yyidx<0 ){
663-#if YYSTACKDEPTH<=0
664- if( yypParser->yystksz <=0 ){
665- memset(&yyminorunion, 0, sizeof(yyminorunion));
666- yyStackOverflow(yypParser, &yyminorunion);
667- return;
668- }
830+ assert( yypParser->yytos!=0 );
831+#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
832+ yyendofinput = (yymajor==0);
669833 #endif
670- yypParser->yyidx = 0;
671- yypParser->yyerrcnt = -1;
672- yypParser->yystack[0].stateno = 0;
673- yypParser->yystack[0].major = 0;
674- }
675- yyminorunion.yy0 = yyminor;
676- yyendofinput = (yymajor==0);
677834 ParseARG_STORE;
678835
679836 #ifndef NDEBUG
680837 if( yyTraceFILE ){
681- fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
838+ fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
839+ fflush(yyTraceFILE);
682840 }
683841 #endif
684842
685843 do{
686- yyact = yy_find_shift_action(yypParser,yymajor);
687- if( yyact<YYNSTATE ){
688- assert( !yyendofinput ); /* Impossible to shift the $ token */
689- yy_shift(yypParser,yyact,yymajor,&yyminorunion);
844+ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
845+ if( yyact <= YY_MAX_SHIFTREDUCE ){
846+ yy_shift(yypParser,yyact,yymajor,yyminor);
847+#ifndef YYNOERRORRECOVERY
690848 yypParser->yyerrcnt--;
849+#endif
691850 yymajor = YYNOCODE;
692- }else if( yyact < YYNSTATE + YYNRULE ){
693- yy_reduce(yypParser,yyact-YYNSTATE);
851+ }else if( yyact <= YY_MAX_REDUCE ){
852+ yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
694853 }else{
854+ assert( yyact == YY_ERROR_ACTION );
855+ yyminorunion.yy0 = yyminor;
695856 #ifdef YYERRORSYMBOL
696857 int yymx;
697858 #endif
698- assert( yyact == YY_ERROR_ACTION );
699859 #ifndef NDEBUG
700860 if( yyTraceFILE ){
701861 fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
862+ fflush(yyTraceFILE);
702863 }
703864 #endif
704865 #ifdef YYERRORSYMBOL
@@ -722,40 +883,53 @@
722883 **
723884 */
724885 if( yypParser->yyerrcnt<0 ){
725- yy_syntax_error(yypParser,yymajor,yyminorunion);
886+ yy_syntax_error(yypParser,yymajor,yyminor);
726887 }
727- yymx = yypParser->yystack[yypParser->yyidx].major;
888+ yymx = yypParser->yytos->major;
728889 if( yymx==YYERRORSYMBOL || yyerrorhit ){
729890 #ifndef NDEBUG
730891 if( yyTraceFILE ){
731892 fprintf(yyTraceFILE,"%sDiscard input token %s\n",
732893 yyTracePrompt,yyTokenName[yymajor]);
894+ fflush(yyTraceFILE);
733895 }
734896 #endif
735- yy_destructor(yymajor,&yyminorunion);
897+ yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
736898 yymajor = YYNOCODE;
737899 }else{
738- while(
739- yypParser->yyidx >= 0 &&
740- yymx != YYERRORSYMBOL &&
741- (yyact = yy_find_reduce_action(
742- yypParser->yystack[yypParser->yyidx].stateno,
743- YYERRORSYMBOL)) >= YYNSTATE
900+ while( yypParser->yytos >= yypParser->yystack
901+ && yymx != YYERRORSYMBOL
902+ && (yyact = yy_find_reduce_action(
903+ yypParser->yytos->stateno,
904+ YYERRORSYMBOL)) >= YY_MIN_REDUCE
744905 ){
745906 yy_pop_parser_stack(yypParser);
746907 }
747- if( yypParser->yyidx < 0 || yymajor==0 ){
748- yy_destructor(yymajor,&yyminorunion);
908+ if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
909+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
749910 yy_parse_failed(yypParser);
911+#ifndef YYNOERRORRECOVERY
912+ yypParser->yyerrcnt = -1;
913+#endif
750914 yymajor = YYNOCODE;
751915 }else if( yymx!=YYERRORSYMBOL ){
752- YYMINORTYPE u2;
753- u2.YYERRSYMDT = 0;
754- yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
916+ yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
755917 }
756918 }
757919 yypParser->yyerrcnt = 3;
758920 yyerrorhit = 1;
921+#elif defined(YYNOERRORRECOVERY)
922+ /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
923+ ** do any kind of error recovery. Instead, simply invoke the syntax
924+ ** error routine and continue going as if nothing had happened.
925+ **
926+ ** Applications can set this macro (for example inside %include) if
927+ ** they intend to abandon the parse upon the first syntax error seen.
928+ */
929+ yy_syntax_error(yypParser,yymajor, yyminor);
930+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
931+ yymajor = YYNOCODE;
932+
759933 #else /* YYERRORSYMBOL is not defined */
760934 /* This is what we do if the grammar does not define ERROR:
761935 **
@@ -767,16 +941,32 @@
767941 ** three input tokens have been successfully shifted.
768942 */
769943 if( yypParser->yyerrcnt<=0 ){
770- yy_syntax_error(yypParser,yymajor,yyminorunion);
944+ yy_syntax_error(yypParser,yymajor, yyminor);
771945 }
772946 yypParser->yyerrcnt = 3;
773- yy_destructor(yymajor,&yyminorunion);
947+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
774948 if( yyendofinput ){
775949 yy_parse_failed(yypParser);
950+#ifndef YYNOERRORRECOVERY
951+ yypParser->yyerrcnt = -1;
952+#endif
776953 }
777954 yymajor = YYNOCODE;
778955 #endif
779956 }
780- }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
957+ }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack );
958+#ifndef NDEBUG
959+ if( yyTraceFILE ){
960+ yyStackEntry *i;
961+ char cDiv = '[';
962+ fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
963+ for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
964+ fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);
965+ cDiv = ' ';
966+ }
967+ fprintf(yyTraceFILE,"]\n");
968+ fflush(yyTraceFILE);
969+ }
970+#endif
781971 return;
782972 }
Show on old repository browser