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

Side by Side Diff: third_party/sqlite/src/tool/lemon.c

Issue 2751253002: [sql] Import SQLite 3.17.0. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/tool/kvtest-speed.sh ('k') | third_party/sqlite/src/tool/lempar.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** This file contains all sources (including headers) to the LEMON 2 ** This file contains all sources (including headers) to the LEMON
3 ** LALR(1) parser generator. The sources have been combined into a 3 ** LALR(1) parser generator. The sources have been combined into a
4 ** single file to make it easy to include LEMON in the source tree 4 ** single file to make it easy to include LEMON in the source tree
5 ** and Makefile of another program. 5 ** and Makefile of another program.
6 ** 6 **
7 ** The author of this program disclaims copyright. 7 ** The author of this program disclaims copyright.
8 */ 8 */
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <stdarg.h> 10 #include <stdarg.h>
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 enum symbol_type type; /* Symbols are all either TERMINALS or NTs */ 256 enum symbol_type type; /* Symbols are all either TERMINALS or NTs */
257 struct rule *rule; /* Linked list of rules of this (if an NT) */ 257 struct rule *rule; /* Linked list of rules of this (if an NT) */
258 struct symbol *fallback; /* fallback token in case this token doesn't parse */ 258 struct symbol *fallback; /* fallback token in case this token doesn't parse */
259 int prec; /* Precedence if defined (-1 otherwise) */ 259 int prec; /* Precedence if defined (-1 otherwise) */
260 enum e_assoc assoc; /* Associativity if precedence is defined */ 260 enum e_assoc assoc; /* Associativity if precedence is defined */
261 char *firstset; /* First-set for all rules of this symbol */ 261 char *firstset; /* First-set for all rules of this symbol */
262 Boolean lambda; /* True if NT and can generate an empty string */ 262 Boolean lambda; /* True if NT and can generate an empty string */
263 int useCnt; /* Number of times used */ 263 int useCnt; /* Number of times used */
264 char *destructor; /* Code which executes whenever this symbol is 264 char *destructor; /* Code which executes whenever this symbol is
265 ** popped from the stack during error processing */ 265 ** popped from the stack during error processing */
266 int destLineno; /* Line number for start of destructor */ 266 int destLineno; /* Line number for start of destructor. Set to
267 ** -1 for duplicate destructors. */
267 char *datatype; /* The data type of information held by this 268 char *datatype; /* The data type of information held by this
268 ** object. Only used if type==NONTERMINAL */ 269 ** object. Only used if type==NONTERMINAL */
269 int dtnum; /* The data type number. In the parser, the value 270 int dtnum; /* The data type number. In the parser, the value
270 ** stack is a union. The .yy%d element of this 271 ** stack is a union. The .yy%d element of this
271 ** union is the correct data type for this object */ 272 ** union is the correct data type for this object */
272 /* The following fields are used by MULTITERMINALs only */ 273 /* The following fields are used by MULTITERMINALs only */
273 int nsubsym; /* Number of constituent symbols in the MULTI */ 274 int nsubsym; /* Number of constituent symbols in the MULTI */
274 struct symbol **subsym; /* Array of constituent symbols */ 275 struct symbol **subsym; /* Array of constituent symbols */
275 }; 276 };
276 277
277 /* Each production rule in the grammar is stored in the following 278 /* Each production rule in the grammar is stored in the following
278 ** structure. */ 279 ** structure. */
279 struct rule { 280 struct rule {
280 struct symbol *lhs; /* Left-hand side of the rule */ 281 struct symbol *lhs; /* Left-hand side of the rule */
281 const char *lhsalias; /* Alias for the LHS (NULL if none) */ 282 const char *lhsalias; /* Alias for the LHS (NULL if none) */
282 int lhsStart; /* True if left-hand side is the start symbol */ 283 int lhsStart; /* True if left-hand side is the start symbol */
283 int ruleline; /* Line number for the rule */ 284 int ruleline; /* Line number for the rule */
284 int nrhs; /* Number of RHS symbols */ 285 int nrhs; /* Number of RHS symbols */
285 struct symbol **rhs; /* The RHS symbols */ 286 struct symbol **rhs; /* The RHS symbols */
286 const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */ 287 const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
287 int line; /* Line number at which code begins */ 288 int line; /* Line number at which code begins */
288 const char *code; /* The code executed when this rule is reduced */ 289 const char *code; /* The code executed when this rule is reduced */
290 const char *codePrefix; /* Setup code before code[] above */
291 const char *codeSuffix; /* Breakdown code after code[] above */
292 int noCode; /* True if this rule has no associated C code */
293 int codeEmitted; /* True if the code has been emitted already */
289 struct symbol *precsym; /* Precedence symbol for this rule */ 294 struct symbol *precsym; /* Precedence symbol for this rule */
290 int index; /* An index number for this rule */ 295 int index; /* An index number for this rule */
296 int iRule; /* Rule number as used in the generated tables */
291 Boolean canReduce; /* True if this rule is ever reduced */ 297 Boolean canReduce; /* True if this rule is ever reduced */
298 Boolean doesReduce; /* Reduce actions occur after optimization */
292 struct rule *nextlhs; /* Next rule with the same LHS */ 299 struct rule *nextlhs; /* Next rule with the same LHS */
293 struct rule *next; /* Next rule in the global list */ 300 struct rule *next; /* Next rule in the global list */
294 }; 301 };
295 302
296 /* A configuration is a production rule of the grammar together with 303 /* A configuration is a production rule of the grammar together with
297 ** a mark (dot) showing how much of that rule has been processed so far. 304 ** a mark (dot) showing how much of that rule has been processed so far.
298 ** Configurations also contain a follow-set which is a list of terminal 305 ** Configurations also contain a follow-set which is a list of terminal
299 ** symbols which are allowed to immediately follow the end of the rule. 306 ** symbols which are allowed to immediately follow the end of the rule.
300 ** Every configuration is recorded as an instance of the following: */ 307 ** Every configuration is recorded as an instance of the following: */
301 enum cfgstatus { 308 enum cfgstatus {
(...skipping 27 matching lines...) Expand all
329 }; 336 };
330 337
331 /* Every shift or reduce operation is stored as one of the following */ 338 /* Every shift or reduce operation is stored as one of the following */
332 struct action { 339 struct action {
333 struct symbol *sp; /* The look-ahead symbol */ 340 struct symbol *sp; /* The look-ahead symbol */
334 enum e_action type; 341 enum e_action type;
335 union { 342 union {
336 struct state *stp; /* The new state, if a shift */ 343 struct state *stp; /* The new state, if a shift */
337 struct rule *rp; /* The rule, if a reduce */ 344 struct rule *rp; /* The rule, if a reduce */
338 } x; 345 } x;
346 struct symbol *spOpt; /* SHIFTREDUCE optimization to this symbol */
339 struct action *next; /* Next action for this state */ 347 struct action *next; /* Next action for this state */
340 struct action *collide; /* Next action with the same hash */ 348 struct action *collide; /* Next action with the same hash */
341 }; 349 };
342 350
343 /* Each state of the generated parser's finite state machine 351 /* Each state of the generated parser's finite state machine
344 ** is encoded as an instance of the following structure. */ 352 ** is encoded as an instance of the following structure. */
345 struct state { 353 struct state {
346 struct config *bp; /* The basis configurations for this state */ 354 struct config *bp; /* The basis configurations for this state */
347 struct config *cfp; /* All configurations in this set */ 355 struct config *cfp; /* All configurations in this set */
348 int statenum; /* Sequential number for this state */ 356 int statenum; /* Sequential number for this state */
349 struct action *ap; /* Array of actions for this state */ 357 struct action *ap; /* List of actions for this state */
350 int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ 358 int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */
351 int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ 359 int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */
352 int iDfltReduce; /* Default action is to REDUCE by this rule */ 360 int iDfltReduce; /* Default action is to REDUCE by this rule */
353 struct rule *pDfltReduce;/* The default REDUCE rule. */ 361 struct rule *pDfltReduce;/* The default REDUCE rule. */
354 int autoReduce; /* True if this is an auto-reduce state */ 362 int autoReduce; /* True if this is an auto-reduce state */
355 }; 363 };
356 #define NO_OFFSET (-2147483647) 364 #define NO_OFFSET (-2147483647)
357 365
358 /* A followset propagation link indicates that the contents of one 366 /* A followset propagation link indicates that the contents of one
359 ** configuration followset should be propagated to another whenever 367 ** configuration followset should be propagated to another whenever
360 ** the first changes. */ 368 ** the first changes. */
361 struct plink { 369 struct plink {
362 struct config *cfp; /* The configuration to which linked */ 370 struct config *cfp; /* The configuration to which linked */
363 struct plink *next; /* The next propagate link */ 371 struct plink *next; /* The next propagate link */
364 }; 372 };
365 373
366 /* The state vector for the entire parser generator is recorded as 374 /* The state vector for the entire parser generator is recorded as
367 ** follows. (LEMON uses no global variables and makes little use of 375 ** follows. (LEMON uses no global variables and makes little use of
368 ** static variables. Fields in the following structure can be thought 376 ** static variables. Fields in the following structure can be thought
369 ** of as begin global variables in the program.) */ 377 ** of as begin global variables in the program.) */
370 struct lemon { 378 struct lemon {
371 struct state **sorted; /* Table of states sorted by state number */ 379 struct state **sorted; /* Table of states sorted by state number */
372 struct rule *rule; /* List of all rules */ 380 struct rule *rule; /* List of all rules */
381 struct rule *startRule; /* First rule */
373 int nstate; /* Number of states */ 382 int nstate; /* Number of states */
374 int nxstate; /* nstate with tail degenerate states removed */ 383 int nxstate; /* nstate with tail degenerate states removed */
375 int nrule; /* Number of rules */ 384 int nrule; /* Number of rules */
376 int nsymbol; /* Number of terminal and nonterminal symbols */ 385 int nsymbol; /* Number of terminal and nonterminal symbols */
377 int nterminal; /* Number of terminal symbols */ 386 int nterminal; /* Number of terminal symbols */
378 struct symbol **symbols; /* Sorted array of pointers to symbols */ 387 struct symbol **symbols; /* Sorted array of pointers to symbols */
379 int errorcnt; /* Number of errors */ 388 int errorcnt; /* Number of errors */
380 struct symbol *errsym; /* The error symbol */ 389 struct symbol *errsym; /* The error symbol */
381 struct symbol *wildcard; /* Token that matches anything */ 390 struct symbol *wildcard; /* Token that matches anything */
382 char *name; /* Name of the generated parser */ 391 char *name; /* Name of the generated parser */
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 enum e_action type, 528 enum e_action type,
520 struct symbol *sp, 529 struct symbol *sp,
521 char *arg 530 char *arg
522 ){ 531 ){
523 struct action *newaction; 532 struct action *newaction;
524 newaction = Action_new(); 533 newaction = Action_new();
525 newaction->next = *app; 534 newaction->next = *app;
526 *app = newaction; 535 *app = newaction;
527 newaction->type = type; 536 newaction->type = type;
528 newaction->sp = sp; 537 newaction->sp = sp;
538 newaction->spOpt = 0;
529 if( type==SHIFT ){ 539 if( type==SHIFT ){
530 newaction->x.stp = (struct state *)arg; 540 newaction->x.stp = (struct state *)arg;
531 }else{ 541 }else{
532 newaction->x.rp = (struct rule *)arg; 542 newaction->x.rp = (struct rule *)arg;
533 } 543 }
534 } 544 }
535 /********************** New code to implement the "acttab" module ***********/ 545 /********************** New code to implement the "acttab" module ***********/
536 /* 546 /*
537 ** This module implements routines use to construct the yy_action[] table. 547 ** This module implements routines use to construct the yy_action[] table.
538 */ 548 */
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 859
850 Configlist_init(); 860 Configlist_init();
851 861
852 /* Find the start symbol */ 862 /* Find the start symbol */
853 if( lemp->start ){ 863 if( lemp->start ){
854 sp = Symbol_find(lemp->start); 864 sp = Symbol_find(lemp->start);
855 if( sp==0 ){ 865 if( sp==0 ){
856 ErrorMsg(lemp->filename,0, 866 ErrorMsg(lemp->filename,0,
857 "The specified start symbol \"%s\" is not \ 867 "The specified start symbol \"%s\" is not \
858 in a nonterminal of the grammar. \"%s\" will be used as the start \ 868 in a nonterminal of the grammar. \"%s\" will be used as the start \
859 symbol instead.",lemp->start,lemp->rule->lhs->name); 869 symbol instead.",lemp->start,lemp->startRule->lhs->name);
860 lemp->errorcnt++; 870 lemp->errorcnt++;
861 sp = lemp->rule->lhs; 871 sp = lemp->startRule->lhs;
862 } 872 }
863 }else{ 873 }else{
864 sp = lemp->rule->lhs; 874 sp = lemp->startRule->lhs;
865 } 875 }
866 876
867 /* Make sure the start symbol doesn't occur on the right-hand side of 877 /* Make sure the start symbol doesn't occur on the right-hand side of
868 ** any rule. Report an error if it does. (YACC would generate a new 878 ** any rule. Report an error if it does. (YACC would generate a new
869 ** start symbol in this case.) */ 879 ** start symbol in this case.) */
870 for(rp=lemp->rule; rp; rp=rp->next){ 880 for(rp=lemp->rule; rp; rp=rp->next){
871 int i; 881 int i;
872 for(i=0; i<rp->nrhs; i++){ 882 for(i=0; i<rp->nrhs; i++){
873 if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */ 883 if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */
874 ErrorMsg(lemp->filename,0, 884 ErrorMsg(lemp->filename,0,
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); 1118 Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
1109 } 1119 }
1110 } 1120 }
1111 } 1121 }
1112 } 1122 }
1113 } 1123 }
1114 1124
1115 /* Add the accepting token */ 1125 /* Add the accepting token */
1116 if( lemp->start ){ 1126 if( lemp->start ){
1117 sp = Symbol_find(lemp->start); 1127 sp = Symbol_find(lemp->start);
1118 if( sp==0 ) sp = lemp->rule->lhs; 1128 if( sp==0 ) sp = lemp->startRule->lhs;
1119 }else{ 1129 }else{
1120 sp = lemp->rule->lhs; 1130 sp = lemp->startRule->lhs;
1121 } 1131 }
1122 /* Add to the first state (which is always the starting state of the 1132 /* Add to the first state (which is always the starting state of the
1123 ** finite state machine) an action to ACCEPT if the lookahead is the 1133 ** finite state machine) an action to ACCEPT if the lookahead is the
1124 ** start nonterminal. */ 1134 ** start nonterminal. */
1125 Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); 1135 Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0);
1126 1136
1127 /* Resolve conflicts */ 1137 /* Resolve conflicts */
1128 for(i=0; i<lemp->nstate; i++){ 1138 for(i=0; i<lemp->nstate; i++){
1129 struct action *ap, *nap; 1139 struct action *ap, *nap;
1130 stp = lemp->sorted[i]; 1140 stp = lemp->sorted[i];
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 1498
1489 static char *user_templatename = NULL; 1499 static char *user_templatename = NULL;
1490 static void handle_T_option(char *z){ 1500 static void handle_T_option(char *z){
1491 user_templatename = (char *) malloc( lemonStrlen(z)+1 ); 1501 user_templatename = (char *) malloc( lemonStrlen(z)+1 );
1492 if( user_templatename==0 ){ 1502 if( user_templatename==0 ){
1493 memory_error(); 1503 memory_error();
1494 } 1504 }
1495 lemon_strcpy(user_templatename, z); 1505 lemon_strcpy(user_templatename, z);
1496 } 1506 }
1497 1507
1508 /* Merge together to lists of rules ordered by rule.iRule */
1509 static struct rule *Rule_merge(struct rule *pA, struct rule *pB){
1510 struct rule *pFirst = 0;
1511 struct rule **ppPrev = &pFirst;
1512 while( pA && pB ){
1513 if( pA->iRule<pB->iRule ){
1514 *ppPrev = pA;
1515 ppPrev = &pA->next;
1516 pA = pA->next;
1517 }else{
1518 *ppPrev = pB;
1519 ppPrev = &pB->next;
1520 pB = pB->next;
1521 }
1522 }
1523 if( pA ){
1524 *ppPrev = pA;
1525 }else{
1526 *ppPrev = pB;
1527 }
1528 return pFirst;
1529 }
1530
1531 /*
1532 ** Sort a list of rules in order of increasing iRule value
1533 */
1534 static struct rule *Rule_sort(struct rule *rp){
1535 int i;
1536 struct rule *pNext;
1537 struct rule *x[32];
1538 memset(x, 0, sizeof(x));
1539 while( rp ){
1540 pNext = rp->next;
1541 rp->next = 0;
1542 for(i=0; i<sizeof(x)/sizeof(x[0]) && x[i]; i++){
1543 rp = Rule_merge(x[i], rp);
1544 x[i] = 0;
1545 }
1546 x[i] = rp;
1547 rp = pNext;
1548 }
1549 rp = 0;
1550 for(i=0; i<sizeof(x)/sizeof(x[0]); i++){
1551 rp = Rule_merge(x[i], rp);
1552 }
1553 return rp;
1554 }
1555
1498 /* forward reference */ 1556 /* forward reference */
1499 static const char *minimum_size_type(int lwr, int upr, int *pnByte); 1557 static const char *minimum_size_type(int lwr, int upr, int *pnByte);
1500 1558
1501 /* Print a single line of the "Parser Stats" output 1559 /* Print a single line of the "Parser Stats" output
1502 */ 1560 */
1503 static void stats_line(const char *zLabel, int iValue){ 1561 static void stats_line(const char *zLabel, int iValue){
1504 int nLabel = lemonStrlen(zLabel); 1562 int nLabel = lemonStrlen(zLabel);
1505 printf(" %s%.*s %5d\n", zLabel, 1563 printf(" %s%.*s %5d\n", zLabel,
1506 35-nLabel, "................................", 1564 35-nLabel, "................................",
1507 iValue); 1565 iValue);
(...skipping 28 matching lines...) Expand all
1536 {OPT_FLAG, "s", (char*)&statistics, 1594 {OPT_FLAG, "s", (char*)&statistics,
1537 "Print parser stats to standard output."}, 1595 "Print parser stats to standard output."},
1538 {OPT_FLAG, "x", (char*)&version, "Print the version number."}, 1596 {OPT_FLAG, "x", (char*)&version, "Print the version number."},
1539 {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."}, 1597 {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."},
1540 {OPT_FSTR, "W", 0, "Ignored. (Placeholder for '-W' compiler options.)"}, 1598 {OPT_FSTR, "W", 0, "Ignored. (Placeholder for '-W' compiler options.)"},
1541 {OPT_FLAG,0,0,0} 1599 {OPT_FLAG,0,0,0}
1542 }; 1600 };
1543 int i; 1601 int i;
1544 int exitcode; 1602 int exitcode;
1545 struct lemon lem; 1603 struct lemon lem;
1604 struct rule *rp;
1546 1605
1547 OptInit(argv,options,stderr); 1606 OptInit(argv,options,stderr);
1548 if( version ){ 1607 if( version ){
1549 printf("Lemon version 1.0\n"); 1608 printf("Lemon version 1.0\n");
1550 exit(0); 1609 exit(0);
1551 } 1610 }
1552 if( OptNArgs()!=1 ){ 1611 if( OptNArgs()!=1 ){
1553 fprintf(stderr,"Exactly one filename argument is required.\n"); 1612 fprintf(stderr,"Exactly one filename argument is required.\n");
1554 exit(1); 1613 exit(1);
1555 } 1614 }
(...skipping 26 matching lines...) Expand all
1582 lem.symbols = Symbol_arrayof(); 1641 lem.symbols = Symbol_arrayof();
1583 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i; 1642 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1584 qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp); 1643 qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp);
1585 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i; 1644 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1586 while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; } 1645 while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; }
1587 assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 ); 1646 assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 );
1588 lem.nsymbol = i - 1; 1647 lem.nsymbol = i - 1;
1589 for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++); 1648 for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++);
1590 lem.nterminal = i; 1649 lem.nterminal = i;
1591 1650
1651 /* Assign sequential rule numbers. Start with 0. Put rules that have no
1652 ** reduce action C-code associated with them last, so that the switch()
1653 ** statement that selects reduction actions will have a smaller jump table.
1654 */
1655 for(i=0, rp=lem.rule; rp; rp=rp->next){
1656 rp->iRule = rp->code ? i++ : -1;
1657 }
1658 for(rp=lem.rule; rp; rp=rp->next){
1659 if( rp->iRule<0 ) rp->iRule = i++;
1660 }
1661 lem.startRule = lem.rule;
1662 lem.rule = Rule_sort(lem.rule);
1663
1592 /* Generate a reprint of the grammar, if requested on the command line */ 1664 /* Generate a reprint of the grammar, if requested on the command line */
1593 if( rpflag ){ 1665 if( rpflag ){
1594 Reprint(&lem); 1666 Reprint(&lem);
1595 }else{ 1667 }else{
1596 /* Initialize the size for all follow and first sets */ 1668 /* Initialize the size for all follow and first sets */
1597 SetSize(lem.nterminal+1); 1669 SetSize(lem.nterminal+1);
1598 1670
1599 /* Find the precedence for every production rule (that has one) */ 1671 /* Find the precedence for every production rule (that has one) */
1600 FindRulePrecedences(&lem); 1672 FindRulePrecedences(&lem);
1601 1673
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 fragment which begins on this line."); 2213 fragment which begins on this line.");
2142 psp->errorcnt++; 2214 psp->errorcnt++;
2143 }else if( psp->prevrule->code!=0 ){ 2215 }else if( psp->prevrule->code!=0 ){
2144 ErrorMsg(psp->filename,psp->tokenlineno, 2216 ErrorMsg(psp->filename,psp->tokenlineno,
2145 "Code fragment beginning on this line is not the first \ 2217 "Code fragment beginning on this line is not the first \
2146 to follow the previous rule."); 2218 to follow the previous rule.");
2147 psp->errorcnt++; 2219 psp->errorcnt++;
2148 }else{ 2220 }else{
2149 psp->prevrule->line = psp->tokenlineno; 2221 psp->prevrule->line = psp->tokenlineno;
2150 psp->prevrule->code = &x[1]; 2222 psp->prevrule->code = &x[1];
2223 psp->prevrule->noCode = 0;
2151 } 2224 }
2152 }else if( x[0]=='[' ){ 2225 }else if( x[0]=='[' ){
2153 psp->state = PRECEDENCE_MARK_1; 2226 psp->state = PRECEDENCE_MARK_1;
2154 }else{ 2227 }else{
2155 ErrorMsg(psp->filename,psp->tokenlineno, 2228 ErrorMsg(psp->filename,psp->tokenlineno,
2156 "Token \"%s\" should be either \"%%\" or a nonterminal name.", 2229 "Token \"%s\" should be either \"%%\" or a nonterminal name.",
2157 x); 2230 x);
2158 psp->errorcnt++; 2231 psp->errorcnt++;
2159 } 2232 }
2160 break; 2233 break;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2247 rp->rhs = (struct symbol**)&rp[1]; 2320 rp->rhs = (struct symbol**)&rp[1];
2248 rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]); 2321 rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
2249 for(i=0; i<psp->nrhs; i++){ 2322 for(i=0; i<psp->nrhs; i++){
2250 rp->rhs[i] = psp->rhs[i]; 2323 rp->rhs[i] = psp->rhs[i];
2251 rp->rhsalias[i] = psp->alias[i]; 2324 rp->rhsalias[i] = psp->alias[i];
2252 } 2325 }
2253 rp->lhs = psp->lhs; 2326 rp->lhs = psp->lhs;
2254 rp->lhsalias = psp->lhsalias; 2327 rp->lhsalias = psp->lhsalias;
2255 rp->nrhs = psp->nrhs; 2328 rp->nrhs = psp->nrhs;
2256 rp->code = 0; 2329 rp->code = 0;
2330 rp->noCode = 1;
2257 rp->precsym = 0; 2331 rp->precsym = 0;
2258 rp->index = psp->gp->nrule++; 2332 rp->index = psp->gp->nrule++;
2259 rp->nextlhs = rp->lhs->rule; 2333 rp->nextlhs = rp->lhs->rule;
2260 rp->lhs->rule = rp; 2334 rp->lhs->rule = rp;
2261 rp->next = 0; 2335 rp->next = 0;
2262 if( psp->firstrule==0 ){ 2336 if( psp->firstrule==0 ){
2263 psp->firstrule = psp->lastrule = rp; 2337 psp->firstrule = psp->lastrule = rp;
2264 }else{ 2338 }else{
2265 psp->lastrule->next = rp; 2339 psp->lastrule->next = rp;
2266 psp->lastrule = rp; 2340 psp->lastrule = rp;
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
3045 ){ 3119 ){
3046 int result = 1; 3120 int result = 1;
3047 switch( ap->type ){ 3121 switch( ap->type ){
3048 case SHIFT: { 3122 case SHIFT: {
3049 struct state *stp = ap->x.stp; 3123 struct state *stp = ap->x.stp;
3050 fprintf(fp,"%*s shift %-7d",indent,ap->sp->name,stp->statenum); 3124 fprintf(fp,"%*s shift %-7d",indent,ap->sp->name,stp->statenum);
3051 break; 3125 break;
3052 } 3126 }
3053 case REDUCE: { 3127 case REDUCE: {
3054 struct rule *rp = ap->x.rp; 3128 struct rule *rp = ap->x.rp;
3055 fprintf(fp,"%*s reduce %-7d",indent,ap->sp->name,rp->index); 3129 fprintf(fp,"%*s reduce %-7d",indent,ap->sp->name,rp->iRule);
3056 RulePrint(fp, rp, -1); 3130 RulePrint(fp, rp, -1);
3057 break; 3131 break;
3058 } 3132 }
3059 case SHIFTREDUCE: { 3133 case SHIFTREDUCE: {
3060 struct rule *rp = ap->x.rp; 3134 struct rule *rp = ap->x.rp;
3061 fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->index); 3135 fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->iRule);
3062 RulePrint(fp, rp, -1); 3136 RulePrint(fp, rp, -1);
3063 break; 3137 break;
3064 } 3138 }
3065 case ACCEPT: 3139 case ACCEPT:
3066 fprintf(fp,"%*s accept",indent,ap->sp->name); 3140 fprintf(fp,"%*s accept",indent,ap->sp->name);
3067 break; 3141 break;
3068 case ERROR: 3142 case ERROR:
3069 fprintf(fp,"%*s error",indent,ap->sp->name); 3143 fprintf(fp,"%*s error",indent,ap->sp->name);
3070 break; 3144 break;
3071 case SRCONFLICT: 3145 case SRCONFLICT:
3072 case RRCONFLICT: 3146 case RRCONFLICT:
3073 fprintf(fp,"%*s reduce %-7d ** Parsing conflict **", 3147 fprintf(fp,"%*s reduce %-7d ** Parsing conflict **",
3074 indent,ap->sp->name,ap->x.rp->index); 3148 indent,ap->sp->name,ap->x.rp->iRule);
3075 break; 3149 break;
3076 case SSCONFLICT: 3150 case SSCONFLICT:
3077 fprintf(fp,"%*s shift %-7d ** Parsing conflict **", 3151 fprintf(fp,"%*s shift %-7d ** Parsing conflict **",
3078 indent,ap->sp->name,ap->x.stp->statenum); 3152 indent,ap->sp->name,ap->x.stp->statenum);
3079 break; 3153 break;
3080 case SH_RESOLVED: 3154 case SH_RESOLVED:
3081 if( showPrecedenceConflict ){ 3155 if( showPrecedenceConflict ){
3082 fprintf(fp,"%*s shift %-7d -- dropped by precedence", 3156 fprintf(fp,"%*s shift %-7d -- dropped by precedence",
3083 indent,ap->sp->name,ap->x.stp->statenum); 3157 indent,ap->sp->name,ap->x.stp->statenum);
3084 }else{ 3158 }else{
3085 result = 0; 3159 result = 0;
3086 } 3160 }
3087 break; 3161 break;
3088 case RD_RESOLVED: 3162 case RD_RESOLVED:
3089 if( showPrecedenceConflict ){ 3163 if( showPrecedenceConflict ){
3090 fprintf(fp,"%*s reduce %-7d -- dropped by precedence", 3164 fprintf(fp,"%*s reduce %-7d -- dropped by precedence",
3091 indent,ap->sp->name,ap->x.rp->index); 3165 indent,ap->sp->name,ap->x.rp->iRule);
3092 }else{ 3166 }else{
3093 result = 0; 3167 result = 0;
3094 } 3168 }
3095 break; 3169 break;
3096 case NOT_USED: 3170 case NOT_USED:
3097 result = 0; 3171 result = 0;
3098 break; 3172 break;
3099 } 3173 }
3174 if( result && ap->spOpt ){
3175 fprintf(fp," /* because %s==%s */", ap->sp->name, ap->spOpt->name);
3176 }
3100 return result; 3177 return result;
3101 } 3178 }
3102 3179
3103 /* Generate the "*.out" log file */ 3180 /* Generate the "*.out" log file */
3104 void ReportOutput(struct lemon *lemp) 3181 void ReportOutput(struct lemon *lemp)
3105 { 3182 {
3106 int i; 3183 int i;
3107 struct state *stp; 3184 struct state *stp;
3108 struct config *cfp; 3185 struct config *cfp;
3109 struct action *ap; 3186 struct action *ap;
3110 FILE *fp; 3187 FILE *fp;
3111 3188
3112 fp = file_open(lemp,".out","wb"); 3189 fp = file_open(lemp,".out","wb");
3113 if( fp==0 ) return; 3190 if( fp==0 ) return;
3114 for(i=0; i<lemp->nxstate; i++){ 3191 for(i=0; i<lemp->nxstate; i++){
3115 stp = lemp->sorted[i]; 3192 stp = lemp->sorted[i];
3116 fprintf(fp,"State %d:\n",stp->statenum); 3193 fprintf(fp,"State %d:\n",stp->statenum);
3117 if( lemp->basisflag ) cfp=stp->bp; 3194 if( lemp->basisflag ) cfp=stp->bp;
3118 else cfp=stp->cfp; 3195 else cfp=stp->cfp;
3119 while( cfp ){ 3196 while( cfp ){
3120 char buf[20]; 3197 char buf[20];
3121 if( cfp->dot==cfp->rp->nrhs ){ 3198 if( cfp->dot==cfp->rp->nrhs ){
3122 lemon_sprintf(buf,"(%d)",cfp->rp->index); 3199 lemon_sprintf(buf,"(%d)",cfp->rp->iRule);
3123 fprintf(fp," %5s ",buf); 3200 fprintf(fp," %5s ",buf);
3124 }else{ 3201 }else{
3125 fprintf(fp," "); 3202 fprintf(fp," ");
3126 } 3203 }
3127 ConfigPrint(fp,cfp); 3204 ConfigPrint(fp,cfp);
3128 fprintf(fp,"\n"); 3205 fprintf(fp,"\n");
3129 #if 0 3206 #if 0
3130 SetPrint(fp,cfp->fws,lemp); 3207 SetPrint(fp,cfp->fws,lemp);
3131 PlinkPrint(fp,cfp->fplp,"To "); 3208 PlinkPrint(fp,cfp->fplp,"To ");
3132 PlinkPrint(fp,cfp->bplp,"From"); 3209 PlinkPrint(fp,cfp->bplp,"From");
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3213 3290
3214 /* Given an action, compute the integer value for that action 3291 /* Given an action, compute the integer value for that action
3215 ** which is to be put in the action table of the generated machine. 3292 ** which is to be put in the action table of the generated machine.
3216 ** Return negative if no action should be generated. 3293 ** Return negative if no action should be generated.
3217 */ 3294 */
3218 PRIVATE int compute_action(struct lemon *lemp, struct action *ap) 3295 PRIVATE int compute_action(struct lemon *lemp, struct action *ap)
3219 { 3296 {
3220 int act; 3297 int act;
3221 switch( ap->type ){ 3298 switch( ap->type ){
3222 case SHIFT: act = ap->x.stp->statenum; break; 3299 case SHIFT: act = ap->x.stp->statenum; break;
3223 case SHIFTREDUCE: act = ap->x.rp->index + lemp->nstate; break; 3300 case SHIFTREDUCE: act = ap->x.rp->iRule + lemp->nstate; break;
3224 case REDUCE: act = ap->x.rp->index + lemp->nstate+lemp->nrule; break; 3301 case REDUCE: act = ap->x.rp->iRule + lemp->nstate+lemp->nrule; break;
3225 case ERROR: act = lemp->nstate + lemp->nrule*2; break; 3302 case ERROR: act = lemp->nstate + lemp->nrule*2; break;
3226 case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break; 3303 case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break;
3227 default: act = -1; break; 3304 default: act = -1; break;
3228 } 3305 }
3229 return act; 3306 return act;
3230 } 3307 }
3231 3308
3232 #define LINESIZE 1000 3309 #define LINESIZE 1000
3233 /* The next cluster of routines are for reading the template file 3310 /* The next cluster of routines are for reading the template file
3234 ** and writing the results to the generated parser */ 3311 ** and writing the results to the generated parser */
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
3423 ** If n==-1, then the previous character is overwritten. 3500 ** If n==-1, then the previous character is overwritten.
3424 */ 3501 */
3425 PRIVATE char *append_str(const char *zText, int n, int p1, int p2){ 3502 PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
3426 static char empty[1] = { 0 }; 3503 static char empty[1] = { 0 };
3427 static char *z = 0; 3504 static char *z = 0;
3428 static int alloced = 0; 3505 static int alloced = 0;
3429 static int used = 0; 3506 static int used = 0;
3430 int c; 3507 int c;
3431 char zInt[40]; 3508 char zInt[40];
3432 if( zText==0 ){ 3509 if( zText==0 ){
3510 if( used==0 && z!=0 ) z[0] = 0;
3433 used = 0; 3511 used = 0;
3434 return z; 3512 return z;
3435 } 3513 }
3436 if( n<=0 ){ 3514 if( n<=0 ){
3437 if( n<0 ){ 3515 if( n<0 ){
3438 used += n; 3516 used += n;
3439 assert( used>=0 ); 3517 assert( used>=0 );
3440 } 3518 }
3441 n = lemonStrlen(zText); 3519 n = lemonStrlen(zText);
3442 } 3520 }
(...skipping 13 matching lines...) Expand all
3456 n--; 3534 n--;
3457 }else{ 3535 }else{
3458 z[used++] = (char)c; 3536 z[used++] = (char)c;
3459 } 3537 }
3460 } 3538 }
3461 z[used] = 0; 3539 z[used] = 0;
3462 return z; 3540 return z;
3463 } 3541 }
3464 3542
3465 /* 3543 /*
3466 ** zCode is a string that is the action associated with a rule. Expand 3544 ** Write and transform the rp->code string so that symbols are expanded.
3467 ** the symbols in this string so that the refer to elements of the parser 3545 ** Populate the rp->codePrefix and rp->codeSuffix strings, as appropriate.
3468 ** stack. 3546 **
3547 ** Return 1 if the expanded code requires that "yylhsminor" local variable
3548 ** to be defined.
3469 */ 3549 */
3470 PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ 3550 PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
3471 char *cp, *xp; 3551 char *cp, *xp;
3472 int i; 3552 int i;
3473 char lhsused = 0; /* True if the LHS element has been used */ 3553 int rc = 0; /* True if yylhsminor is used */
3474 char used[MAXRHS]; /* True for each RHS element which is used */ 3554 int dontUseRhs0 = 0; /* If true, use of left-most RHS label is illegal */
3555 const char *zSkip = 0; /* The zOvwrt comment within rp->code, or NULL */
3556 char lhsused = 0; /* True if the LHS element has been used */
3557 char lhsdirect; /* True if LHS writes directly into stack */
3558 char used[MAXRHS]; /* True for each RHS element which is used */
3559 char zLhs[50]; /* Convert the LHS symbol into this string */
3560 char zOvwrt[900]; /* Comment that to allow LHS to overwrite RHS */
3475 3561
3476 for(i=0; i<rp->nrhs; i++) used[i] = 0; 3562 for(i=0; i<rp->nrhs; i++) used[i] = 0;
3477 lhsused = 0; 3563 lhsused = 0;
3478 3564
3479 if( rp->code==0 ){ 3565 if( rp->code==0 ){
3480 static char newlinestr[2] = { '\n', '\0' }; 3566 static char newlinestr[2] = { '\n', '\0' };
3481 rp->code = newlinestr; 3567 rp->code = newlinestr;
3482 rp->line = rp->ruleline; 3568 rp->line = rp->ruleline;
3569 rp->noCode = 1;
3570 }else{
3571 rp->noCode = 0;
3572 }
3573
3574
3575 if( rp->nrhs==0 ){
3576 /* If there are no RHS symbols, then writing directly to the LHS is ok */
3577 lhsdirect = 1;
3578 }else if( rp->rhsalias[0]==0 ){
3579 /* The left-most RHS symbol has no value. LHS direct is ok. But
3580 ** we have to call the distructor on the RHS symbol first. */
3581 lhsdirect = 1;
3582 if( has_destructor(rp->rhs[0],lemp) ){
3583 append_str(0,0,0,0);
3584 append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
3585 rp->rhs[0]->index,1-rp->nrhs);
3586 rp->codePrefix = Strsafe(append_str(0,0,0,0));
3587 rp->noCode = 0;
3588 }
3589 }else if( rp->lhsalias==0 ){
3590 /* There is no LHS value symbol. */
3591 lhsdirect = 1;
3592 }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
3593 /* The LHS symbol and the left-most RHS symbol are the same, so
3594 ** direct writing is allowed */
3595 lhsdirect = 1;
3596 lhsused = 1;
3597 used[0] = 1;
3598 if( rp->lhs->dtnum!=rp->rhs[0]->dtnum ){
3599 ErrorMsg(lemp->filename,rp->ruleline,
3600 "%s(%s) and %s(%s) share the same label but have "
3601 "different datatypes.",
3602 rp->lhs->name, rp->lhsalias, rp->rhs[0]->name, rp->rhsalias[0]);
3603 lemp->errorcnt++;
3604 }
3605 }else{
3606 lemon_sprintf(zOvwrt, "/*%s-overwrites-%s*/",
3607 rp->lhsalias, rp->rhsalias[0]);
3608 zSkip = strstr(rp->code, zOvwrt);
3609 if( zSkip!=0 ){
3610 /* The code contains a special comment that indicates that it is safe
3611 ** for the LHS label to overwrite left-most RHS label. */
3612 lhsdirect = 1;
3613 }else{
3614 lhsdirect = 0;
3615 }
3616 }
3617 if( lhsdirect ){
3618 sprintf(zLhs, "yymsp[%d].minor.yy%d",1-rp->nrhs,rp->lhs->dtnum);
3619 }else{
3620 rc = 1;
3621 sprintf(zLhs, "yylhsminor.yy%d",rp->lhs->dtnum);
3483 } 3622 }
3484 3623
3485 append_str(0,0,0,0); 3624 append_str(0,0,0,0);
3486 3625
3487 /* This const cast is wrong but harmless, if we're careful. */ 3626 /* This const cast is wrong but harmless, if we're careful. */
3488 for(cp=(char *)rp->code; *cp; cp++){ 3627 for(cp=(char *)rp->code; *cp; cp++){
3628 if( cp==zSkip ){
3629 append_str(zOvwrt,0,0,0);
3630 cp += lemonStrlen(zOvwrt)-1;
3631 dontUseRhs0 = 1;
3632 continue;
3633 }
3489 if( ISALPHA(*cp) && (cp==rp->code || (!ISALNUM(cp[-1]) && cp[-1]!='_')) ){ 3634 if( ISALPHA(*cp) && (cp==rp->code || (!ISALNUM(cp[-1]) && cp[-1]!='_')) ){
3490 char saved; 3635 char saved;
3491 for(xp= &cp[1]; ISALNUM(*xp) || *xp=='_'; xp++); 3636 for(xp= &cp[1]; ISALNUM(*xp) || *xp=='_'; xp++);
3492 saved = *xp; 3637 saved = *xp;
3493 *xp = 0; 3638 *xp = 0;
3494 if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ 3639 if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
3495 append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); 3640 append_str(zLhs,0,0,0);
3496 cp = xp; 3641 cp = xp;
3497 lhsused = 1; 3642 lhsused = 1;
3498 }else{ 3643 }else{
3499 for(i=0; i<rp->nrhs; i++){ 3644 for(i=0; i<rp->nrhs; i++){
3500 if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){ 3645 if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){
3501 if( cp!=rp->code && cp[-1]=='@' ){ 3646 if( i==0 && dontUseRhs0 ){
3647 ErrorMsg(lemp->filename,rp->ruleline,
3648 "Label %s used after '%s'.",
3649 rp->rhsalias[0], zOvwrt);
3650 lemp->errorcnt++;
3651 }else if( cp!=rp->code && cp[-1]=='@' ){
3502 /* If the argument is of the form @X then substituted 3652 /* If the argument is of the form @X then substituted
3503 ** the token number of X, not the value of X */ 3653 ** the token number of X, not the value of X */
3504 append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); 3654 append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0);
3505 }else{ 3655 }else{
3506 struct symbol *sp = rp->rhs[i]; 3656 struct symbol *sp = rp->rhs[i];
3507 int dtnum; 3657 int dtnum;
3508 if( sp->type==MULTITERMINAL ){ 3658 if( sp->type==MULTITERMINAL ){
3509 dtnum = sp->subsym[0]->dtnum; 3659 dtnum = sp->subsym[0]->dtnum;
3510 }else{ 3660 }else{
3511 dtnum = sp->dtnum; 3661 dtnum = sp->dtnum;
3512 } 3662 }
3513 append_str("yymsp[%d].minor.yy%d",0,i-rp->nrhs+1, dtnum); 3663 append_str("yymsp[%d].minor.yy%d",0,i-rp->nrhs+1, dtnum);
3514 } 3664 }
3515 cp = xp; 3665 cp = xp;
3516 used[i] = 1; 3666 used[i] = 1;
3517 break; 3667 break;
3518 } 3668 }
3519 } 3669 }
3520 } 3670 }
3521 *xp = saved; 3671 *xp = saved;
3522 } 3672 }
3523 append_str(cp, 1, 0, 0); 3673 append_str(cp, 1, 0, 0);
3524 } /* End loop */ 3674 } /* End loop */
3525 3675
3676 /* Main code generation completed */
3677 cp = append_str(0,0,0,0);
3678 if( cp && cp[0] ) rp->code = Strsafe(cp);
3679 append_str(0,0,0,0);
3680
3526 /* Check to make sure the LHS has been used */ 3681 /* Check to make sure the LHS has been used */
3527 if( rp->lhsalias && !lhsused ){ 3682 if( rp->lhsalias && !lhsused ){
3528 ErrorMsg(lemp->filename,rp->ruleline, 3683 ErrorMsg(lemp->filename,rp->ruleline,
3529 "Label \"%s\" for \"%s(%s)\" is never used.", 3684 "Label \"%s\" for \"%s(%s)\" is never used.",
3530 rp->lhsalias,rp->lhs->name,rp->lhsalias); 3685 rp->lhsalias,rp->lhs->name,rp->lhsalias);
3531 lemp->errorcnt++; 3686 lemp->errorcnt++;
3532 } 3687 }
3533 3688
3534 /* Generate destructor code for RHS symbols which are not used in the 3689 /* Generate destructor code for RHS minor values which are not referenced.
3535 ** reduce code */ 3690 ** Generate error messages for unused labels and duplicate labels.
3691 */
3536 for(i=0; i<rp->nrhs; i++){ 3692 for(i=0; i<rp->nrhs; i++){
3537 if( rp->rhsalias[i] && !used[i] ){ 3693 if( rp->rhsalias[i] ){
3538 ErrorMsg(lemp->filename,rp->ruleline, 3694 if( i>0 ){
3539 "Label %s for \"%s(%s)\" is never used.", 3695 int j;
3540 rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]); 3696 if( rp->lhsalias && strcmp(rp->lhsalias,rp->rhsalias[i])==0 ){
3541 lemp->errorcnt++; 3697 ErrorMsg(lemp->filename,rp->ruleline,
3542 }else if( rp->rhsalias[i]==0 ){ 3698 "%s(%s) has the same label as the LHS but is not the left-most "
3543 if( has_destructor(rp->rhs[i],lemp) ){ 3699 "symbol on the RHS.",
3544 append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0, 3700 rp->rhs[i]->name, rp->rhsalias);
3545 rp->rhs[i]->index,i-rp->nrhs+1); 3701 lemp->errorcnt++;
3546 }else{ 3702 }
3547 /* No destructor defined for this term */ 3703 for(j=0; j<i; j++){
3704 if( rp->rhsalias[j] && strcmp(rp->rhsalias[j],rp->rhsalias[i])==0 ){
3705 ErrorMsg(lemp->filename,rp->ruleline,
3706 "Label %s used for multiple symbols on the RHS of a rule.",
3707 rp->rhsalias[i]);
3708 lemp->errorcnt++;
3709 break;
3710 }
3711 }
3548 } 3712 }
3713 if( !used[i] ){
3714 ErrorMsg(lemp->filename,rp->ruleline,
3715 "Label %s for \"%s(%s)\" is never used.",
3716 rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
3717 lemp->errorcnt++;
3718 }
3719 }else if( i>0 && has_destructor(rp->rhs[i],lemp) ){
3720 append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
3721 rp->rhs[i]->index,i-rp->nrhs+1);
3549 } 3722 }
3550 } 3723 }
3551 if( rp->code ){ 3724
3552 cp = append_str(0,0,0,0); 3725 /* If unable to write LHS values directly into the stack, write the
3553 rp->code = Strsafe(cp?cp:""); 3726 ** saved LHS value now. */
3727 if( lhsdirect==0 ){
3728 append_str(" yymsp[%d].minor.yy%d = ", 0, 1-rp->nrhs, rp->lhs->dtnum);
3729 append_str(zLhs, 0, 0, 0);
3730 append_str(";\n", 0, 0, 0);
3554 } 3731 }
3732
3733 /* Suffix code generation complete */
3734 cp = append_str(0,0,0,0);
3735 if( cp && cp[0] ){
3736 rp->codeSuffix = Strsafe(cp);
3737 rp->noCode = 0;
3738 }
3739
3740 return rc;
3555 } 3741 }
3556 3742
3557 /* 3743 /*
3558 ** Generate code which executes when the rule "rp" is reduced. Write 3744 ** Generate code which executes when the rule "rp" is reduced. Write
3559 ** the code to "out". Make sure lineno stays up-to-date. 3745 ** the code to "out". Make sure lineno stays up-to-date.
3560 */ 3746 */
3561 PRIVATE void emit_code( 3747 PRIVATE void emit_code(
3562 FILE *out, 3748 FILE *out,
3563 struct rule *rp, 3749 struct rule *rp,
3564 struct lemon *lemp, 3750 struct lemon *lemp,
3565 int *lineno 3751 int *lineno
3566 ){ 3752 ){
3567 const char *cp; 3753 const char *cp;
3568 3754
3755 /* Setup code prior to the #line directive */
3756 if( rp->codePrefix && rp->codePrefix[0] ){
3757 fprintf(out, "{%s", rp->codePrefix);
3758 for(cp=rp->codePrefix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3759 }
3760
3569 /* Generate code to do the reduce action */ 3761 /* Generate code to do the reduce action */
3570 if( rp->code ){ 3762 if( rp->code ){
3571 if( !lemp->nolinenosflag ){ 3763 if( !lemp->nolinenosflag ){
3572 (*lineno)++; 3764 (*lineno)++;
3573 tplt_linedir(out,rp->line,lemp->filename); 3765 tplt_linedir(out,rp->line,lemp->filename);
3574 } 3766 }
3575 fprintf(out,"{%s",rp->code); 3767 fprintf(out,"{%s",rp->code);
3576 for(cp=rp->code; *cp; cp++){ 3768 for(cp=rp->code; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3577 if( *cp=='\n' ) (*lineno)++;
3578 } /* End loop */
3579 fprintf(out,"}\n"); (*lineno)++; 3769 fprintf(out,"}\n"); (*lineno)++;
3580 if( !lemp->nolinenosflag ){ 3770 if( !lemp->nolinenosflag ){
3581 (*lineno)++; 3771 (*lineno)++;
3582 tplt_linedir(out,*lineno,lemp->outname); 3772 tplt_linedir(out,*lineno,lemp->outname);
3583 } 3773 }
3584 } /* End if( rp->code ) */ 3774 }
3775
3776 /* Generate breakdown code that occurs after the #line directive */
3777 if( rp->codeSuffix && rp->codeSuffix[0] ){
3778 fprintf(out, "%s", rp->codeSuffix);
3779 for(cp=rp->codeSuffix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
3780 }
3781
3782 if( rp->codePrefix ){
3783 fprintf(out, "}\n"); (*lineno)++;
3784 }
3585 3785
3586 return; 3786 return;
3587 } 3787 }
3588 3788
3589 /* 3789 /*
3590 ** Print the definition of the union used for the parser's data stack. 3790 ** Print the definition of the union used for the parser's data stack.
3591 ** This union contains fields for every possible data type for tokens 3791 ** This union contains fields for every possible data type for tokens
3592 ** and nonterminals. In the process of computing and printing this 3792 ** and nonterminals. In the process of computing and printing this
3593 ** union, also set the ".dtnum" field of every terminal and nonterminal 3793 ** union, also set the ".dtnum" field of every terminal and nonterminal
3594 ** symbol. 3794 ** symbol.
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
3947 if( pActtab->aAction[jj].action<0 ) nn++; 4147 if( pActtab->aAction[jj].action<0 ) nn++;
3948 } 4148 }
3949 printf("%4d: State %3d %s n: %2d size: %5d freespace: %d\n", 4149 printf("%4d: State %3d %s n: %2d size: %5d freespace: %d\n",
3950 i, stp->statenum, ax[i].isTkn ? "Token" : "Var ", 4150 i, stp->statenum, ax[i].isTkn ? "Token" : "Var ",
3951 ax[i].nAction, pActtab->nAction, nn); 4151 ax[i].nAction, pActtab->nAction, nn);
3952 } 4152 }
3953 #endif 4153 #endif
3954 } 4154 }
3955 free(ax); 4155 free(ax);
3956 4156
4157 /* Mark rules that are actually used for reduce actions after all
4158 ** optimizations have been applied
4159 */
4160 for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE;
4161 for(i=0; i<lemp->nxstate; i++){
4162 for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
4163 if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){
4164 ap->x.rp->doesReduce = i;
4165 }
4166 }
4167 }
4168
3957 /* Finish rendering the constants now that the action table has 4169 /* Finish rendering the constants now that the action table has
3958 ** been computed */ 4170 ** been computed */
3959 fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++; 4171 fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++;
3960 fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; 4172 fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++;
3961 fprintf(out,"#define YY_MAX_SHIFT %d\n",lemp->nxstate-1); lineno++; 4173 fprintf(out,"#define YY_MAX_SHIFT %d\n",lemp->nxstate-1); lineno++;
3962 fprintf(out,"#define YY_MIN_SHIFTREDUCE %d\n",lemp->nstate); lineno++; 4174 fprintf(out,"#define YY_MIN_SHIFTREDUCE %d\n",lemp->nstate); lineno++;
3963 i = lemp->nstate + lemp->nrule; 4175 i = lemp->nstate + lemp->nrule;
3964 fprintf(out,"#define YY_MAX_SHIFTREDUCE %d\n", i-1); lineno++; 4176 fprintf(out,"#define YY_MAX_SHIFTREDUCE %d\n", i-1); lineno++;
3965 fprintf(out,"#define YY_MIN_REDUCE %d\n", i); lineno++; 4177 fprintf(out,"#define YY_MIN_REDUCE %d\n", i); lineno++;
3966 i = lemp->nstate + lemp->nrule*2; 4178 i = lemp->nstate + lemp->nrule*2;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4012 if( j==9 || i==n-1 ){ 4224 if( j==9 || i==n-1 ){
4013 fprintf(out, "\n"); lineno++; 4225 fprintf(out, "\n"); lineno++;
4014 j = 0; 4226 j = 0;
4015 }else{ 4227 }else{
4016 j++; 4228 j++;
4017 } 4229 }
4018 } 4230 }
4019 fprintf(out, "};\n"); lineno++; 4231 fprintf(out, "};\n"); lineno++;
4020 4232
4021 /* Output the yy_shift_ofst[] table */ 4233 /* Output the yy_shift_ofst[] table */
4022 fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
4023 n = lemp->nxstate; 4234 n = lemp->nxstate;
4024 while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; 4235 while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
4025 fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; 4236 fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", lemp->nactiontab); lineno++;
4026 fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; 4237 fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++;
4027 fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; 4238 fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++;
4239 fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++;
4028 fprintf(out, "static const %s yy_shift_ofst[] = {\n", 4240 fprintf(out, "static const %s yy_shift_ofst[] = {\n",
4029 minimum_size_type(mnTknOfst-1, mxTknOfst, &sz)); lineno++; 4241 minimum_size_type(mnTknOfst, lemp->nterminal+lemp->nactiontab, &sz));
4242 lineno++;
4030 lemp->tablesize += n*sz; 4243 lemp->tablesize += n*sz;
4031 for(i=j=0; i<n; i++){ 4244 for(i=j=0; i<n; i++){
4032 int ofst; 4245 int ofst;
4033 stp = lemp->sorted[i]; 4246 stp = lemp->sorted[i];
4034 ofst = stp->iTknOfst; 4247 ofst = stp->iTknOfst;
4035 if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; 4248 if( ofst==NO_OFFSET ) ofst = lemp->nactiontab;
4036 if( j==0 ) fprintf(out," /* %5d */ ", i); 4249 if( j==0 ) fprintf(out," /* %5d */ ", i);
4037 fprintf(out, " %4d,", ofst); 4250 fprintf(out, " %4d,", ofst);
4038 if( j==9 || i==n-1 ){ 4251 if( j==9 || i==n-1 ){
4039 fprintf(out, "\n"); lineno++; 4252 fprintf(out, "\n"); lineno++;
4040 j = 0; 4253 j = 0;
4041 }else{ 4254 }else{
4042 j++; 4255 j++;
4043 } 4256 }
4044 } 4257 }
4045 fprintf(out, "};\n"); lineno++; 4258 fprintf(out, "};\n"); lineno++;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4115 if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } 4328 if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; }
4116 } 4329 }
4117 if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } 4330 if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; }
4118 tplt_xfer(lemp->name,in,out,&lineno); 4331 tplt_xfer(lemp->name,in,out,&lineno);
4119 4332
4120 /* Generate a table containing a text string that describes every 4333 /* Generate a table containing a text string that describes every
4121 ** rule in the rule set of the grammar. This information is used 4334 ** rule in the rule set of the grammar. This information is used
4122 ** when tracing REDUCE actions. 4335 ** when tracing REDUCE actions.
4123 */ 4336 */
4124 for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ 4337 for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
4125 assert( rp->index==i ); 4338 assert( rp->iRule==i );
4126 fprintf(out," /* %3d */ \"", i); 4339 fprintf(out," /* %3d */ \"", i);
4127 writeRuleText(out, rp); 4340 writeRuleText(out, rp);
4128 fprintf(out,"\",\n"); lineno++; 4341 fprintf(out,"\",\n"); lineno++;
4129 } 4342 }
4130 tplt_xfer(lemp->name,in,out,&lineno); 4343 tplt_xfer(lemp->name,in,out,&lineno);
4131 4344
4132 /* Generate code which executes every time a symbol is popped from 4345 /* Generate code which executes every time a symbol is popped from
4133 ** the stack while processing errors or while destroying the parser. 4346 ** the stack while processing errors or while destroying the parser.
4134 ** (In other words, generate the %destructor actions) 4347 ** (In other words, generate the %destructor actions)
4135 */ 4348 */
(...skipping 29 matching lines...) Expand all
4165 dflt_sp = sp; 4378 dflt_sp = sp;
4166 } 4379 }
4167 if( dflt_sp!=0 ){ 4380 if( dflt_sp!=0 ){
4168 emit_destructor_code(out,dflt_sp,lemp,&lineno); 4381 emit_destructor_code(out,dflt_sp,lemp,&lineno);
4169 } 4382 }
4170 fprintf(out," break;\n"); lineno++; 4383 fprintf(out," break;\n"); lineno++;
4171 } 4384 }
4172 for(i=0; i<lemp->nsymbol; i++){ 4385 for(i=0; i<lemp->nsymbol; i++){
4173 struct symbol *sp = lemp->symbols[i]; 4386 struct symbol *sp = lemp->symbols[i];
4174 if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; 4387 if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
4388 if( sp->destLineno<0 ) continue; /* Already emitted */
4175 fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; 4389 fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++;
4176 4390
4177 /* Combine duplicate destructors into a single case */ 4391 /* Combine duplicate destructors into a single case */
4178 for(j=i+1; j<lemp->nsymbol; j++){ 4392 for(j=i+1; j<lemp->nsymbol; j++){
4179 struct symbol *sp2 = lemp->symbols[j]; 4393 struct symbol *sp2 = lemp->symbols[j];
4180 if( sp2 && sp2->type!=TERMINAL && sp2->destructor 4394 if( sp2 && sp2->type!=TERMINAL && sp2->destructor
4181 && sp2->dtnum==sp->dtnum 4395 && sp2->dtnum==sp->dtnum
4182 && strcmp(sp->destructor,sp2->destructor)==0 ){ 4396 && strcmp(sp->destructor,sp2->destructor)==0 ){
4183 fprintf(out," case %d: /* %s */\n", 4397 fprintf(out," case %d: /* %s */\n",
4184 sp2->index, sp2->name); lineno++; 4398 sp2->index, sp2->name); lineno++;
4185 sp2->destructor = 0; 4399 sp2->destLineno = -1; /* Avoid emitting this destructor again */
4186 } 4400 }
4187 } 4401 }
4188 4402
4189 emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); 4403 emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
4190 fprintf(out," break;\n"); lineno++; 4404 fprintf(out," break;\n"); lineno++;
4191 } 4405 }
4192 tplt_xfer(lemp->name,in,out,&lineno); 4406 tplt_xfer(lemp->name,in,out,&lineno);
4193 4407
4194 /* Generate code which executes whenever the parser stack overflows */ 4408 /* Generate code which executes whenever the parser stack overflows */
4195 tplt_print(out,lemp,lemp->overflow,&lineno); 4409 tplt_print(out,lemp,lemp->overflow,&lineno);
4196 tplt_xfer(lemp->name,in,out,&lineno); 4410 tplt_xfer(lemp->name,in,out,&lineno);
4197 4411
4198 /* Generate the table of rule information 4412 /* Generate the table of rule information
4199 ** 4413 **
4200 ** Note: This code depends on the fact that rules are number 4414 ** Note: This code depends on the fact that rules are number
4201 ** sequentually beginning with 0. 4415 ** sequentually beginning with 0.
4202 */ 4416 */
4203 for(rp=lemp->rule; rp; rp=rp->next){ 4417 for(rp=lemp->rule; rp; rp=rp->next){
4204 fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++; 4418 fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++;
4205 } 4419 }
4206 tplt_xfer(lemp->name,in,out,&lineno); 4420 tplt_xfer(lemp->name,in,out,&lineno);
4207 4421
4208 /* Generate code which execution during each REDUCE action */ 4422 /* Generate code which execution during each REDUCE action */
4423 i = 0;
4209 for(rp=lemp->rule; rp; rp=rp->next){ 4424 for(rp=lemp->rule; rp; rp=rp->next){
4210 translate_code(lemp, rp); 4425 i += translate_code(lemp, rp);
4426 }
4427 if( i ){
4428 fprintf(out," YYMINORTYPE yylhsminor;\n"); lineno++;
4211 } 4429 }
4212 /* First output rules other than the default: rule */ 4430 /* First output rules other than the default: rule */
4213 for(rp=lemp->rule; rp; rp=rp->next){ 4431 for(rp=lemp->rule; rp; rp=rp->next){
4214 struct rule *rp2; /* Other rules with the same action */ 4432 struct rule *rp2; /* Other rules with the same action */
4215 if( rp->code==0 ) continue; 4433 if( rp->codeEmitted ) continue;
4216 if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ 4434 if( rp->noCode ){
4217 fprintf(out," case %d: /* ", rp->index); 4435 /* No C code actions, so this will be part of the "default:" rule */
4436 continue;
4437 }
4438 fprintf(out," case %d: /* ", rp->iRule);
4218 writeRuleText(out, rp); 4439 writeRuleText(out, rp);
4219 fprintf(out, " */\n"); lineno++; 4440 fprintf(out, " */\n"); lineno++;
4220 for(rp2=rp->next; rp2; rp2=rp2->next){ 4441 for(rp2=rp->next; rp2; rp2=rp2->next){
4221 if( rp2->code==rp->code ){ 4442 if( rp2->code==rp->code && rp2->codePrefix==rp->codePrefix
4222 fprintf(out," case %d: /* ", rp2->index); 4443 && rp2->codeSuffix==rp->codeSuffix ){
4444 fprintf(out," case %d: /* ", rp2->iRule);
4223 writeRuleText(out, rp2); 4445 writeRuleText(out, rp2);
4224 fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++; 4446 fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++;
4225 rp2->code = 0; 4447 rp2->codeEmitted = 1;
4226 } 4448 }
4227 } 4449 }
4228 emit_code(out,rp,lemp,&lineno); 4450 emit_code(out,rp,lemp,&lineno);
4229 fprintf(out," break;\n"); lineno++; 4451 fprintf(out," break;\n"); lineno++;
4230 rp->code = 0; 4452 rp->codeEmitted = 1;
4231 } 4453 }
4232 /* Finally, output the default: rule. We choose as the default: all 4454 /* Finally, output the default: rule. We choose as the default: all
4233 ** empty actions. */ 4455 ** empty actions. */
4234 fprintf(out," default:\n"); lineno++; 4456 fprintf(out," default:\n"); lineno++;
4235 for(rp=lemp->rule; rp; rp=rp->next){ 4457 for(rp=lemp->rule; rp; rp=rp->next){
4236 if( rp->code==0 ) continue; 4458 if( rp->codeEmitted ) continue;
4237 assert( rp->code[0]=='\n' && rp->code[1]==0 ); 4459 assert( rp->noCode );
4238 fprintf(out," /* (%d) ", rp->index); 4460 fprintf(out," /* (%d) ", rp->iRule);
4239 writeRuleText(out, rp); 4461 writeRuleText(out, rp);
4240 fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++; 4462 if( rp->doesReduce ){
4463 fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++;
4464 }else{
4465 fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n",
4466 rp->iRule); lineno++;
4467 }
4241 } 4468 }
4242 fprintf(out," break;\n"); lineno++; 4469 fprintf(out," break;\n"); lineno++;
4243 tplt_xfer(lemp->name,in,out,&lineno); 4470 tplt_xfer(lemp->name,in,out,&lineno);
4244 4471
4245 /* Generate code which executes if a parse fails */ 4472 /* Generate code which executes if a parse fails */
4246 tplt_print(out,lemp,lemp->failure,&lineno); 4473 tplt_print(out,lemp,lemp->failure,&lineno);
4247 tplt_xfer(lemp->name,in,out,&lineno); 4474 tplt_xfer(lemp->name,in,out,&lineno);
4248 4475
4249 /* Generate code which executes when a syntax error occurs */ 4476 /* Generate code which executes when a syntax error occurs */
4250 tplt_print(out,lemp,lemp->error,&lineno); 4477 tplt_print(out,lemp,lemp->error,&lineno);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4301 /* Reduce the size of the action tables, if possible, by making use 4528 /* Reduce the size of the action tables, if possible, by making use
4302 ** of defaults. 4529 ** of defaults.
4303 ** 4530 **
4304 ** In this version, we take the most frequent REDUCE action and make 4531 ** In this version, we take the most frequent REDUCE action and make
4305 ** it the default. Except, there is no default if the wildcard token 4532 ** it the default. Except, there is no default if the wildcard token
4306 ** is a possible look-ahead. 4533 ** is a possible look-ahead.
4307 */ 4534 */
4308 void CompressTables(struct lemon *lemp) 4535 void CompressTables(struct lemon *lemp)
4309 { 4536 {
4310 struct state *stp; 4537 struct state *stp;
4311 struct action *ap, *ap2; 4538 struct action *ap, *ap2, *nextap;
4312 struct rule *rp, *rp2, *rbest; 4539 struct rule *rp, *rp2, *rbest;
4313 int nbest, n; 4540 int nbest, n;
4314 int i; 4541 int i;
4315 int usesWildcard; 4542 int usesWildcard;
4316 4543
4317 for(i=0; i<lemp->nstate; i++){ 4544 for(i=0; i<lemp->nstate; i++){
4318 stp = lemp->sorted[i]; 4545 stp = lemp->sorted[i];
4319 nbest = 0; 4546 nbest = 0;
4320 rbest = 0; 4547 rbest = 0;
4321 usesWildcard = 0; 4548 usesWildcard = 0;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4378 for(ap=stp->ap; ap; ap=ap->next){ 4605 for(ap=stp->ap; ap; ap=ap->next){
4379 struct state *pNextState; 4606 struct state *pNextState;
4380 if( ap->type!=SHIFT ) continue; 4607 if( ap->type!=SHIFT ) continue;
4381 pNextState = ap->x.stp; 4608 pNextState = ap->x.stp;
4382 if( pNextState->autoReduce && pNextState->pDfltReduce!=0 ){ 4609 if( pNextState->autoReduce && pNextState->pDfltReduce!=0 ){
4383 ap->type = SHIFTREDUCE; 4610 ap->type = SHIFTREDUCE;
4384 ap->x.rp = pNextState->pDfltReduce; 4611 ap->x.rp = pNextState->pDfltReduce;
4385 } 4612 }
4386 } 4613 }
4387 } 4614 }
4615
4616 /* If a SHIFTREDUCE action specifies a rule that has a single RHS term
4617 ** (meaning that the SHIFTREDUCE will land back in the state where it
4618 ** started) and if there is no C-code associated with the reduce action,
4619 ** then we can go ahead and convert the action to be the same as the
4620 ** action for the RHS of the rule.
4621 */
4622 for(i=0; i<lemp->nstate; i++){
4623 stp = lemp->sorted[i];
4624 for(ap=stp->ap; ap; ap=nextap){
4625 nextap = ap->next;
4626 if( ap->type!=SHIFTREDUCE ) continue;
4627 rp = ap->x.rp;
4628 if( rp->noCode==0 ) continue;
4629 if( rp->nrhs!=1 ) continue;
4630 #if 1
4631 /* Only apply this optimization to non-terminals. It would be OK to
4632 ** apply it to terminal symbols too, but that makes the parser tables
4633 ** larger. */
4634 if( ap->sp->index<lemp->nterminal ) continue;
4635 #endif
4636 /* If we reach this point, it means the optimization can be applied */
4637 nextap = ap;
4638 for(ap2=stp->ap; ap2 && (ap2==ap || ap2->sp!=rp->lhs); ap2=ap2->next){}
4639 assert( ap2!=0 );
4640 ap->spOpt = ap2->sp;
4641 ap->type = ap2->type;
4642 ap->x = ap2->x;
4643 }
4644 }
4388 } 4645 }
4389 4646
4390 4647
4391 /* 4648 /*
4392 ** Compare two states for sorting purposes. The smaller state is the 4649 ** Compare two states for sorting purposes. The smaller state is the
4393 ** one with the most non-terminal actions. If they have the same number 4650 ** one with the most non-terminal actions. If they have the same number
4394 ** of non-terminal actions, then the smaller is the one with the most 4651 ** of non-terminal actions, then the smaller is the one with the most
4395 ** token actions. 4652 ** token actions.
4396 */ 4653 */
4397 static int stateResortCompare(const void *a, const void *b){ 4654 static int stateResortCompare(const void *a, const void *b){
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
5170 ** as it is removed. ("f" may be null to avoid this step.) */ 5427 ** as it is removed. ("f" may be null to avoid this step.) */
5171 void Configtable_clear(int(*f)(struct config *)) 5428 void Configtable_clear(int(*f)(struct config *))
5172 { 5429 {
5173 int i; 5430 int i;
5174 if( x4a==0 || x4a->count==0 ) return; 5431 if( x4a==0 || x4a->count==0 ) return;
5175 if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data); 5432 if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data);
5176 for(i=0; i<x4a->size; i++) x4a->ht[i] = 0; 5433 for(i=0; i<x4a->size; i++) x4a->ht[i] = 0;
5177 x4a->count = 0; 5434 x4a->count = 0;
5178 return; 5435 return;
5179 } 5436 }
OLDNEW
« no previous file with comments | « third_party/sqlite/src/tool/kvtest-speed.sh ('k') | third_party/sqlite/src/tool/lempar.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698