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