PageRenderTime 72ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/kegogi/lemon.c

http://github.com/zedshaw/mongrel2
C | 2141 lines | 1631 code | 147 blank | 363 comment | 270 complexity | 3a8db045f48383021b5311b21b02ba0e MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, Unlicense

Large files files are truncated, but you can click here to view the full file

  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. #ifndef __WIN32__
  16. # if defined(_WIN32) || defined(WIN32)
  17. # define __WIN32__
  18. # endif
  19. #endif
  20. #ifdef __WIN32__
  21. extern int access();
  22. #else
  23. #include <unistd.h>
  24. #endif
  25. /* #define PRIVATE static */
  26. #define PRIVATE
  27. #ifdef TEST
  28. #define MAXRHS 5 /* Set low to exercise exception code */
  29. #else
  30. #define MAXRHS 1000
  31. #endif
  32. static char *msort(char*,char**,int(*)(const char*,const char*));
  33. /*
  34. ** Compilers are getting increasingly pedantic about type conversions
  35. ** as C evolves ever closer to Ada.... To work around the latest problems
  36. ** we have to define the following variant of strlen().
  37. */
  38. #define lemonStrlen(X) ((int)strlen(X))
  39. static struct action *Action_new(void);
  40. static struct action *Action_sort(struct action *);
  41. /********** From the file "build.h" ************************************/
  42. void FindRulePrecedences();
  43. void FindFirstSets();
  44. void FindStates();
  45. void FindLinks();
  46. void FindFollowSets();
  47. void FindActions();
  48. /********* From the file "configlist.h" *********************************/
  49. void Configlist_init(/* void */);
  50. struct config *Configlist_add(/* struct rule *, int */);
  51. struct config *Configlist_addbasis(/* struct rule *, int */);
  52. void Configlist_closure(/* void */);
  53. void Configlist_sort(/* void */);
  54. void Configlist_sortbasis(/* void */);
  55. struct config *Configlist_return(/* void */);
  56. struct config *Configlist_basis(/* void */);
  57. void Configlist_eat(/* struct config * */);
  58. void Configlist_reset(/* void */);
  59. /********* From the file "error.h" ***************************************/
  60. void ErrorMsg(const char *, int,const char *, ...);
  61. /****** From the file "option.h" ******************************************/
  62. struct s_options {
  63. enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR,
  64. OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type;
  65. char *label;
  66. char *arg;
  67. char *message;
  68. };
  69. int OptInit(/* char**,struct s_options*,FILE* */);
  70. int OptNArgs(/* void */);
  71. char *OptArg(/* int */);
  72. void OptErr(/* int */);
  73. void OptPrint(/* void */);
  74. /******** From the file "parse.h" *****************************************/
  75. void Parse(/* struct lemon *lemp */);
  76. /********* From the file "plink.h" ***************************************/
  77. struct plink *Plink_new(/* void */);
  78. void Plink_add(/* struct plink **, struct config * */);
  79. void Plink_copy(/* struct plink **, struct plink * */);
  80. void Plink_delete(/* struct plink * */);
  81. /********** From the file "report.h" *************************************/
  82. void Reprint(/* struct lemon * */);
  83. void ReportOutput(/* struct lemon * */);
  84. void ReportTable(/* struct lemon * */);
  85. void ReportHeader(/* struct lemon * */);
  86. void CompressTables(/* struct lemon * */);
  87. void ResortStates(/* struct lemon * */);
  88. /********** From the file "set.h" ****************************************/
  89. void SetSize(/* int N */); /* All sets will be of size N */
  90. char *SetNew(/* void */); /* A new set for element 0..N */
  91. void SetFree(/* char* */); /* Deallocate a set */
  92. int SetAdd(/* char*,int */); /* Add element to a set */
  93. int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */
  94. #define SetFind(X,Y) (X[Y]) /* True if Y is in set X */
  95. /********** From the file "struct.h" *************************************/
  96. /*
  97. ** Principal data structures for the LEMON parser generator.
  98. */
  99. typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean;
  100. /* Symbols (terminals and nonterminals) of the grammar are stored
  101. ** in the following: */
  102. struct symbol {
  103. char *name; /* Name of the symbol */
  104. int index; /* Index number for this symbol */
  105. enum {
  106. TERMINAL,
  107. NONTERMINAL,
  108. MULTITERMINAL
  109. } type; /* Symbols are all either TERMINALS or NTs */
  110. struct rule *rule; /* Linked list of rules of this (if an NT) */
  111. struct symbol *fallback; /* fallback token in case this token doesn't parse */
  112. int prec; /* Precedence if defined (-1 otherwise) */
  113. enum e_assoc {
  114. LEFT,
  115. RIGHT,
  116. NONE,
  117. UNK
  118. } assoc; /* Associativity if precedence is defined */
  119. char *firstset; /* First-set for all rules of this symbol */
  120. Boolean lambda; /* True if NT and can generate an empty string */
  121. int useCnt; /* Number of times used */
  122. char *destructor; /* Code which executes whenever this symbol is
  123. ** popped from the stack during error processing */
  124. int destLineno; /* Line number for start of destructor */
  125. char *datatype; /* The data type of information held by this
  126. ** object. Only used if type==NONTERMINAL */
  127. int dtnum; /* The data type number. In the parser, the value
  128. ** stack is a union. The .yy%d element of this
  129. ** union is the correct data type for this object */
  130. /* The following fields are used by MULTITERMINALs only */
  131. int nsubsym; /* Number of constituent symbols in the MULTI */
  132. struct symbol **subsym; /* Array of constituent symbols */
  133. };
  134. /* Each production rule in the grammar is stored in the following
  135. ** structure. */
  136. struct rule {
  137. struct symbol *lhs; /* Left-hand side of the rule */
  138. char *lhsalias; /* Alias for the LHS (NULL if none) */
  139. int lhsStart; /* True if left-hand side is the start symbol */
  140. int ruleline; /* Line number for the rule */
  141. int nrhs; /* Number of RHS symbols */
  142. struct symbol **rhs; /* The RHS symbols */
  143. char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
  144. int line; /* Line number at which code begins */
  145. char *code; /* The code executed when this rule is reduced */
  146. struct symbol *precsym; /* Precedence symbol for this rule */
  147. int index; /* An index number for this rule */
  148. Boolean canReduce; /* True if this rule is ever reduced */
  149. struct rule *nextlhs; /* Next rule with the same LHS */
  150. struct rule *next; /* Next rule in the global list */
  151. };
  152. /* A configuration is a production rule of the grammar together with
  153. ** a mark (dot) showing how much of that rule has been processed so far.
  154. ** Configurations also contain a follow-set which is a list of terminal
  155. ** symbols which are allowed to immediately follow the end of the rule.
  156. ** Every configuration is recorded as an instance of the following: */
  157. struct config {
  158. struct rule *rp; /* The rule upon which the configuration is based */
  159. int dot; /* The parse point */
  160. char *fws; /* Follow-set for this configuration only */
  161. struct plink *fplp; /* Follow-set forward propagation links */
  162. struct plink *bplp; /* Follow-set backwards propagation links */
  163. struct state *stp; /* Pointer to state which contains this */
  164. enum {
  165. COMPLETE, /* The status is used during followset and */
  166. INCOMPLETE /* shift computations */
  167. } status;
  168. struct config *next; /* Next configuration in the state */
  169. struct config *bp; /* The next basis configuration */
  170. };
  171. /* Every shift or reduce operation is stored as one of the following */
  172. struct action {
  173. struct symbol *sp; /* The look-ahead symbol */
  174. enum e_action {
  175. SHIFT,
  176. ACCEPT,
  177. REDUCE,
  178. ERROR,
  179. SSCONFLICT, /* A shift/shift conflict */
  180. SRCONFLICT, /* Was a reduce, but part of a conflict */
  181. RRCONFLICT, /* Was a reduce, but part of a conflict */
  182. SH_RESOLVED, /* Was a shift. Precedence resolved conflict */
  183. RD_RESOLVED, /* Was reduce. Precedence resolved conflict */
  184. NOT_USED /* Deleted by compression */
  185. } type;
  186. union {
  187. struct state *stp; /* The new state, if a shift */
  188. struct rule *rp; /* The rule, if a reduce */
  189. } x;
  190. struct action *next; /* Next action for this state */
  191. struct action *collide; /* Next action with the same hash */
  192. };
  193. /* Each state of the generated parser's finite state machine
  194. ** is encoded as an instance of the following structure. */
  195. struct state {
  196. struct config *bp; /* The basis configurations for this state */
  197. struct config *cfp; /* All configurations in this set */
  198. int statenum; /* Sequential number for this state */
  199. struct action *ap; /* Array of actions for this state */
  200. int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */
  201. int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */
  202. int iDflt; /* Default action */
  203. };
  204. #define NO_OFFSET (-2147483647)
  205. /* A followset propagation link indicates that the contents of one
  206. ** configuration followset should be propagated to another whenever
  207. ** the first changes. */
  208. struct plink {
  209. struct config *cfp; /* The configuration to which linked */
  210. struct plink *next; /* The next propagate link */
  211. };
  212. /* The state vector for the entire parser generator is recorded as
  213. ** follows. (LEMON uses no global variables and makes little use of
  214. ** static variables. Fields in the following structure can be thought
  215. ** of as begin global variables in the program.) */
  216. struct lemon {
  217. struct state **sorted; /* Table of states sorted by state number */
  218. struct rule *rule; /* List of all rules */
  219. int nstate; /* Number of states */
  220. int nrule; /* Number of rules */
  221. int nsymbol; /* Number of terminal and nonterminal symbols */
  222. int nterminal; /* Number of terminal symbols */
  223. struct symbol **symbols; /* Sorted array of pointers to symbols */
  224. int errorcnt; /* Number of errors */
  225. struct symbol *errsym; /* The error symbol */
  226. struct symbol *wildcard; /* Token that matches anything */
  227. char *name; /* Name of the generated parser */
  228. char *arg; /* Declaration of the 3th argument to parser */
  229. char *tokentype; /* Type of terminal symbols in the parser stack */
  230. char *vartype; /* The default type of non-terminal symbols */
  231. char *start; /* Name of the start symbol for the grammar */
  232. char *stacksize; /* Size of the parser stack */
  233. char *include; /* Code to put at the start of the C file */
  234. char *error; /* Code to execute when an error is seen */
  235. char *overflow; /* Code to execute on a stack overflow */
  236. char *failure; /* Code to execute on parser failure */
  237. char *accept; /* Code to execute when the parser excepts */
  238. char *extracode; /* Code appended to the generated file */
  239. char *tokendest; /* Code to execute to destroy token data */
  240. char *vardest; /* Code for the default non-terminal destructor */
  241. char *filename; /* Name of the input file */
  242. char *outname; /* Name of the current output file */
  243. char *tokenprefix; /* A prefix added to token names in the .h file */
  244. int nconflict; /* Number of parsing conflicts */
  245. int tablesize; /* Size of the parse tables */
  246. int basisflag; /* Print only basis configurations */
  247. int has_fallback; /* True if any %fallback is seen in the grammar */
  248. int nolinenosflag; /* True if #line statements should not be printed */
  249. char *argv0; /* Name of the program */
  250. };
  251. #define MemoryCheck(X) if((X)==0){ \
  252. extern void memory_error(); \
  253. memory_error(); \
  254. }
  255. /**************** From the file "table.h" *********************************/
  256. /*
  257. ** All code in this file has been automatically generated
  258. ** from a specification in the file
  259. ** "table.q"
  260. ** by the associative array code building program "aagen".
  261. ** Do not edit this file! Instead, edit the specification
  262. ** file, then rerun aagen.
  263. */
  264. /*
  265. ** Code for processing tables in the LEMON parser generator.
  266. */
  267. /* Routines for handling a strings */
  268. char *Strsafe();
  269. void Strsafe_init(/* void */);
  270. int Strsafe_insert(/* char * */);
  271. char *Strsafe_find(/* char * */);
  272. /* Routines for handling symbols of the grammar */
  273. struct symbol *Symbol_new();
  274. int Symbolcmpp(/* struct symbol **, struct symbol ** */);
  275. void Symbol_init(/* void */);
  276. int Symbol_insert(/* struct symbol *, char * */);
  277. struct symbol *Symbol_find(/* char * */);
  278. struct symbol *Symbol_Nth(/* int */);
  279. int Symbol_count(/* */);
  280. struct symbol **Symbol_arrayof(/* */);
  281. /* Routines to manage the state table */
  282. int Configcmp(/* struct config *, struct config * */);
  283. struct state *State_new();
  284. void State_init(/* void */);
  285. int State_insert(/* struct state *, struct config * */);
  286. struct state *State_find(/* struct config * */);
  287. struct state **State_arrayof(/* */);
  288. /* Routines used for efficiency in Configlist_add */
  289. void Configtable_init(/* void */);
  290. int Configtable_insert(/* struct config * */);
  291. struct config *Configtable_find(/* struct config * */);
  292. void Configtable_clear(/* int(*)(struct config *) */);
  293. /****************** From the file "action.c" *******************************/
  294. /*
  295. ** Routines processing parser actions in the LEMON parser generator.
  296. */
  297. /* Allocate a new parser action */
  298. static struct action *Action_new(void){
  299. static struct action *freelist = 0;
  300. struct action *new;
  301. if( freelist==0 ){
  302. int i;
  303. int amt = 100;
  304. freelist = (struct action *)calloc(amt, sizeof(struct action));
  305. if( freelist==0 ){
  306. fprintf(stderr,"Unable to allocate memory for a new parser action.");
  307. exit(1);
  308. }
  309. for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
  310. freelist[amt-1].next = 0;
  311. }
  312. new = freelist;
  313. freelist = freelist->next;
  314. return new;
  315. }
  316. /* Compare two actions for sorting purposes. Return negative, zero, or
  317. ** positive if the first action is less than, equal to, or greater than
  318. ** the first
  319. */
  320. static int actioncmp(
  321. struct action *ap1,
  322. struct action *ap2
  323. ){
  324. int rc;
  325. rc = ap1->sp->index - ap2->sp->index;
  326. if( rc==0 ){
  327. rc = (int)ap1->type - (int)ap2->type;
  328. }
  329. if( rc==0 && ap1->type==REDUCE ){
  330. rc = ap1->x.rp->index - ap2->x.rp->index;
  331. }
  332. return rc;
  333. }
  334. /* Sort parser actions */
  335. static struct action *Action_sort(
  336. struct action *ap
  337. ){
  338. ap = (struct action *)msort((char *)ap,(char **)&ap->next,
  339. (int(*)(const char*,const char*))actioncmp);
  340. return ap;
  341. }
  342. void Action_add(app,type,sp,arg)
  343. struct action **app;
  344. enum e_action type;
  345. struct symbol *sp;
  346. char *arg;
  347. {
  348. struct action *new;
  349. new = Action_new();
  350. new->next = *app;
  351. *app = new;
  352. new->type = type;
  353. new->sp = sp;
  354. if( type==SHIFT ){
  355. new->x.stp = (struct state *)arg;
  356. }else{
  357. new->x.rp = (struct rule *)arg;
  358. }
  359. }
  360. /********************** New code to implement the "acttab" module ***********/
  361. /*
  362. ** This module implements routines use to construct the yy_action[] table.
  363. */
  364. /*
  365. ** The state of the yy_action table under construction is an instance of
  366. ** the following structure
  367. */
  368. typedef struct acttab acttab;
  369. struct acttab {
  370. int nAction; /* Number of used slots in aAction[] */
  371. int nActionAlloc; /* Slots allocated for aAction[] */
  372. struct {
  373. int lookahead; /* Value of the lookahead token */
  374. int action; /* Action to take on the given lookahead */
  375. } *aAction, /* The yy_action[] table under construction */
  376. *aLookahead; /* A single new transaction set */
  377. int mnLookahead; /* Minimum aLookahead[].lookahead */
  378. int mnAction; /* Action associated with mnLookahead */
  379. int mxLookahead; /* Maximum aLookahead[].lookahead */
  380. int nLookahead; /* Used slots in aLookahead[] */
  381. int nLookaheadAlloc; /* Slots allocated in aLookahead[] */
  382. };
  383. /* Return the number of entries in the yy_action table */
  384. #define acttab_size(X) ((X)->nAction)
  385. /* The value for the N-th entry in yy_action */
  386. #define acttab_yyaction(X,N) ((X)->aAction[N].action)
  387. /* The value for the N-th entry in yy_lookahead */
  388. #define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead)
  389. /* Free all memory associated with the given acttab */
  390. void acttab_free(acttab *p){
  391. free( p->aAction );
  392. free( p->aLookahead );
  393. free( p );
  394. }
  395. /* Allocate a new acttab structure */
  396. acttab *acttab_alloc(void){
  397. acttab *p = calloc( 1, sizeof(*p) );
  398. if( p==0 ){
  399. fprintf(stderr,"Unable to allocate memory for a new acttab.");
  400. exit(1);
  401. }
  402. memset(p, 0, sizeof(*p));
  403. return p;
  404. }
  405. /* Add a new action to the current transaction set
  406. */
  407. void acttab_action(acttab *p, int lookahead, int action){
  408. if( p->nLookahead>=p->nLookaheadAlloc ){
  409. p->nLookaheadAlloc += 25;
  410. p->aLookahead = realloc( p->aLookahead,
  411. sizeof(p->aLookahead[0])*p->nLookaheadAlloc );
  412. if( p->aLookahead==0 ){
  413. fprintf(stderr,"malloc failed\n");
  414. exit(1);
  415. }
  416. }
  417. if( p->nLookahead==0 ){
  418. p->mxLookahead = lookahead;
  419. p->mnLookahead = lookahead;
  420. p->mnAction = action;
  421. }else{
  422. if( p->mxLookahead<lookahead ) p->mxLookahead = lookahead;
  423. if( p->mnLookahead>lookahead ){
  424. p->mnLookahead = lookahead;
  425. p->mnAction = action;
  426. }
  427. }
  428. p->aLookahead[p->nLookahead].lookahead = lookahead;
  429. p->aLookahead[p->nLookahead].action = action;
  430. p->nLookahead++;
  431. }
  432. /*
  433. ** Add the transaction set built up with prior calls to acttab_action()
  434. ** into the current action table. Then reset the transaction set back
  435. ** to an empty set in preparation for a new round of acttab_action() calls.
  436. **
  437. ** Return the offset into the action table of the new transaction.
  438. */
  439. int acttab_insert(acttab *p){
  440. int i, j, k, n;
  441. assert( p->nLookahead>0 );
  442. /* Make sure we have enough space to hold the expanded action table
  443. ** in the worst case. The worst case occurs if the transaction set
  444. ** must be appended to the current action table
  445. */
  446. n = p->mxLookahead + 1;
  447. if( p->nAction + n >= p->nActionAlloc ){
  448. int oldAlloc = p->nActionAlloc;
  449. p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20;
  450. p->aAction = realloc( p->aAction,
  451. sizeof(p->aAction[0])*p->nActionAlloc);
  452. if( p->aAction==0 ){
  453. fprintf(stderr,"malloc failed\n");
  454. exit(1);
  455. }
  456. for(i=oldAlloc; i<p->nActionAlloc; i++){
  457. p->aAction[i].lookahead = -1;
  458. p->aAction[i].action = -1;
  459. }
  460. }
  461. /* Scan the existing action table looking for an offset where we can
  462. ** insert the current transaction set. Fall out of the loop when that
  463. ** offset is found. In the worst case, we fall out of the loop when
  464. ** i reaches p->nAction, which means we append the new transaction set.
  465. **
  466. ** i is the index in p->aAction[] where p->mnLookahead is inserted.
  467. */
  468. for(i=0; i<p->nAction+p->mnLookahead; i++){
  469. if( p->aAction[i].lookahead<0 ){
  470. for(j=0; j<p->nLookahead; j++){
  471. k = p->aLookahead[j].lookahead - p->mnLookahead + i;
  472. if( k<0 ) break;
  473. if( p->aAction[k].lookahead>=0 ) break;
  474. }
  475. if( j<p->nLookahead ) continue;
  476. for(j=0; j<p->nAction; j++){
  477. if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
  478. }
  479. if( j==p->nAction ){
  480. break; /* Fits in empty slots */
  481. }
  482. }else if( p->aAction[i].lookahead==p->mnLookahead ){
  483. if( p->aAction[i].action!=p->mnAction ) continue;
  484. for(j=0; j<p->nLookahead; j++){
  485. k = p->aLookahead[j].lookahead - p->mnLookahead + i;
  486. if( k<0 || k>=p->nAction ) break;
  487. if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break;
  488. if( p->aLookahead[j].action!=p->aAction[k].action ) break;
  489. }
  490. if( j<p->nLookahead ) continue;
  491. n = 0;
  492. for(j=0; j<p->nAction; j++){
  493. if( p->aAction[j].lookahead<0 ) continue;
  494. if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++;
  495. }
  496. if( n==p->nLookahead ){
  497. break; /* Same as a prior transaction set */
  498. }
  499. }
  500. }
  501. /* Insert transaction set at index i. */
  502. for(j=0; j<p->nLookahead; j++){
  503. k = p->aLookahead[j].lookahead - p->mnLookahead + i;
  504. p->aAction[k] = p->aLookahead[j];
  505. if( k>=p->nAction ) p->nAction = k+1;
  506. }
  507. p->nLookahead = 0;
  508. /* Return the offset that is added to the lookahead in order to get the
  509. ** index into yy_action of the action */
  510. return i - p->mnLookahead;
  511. }
  512. /********************** From the file "build.c" *****************************/
  513. /*
  514. ** Routines to construction the finite state machine for the LEMON
  515. ** parser generator.
  516. */
  517. /* Find a precedence symbol of every rule in the grammar.
  518. **
  519. ** Those rules which have a precedence symbol coded in the input
  520. ** grammar using the "[symbol]" construct will already have the
  521. ** rp->precsym field filled. Other rules take as their precedence
  522. ** symbol the first RHS symbol with a defined precedence. If there
  523. ** are not RHS symbols with a defined precedence, the precedence
  524. ** symbol field is left blank.
  525. */
  526. void FindRulePrecedences(xp)
  527. struct lemon *xp;
  528. {
  529. struct rule *rp;
  530. for(rp=xp->rule; rp; rp=rp->next){
  531. if( rp->precsym==0 ){
  532. int i, j;
  533. for(i=0; i<rp->nrhs && rp->precsym==0; i++){
  534. struct symbol *sp = rp->rhs[i];
  535. if( sp->type==MULTITERMINAL ){
  536. for(j=0; j<sp->nsubsym; j++){
  537. if( sp->subsym[j]->prec>=0 ){
  538. rp->precsym = sp->subsym[j];
  539. break;
  540. }
  541. }
  542. }else if( sp->prec>=0 ){
  543. rp->precsym = rp->rhs[i];
  544. }
  545. }
  546. }
  547. }
  548. return;
  549. }
  550. /* Find all nonterminals which will generate the empty string.
  551. ** Then go back and compute the first sets of every nonterminal.
  552. ** The first set is the set of all terminal symbols which can begin
  553. ** a string generated by that nonterminal.
  554. */
  555. void FindFirstSets(lemp)
  556. struct lemon *lemp;
  557. {
  558. int i, j;
  559. struct rule *rp;
  560. int progress;
  561. for(i=0; i<lemp->nsymbol; i++){
  562. lemp->symbols[i]->lambda = LEMON_FALSE;
  563. }
  564. for(i=lemp->nterminal; i<lemp->nsymbol; i++){
  565. lemp->symbols[i]->firstset = SetNew();
  566. }
  567. /* First compute all lambdas */
  568. do{
  569. progress = 0;
  570. for(rp=lemp->rule; rp; rp=rp->next){
  571. if( rp->lhs->lambda ) continue;
  572. for(i=0; i<rp->nrhs; i++){
  573. struct symbol *sp = rp->rhs[i];
  574. if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break;
  575. }
  576. if( i==rp->nrhs ){
  577. rp->lhs->lambda = LEMON_TRUE;
  578. progress = 1;
  579. }
  580. }
  581. }while( progress );
  582. /* Now compute all first sets */
  583. do{
  584. struct symbol *s1, *s2;
  585. progress = 0;
  586. for(rp=lemp->rule; rp; rp=rp->next){
  587. s1 = rp->lhs;
  588. for(i=0; i<rp->nrhs; i++){
  589. s2 = rp->rhs[i];
  590. if( s2->type==TERMINAL ){
  591. progress += SetAdd(s1->firstset,s2->index);
  592. break;
  593. }else if( s2->type==MULTITERMINAL ){
  594. for(j=0; j<s2->nsubsym; j++){
  595. progress += SetAdd(s1->firstset,s2->subsym[j]->index);
  596. }
  597. break;
  598. }else if( s1==s2 ){
  599. if( s1->lambda==LEMON_FALSE ) break;
  600. }else{
  601. progress += SetUnion(s1->firstset,s2->firstset);
  602. if( s2->lambda==LEMON_FALSE ) break;
  603. }
  604. }
  605. }
  606. }while( progress );
  607. return;
  608. }
  609. /* Compute all LR(0) states for the grammar. Links
  610. ** are added to between some states so that the LR(1) follow sets
  611. ** can be computed later.
  612. */
  613. PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */
  614. void FindStates(lemp)
  615. struct lemon *lemp;
  616. {
  617. struct symbol *sp;
  618. struct rule *rp;
  619. Configlist_init();
  620. /* Find the start symbol */
  621. if( lemp->start ){
  622. sp = Symbol_find(lemp->start);
  623. if( sp==0 ){
  624. ErrorMsg(lemp->filename,0,
  625. "The specified start symbol \"%s\" is not \
  626. in a nonterminal of the grammar. \"%s\" will be used as the start \
  627. symbol instead.",lemp->start,lemp->rule->lhs->name);
  628. lemp->errorcnt++;
  629. sp = lemp->rule->lhs;
  630. }
  631. }else{
  632. sp = lemp->rule->lhs;
  633. }
  634. /* Make sure the start symbol doesn't occur on the right-hand side of
  635. ** any rule. Report an error if it does. (YACC would generate a new
  636. ** start symbol in this case.) */
  637. for(rp=lemp->rule; rp; rp=rp->next){
  638. int i;
  639. for(i=0; i<rp->nrhs; i++){
  640. if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */
  641. ErrorMsg(lemp->filename,0,
  642. "The start symbol \"%s\" occurs on the \
  643. right-hand side of a rule. This will result in a parser which \
  644. does not work properly.",sp->name);
  645. lemp->errorcnt++;
  646. }
  647. }
  648. }
  649. /* The basis configuration set for the first state
  650. ** is all rules which have the start symbol as their
  651. ** left-hand side */
  652. for(rp=sp->rule; rp; rp=rp->nextlhs){
  653. struct config *newcfp;
  654. rp->lhsStart = 1;
  655. newcfp = Configlist_addbasis(rp,0);
  656. SetAdd(newcfp->fws,0);
  657. }
  658. /* Compute the first state. All other states will be
  659. ** computed automatically during the computation of the first one.
  660. ** The returned pointer to the first state is not used. */
  661. (void)getstate(lemp);
  662. return;
  663. }
  664. /* Return a pointer to a state which is described by the configuration
  665. ** list which has been built from calls to Configlist_add.
  666. */
  667. PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */
  668. PRIVATE struct state *getstate(lemp)
  669. struct lemon *lemp;
  670. {
  671. struct config *cfp, *bp;
  672. struct state *stp;
  673. /* Extract the sorted basis of the new state. The basis was constructed
  674. ** by prior calls to "Configlist_addbasis()". */
  675. Configlist_sortbasis();
  676. bp = Configlist_basis();
  677. /* Get a state with the same basis */
  678. stp = State_find(bp);
  679. if( stp ){
  680. /* A state with the same basis already exists! Copy all the follow-set
  681. ** propagation links from the state under construction into the
  682. ** preexisting state, then return a pointer to the preexisting state */
  683. struct config *x, *y;
  684. for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){
  685. Plink_copy(&y->bplp,x->bplp);
  686. Plink_delete(x->fplp);
  687. x->fplp = x->bplp = 0;
  688. }
  689. cfp = Configlist_return();
  690. Configlist_eat(cfp);
  691. }else{
  692. /* This really is a new state. Construct all the details */
  693. Configlist_closure(lemp); /* Compute the configuration closure */
  694. Configlist_sort(); /* Sort the configuration closure */
  695. cfp = Configlist_return(); /* Get a pointer to the config list */
  696. stp = State_new(); /* A new state structure */
  697. MemoryCheck(stp);
  698. stp->bp = bp; /* Remember the configuration basis */
  699. stp->cfp = cfp; /* Remember the configuration closure */
  700. stp->statenum = lemp->nstate++; /* Every state gets a sequence number */
  701. stp->ap = 0; /* No actions, yet. */
  702. State_insert(stp,stp->bp); /* Add to the state table */
  703. buildshifts(lemp,stp); /* Recursively compute successor states */
  704. }
  705. return stp;
  706. }
  707. /*
  708. ** Return true if two symbols are the same.
  709. */
  710. int same_symbol(a,b)
  711. struct symbol *a;
  712. struct symbol *b;
  713. {
  714. int i;
  715. if( a==b ) return 1;
  716. if( a->type!=MULTITERMINAL ) return 0;
  717. if( b->type!=MULTITERMINAL ) return 0;
  718. if( a->nsubsym!=b->nsubsym ) return 0;
  719. for(i=0; i<a->nsubsym; i++){
  720. if( a->subsym[i]!=b->subsym[i] ) return 0;
  721. }
  722. return 1;
  723. }
  724. /* Construct all successor states to the given state. A "successor"
  725. ** state is any state which can be reached by a shift action.
  726. */
  727. PRIVATE void buildshifts(lemp,stp)
  728. struct lemon *lemp;
  729. struct state *stp; /* The state from which successors are computed */
  730. {
  731. struct config *cfp; /* For looping thru the config closure of "stp" */
  732. struct config *bcfp; /* For the inner loop on config closure of "stp" */
  733. struct config *new; /* */
  734. struct symbol *sp; /* Symbol following the dot in configuration "cfp" */
  735. struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */
  736. struct state *newstp; /* A pointer to a successor state */
  737. /* Each configuration becomes complete after it contibutes to a successor
  738. ** state. Initially, all configurations are incomplete */
  739. for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE;
  740. /* Loop through all configurations of the state "stp" */
  741. for(cfp=stp->cfp; cfp; cfp=cfp->next){
  742. if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */
  743. if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */
  744. Configlist_reset(); /* Reset the new config set */
  745. sp = cfp->rp->rhs[cfp->dot]; /* Symbol after the dot */
  746. /* For every configuration in the state "stp" which has the symbol "sp"
  747. ** following its dot, add the same configuration to the basis set under
  748. ** construction but with the dot shifted one symbol to the right. */
  749. for(bcfp=cfp; bcfp; bcfp=bcfp->next){
  750. if( bcfp->status==COMPLETE ) continue; /* Already used */
  751. if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */
  752. bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */
  753. if( !same_symbol(bsp,sp) ) continue; /* Must be same as for "cfp" */
  754. bcfp->status = COMPLETE; /* Mark this config as used */
  755. new = Configlist_addbasis(bcfp->rp,bcfp->dot+1);
  756. Plink_add(&new->bplp,bcfp);
  757. }
  758. /* Get a pointer to the state described by the basis configuration set
  759. ** constructed in the preceding loop */
  760. newstp = getstate(lemp);
  761. /* The state "newstp" is reached from the state "stp" by a shift action
  762. ** on the symbol "sp" */
  763. if( sp->type==MULTITERMINAL ){
  764. int i;
  765. for(i=0; i<sp->nsubsym; i++){
  766. Action_add(&stp->ap,SHIFT,sp->subsym[i],(char*)newstp);
  767. }
  768. }else{
  769. Action_add(&stp->ap,SHIFT,sp,(char *)newstp);
  770. }
  771. }
  772. }
  773. /*
  774. ** Construct the propagation links
  775. */
  776. void FindLinks(lemp)
  777. struct lemon *lemp;
  778. {
  779. int i;
  780. struct config *cfp, *other;
  781. struct state *stp;
  782. struct plink *plp;
  783. /* Housekeeping detail:
  784. ** Add to every propagate link a pointer back to the state to
  785. ** which the link is attached. */
  786. for(i=0; i<lemp->nstate; i++){
  787. stp = lemp->sorted[i];
  788. for(cfp=stp->cfp; cfp; cfp=cfp->next){
  789. cfp->stp = stp;
  790. }
  791. }
  792. /* Convert all backlinks into forward links. Only the forward
  793. ** links are used in the follow-set computation. */
  794. for(i=0; i<lemp->nstate; i++){
  795. stp = lemp->sorted[i];
  796. for(cfp=stp->cfp; cfp; cfp=cfp->next){
  797. for(plp=cfp->bplp; plp; plp=plp->next){
  798. other = plp->cfp;
  799. Plink_add(&other->fplp,cfp);
  800. }
  801. }
  802. }
  803. }
  804. /* Compute all followsets.
  805. **
  806. ** A followset is the set of all symbols which can come immediately
  807. ** after a configuration.
  808. */
  809. void FindFollowSets(lemp)
  810. struct lemon *lemp;
  811. {
  812. int i;
  813. struct config *cfp;
  814. struct plink *plp;
  815. int progress;
  816. int change;
  817. for(i=0; i<lemp->nstate; i++){
  818. for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
  819. cfp->status = INCOMPLETE;
  820. }
  821. }
  822. do{
  823. progress = 0;
  824. for(i=0; i<lemp->nstate; i++){
  825. for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
  826. if( cfp->status==COMPLETE ) continue;
  827. for(plp=cfp->fplp; plp; plp=plp->next){
  828. change = SetUnion(plp->cfp->fws,cfp->fws);
  829. if( change ){
  830. plp->cfp->status = INCOMPLETE;
  831. progress = 1;
  832. }
  833. }
  834. cfp->status = COMPLETE;
  835. }
  836. }
  837. }while( progress );
  838. }
  839. static int resolve_conflict();
  840. /* Compute the reduce actions, and resolve conflicts.
  841. */
  842. void FindActions(lemp)
  843. struct lemon *lemp;
  844. {
  845. int i,j;
  846. struct config *cfp;
  847. struct state *stp;
  848. struct symbol *sp;
  849. struct rule *rp;
  850. /* Add all of the reduce actions
  851. ** A reduce action is added for each element of the followset of
  852. ** a configuration which has its dot at the extreme right.
  853. */
  854. for(i=0; i<lemp->nstate; i++){ /* Loop over all states */
  855. stp = lemp->sorted[i];
  856. for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */
  857. if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */
  858. for(j=0; j<lemp->nterminal; j++){
  859. if( SetFind(cfp->fws,j) ){
  860. /* Add a reduce action to the state "stp" which will reduce by the
  861. ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */
  862. Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
  863. }
  864. }
  865. }
  866. }
  867. }
  868. /* Add the accepting token */
  869. if( lemp->start ){
  870. sp = Symbol_find(lemp->start);
  871. if( sp==0 ) sp = lemp->rule->lhs;
  872. }else{
  873. sp = lemp->rule->lhs;
  874. }
  875. /* Add to the first state (which is always the starting state of the
  876. ** finite state machine) an action to ACCEPT if the lookahead is the
  877. ** start nonterminal. */
  878. Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0);
  879. /* Resolve conflicts */
  880. for(i=0; i<lemp->nstate; i++){
  881. struct action *ap, *nap;
  882. struct state *stp;
  883. stp = lemp->sorted[i];
  884. /* assert( stp->ap ); */
  885. stp->ap = Action_sort(stp->ap);
  886. for(ap=stp->ap; ap && ap->next; ap=ap->next){
  887. for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
  888. /* The two actions "ap" and "nap" have the same lookahead.
  889. ** Figure out which one should be used */
  890. lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym);
  891. }
  892. }
  893. }
  894. /* Report an error for each rule that can never be reduced. */
  895. for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE;
  896. for(i=0; i<lemp->nstate; i++){
  897. struct action *ap;
  898. for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
  899. if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE;
  900. }
  901. }
  902. for(rp=lemp->rule; rp; rp=rp->next){
  903. if( rp->canReduce ) continue;
  904. ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n");
  905. lemp->errorcnt++;
  906. }
  907. }
  908. /* Resolve a conflict between the two given actions. If the
  909. ** conflict can't be resolved, return non-zero.
  910. **
  911. ** NO LONGER TRUE:
  912. ** To resolve a conflict, first look to see if either action
  913. ** is on an error rule. In that case, take the action which
  914. ** is not associated with the error rule. If neither or both
  915. ** actions are associated with an error rule, then try to
  916. ** use precedence to resolve the conflict.
  917. **
  918. ** If either action is a SHIFT, then it must be apx. This
  919. ** function won't work if apx->type==REDUCE and apy->type==SHIFT.
  920. */
  921. static int resolve_conflict(apx,apy,errsym)
  922. struct action *apx;
  923. struct action *apy;
  924. struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
  925. {
  926. struct symbol *spx, *spy;
  927. int errcnt = 0;
  928. assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */
  929. if( apx->type==SHIFT && apy->type==SHIFT ){
  930. apy->type = SSCONFLICT;
  931. errcnt++;
  932. }
  933. if( apx->type==SHIFT && apy->type==REDUCE ){
  934. spx = apx->sp;
  935. spy = apy->x.rp->precsym;
  936. if( spy==0 || spx->prec<0 || spy->prec<0 ){
  937. /* Not enough precedence information. */
  938. apy->type = SRCONFLICT;
  939. errcnt++;
  940. }else if( spx->prec>spy->prec ){ /* Lower precedence wins */
  941. apy->type = RD_RESOLVED;
  942. }else if( spx->prec<spy->prec ){
  943. apx->type = SH_RESOLVED;
  944. }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */
  945. apy->type = RD_RESOLVED; /* associativity */
  946. }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */
  947. apx->type = SH_RESOLVED;
  948. }else{
  949. assert( spx->prec==spy->prec && spx->assoc==NONE );
  950. apy->type = SRCONFLICT;
  951. errcnt++;
  952. }
  953. }else if( apx->type==REDUCE && apy->type==REDUCE ){
  954. spx = apx->x.rp->precsym;
  955. spy = apy->x.rp->precsym;
  956. if( spx==0 || spy==0 || spx->prec<0 ||
  957. spy->prec<0 || spx->prec==spy->prec ){
  958. apy->type = RRCONFLICT;
  959. errcnt++;
  960. }else if( spx->prec>spy->prec ){
  961. apy->type = RD_RESOLVED;
  962. }else if( spx->prec<spy->prec ){
  963. apx->type = RD_RESOLVED;
  964. }
  965. }else{
  966. assert(
  967. apx->type==SH_RESOLVED ||
  968. apx->type==RD_RESOLVED ||
  969. apx->type==SSCONFLICT ||
  970. apx->type==SRCONFLICT ||
  971. apx->type==RRCONFLICT ||
  972. apy->type==SH_RESOLVED ||
  973. apy->type==RD_RESOLVED ||
  974. apy->type==SSCONFLICT ||
  975. apy->type==SRCONFLICT ||
  976. apy->type==RRCONFLICT
  977. );
  978. /* The REDUCE/SHIFT case cannot happen because SHIFTs come before
  979. ** REDUCEs on the list. If we reach this point it must be because
  980. ** the parser conflict had already been resolved. */
  981. }
  982. return errcnt;
  983. }
  984. /********************* From the file "configlist.c" *************************/
  985. /*
  986. ** Routines to processing a configuration list and building a state
  987. ** in the LEMON parser generator.
  988. */
  989. static struct config *freelist = 0; /* List of free configurations */
  990. static struct config *current = 0; /* Top of list of configurations */
  991. static struct config **currentend = 0; /* Last on list of configs */
  992. static struct config *basis = 0; /* Top of list of basis configs */
  993. static struct config **basisend = 0; /* End of list of basis configs */
  994. /* Return a pointer to a new configuration */
  995. PRIVATE struct config *newconfig(){
  996. struct config *new;
  997. if( freelist==0 ){
  998. int i;
  999. int amt = 3;
  1000. freelist = (struct config *)calloc( amt, sizeof(struct config) );
  1001. if( freelist==0 ){
  1002. fprintf(stderr,"Unable to allocate memory for a new configuration.");
  1003. exit(1);
  1004. }
  1005. for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
  1006. freelist[amt-1].next = 0;
  1007. }
  1008. new = freelist;
  1009. freelist = freelist->next;
  1010. return new;
  1011. }
  1012. /* The configuration "old" is no longer used */
  1013. PRIVATE void deleteconfig(old)
  1014. struct config *old;
  1015. {
  1016. old->next = freelist;
  1017. freelist = old;
  1018. }
  1019. /* Initialized the configuration list builder */
  1020. void Configlist_init(){
  1021. current = 0;
  1022. currentend = &current;
  1023. basis = 0;
  1024. basisend = &basis;
  1025. Configtable_init();
  1026. return;
  1027. }
  1028. /* Initialized the configuration list builder */
  1029. void Configlist_reset(){
  1030. current = 0;
  1031. currentend = &current;
  1032. basis = 0;
  1033. basisend = &basis;
  1034. Configtable_clear(0);
  1035. return;
  1036. }
  1037. /* Add another configuration to the configuration list */
  1038. struct config *Configlist_add(rp,dot)
  1039. struct rule *rp; /* The rule */
  1040. int dot; /* Index into the RHS of the rule where the dot goes */
  1041. {
  1042. struct config *cfp, model;
  1043. assert( currentend!=0 );
  1044. model.rp = rp;
  1045. model.dot = dot;
  1046. cfp = Configtable_find(&model);
  1047. if( cfp==0 ){
  1048. cfp = newconfig();
  1049. cfp->rp = rp;
  1050. cfp->dot = dot;
  1051. cfp->fws = SetNew();
  1052. cfp->stp = 0;
  1053. cfp->fplp = cfp->bplp = 0;
  1054. cfp->next = 0;
  1055. cfp->bp = 0;
  1056. *currentend = cfp;
  1057. currentend = &cfp->next;
  1058. Configtable_insert(cfp);
  1059. }
  1060. return cfp;
  1061. }
  1062. /* Add a basis configuration to the configuration list */
  1063. struct config *Configlist_addbasis(rp,dot)
  1064. struct rule *rp;
  1065. int dot;
  1066. {
  1067. struct config *cfp, model;
  1068. assert( basisend!=0 );
  1069. assert( currentend!=0 );
  1070. model.rp = rp;
  1071. model.dot = dot;
  1072. cfp = Configtable_find(&model);
  1073. if( cfp==0 ){
  1074. cfp = newconfig();
  1075. cfp->rp = rp;
  1076. cfp->dot = dot;
  1077. cfp->fws = SetNew();
  1078. cfp->stp = 0;
  1079. cfp->fplp = cfp->bplp = 0;
  1080. cfp->next = 0;
  1081. cfp->bp = 0;
  1082. *currentend = cfp;
  1083. currentend = &cfp->next;
  1084. *basisend = cfp;
  1085. basisend = &cfp->bp;
  1086. Configtable_insert(cfp);
  1087. }
  1088. return cfp;
  1089. }
  1090. /* Compute the closure of the configuration list */
  1091. void Configlist_closure(lemp)
  1092. struct lemon *lemp;
  1093. {
  1094. struct config *cfp, *newcfp;
  1095. struct rule *rp, *newrp;
  1096. struct symbol *sp, *xsp;
  1097. int i, dot;
  1098. assert( currentend!=0 );
  1099. for(cfp=current; cfp; cfp=cfp->next){
  1100. rp = cfp->rp;
  1101. dot = cfp->dot;
  1102. if( dot>=rp->nrhs ) continue;
  1103. sp = rp->rhs[dot];
  1104. if( sp->type==NONTERMINAL ){
  1105. if( sp->rule==0 && sp!=lemp->errsym ){
  1106. ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.",
  1107. sp->name);
  1108. lemp->errorcnt++;
  1109. }
  1110. for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){
  1111. newcfp = Configlist_add(newrp,0);
  1112. for(i=dot+1; i<rp->nrhs; i++){
  1113. xsp = rp->rhs[i];
  1114. if( xsp->type==TERMINAL ){
  1115. SetAdd(newcfp->fws,xsp->index);
  1116. break;
  1117. }else if( xsp->type==MULTITERMINAL ){
  1118. int k;
  1119. for(k=0; k<xsp->nsubsym; k++){
  1120. SetAdd(newcfp->fws, xsp->subsym[k]->index);
  1121. }
  1122. break;
  1123. }else{
  1124. SetUnion(newcfp->fws,xsp->firstset);
  1125. if( xsp->lambda==LEMON_FALSE ) break;
  1126. }
  1127. }
  1128. if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
  1129. }
  1130. }
  1131. }
  1132. return;
  1133. }
  1134. /* Sort the configuration list */
  1135. void Configlist_sort(){
  1136. current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp);
  1137. currentend = 0;
  1138. return;
  1139. }
  1140. /* Sort the basis configuration list */
  1141. void Configlist_sortbasis(){
  1142. basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp);
  1143. basisend = 0;
  1144. return;
  1145. }
  1146. /* Return a pointer to the head of the configuration list and
  1147. ** reset the list */
  1148. struct config *Configlist_return(){
  1149. struct config *old;
  1150. old = current;
  1151. current = 0;
  1152. currentend = 0;
  1153. return old;
  1154. }
  1155. /* Return a pointer to the head of the configuration list and
  1156. ** reset the list */
  1157. struct config *Configlist_basis(){
  1158. struct config *old;
  1159. old = basis;
  1160. basis = 0;
  1161. basisend = 0;
  1162. return old;
  1163. }
  1164. /* Free all elements of the given configuration list */
  1165. void Configlist_eat(cfp)
  1166. struct config *cfp;
  1167. {
  1168. struct config *nextcfp;
  1169. for(; cfp; cfp=nextcfp){
  1170. nextcfp = cfp->next;
  1171. assert( cfp->fplp==0 );
  1172. assert( cfp->bplp==0 );
  1173. if( cfp->fws ) SetFree(cfp->fws);
  1174. deleteconfig(cfp);
  1175. }
  1176. return;
  1177. }
  1178. /***************** From the file "error.c" *********************************/
  1179. /*
  1180. ** Code for printing error message.
  1181. */
  1182. /* Find a good place to break "msg" so that its length is at least "min"
  1183. ** but no more than "max". Make the point as close to max as possible.
  1184. */
  1185. static int findbreak(msg,min,max)
  1186. char *msg;
  1187. int min;
  1188. int max;
  1189. {
  1190. int i,spot;
  1191. char c;
  1192. for(i=spot=min; i<=max; i++){
  1193. c = msg[i];
  1194. if( c=='\t' ) msg[i] = ' ';
  1195. if( c=='\n' ){ msg[i] = ' '; spot = i; break; }
  1196. if( c==0 ){ spot = i; break; }
  1197. if( c=='-' && i<max-1 ) spot = i+1;
  1198. if( c==' ' ) spot = i;
  1199. }
  1200. return spot;
  1201. }
  1202. /*
  1203. ** The error message is split across multiple lines if necessary. The
  1204. ** splits occur at a space, if there is a space available near the end
  1205. ** of the line.
  1206. */
  1207. #define ERRMSGSIZE 10000 /* Hope this is big enough. No way to error check */
  1208. #define LINEWIDTH 79 /* Max width of any output line */
  1209. #define PREFIXLIMIT 30 /* Max width of the prefix on each line */
  1210. void ErrorMsg(const char *filename, int lineno, const char *format, ...){
  1211. char errmsg[ERRMSGSIZE];
  1212. char prefix[PREFIXLIMIT+10];
  1213. int errmsgsize;
  1214. int prefixsize;
  1215. int availablewidth;
  1216. va_list ap;
  1217. int end, restart, base;
  1218. va_start(ap, format);
  1219. /* Prepare a prefix to be prepended to every output line */
  1220. if( lineno>0 ){
  1221. sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno);
  1222. }else{
  1223. sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename);
  1224. }
  1225. prefixsize = lemonStrlen(prefix);
  1226. availablewidth = LINEWIDTH - prefixsize;
  1227. /* Generate the error message */
  1228. vsprintf(errmsg,format,ap);
  1229. va_end(ap);
  1230. errmsgsize = lemonStrlen(errmsg);
  1231. /* Remove trailing '\n's from the error message. */
  1232. while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){
  1233. errmsg[--errmsgsize] = 0;
  1234. }
  1235. /* Print the error message */
  1236. base = 0;
  1237. while( errmsg[base]!=0 ){
  1238. end = restart = findbreak(&errmsg[base],0,availablewidth);
  1239. restart += base;
  1240. while( errmsg[restart]==' ' ) restart++;
  1241. fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]);
  1242. base = restart;
  1243. }
  1244. }
  1245. /**************** From the file "main.c" ************************************/
  1246. /*
  1247. ** Main program file for the LEMON parser generator.
  1248. */
  1249. /* Report an out-of-memory condition and abort. This function
  1250. ** is used mostly by the "MemoryCheck" macro in struct.h
  1251. */
  1252. void memory_error(){
  1253. fprintf(stderr,"Out of memory. Aborting...\n");
  1254. exit(1);
  1255. }
  1256. static int nDefine = 0; /* Number of -D options on the command line */
  1257. static char **azDefine = 0; /* Name of the -D macros */
  1258. /* This routine is called with the argument to each -D command-line option.
  1259. ** Add the macro defined to the azDefine array.
  1260. */
  1261. static void handle_D_option(char *z){
  1262. char **paz;
  1263. nDefine++;
  1264. azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine);
  1265. if( azDefine==0 ){
  1266. fprintf(stderr,"out of memory\n");
  1267. exit(1);
  1268. }
  1269. paz = &azDefine[nDefine-1];
  1270. *paz = malloc( lemonStrlen(z)+1 );
  1271. if( *paz==0 ){
  1272. fprintf(stderr,"out of memory\n");
  1273. exit(1);
  1274. }
  1275. strcpy(*paz, z);
  1276. for(z=*paz; *z && *z!='='; z++){}
  1277. *z = 0;
  1278. }
  1279. /* The main program. Parse the command line and do it... */
  1280. int main(argc,argv)
  1281. int argc;
  1282. char **argv;
  1283. {
  1284. static int version = 0;
  1285. static int rpflag = 0;
  1286. static int basisflag = 0;
  1287. static int compress = 0;
  1288. static int quiet = 0;
  1289. static int statistics = 0;
  1290. static int mhflag = 0;
  1291. static int nolinenosflag = 0;
  1292. static struct s_options options[] = {
  1293. {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},
  1294. {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},
  1295. {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},
  1296. {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},
  1297. {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."},
  1298. {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."},
  1299. {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."},
  1300. {OPT_FLAG, "s", (char*)&statistics,
  1301. "Print parser stats to standard output."},
  1302. {OPT_FLAG, "x", (char*)&version, "Print the version number."},
  1303. {OPT_FLAG,0,0,0}
  1304. };
  1305. int i;
  1306. struct lemon lem;
  1307. OptInit(argv,options,stderr);
  1308. if( version ){
  1309. printf("Lemon version 1.0\n");
  1310. exit(0);
  1311. }
  1312. if( OptNArgs()!=1 ){
  1313. fprintf(stderr,"Exactly one filename argument is required.\n");
  1314. exit(1);
  1315. }
  1316. memset(&lem, 0, sizeof(lem));
  1317. lem.errorcnt = 0;
  1318. /* Initialize the machine */
  1319. Strsafe_init();
  1320. Symbol_init();
  1321. State_init();
  1322. lem.argv0 = argv[0];
  1323. lem.filename = OptArg(0);
  1324. lem.basisflag = basisflag;
  1325. lem.nolinenosflag = nolinenosflag;
  1326. Symbol_new("$");
  1327. lem.errsym = Symbol_new("error");
  1328. lem.errsym->useCnt = 0;
  1329. /* Parse the input file */
  1330. Parse(&lem);
  1331. if( lem.errorcnt ) exit(lem.errorcnt);
  1332. if( lem.nrule==0 ){
  1333. fprintf(stderr,"Empty grammar.\n");
  1334. exit(1);
  1335. }
  1336. /* Count and index the symbols of the grammar */
  1337. lem.nsymbol = Symbol_count();
  1338. Symbol_new("{default}");
  1339. lem.symbols = Symbol_arrayof();
  1340. for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
  1341. qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*),
  1342. (int(*)())Symbolcmpp);
  1343. for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
  1344. for(i=1; isupper(lem.symbols[i]->name[0]); i++);
  1345. lem.nterminal = i;
  1346. /* Generate a reprint of the grammar, if requested on the command line */
  1347. if( rpflag ){
  1348. Reprint(&lem);
  1349. }else{
  1350. /* Initialize the size for all follow and first sets */
  1351. SetSize(lem.nterminal+1);
  1352. /* Find the precedence for every production rule (that has one) */
  1353. FindRulePrecedences(&lem);
  1354. /* Compute the lambda-nonterminals and the first-sets for every
  1355. ** nonterminal */
  1356. FindFirstSets(&lem);
  1357. /* Compute all LR(0) states. Also record follow-set propagation
  1358. ** links so that the follow-set can be computed later */
  1359. lem.nstate = 0;
  1360. FindStates(&lem);
  1361. lem.sorted = State_arrayof();
  1362. /* Tie up loose ends on the propagation links */
  1363. FindLinks(&lem);
  1364. /* Compute the follow set of every reducible configuration */
  1365. FindFollowSets(&lem);
  1366. /* Compute the action tables */
  1367. FindActions(&lem);
  1368. /* Compress the action tables */
  1369. if( compress==0 ) CompressTables(&lem);
  1370. /* Reorder and renumber the states so that states with fewer choices
  1371. ** occur at the end. */
  1372. ResortStates(&lem);
  1373. /* Generate a report of the parser generated. (the "y.output" file) */
  1374. if( !quiet ) ReportOutput(&lem);
  1375. /* Generate the source code for the parser */
  1376. ReportTable(&lem, mhflag);
  1377. /* Produce a header file for use by the scanner. (This step is
  1378. ** omitted if the "-m" option is used because makeheaders will
  1379. ** generate the file for us.) */
  1380. if( !mhflag ) ReportHeader(&lem);
  1381. }
  1382. if( statistics ){
  1383. printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n",
  1384. lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule);
  1385. printf(" %d states, %d parser table entries, %d conflicts\n",
  1386. lem.nstate, lem.tablesize, lem.nconflict);
  1387. }
  1388. if( lem.nconflict ){
  1389. fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
  1390. }
  1391. exit(lem.errorcnt + lem.nconflict);
  1392. return (lem.errorcnt + lem.nconflict);
  1393. }
  1394. /******************** From the file "msort.c" *******************************/
  1395. /*
  1396. ** A generic merge-sort program.
  1397. **
  1398. ** USAGE:
  1399. ** Let "ptr" be a pointer to some structure which is at the head of
  1400. ** a null-terminated list. Then to sort the list call:
  1401. **
  1402. ** ptr = msort(ptr,&(ptr->next),cmpfnc);
  1403. **
  1404. ** In the above, "cmpfnc" is a pointer to a function which compares
  1405. ** two instances of the structure and returns an integer, as in
  1406. ** strcmp. The second argument is a pointer to the pointer to the
  1407. ** second element of the linked list. This address is used to compute
  1408. ** the offset to the "next" field within the structure. The offset to
  1409. ** the "next" field must be constant for all structures in the list.
  1410. **
  1411. ** The function returns a new pointer which is the head of the list
  1412. ** after sorting.
  1413. **
  1414. ** ALGORITHM:
  1415. ** …

Large files files are truncated, but you can click here to view the full file