15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains all sources (including headers) to the LEMON 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** LALR(1) parser generator. The sources have been combined into a 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** single file to make it easy to include LEMON in the source tree 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and Makefile of another program. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author of this program disclaims copyright. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __WIN32__ 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if defined(_WIN32) || defined(WIN32) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define __WIN32__ 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __WIN32__ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int access(const char *path, int mode); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define PRIVATE static */ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PRIVATE 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef TEST 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXRHS 5 /* Set low to exercise exception code */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXRHS 1000 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int showPrecedenceConflict = 0; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char **made_files = NULL; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int made_files_count = 0; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int successful_exit = 0; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void LemonAtExit(void) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if we failed, delete (most) files we made, to unconfuse build tools. */ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < made_files_count; i++) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!successful_exit) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove(made_files[i]); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(made_files); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) made_files_count = 0; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) made_files = NULL; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *msort(char*,char**,int(*)(const char*,const char*)); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Compilers are getting increasingly pedantic about type conversions 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** as C evolves ever closer to Ada.... To work around the latest problems 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** we have to define the following variant of strlen(). 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define lemonStrlen(X) ((int)strlen(X)) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* a few forward declarations... */ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rule; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct lemon; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct action; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct action *Action_new(void); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct action *Action_sort(struct action *); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********** From the file "build.h" ************************************/ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindRulePrecedences(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindFirstSets(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindStates(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindLinks(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindFollowSets(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindActions(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********* From the file "configlist.h" *********************************/ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_init(void); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_add(struct rule *, int); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_addbasis(struct rule *, int); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_closure(struct lemon *); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_sort(void); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_sortbasis(void); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_return(void); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_basis(void); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_eat(struct config *); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_reset(void); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********* From the file "error.h" ***************************************/ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ErrorMsg(const char *, int,const char *, ...); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/****** From the file "option.h" ******************************************/ 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum option_type { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR}; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct s_options { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum option_type type; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *label; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *arg; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int OptInit(char**,struct s_options*,FILE*); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int OptNArgs(void); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *OptArg(int); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OptErr(int); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OptPrint(void); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/******** From the file "parse.h" *****************************************/ 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Parse(struct lemon *lemp); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********* From the file "plink.h" ***************************************/ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct plink *Plink_new(void); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Plink_add(struct plink **, struct config *); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Plink_copy(struct plink **, struct plink *); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Plink_delete(struct plink *); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********** From the file "report.h" *************************************/ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Reprint(struct lemon *); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReportOutput(struct lemon *); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReportTable(struct lemon *, int); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReportHeader(struct lemon *); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompressTables(struct lemon *); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResortStates(struct lemon *); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********** From the file "set.h" ****************************************/ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetSize(int); /* All sets will be of size N */ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *SetNew(void); /* A new set for element 0..N */ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetFree(char*); /* Deallocate a set */ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *SetNew(void); /* A new set for element 0..N */ 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SetAdd(char*,int); /* Add element to a set */ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SetUnion(char *,char *); /* A <- A U B, thru element N */ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********** From the file "struct.h" *************************************/ 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Principal data structures for the LEMON parser generator. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Symbols (terminals and nonterminals) of the grammar are stored 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the following: */ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum symbol_type { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TERMINAL, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NONTERMINAL, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MULTITERMINAL 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum e_assoc { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LEFT, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RIGHT, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NONE, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNK 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *name; /* Name of the symbol */ 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index; /* Index number for this symbol */ 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum symbol_type type; /* Symbols are all either TERMINALS or NTs */ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rule; /* Linked list of rules of this (if an NT) */ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *fallback; /* fallback token in case this token doesn't parse */ 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prec; /* Precedence if defined (-1 otherwise) */ 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum e_assoc assoc; /* Associativity if precedence is defined */ 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *firstset; /* First-set for all rules of this symbol */ 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Boolean lambda; /* True if NT and can generate an empty string */ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int useCnt; /* Number of times used */ 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *destructor; /* Code which executes whenever this symbol is 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** popped from the stack during error processing */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int destLineno; /* Line number for start of destructor */ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *datatype; /* The data type of information held by this 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** object. Only used if type==NONTERMINAL */ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dtnum; /* The data type number. In the parser, the value 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** stack is a union. The .yy%d element of this 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** union is the correct data type for this object */ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The following fields are used by MULTITERMINALs only */ 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nsubsym; /* Number of constituent symbols in the MULTI */ 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol **subsym; /* Array of constituent symbols */ 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Each production rule in the grammar is stored in the following 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** structure. */ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rule { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *lhs; /* Left-hand side of the rule */ 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *lhsalias; /* Alias for the LHS (NULL if none) */ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lhsStart; /* True if left-hand side is the start symbol */ 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ruleline; /* Line number for the rule */ 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nrhs; /* Number of RHS symbols */ 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol **rhs; /* The RHS symbols */ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int line; /* Line number at which code begins */ 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *code; /* The code executed when this rule is reduced */ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *precsym; /* Precedence symbol for this rule */ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index; /* An index number for this rule */ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Boolean canReduce; /* True if this rule is ever reduced */ 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *nextlhs; /* Next rule with the same LHS */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *next; /* Next rule in the global list */ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A configuration is a production rule of the grammar together with 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a mark (dot) showing how much of that rule has been processed so far. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Configurations also contain a follow-set which is a list of terminal 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** symbols which are allowed to immediately follow the end of the rule. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Every configuration is recorded as an instance of the following: */ 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum cfgstatus { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPLETE, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INCOMPLETE 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; /* The rule upon which the configuration is based */ 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dot; /* The parse point */ 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *fws; /* Follow-set for this configuration only */ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *fplp; /* Follow-set forward propagation links */ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *bplp; /* Follow-set backwards propagation links */ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; /* Pointer to state which contains this */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum cfgstatus status; /* used during followset and shift computations */ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *next; /* Next configuration in the state */ 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *bp; /* The next basis configuration */ 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum e_action { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHIFT, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACCEPT, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REDUCE, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSCONFLICT, /* A shift/shift conflict */ 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SRCONFLICT, /* Was a reduce, but part of a conflict */ 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RRCONFLICT, /* Was a reduce, but part of a conflict */ 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOT_USED /* Deleted by compression */ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Every shift or reduce operation is stored as one of the following */ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct action { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; /* The look-ahead symbol */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum e_action type; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; /* The new state, if a shift */ 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; /* The rule, if a reduce */ 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } x; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *next; /* Next action for this state */ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *collide; /* Next action with the same hash */ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Each state of the generated parser's finite state machine 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is encoded as an instance of the following structure. */ 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct state { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *bp; /* The basis configurations for this state */ 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp; /* All configurations in this set */ 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int statenum; /* Sequential number for this state */ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap; /* Array of actions for this state */ 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iDflt; /* Default action */ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NO_OFFSET (-2147483647) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A followset propagation link indicates that the contents of one 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** configuration followset should be propagated to another whenever 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the first changes. */ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct plink { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp; /* The configuration to which linked */ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *next; /* The next propagate link */ 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The state vector for the entire parser generator is recorded as 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** follows. (LEMON uses no global variables and makes little use of 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** static variables. Fields in the following structure can be thought 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of as begin global variables in the program.) */ 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct lemon { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state **sorted; /* Table of states sorted by state number */ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rule; /* List of all rules */ 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nstate; /* Number of states */ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nrule; /* Number of rules */ 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nsymbol; /* Number of terminal and nonterminal symbols */ 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nterminal; /* Number of terminal symbols */ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol **symbols; /* Sorted array of pointers to symbols */ 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int errorcnt; /* Number of errors */ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *errsym; /* The error symbol */ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *wildcard; /* Token that matches anything */ 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *name; /* Name of the generated parser */ 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *arg; /* Declaration of the 3th argument to parser */ 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *tokentype; /* Type of terminal symbols in the parser stack */ 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *vartype; /* The default type of non-terminal symbols */ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *start; /* Name of the start symbol for the grammar */ 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *stacksize; /* Size of the parser stack */ 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *include; /* Code to put at the start of the C file */ 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *error; /* Code to execute when an error is seen */ 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *overflow; /* Code to execute on a stack overflow */ 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *failure; /* Code to execute on parser failure */ 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *accept; /* Code to execute when the parser excepts */ 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *extracode; /* Code appended to the generated file */ 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *tokendest; /* Code to execute to destroy token data */ 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *vardest; /* Code for the default non-terminal destructor */ 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *filename; /* Name of the input file */ 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *outname; /* Name of the current output file */ 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *tokenprefix; /* A prefix added to token names in the .h file */ 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nconflict; /* Number of parsing conflicts */ 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tablesize; /* Size of the parse tables */ 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int basisflag; /* Print only basis configurations */ 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int has_fallback; /* True if any %fallback is seen in the grammar */ 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nolinenosflag; /* True if #line statements should not be printed */ 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *argv0; /* Name of the program */ 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MemoryCheck(X) if((X)==0){ \ 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void memory_error(); \ 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_error(); \ 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**************** From the file "table.h" *********************************/ 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All code in this file has been automatically generated 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from a specification in the file 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "table.q" 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by the associative array code building program "aagen". 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Do not edit this file! Instead, edit the specification 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file, then rerun aagen. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Code for processing tables in the LEMON parser generator. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Routines for handling a strings */ 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *Strsafe(const char *); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Strsafe_init(void); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Strsafe_insert(const char *); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *Strsafe_find(const char *); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Routines for handling symbols of the grammar */ 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol *Symbol_new(const char *); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Symbolcmpp(const void *, const void *); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Symbol_init(void); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Symbol_insert(struct symbol *, const char *); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol *Symbol_find(const char *); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol *Symbol_Nth(int); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Symbol_count(void); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol **Symbol_arrayof(void); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Routines to manage the state table */ 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Configcmp(const char *, const char *); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct state *State_new(void); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void State_init(void); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int State_insert(struct state *, struct config *); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct state *State_find(struct config *); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct state **State_arrayof(/* */); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Routines used for efficiency in Configlist_add */ 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configtable_init(void); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Configtable_insert(struct config *); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configtable_find(struct config *); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configtable_clear(int(*)(struct config *)); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/****************** From the file "action.c" *******************************/ 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Routines processing parser actions in the LEMON parser generator. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new parser action */ 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct action *Action_new(void){ 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static struct action *freelist = 0; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *newaction; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( freelist==0 ){ 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int amt = 100; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freelist = (struct action *)calloc(amt, sizeof(struct action)); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( freelist==0 ){ 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Unable to allocate memory for a new parser action."); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1]; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freelist[amt-1].next = 0; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newaction = freelist; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freelist = freelist->next; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return newaction; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compare two actions for sorting purposes. Return negative, zero, or 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** positive if the first action is less than, equal to, or greater than 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the first 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int actioncmp( 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap1, 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap2 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = ap1->sp->index - ap2->sp->index; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==0 ){ 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = (int)ap1->type - (int)ap2->type; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==0 && ap1->type==REDUCE ){ 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = ap1->x.rp->index - ap2->x.rp->index; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==0 ){ 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = (int) (ap2 - ap1); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Sort parser actions */ 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct action *Action_sort( 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap = (struct action *)msort((char *)ap,(char **)&ap->next, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int(*)(const char*,const char*))actioncmp); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ap; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Action_add( 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action **app, 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum e_action type, 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *arg 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *newaction; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newaction = Action_new(); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newaction->next = *app; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *app = newaction; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newaction->type = type; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newaction->sp = sp; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( type==SHIFT ){ 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newaction->x.stp = (struct state *)arg; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newaction->x.rp = (struct rule *)arg; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********************** New code to implement the "acttab" module ***********/ 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This module implements routines use to construct the yy_action[] table. 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The state of the yy_action table under construction is an instance of 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the following structure. 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The yy_action table maps the pair (state_number, lookahead) into an 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** action_number. The table is an array of integers pairs. The state_number 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** determines an initial offset into the yy_action array. The lookahead 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** value is then added to this initial offset to get an index X into the 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** yy_action array. If the aAction[X].lookahead equals the value of the 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the lookahead input, then the value of the action_number output is 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** aAction[X].action. If the lookaheads do not match then the 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** default action for the state_number is returned. 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All actions associated with a single state_number are first entered 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** into aLookahead[] using multiple calls to acttab_action(). Then the 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** actions for that single state_number are placed into the aAction[] 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** array with a single call to acttab_insert(). The acttab_insert() call 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** also resets the aLookahead[] array in preparation for the next 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** state number. 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct lookahead_action { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lookahead; /* Value of the lookahead token */ 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int action; /* Action to take on the given lookahead */ 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct acttab acttab; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct acttab { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nAction; /* Number of used slots in aAction[] */ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nActionAlloc; /* Slots allocated for aAction[] */ 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lookahead_action 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aAction, /* The yy_action[] table under construction */ 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aLookahead; /* A single new transaction set */ 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mnLookahead; /* Minimum aLookahead[].lookahead */ 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mnAction; /* Action associated with mnLookahead */ 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mxLookahead; /* Maximum aLookahead[].lookahead */ 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nLookahead; /* Used slots in aLookahead[] */ 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return the number of entries in the yy_action table */ 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define acttab_size(X) ((X)->nAction) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The value for the N-th entry in yy_action */ 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define acttab_yyaction(X,N) ((X)->aAction[N].action) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The value for the N-th entry in yy_lookahead */ 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Free all memory associated with the given acttab */ 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void acttab_free(acttab *p){ 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free( p->aAction ); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free( p->aLookahead ); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free( p ); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new acttab structure */ 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)acttab *acttab_alloc(void){ 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) acttab *p = (acttab *) calloc( 1, sizeof(*p) ); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p==0 ){ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Unable to allocate memory for a new acttab."); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(p, 0, sizeof(*p)); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a new action to the current transaction set. 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine is called once for each lookahead for a particular 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** state. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void acttab_action(acttab *p, int lookahead, int action){ 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->nLookahead>=p->nLookaheadAlloc ){ 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nLookaheadAlloc += 25; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead, 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aLookahead==0 ){ 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"malloc failed\n"); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->nLookahead==0 ){ 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->mxLookahead = lookahead; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->mnLookahead = lookahead; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->mnAction = action; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->mxLookahead<lookahead ) p->mxLookahead = lookahead; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->mnLookahead>lookahead ){ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->mnLookahead = lookahead; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->mnAction = action; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aLookahead[p->nLookahead].lookahead = lookahead; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aLookahead[p->nLookahead].action = action; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nLookahead++; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Add the transaction set built up with prior calls to acttab_action() 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** into the current action table. Then reset the transaction set back 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to an empty set in preparation for a new round of acttab_action() calls. 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the offset into the action table of the new transaction. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int acttab_insert(acttab *p){ 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j, k, n; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( p->nLookahead>0 ); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Make sure we have enough space to hold the expanded action table 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** in the worst case. The worst case occurs if the transaction set 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** must be appended to the current action table 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = p->mxLookahead + 1; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->nAction + n >= p->nActionAlloc ){ 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int oldAlloc = p->nActionAlloc; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aAction = (struct lookahead_action *) realloc( p->aAction, 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(p->aAction[0])*p->nActionAlloc); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction==0 ){ 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"malloc failed\n"); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=oldAlloc; i<p->nActionAlloc; i++){ 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aAction[i].lookahead = -1; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aAction[i].action = -1; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Scan the existing action table looking for an offset that is a 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** duplicate of the current transaction set. Fall out of the loop 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** if and when the duplicate is found. 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** i is the index in p->aAction[] where p->mnLookahead is inserted. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=p->nAction-1; i>=0; i--){ 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction[i].lookahead==p->mnLookahead ){ 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* All lookaheads and actions in the aLookahead[] transaction 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** must match against the candidate aAction[i] entry. */ 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction[i].action!=p->mnAction ) continue; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<p->nLookahead; j++){ 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k = p->aLookahead[j].lookahead - p->mnLookahead + i; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( k<0 || k>=p->nAction ) break; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aLookahead[j].action!=p->aAction[k].action ) break; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j<p->nLookahead ) continue; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No possible lookahead value that is not in the aLookahead[] 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** transaction is allowed to match aAction[i] */ 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 0; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<p->nAction; j++){ 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction[j].lookahead<0 ) continue; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n==p->nLookahead ){ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; /* An exact match is found at offset i */ 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If no existing offsets exactly match the current transaction, find an 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** an empty offset in the aAction[] table in which we can add the 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** aLookahead[] transaction. 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ){ 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Look for holes in the aAction[] table that fit the current 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** aLookahead[] transaction. Leave i set to the offset of the hole. 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** If no holes are found, i is left at p->nAction, which means the 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** transaction will be appended. */ 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<p->nActionAlloc - p->mxLookahead; i++){ 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction[i].lookahead<0 ){ 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<p->nLookahead; j++){ 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k = p->aLookahead[j].lookahead - p->mnLookahead + i; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( k<0 ) break; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction[k].lookahead>=0 ) break; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j<p->nLookahead ) continue; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<p->nAction; j++){ 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==p->nAction ){ 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; /* Fits in empty slots */ 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Insert transaction set at index i. */ 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<p->nLookahead; j++){ 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k = p->aLookahead[j].lookahead - p->mnLookahead + i; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aAction[k] = p->aLookahead[j]; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( k>=p->nAction ) p->nAction = k+1; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nLookahead = 0; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Return the offset that is added to the lookahead in order to get the 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index into yy_action of the action */ 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i - p->mnLookahead; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********************** From the file "build.c" *****************************/ 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Routines to construction the finite state machine for the LEMON 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** parser generator. 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Find a precedence symbol of every rule in the grammar. 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Those rules which have a precedence symbol coded in the input 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** grammar using the "[symbol]" construct will already have the 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** rp->precsym field filled. Other rules take as their precedence 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** symbol the first RHS symbol with a defined precedence. If there 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are not RHS symbols with a defined precedence, the precedence 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** symbol field is left blank. 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindRulePrecedences(struct lemon *xp) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=xp->rule; rp; rp=rp->next){ 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->precsym==0 ){ 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs && rp->precsym==0; i++){ 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = rp->rhs[i]; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==MULTITERMINAL ){ 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<sp->nsubsym; j++){ 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->subsym[j]->prec>=0 ){ 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->precsym = sp->subsym[j]; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( sp->prec>=0 ){ 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->precsym = rp->rhs[i]; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Find all nonterminals which will generate the empty string. 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Then go back and compute the first sets of every nonterminal. 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The first set is the set of all terminal symbols which can begin 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a string generated by that nonterminal. 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindFirstSets(struct lemon *lemp) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int progress; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->symbols[i]->lambda = LEMON_FALSE; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=lemp->nterminal; i<lemp->nsymbol; i++){ 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->symbols[i]->firstset = SetNew(); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* First compute all lambdas */ 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do{ 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 0; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->lhs->lambda ) continue; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs; i++){ 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = rp->rhs[i]; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i==rp->nrhs ){ 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->lhs->lambda = LEMON_TRUE; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 1; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }while( progress ); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now compute all first sets */ 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do{ 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *s1, *s2; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 0; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s1 = rp->lhs; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs; i++){ 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s2 = rp->rhs[i]; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( s2->type==TERMINAL ){ 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress += SetAdd(s1->firstset,s2->index); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( s2->type==MULTITERMINAL ){ 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<s2->nsubsym; j++){ 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress += SetAdd(s1->firstset,s2->subsym[j]->index); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( s1==s2 ){ 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( s1->lambda==LEMON_FALSE ) break; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress += SetUnion(s1->firstset,s2->firstset); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( s2->lambda==LEMON_FALSE ) break; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }while( progress ); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compute all LR(0) states for the grammar. Links 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are added to between some states so that the LR(1) follow sets 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** can be computed later. 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE struct state *getstate(struct lemon *); /* forward reference */ 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindStates(struct lemon *lemp) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configlist_init(); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find the start symbol */ 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->start ){ 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = Symbol_find(lemp->start); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp==0 ){ 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(lemp->filename,0, 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"The specified start symbol \"%s\" is not \ 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)in a nonterminal of the grammar. \"%s\" will be used as the start \ 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)symbol instead.",lemp->start,lemp->rule->lhs->name); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = lemp->rule->lhs; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = lemp->rule->lhs; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Make sure the start symbol doesn't occur on the right-hand side of 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** any rule. Report an error if it does. (YACC would generate a new 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** start symbol in this case.) */ 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs; i++){ 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */ 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(lemp->filename,0, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"The start symbol \"%s\" occurs on the \ 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)right-hand side of a rule. This will result in a parser which \ 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)does not work properly.",sp->name); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The basis configuration set for the first state 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is all rules which have the start symbol as their 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** left-hand side */ 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=sp->rule; rp; rp=rp->nextlhs){ 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *newcfp; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->lhsStart = 1; 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newcfp = Configlist_addbasis(rp,0); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAdd(newcfp->fws,0); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute the first state. All other states will be 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** computed automatically during the computation of the first one. 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The returned pointer to the first state is not used. */ 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void)getstate(lemp); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to a state which is described by the configuration 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** list which has been built from calls to Configlist_add. 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void buildshifts(struct lemon *, struct state *); /* Forwd ref */ 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE struct state *getstate(struct lemon *lemp) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp, *bp; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Extract the sorted basis of the new state. The basis was constructed 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** by prior calls to "Configlist_addbasis()". */ 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configlist_sortbasis(); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bp = Configlist_basis(); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get a state with the same basis */ 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = State_find(bp); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( stp ){ 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* A state with the same basis already exists! Copy all the follow-set 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** propagation links from the state under construction into the 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** preexisting state, then return a pointer to the preexisting state */ 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *x, *y; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){ 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Plink_copy(&y->bplp,x->bplp); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Plink_delete(x->fplp); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x->fplp = x->bplp = 0; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp = Configlist_return(); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configlist_eat(cfp); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This really is a new state. Construct all the details */ 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configlist_closure(lemp); /* Compute the configuration closure */ 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configlist_sort(); /* Sort the configuration closure */ 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp = Configlist_return(); /* Get a pointer to the config list */ 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = State_new(); /* A new state structure */ 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryCheck(stp); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->bp = bp; /* Remember the configuration basis */ 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->cfp = cfp; /* Remember the configuration closure */ 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->statenum = lemp->nstate++; /* Every state gets a sequence number */ 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->ap = 0; /* No actions, yet. */ 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State_insert(stp,stp->bp); /* Add to the state table */ 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buildshifts(lemp,stp); /* Recursively compute successor states */ 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return stp; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return true if two symbols are the same. 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int same_symbol(struct symbol *a, struct symbol *b) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a==b ) return 1; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a->type!=MULTITERMINAL ) return 0; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( b->type!=MULTITERMINAL ) return 0; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a->nsubsym!=b->nsubsym ) return 0; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<a->nsubsym; i++){ 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a->subsym[i]!=b->subsym[i] ) return 0; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Construct all successor states to the given state. A "successor" 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** state is any state which can be reached by a shift action. 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void buildshifts(struct lemon *lemp, struct state *stp) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp; /* For looping thru the config closure of "stp" */ 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *bcfp; /* For the inner loop on config closure of "stp" */ 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *newcfg; /* */ 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *newstp; /* A pointer to a successor state */ 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Each configuration becomes complete after it contibutes to a successor 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** state. Initially, all configurations are incomplete */ 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop through all configurations of the state "stp" */ 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=stp->cfp; cfp; cfp=cfp->next){ 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */ 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */ 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configlist_reset(); /* Reset the new config set */ 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = cfp->rp->rhs[cfp->dot]; /* Symbol after the dot */ 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* For every configuration in the state "stp" which has the symbol "sp" 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** following its dot, add the same configuration to the basis set under 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** construction but with the dot shifted one symbol to the right. */ 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(bcfp=cfp; bcfp; bcfp=bcfp->next){ 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bcfp->status==COMPLETE ) continue; /* Already used */ 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */ 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */ 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !same_symbol(bsp,sp) ) continue; /* Must be same as for "cfp" */ 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bcfp->status = COMPLETE; /* Mark this config as used */ 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newcfg = Configlist_addbasis(bcfp->rp,bcfp->dot+1); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Plink_add(&newcfg->bplp,bcfp); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get a pointer to the state described by the basis configuration set 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** constructed in the preceding loop */ 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstp = getstate(lemp); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The state "newstp" is reached from the state "stp" by a shift action 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** on the symbol "sp" */ 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==MULTITERMINAL ){ 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<sp->nsubsym; i++){ 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Action_add(&stp->ap,SHIFT,sp->subsym[i],(char*)newstp); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Action_add(&stp->ap,SHIFT,sp,(char *)newstp); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Construct the propagation links 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindLinks(struct lemon *lemp) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp, *other; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *plp; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Housekeeping detail: 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Add to every propagate link a pointer back to the state to 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** which the link is attached. */ 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=stp->cfp; cfp; cfp=cfp->next){ 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->stp = stp; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Convert all backlinks into forward links. Only the forward 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** links are used in the follow-set computation. */ 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=stp->cfp; cfp; cfp=cfp->next){ 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(plp=cfp->bplp; plp; plp=plp->next){ 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other = plp->cfp; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Plink_add(&other->fplp,cfp); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compute all followsets. 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A followset is the set of all symbols which can come immediately 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** after a configuration. 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindFollowSets(struct lemon *lemp) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *plp; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int progress; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int change; 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->status = INCOMPLETE; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do{ 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 0; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp->status==COMPLETE ) continue; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(plp=cfp->fplp; plp; plp=plp->next){ 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change = SetUnion(plp->cfp->fws,cfp->fws); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( change ){ 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plp->cfp->status = INCOMPLETE; 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 1; 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->status = COMPLETE; 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }while( progress ); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int resolve_conflict(struct action *,struct action *, struct symbol *); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compute the reduce actions, and resolve conflicts. 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindActions(struct lemon *lemp) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,j; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp; 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add all of the reduce actions 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** A reduce action is added for each element of the followset of 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a configuration which has its dot at the extreme right. 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ /* Loop over all states */ 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<lemp->nterminal; j++){ 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( SetFind(cfp->fws,j) ){ 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add a reduce action to the state "stp" which will reduce by the 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add the accepting token */ 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->start ){ 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = Symbol_find(lemp->start); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp==0 ) sp = lemp->rule->lhs; 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = lemp->rule->lhs; 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add to the first state (which is always the starting state of the 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** finite state machine) an action to ACCEPT if the lookahead is the 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** start nonterminal. */ 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Resolve conflicts */ 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap, *nap; 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* assert( stp->ap ); */ 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->ap = Action_sort(stp->ap); 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=stp->ap; ap && ap->next; ap=ap->next){ 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The two actions "ap" and "nap" have the same lookahead. 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Figure out which one should be used */ 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Report an error for each rule that can never be reduced. */ 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap; 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE; 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->canReduce ) continue; 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n"); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Resolve a conflict between the two given actions. If the 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** conflict can't be resolved, return non-zero. 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** NO LONGER TRUE: 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To resolve a conflict, first look to see if either action 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is on an error rule. In that case, take the action which 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is not associated with the error rule. If neither or both 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** actions are associated with an error rule, then try to 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** use precedence to resolve the conflict. 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If either action is a SHIFT, then it must be apx. This 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** function won't work if apx->type==REDUCE and apy->type==SHIFT. 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int resolve_conflict( 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *apx, 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *apy, 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *errsym /* The error symbol (if defined. NULL otherwise) */ 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *spx, *spy; 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int errcnt = 0; 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( apx->type==SHIFT && apy->type==SHIFT ){ 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type = SSCONFLICT; 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( apx->type==SHIFT && apy->type==REDUCE ){ 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spx = apx->sp; 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spy = apy->x.rp->precsym; 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( spy==0 || spx->prec<0 || spy->prec<0 ){ 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Not enough precedence information. */ 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type = SRCONFLICT; 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( spx->prec>spy->prec ){ /* higher precedence wins */ 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type = RD_RESOLVED; 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( spx->prec<spy->prec ){ 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type = SH_RESOLVED; 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */ 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type = RD_RESOLVED; /* associativity */ 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */ 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type = SH_RESOLVED; 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( spx->prec==spy->prec && spx->assoc==NONE ); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type = SRCONFLICT; 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( apx->type==REDUCE && apy->type==REDUCE ){ 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spx = apx->x.rp->precsym; 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spy = apy->x.rp->precsym; 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( spx==0 || spy==0 || spx->prec<0 || 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spy->prec<0 || spx->prec==spy->prec ){ 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type = RRCONFLICT; 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( spx->prec>spy->prec ){ 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type = RD_RESOLVED; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( spx->prec<spy->prec ){ 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type = RD_RESOLVED; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type==SH_RESOLVED || 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type==RD_RESOLVED || 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type==SSCONFLICT || 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type==SRCONFLICT || 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apx->type==RRCONFLICT || 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type==SH_RESOLVED || 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type==RD_RESOLVED || 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type==SSCONFLICT || 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type==SRCONFLICT || 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apy->type==RRCONFLICT 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The REDUCE/SHIFT case cannot happen because SHIFTs come before 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** REDUCEs on the list. If we reach this point it must be because 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the parser conflict had already been resolved. */ 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return errcnt; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********************* From the file "configlist.c" *************************/ 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Routines to processing a configuration list and building a state 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the LEMON parser generator. 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct config *freelist = 0; /* List of free configurations */ 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct config *current = 0; /* Top of list of configurations */ 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct config **currentend = 0; /* Last on list of configs */ 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct config *basis = 0; /* Top of list of basis configs */ 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct config **basisend = 0; /* End of list of basis configs */ 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to a new configuration */ 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE struct config *newconfig(){ 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *newcfg; 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( freelist==0 ){ 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int amt = 3; 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freelist = (struct config *)calloc( amt, sizeof(struct config) ); 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( freelist==0 ){ 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Unable to allocate memory for a new configuration."); 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1]; 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freelist[amt-1].next = 0; 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newcfg = freelist; 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freelist = freelist->next; 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return newcfg; 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The configuration "old" is no longer used */ 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void deleteconfig(struct config *old) 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old->next = freelist; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freelist = old; 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Initialized the configuration list builder */ 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_init(){ 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current = 0; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) currentend = ¤t; 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basis = 0; 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basisend = &basis; 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configtable_init(); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Initialized the configuration list builder */ 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_reset(){ 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current = 0; 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) currentend = ¤t; 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basis = 0; 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basisend = &basis; 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configtable_clear(0); 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add another configuration to the configuration list */ 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_add( 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp, /* The rule */ 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dot /* Index into the RHS of the rule where the dot goes */ 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp, model; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( currentend!=0 ); 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.rp = rp; 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.dot = dot; 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp = Configtable_find(&model); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp==0 ){ 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp = newconfig(); 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->rp = rp; 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->dot = dot; 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->fws = SetNew(); 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->stp = 0; 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->fplp = cfp->bplp = 0; 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->next = 0; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->bp = 0; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *currentend = cfp; 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) currentend = &cfp->next; 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configtable_insert(cfp); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cfp; 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a basis configuration to the configuration list */ 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_addbasis(struct rule *rp, int dot) 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp, model; 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( basisend!=0 ); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( currentend!=0 ); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.rp = rp; 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.dot = dot; 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp = Configtable_find(&model); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp==0 ){ 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp = newconfig(); 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->rp = rp; 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->dot = dot; 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->fws = SetNew(); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->stp = 0; 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->fplp = cfp->bplp = 0; 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->next = 0; 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfp->bp = 0; 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *currentend = cfp; 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) currentend = &cfp->next; 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *basisend = cfp; 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basisend = &cfp->bp; 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Configtable_insert(cfp); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cfp; 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compute the closure of the configuration list */ 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_closure(struct lemon *lemp) 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp, *newcfp; 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp, *newrp; 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp, *xsp; 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, dot; 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( currentend!=0 ); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cfp=current; cfp; cfp=cfp->next){ 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp = cfp->rp; 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dot = cfp->dot; 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( dot>=rp->nrhs ) continue; 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = rp->rhs[dot]; 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==NONTERMINAL ){ 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->rule==0 && sp!=lemp->errsym ){ 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.", 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->name); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){ 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newcfp = Configlist_add(newrp,0); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=dot+1; i<rp->nrhs; i++){ 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsp = rp->rhs[i]; 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( xsp->type==TERMINAL ){ 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAdd(newcfp->fws,xsp->index); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( xsp->type==MULTITERMINAL ){ 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int k; 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(k=0; k<xsp->nsubsym; k++){ 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAdd(newcfp->fws, xsp->subsym[k]->index); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetUnion(newcfp->fws,xsp->firstset); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( xsp->lambda==LEMON_FALSE ) break; 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Sort the configuration list */ 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_sort(){ 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) currentend = 0; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Sort the basis configuration list */ 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_sortbasis(){ 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp); 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basisend = 0; 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to the head of the configuration list and 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** reset the list */ 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_return(){ 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *old; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old = current; 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current = 0; 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) currentend = 0; 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return old; 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to the head of the configuration list and 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** reset the list */ 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configlist_basis(){ 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *old; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old = basis; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basis = 0; 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basisend = 0; 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return old; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Free all elements of the given configuration list */ 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configlist_eat(struct config *cfp) 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *nextcfp; 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; cfp; cfp=nextcfp){ 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcfp = cfp->next; 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( cfp->fplp==0 ); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( cfp->bplp==0 ); 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp->fws ) SetFree(cfp->fws); 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deleteconfig(cfp); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***************** From the file "error.c" *********************************/ 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Code for printing error message. 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ErrorMsg(const char *filename, int lineno, const char *format, ...){ 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "%s:%d: ", filename, lineno); 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start(ap, format); 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfprintf(stderr,format,ap); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end(ap); 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "\n"); 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**************** From the file "main.c" ************************************/ 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Main program file for the LEMON parser generator. 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Report an out-of-memory condition and abort. This function 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is used mostly by the "MemoryCheck" macro in struct.h 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void memory_error(){ 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Out of memory. Aborting...\n"); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int nDefine = 0; /* Number of -D options on the command line */ 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char **azDefine = 0; /* Name of the -D macros */ 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This routine is called with the argument to each -D command-line option. 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Add the macro defined to the azDefine array. 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void handle_D_option(char *z){ 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **paz; 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nDefine++; 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine); 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( azDefine==0 ){ 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"out of memory\n"); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paz = &azDefine[nDefine-1]; 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *paz = (char *) malloc( lemonStrlen(z)+1 ); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *paz==0 ){ 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"out of memory\n"); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(*paz, z); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(z=*paz; *z && *z!='='; z++){} 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *z = 0; 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *user_templatename = NULL; 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void handle_T_option(char *z){ 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_templatename = (char *) malloc( lemonStrlen(z)+1 ); 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( user_templatename==0 ){ 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_error(); 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(user_templatename, z); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The main program. Parse the command line and do it... */ 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv) 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int version = 0; 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int rpflag = 0; 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int basisflag = 0; 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int compress = 0; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int quiet = 0; 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int statistics = 0; 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int mhflag = 0; 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int nolinenosflag = 0; 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int noResort = 0; 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static struct s_options options[] = { 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."}, 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."}, 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."}, 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "p", (char*)&showPrecedenceConflict, 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Show conflicts resolved by precedence rules"}, 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"}, 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "s", (char*)&statistics, 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Print parser stats to standard output."}, 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG, "x", (char*)&version, "Print the version number."}, 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {OPT_FLAG,0,0,0} 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int exitcode; 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lemon lem; 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atexit(LemonAtExit); 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptInit(argv,options,stderr); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( version ){ 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Lemon version 1.0\n"); 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(0); 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( OptNArgs()!=1 ){ 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Exactly one filename argument is required.\n"); 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&lem, 0, sizeof(lem)); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.errorcnt = 0; 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize the machine */ 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Strsafe_init(); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol_init(); 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State_init(); 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.argv0 = argv[0]; 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.filename = OptArg(0); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.basisflag = basisflag; 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.nolinenosflag = nolinenosflag; 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol_new("$"); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.errsym = Symbol_new("error"); 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.errsym->useCnt = 0; 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Parse the input file */ 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse(&lem); 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lem.errorcnt ) exit(lem.errorcnt); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lem.nrule==0 ){ 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Empty grammar.\n"); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Count and index the symbols of the grammar */ 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.nsymbol = Symbol_count(); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol_new("{default}"); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.symbols = Symbol_arrayof(); 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), Symbolcmpp); 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; isupper(lem.symbols[i]->name[0]); i++); 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.nterminal = i; 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate a reprint of the grammar, if requested on the command line */ 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rpflag ){ 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reprint(&lem); 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize the size for all follow and first sets */ 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetSize(lem.nterminal+1); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find the precedence for every production rule (that has one) */ 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindRulePrecedences(&lem); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute the lambda-nonterminals and the first-sets for every 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** nonterminal */ 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindFirstSets(&lem); 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute all LR(0) states. Also record follow-set propagation 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** links so that the follow-set can be computed later */ 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.nstate = 0; 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindStates(&lem); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.sorted = State_arrayof(); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Tie up loose ends on the propagation links */ 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindLinks(&lem); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute the follow set of every reducible configuration */ 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindFollowSets(&lem); 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute the action tables */ 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindActions(&lem); 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compress the action tables */ 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( compress==0 ) CompressTables(&lem); 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Reorder and renumber the states so that states with fewer choices 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** occur at the end. This is an optimization that helps make the 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** generated parser tables smaller. */ 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( noResort==0 ) ResortStates(&lem); 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate a report of the parser generated. (the "y.output" file) */ 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !quiet ) ReportOutput(&lem); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate the source code for the parser */ 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportTable(&lem, mhflag); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Produce a header file for use by the scanner. (This step is 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** omitted if the "-m" option is used because makeheaders will 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** generate the file for us.) */ 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !mhflag ) ReportHeader(&lem); 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( statistics ){ 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n", 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(" %d states, %d parser table entries, %d conflicts\n", 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lem.nstate, lem.tablesize, lem.nconflict); 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lem.nconflict > 0 ){ 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* return 0 on success, 1 on failure. */ 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0; 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) successful_exit = (exitcode == 0); 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(exitcode); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (exitcode); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/******************** From the file "msort.c" *******************************/ 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A generic merge-sort program. 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** USAGE: 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Let "ptr" be a pointer to some structure which is at the head of 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a null-terminated list. Then to sort the list call: 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ptr = msort(ptr,&(ptr->next),cmpfnc); 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In the above, "cmpfnc" is a pointer to a function which compares 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** two instances of the structure and returns an integer, as in 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** strcmp. The second argument is a pointer to the pointer to the 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** second element of the linked list. This address is used to compute 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the offset to the "next" field within the structure. The offset to 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the "next" field must be constant for all structures in the list. 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The function returns a new pointer which is the head of the list 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** after sorting. 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ALGORITHM: 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Merge-sort. 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a pointer to the next structure in the linked list. 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Inputs: 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a: A sorted, null-terminated linked list. (May be null). 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** b: A sorted, null-terminated linked list. (May be null). 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** cmp: A pointer to the comparison function. 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** offset: Offset in the structure to the "next" field. 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return Value: 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A pointer to the head of a sorted list containing the elements 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of both a and b. 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Side effects: 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The "next" pointers for elements in the lists a and b are 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** changed. 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *merge( 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *a, 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *b, 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int (*cmp)(const char*,const char*), 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *ptr, *head; 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a==0 ){ 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) head = b; 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( b==0 ){ 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) head = a; 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (*cmp)(a,b)<=0 ){ 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr = a; 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a = NEXT(a); 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr = b; 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = NEXT(b); 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) head = ptr; 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( a && b ){ 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (*cmp)(a,b)<=0 ){ 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT(ptr) = a; 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr = a; 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a = NEXT(a); 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT(ptr) = b; 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr = b; 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = NEXT(b); 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a ) NEXT(ptr) = a; 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else NEXT(ptr) = b; 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return head; 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Inputs: 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** list: Pointer to a singly-linked list of structures. 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** next: Pointer to pointer to the second element of the list. 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** cmp: A comparison function. 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return Value: 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A pointer to the head of a sorted list containing the elements 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** orginally in list. 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Side effects: 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The "next" pointers for elements in list are changed. 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LISTSIZE 30 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *msort( 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *list, 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **next, 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int (*cmp)(const char*,const char*) 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long offset; 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *ep; 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *set[LISTSIZE]; 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = (unsigned long)next - (unsigned long)list; 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<LISTSIZE; i++) set[i] = 0; 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( list ){ 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ep = list; 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = NEXT(list); 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT(ep) = 0; 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<LISTSIZE-1 && set[i]!=0; i++){ 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ep = merge(ep,set[i],cmp,offset); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set[i] = 0; 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set[i] = ep; 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ep = 0; 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset); 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ep; 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************ From the file "option.c" **************************/ 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char **argv; 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct s_options *op; 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static FILE *errstream; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ISOPT(X) ((X)[0]=='-'||(X)[0]=='+'||strchr((X),'=')!=0) 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Print the command line with a carrot pointing to the k-th character 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the n-th field. 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void errline(int n, int k, FILE *err) 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int spcnt, i; 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argv[0] ) fprintf(err,"%s",argv[0]); 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spcnt = lemonStrlen(argv[0]) + 1; 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; i<n && argv[i]; i++){ 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err," %s",argv[i]); 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spcnt += lemonStrlen(argv[i])+1; 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spcnt += k; 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; argv[i]; i++) fprintf(err," %s",argv[i]); 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( spcnt<20 ){ 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"\n%*s^-- here\n",spcnt,""); 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"\n%*shere --^\n",spcnt-7,""); 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the index of the N-th non-switch argument. Return -1 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if N is out of range. 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int argindex(int n) 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dashdash = 0; 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argv!=0 && *argv!=0 ){ 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; argv[i]; i++){ 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( dashdash || !ISOPT(argv[i]) ){ 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n==0 ) return i; 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n--; 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(argv[i],"--")==0 ) dashdash = 1; 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char emsg[] = "Command line syntax error: "; 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Process a flag command line argument. 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int handleflags(int i, FILE *err) 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int v; 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int errcnt = 0; 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; op[j].label; j++){ 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break; 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = argv[i][0]=='-' ? 1 : 0; 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op[j].label==0 ){ 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( err ){ 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"%sundefined option.\n",emsg); 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errline(i,1,err); 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( op[j].type==OPT_FLAG ){ 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *((int*)op[j].arg) = v; 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( op[j].type==OPT_FFLAG ){ 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(void(*)(int))(op[j].arg))(v); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( op[j].type==OPT_FSTR ){ 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(void(*)(char *))(op[j].arg))(&argv[i][2]); 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( err ){ 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"%smissing argument on switch.\n",emsg); 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errline(i,1,err); 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return errcnt; 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Process a command line switch which has an argument. 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int handleswitch(int i, FILE *err) 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lv = 0; 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double dv = 0.0; 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *sv = 0, *end; 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cp; 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int errcnt = 0; 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = strchr(argv[i],'='); 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( cp!=0 ); 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = 0; 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; op[j].label; j++){ 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(argv[i],op[j].label)==0 ) break; 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = '='; 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op[j].label==0 ){ 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( err ){ 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"%sundefined option.\n",emsg); 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errline(i,0,err); 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( op[j].type ){ 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FLAG: 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FFLAG: 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( err ){ 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"%soption requires an argument.\n",emsg); 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errline(i,0,err); 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_DBL: 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FDBL: 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dv = strtod(cp,&end); 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *end ){ 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( err ){ 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"%sillegal character in floating-point argument.\n",emsg); 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errline(i,((unsigned long)end)-(unsigned long)argv[i],err); 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_INT: 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FINT: 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lv = strtol(cp,&end,0); 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *end ){ 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( err ){ 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"%sillegal character in integer argument.\n",emsg); 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errline(i,((unsigned long)end)-(unsigned long)argv[i],err); 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt++; 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_STR: 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FSTR: 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sv = cp; 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( op[j].type ){ 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FLAG: 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FFLAG: 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_DBL: 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(double*)(op[j].arg) = dv; 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FDBL: 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(void(*)(double))(op[j].arg))(dv); 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_INT: 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(int*)(op[j].arg) = lv; 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FINT: 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(void(*)(int))(op[j].arg))((int)lv); 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_STR: 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(char**)(op[j].arg) = sv; 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FSTR: 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(void(*)(char *))(op[j].arg))(sv); 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return errcnt; 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int OptInit(char **a, struct s_options *o, FILE *err) 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int errcnt = 0; 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv = a; 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = o; 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errstream = err; 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argv && *argv && op ){ 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; argv[i]; i++){ 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argv[i][0]=='+' || argv[i][0]=='-' ){ 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt += handleflags(i,err); 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strchr(argv[i],'=') ){ 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errcnt += handleswitch(i,err); 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( errcnt>0 ){ 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(err,"Valid command line options for \"%s\" are:\n",*a); 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptPrint(); 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int OptNArgs(){ 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cnt = 0; 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dashdash = 0; 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argv!=0 && argv[0]!=0 ){ 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; argv[i]; i++){ 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( dashdash || !ISOPT(argv[i]) ) cnt++; 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(argv[i],"--")==0 ) dashdash = 1; 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cnt; 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *OptArg(int n) 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = argindex(n); 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i>=0 ? argv[i] : 0; 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OptErr(int n) 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = argindex(n); 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i>=0 ) errline(i,0,errstream); 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OptPrint(){ 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max, len; 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = 0; 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; op[i].label; i++){ 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = lemonStrlen(op[i].label) + 1; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( op[i].type ){ 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FLAG: 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FFLAG: 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_INT: 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FINT: 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len += 9; /* length of "<integer>" */ 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_DBL: 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FDBL: 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len += 6; /* length of "<real>" */ 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_STR: 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FSTR: 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len += 8; /* length of "<string>" */ 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( len>max ) max = len; 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; op[i].label; i++){ 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( op[i].type ){ 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FLAG: 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FFLAG: 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(errstream," -%-*s %s\n",max,op[i].label,op[i].message); 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_INT: 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FINT: 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(errstream," %s=<integer>%*s %s\n",op[i].label, 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int)(max-lemonStrlen(op[i].label)-9),"",op[i].message); 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_DBL: 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FDBL: 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(errstream," %s=<real>%*s %s\n",op[i].label, 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int)(max-lemonStrlen(op[i].label)-6),"",op[i].message); 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_STR: 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OPT_FSTR: 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(errstream," %s=<string>%*s %s\n",op[i].label, 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int)(max-lemonStrlen(op[i].label)-8),"",op[i].message); 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*********************** From the file "parse.c" ****************************/ 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Input file parser for the LEMON parser generator. 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The state of the parser */ 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum e_state { 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INITIALIZE, 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_DECL_OR_RULE, 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_DECL_KEYWORD, 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_DECL_ARG, 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_PRECEDENCE_SYMBOL, 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_ARROW, 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IN_RHS, 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHS_ALIAS_1, 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHS_ALIAS_2, 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHS_ALIAS_3, 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RHS_ALIAS_1, 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RHS_ALIAS_2, 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRECEDENCE_MARK_1, 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRECEDENCE_MARK_2, 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESYNC_AFTER_RULE_ERROR, 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESYNC_AFTER_DECL_ERROR, 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_DESTRUCTOR_SYMBOL, 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_DATATYPE_SYMBOL, 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_FALLBACK_ID, 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WAITING_FOR_WILDCARD_ID 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct pstate { 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *filename; /* Name of the input file */ 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tokenlineno; /* Linenumber at which current token starts */ 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int errorcnt; /* Number of errors so far */ 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *tokenstart; /* Text of current token */ 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lemon *gp; /* Global state vector */ 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum e_state state; /* The state of the parser */ 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *fallback; /* The fallback token */ 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *lhs; /* Left-hand side of current rule */ 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *lhsalias; /* Alias for the LHS */ 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nrhs; /* Number of right-hand side symbols seen */ 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *rhs[MAXRHS]; /* RHS symbols */ 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */ 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *prevrule; /* Previous rule parsed */ 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *declkeyword; /* Keyword of a declaration */ 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **declargslot; /* Where the declaration argument should be put */ 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int insertLineMacro; /* Add #line before declaration insert */ 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *decllinenoslot; /* Where to write declaration line number */ 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum e_assoc declassoc; /* Assign this association to decl arguments */ 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int preccounter; /* Assign this precedence to decl arguments */ 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *firstrule; /* Pointer to first rule in the grammar */ 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *lastrule; /* Pointer to the most recently parsed rule */ 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Parse a single token */ 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void parseonetoken(struct pstate *psp) 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *x; 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = Strsafe(psp->tokenstart); /* Save the token permanently */ 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno, 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x,psp->state); 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( psp->state ){ 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case INITIALIZE: 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->prevrule = 0; 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->preccounter = 0; 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->firstrule = psp->lastrule = 0; 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->gp->nrule = 0; 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fall thru to next case */ 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_DECL_OR_RULE: 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='%' ){ 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_KEYWORD; 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( islower(x[0]) ){ 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->lhs = Symbol_new(x); 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->nrhs = 0; 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->lhsalias = 0; 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_ARROW; 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( x[0]=='{' ){ 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psp->prevrule==0 ){ 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"There is no prior rule opon which to attach the code \ 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fragment which begins on this line."); 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( psp->prevrule->code!=0 ){ 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"Code fragment beginning on this line is not the first \ 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)to follow the previous rule."); 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->prevrule->line = psp->tokenlineno; 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->prevrule->code = &x[1]; 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( x[0]=='[' ){ 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = PRECEDENCE_MARK_1; 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Token \"%s\" should be either \"%%\" or a nonterminal name.", 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x); 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PRECEDENCE_MARK_1: 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !isupper(x[0]) ){ 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The precedence symbol must be a terminal."); 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( psp->prevrule==0 ){ 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "There is no prior rule to assign precedence \"[%s]\".",x); 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( psp->prevrule->precsym!=0 ){ 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"Precedence mark on this line is not the first \ 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)to follow the previous rule."); 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->prevrule->precsym = Symbol_new(x); 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = PRECEDENCE_MARK_2; 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PRECEDENCE_MARK_2: 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]!=']' ){ 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing \"]\" on precedence mark."); 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_OR_RULE; 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_ARROW: 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]==':' && x[1]==':' && x[2]=='=' ){ 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = IN_RHS; 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( x[0]=='(' ){ 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = LHS_ALIAS_1; 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Expected to see a \":\" following the LHS symbol \"%s\".", 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->lhs->name); 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LHS_ALIAS_1: 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isalpha(x[0]) ){ 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->lhsalias = x; 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = LHS_ALIAS_2; 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"%s\" is not a valid alias for the LHS \"%s\"\n", 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x,psp->lhs->name); 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LHS_ALIAS_2: 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]==')' ){ 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = LHS_ALIAS_3; 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LHS_ALIAS_3: 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]==':' && x[1]==':' && x[2]=='=' ){ 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = IN_RHS; 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing \"->\" following: \"%s(%s)\".", 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->lhs->name,psp->lhsalias); 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case IN_RHS: 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='.' ){ 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp = (struct rule *)calloc( sizeof(struct rule) + 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1); 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp==0 ){ 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Can't allocate enough memory for this rule."); 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->prevrule = 0; 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->ruleline = psp->tokenlineno; 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->rhs = (struct symbol**)&rp[1]; 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]); 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<psp->nrhs; i++){ 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->rhs[i] = psp->rhs[i]; 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->rhsalias[i] = psp->alias[i]; 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->lhs = psp->lhs; 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->lhsalias = psp->lhsalias; 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->nrhs = psp->nrhs; 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->code = 0; 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->precsym = 0; 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->index = psp->gp->nrule++; 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->nextlhs = rp->lhs->rule; 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->lhs->rule = rp; 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->next = 0; 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psp->firstrule==0 ){ 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->firstrule = psp->lastrule = rp; 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->lastrule->next = rp; 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->lastrule = rp; 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->prevrule = rp; 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_OR_RULE; 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( isalpha(x[0]) ){ 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psp->nrhs>=MAXRHS ){ 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Too many symbols on RHS of rule beginning at \"%s\".", 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x); 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->rhs[psp->nrhs] = Symbol_new(x); 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->alias[psp->nrhs] = 0; 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->nrhs++; 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){ 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *msp = psp->rhs[psp->nrhs-1]; 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( msp->type!=MULTITERMINAL ){ 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *origsp = msp; 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp = (struct symbol *) calloc(1,sizeof(*msp)); 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(msp, 0, sizeof(*msp)); 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->type = MULTITERMINAL; 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->nsubsym = 1; 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*)); 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->subsym[0] = origsp; 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->name = origsp->name; 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->rhs[psp->nrhs-1] = msp; 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->nsubsym++; 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->subsym = (struct symbol **) realloc(msp->subsym, 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(struct symbol*)*msp->nsubsym); 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]); 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){ 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cannot form a compound containing a non-terminal"); 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( x[0]=='(' && psp->nrhs>0 ){ 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RHS_ALIAS_1; 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Illegal character on RHS of rule: \"%s\".",x); 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RHS_ALIAS_1: 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isalpha(x[0]) ){ 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->alias[psp->nrhs-1] = x; 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RHS_ALIAS_2; 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n", 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x,psp->rhs[psp->nrhs-1]->name); 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RHS_ALIAS_2: 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]==')' ){ 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = IN_RHS; 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_RULE_ERROR; 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_DECL_KEYWORD: 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isalpha(x[0]) ){ 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declkeyword = x; 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = 0; 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->decllinenoslot = 0; 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 1; 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_ARG; 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(x,"name")==0 ){ 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->name); 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"include")==0 ){ 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->include); 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"code")==0 ){ 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->extracode); 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"token_destructor")==0 ){ 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &psp->gp->tokendest; 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"default_destructor")==0 ){ 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &psp->gp->vardest; 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"token_prefix")==0 ){ 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &psp->gp->tokenprefix; 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"syntax_error")==0 ){ 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->error); 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"parse_accept")==0 ){ 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->accept); 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"parse_failure")==0 ){ 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->failure); 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"stack_overflow")==0 ){ 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->overflow); 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"extra_argument")==0 ){ 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->arg); 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"token_type")==0 ){ 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->tokentype); 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"default_type")==0 ){ 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->vartype); 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"stack_size")==0 ){ 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->stacksize); 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"start_symbol")==0 ){ 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &(psp->gp->start); 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"left")==0 ){ 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->preccounter++; 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declassoc = LEFT; 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"right")==0 ){ 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->preccounter++; 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declassoc = RIGHT; 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"nonassoc")==0 ){ 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->preccounter++; 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declassoc = NONE; 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"destructor")==0 ){ 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"type")==0 ){ 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DATATYPE_SYMBOL; 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"fallback")==0 ){ 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->fallback = 0; 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_FALLBACK_ID; 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( strcmp(x,"wildcard")==0 ){ 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_WILDCARD_ID; 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unknown declaration keyword: \"%%%s\".",x); 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_DECL_ERROR; 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Illegal declaration keyword: \"%s\".",x); 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_DECL_ERROR; 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_DESTRUCTOR_SYMBOL: 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !isalpha(x[0]) ){ 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Symbol name missing after %%destructor keyword"); 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_DECL_ERROR; 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = Symbol_new(x); 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &sp->destructor; 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->decllinenoslot = &sp->destLineno; 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 1; 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_ARG; 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_DATATYPE_SYMBOL: 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !isalpha(x[0]) ){ 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Symbol name missing after %%type keyword"); 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_DECL_ERROR; 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = Symbol_find(x); 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if((sp) && (sp->datatype)){ 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Symbol %%type \"%s\" already defined", x); 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_DECL_ERROR; 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sp){ 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = Symbol_new(x); 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->declargslot = &sp->datatype; 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->insertLineMacro = 0; 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_ARG; 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_PRECEDENCE_SYMBOL: 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='.' ){ 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_OR_RULE; 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( isupper(x[0]) ){ 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = Symbol_new(x); 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->prec>=0 ){ 23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Symbol \"%s\" has already be given a precedence.",x); 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->prec = psp->preccounter; 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->assoc = psp->declassoc; 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Can't assign a precedence to \"%s\".",x); 23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_DECL_ARG: 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){ 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zOld, *zNew; 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zBuf, *z; 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nOld, n, nLine, nNew, nBack; 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addLineMacro; 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zLine[50]; 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zNew = x; 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zNew[0]=='"' || zNew[0]=='{' ) zNew++; 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nNew = lemonStrlen(zNew); 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *psp->declargslot ){ 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zOld = *psp->declargslot; 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zOld = ""; 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nOld = lemonStrlen(zOld); 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = nOld + nNew + 20; 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro && 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0); 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( addLineMacro ){ 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(z=psp->filename, nBack=0; *z; z++){ 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *z=='\\' ) nBack++; 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(zLine, "#line %d ", psp->tokenlineno); 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nLine = lemonStrlen(zLine); 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n += nLine + lemonStrlen(psp->filename) + nBack; 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *psp->declargslot = (char *) realloc(*psp->declargslot, n); 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zBuf = *psp->declargslot + nOld; 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( addLineMacro ){ 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nOld && zBuf[-1]!='\n' ){ 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(zBuf++) = '\n'; 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(zBuf, zLine, nLine); 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zBuf += nLine; 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(zBuf++) = '"'; 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(z=psp->filename; *z; z++){ 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *z=='\\' ){ 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(zBuf++) = '\\'; 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(zBuf++) = *z; 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(zBuf++) = '"'; 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(zBuf++) = '\n'; 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psp->decllinenoslot && psp->decllinenoslot[0]==0 ){ 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->decllinenoslot[0] = psp->tokenlineno; 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(zBuf, zNew, nNew); 23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zBuf += nNew; 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *zBuf = 0; 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_OR_RULE; 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename,psp->tokenlineno, 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Illegal argument to %%%s: %s",psp->declkeyword,x); 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = RESYNC_AFTER_DECL_ERROR; 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_FALLBACK_ID: 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='.' ){ 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_OR_RULE; 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( !isupper(x[0]) ){ 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename, psp->tokenlineno, 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%%fallback argument \"%s\" should be a token", x); 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = Symbol_new(x); 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psp->fallback==0 ){ 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->fallback = sp; 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( sp->fallback ){ 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename, psp->tokenlineno, 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "More than one fallback assigned to token %s", x); 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->fallback = psp->fallback; 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->gp->has_fallback = 1; 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAITING_FOR_WILDCARD_ID: 24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='.' ){ 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->state = WAITING_FOR_DECL_OR_RULE; 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( !isupper(x[0]) ){ 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename, psp->tokenlineno, 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%%wildcard argument \"%s\" should be a token", x); 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = Symbol_new(x); 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psp->gp->wildcard==0 ){ 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->gp->wildcard = sp; 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(psp->filename, psp->tokenlineno, 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extra wildcard to token: %s", x); 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psp->errorcnt++; 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RESYNC_AFTER_RULE_ERROR: 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** break; */ 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RESYNC_AFTER_DECL_ERROR: 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD; 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Run the preprocessor over the input file text. The global variables 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** azDefine[0] through azDefine[nDefine-1] contains the names of all defined 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** comments them out. Text in between is also commented out as appropriate. 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void preprocess_input(char *z){ 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j, k, n; 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int exclude = 0; 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start = 0; 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lineno = 1; 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_lineno = 1; 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; z[i]; i++){ 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z[i]=='\n' ) lineno++; 24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue; 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){ 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( exclude ){ 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclude--; 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( exclude==0 ){ 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=start; j<i; j++) if( z[j]!='\n' ) z[j] = ' '; 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' '; 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( (strncmp(&z[i],"%ifdef",6)==0 && isspace(z[i+6])) 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (strncmp(&z[i],"%ifndef",7)==0 && isspace(z[i+7])) ){ 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( exclude ){ 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclude++; 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=i+7; isspace(z[j]); j++){} 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(n=0; z[j+n] && !isspace(z[j+n]); n++){} 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclude = 1; 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(k=0; k<nDefine; k++){ 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strncmp(azDefine[k],&z[j],n)==0 && lemonStrlen(azDefine[k])==n ){ 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exclude = 0; 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z[i+3]=='n' ) exclude = !exclude; 24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( exclude ){ 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = i; 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_lineno = lineno; 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' '; 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( exclude ){ 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"unterminated %%ifdef starting on line %d\n", start_lineno); 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* In spite of its name, this function is really a scanner. It read 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the entire input file (all at once) then tokenizes it. Each 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** token is passed to the function "parseonetoken" which builds all 25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the appropriate data structures in the global state vector "gp". 25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Parse(struct lemon *gp) 25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pstate ps; 25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *fp; 25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *filebuf; 25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int filesize; 25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lineno; 25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c; 25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cp, *nextcp; 25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int startline = 0; 25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&ps, '\0', sizeof(ps)); 25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.gp = gp; 25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.filename = gp->filename; 25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.errorcnt = 0; 25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.state = INITIALIZE; 25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Begin by reading the input file */ 25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fp = fopen(ps.filename,"rb"); 25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( fp==0 ){ 25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(ps.filename,0,"Can't open this file for reading."); 25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gp->errorcnt++; 25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fseek(fp,0,2); 25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filesize = ftell(fp); 25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rewind(fp); 25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filebuf = (char *)malloc( filesize+1 ); 25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( filebuf==0 ){ 25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", 25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filesize+1); 25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gp->errorcnt++; 25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( fread(filebuf,1,filesize,fp)!=filesize ){ 25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", 25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filesize); 25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(filebuf); 25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gp->errorcnt++; 25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(fp); 25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filebuf[filesize] = 0; 25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Make an initial pass through the file to handle %ifdef and %ifndef */ 25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preprocess_input(filebuf); 25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now scan the text of the input file */ 25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lineno = 1; 25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cp=filebuf; (c= *cp)!=0; ){ 25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='\n' ) lineno++; /* Keep track of the line number */ 25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isspace(c) ){ cp++; continue; } /* Skip all white space */ 25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments */ 25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp+=2; 25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c= *cp)!=0 && c!='\n' ) cp++; 25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ 25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp+=2; 25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ 25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='\n' ) lineno++; 25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c ) cp++; 25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.tokenstart = cp; /* Mark the beginning of the token */ 25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.tokenlineno = lineno; /* Linenumber on which token begins */ 25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='\"' ){ /* String literals */ 25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c= *cp)!=0 && c!='\"' ){ 25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='\n' ) lineno++; 25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c==0 ){ 25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(ps.filename,startline, 25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"String starting on this line is not terminated before the end of the file."); 25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.errorcnt++; 25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp; 25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp+1; 25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( c=='{' ){ /* A block of C code */ 25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level; 25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(level=1; (c= *cp)!=0 && (level>1 || c!='}'); cp++){ 25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='\n' ) lineno++; 26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if( c=='{' ) level++; 26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if( c=='}' ) level--; 26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if( c=='/' && cp[1]=='*' ){ /* Skip comments */ 26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prevc; 26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = &cp[2]; 26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prevc = 0; 26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){ 26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='\n' ) lineno++; 26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prevc = c; 26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ 26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = &cp[2]; 26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c= *cp)!=0 && c!='\n' ) cp++; 26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c ) lineno++; 26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( c=='\'' || c=='\"' ){ /* String a character literals */ 26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int startchar, prevc; 26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) startchar = c; 26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prevc = 0; 26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){ 26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='\n' ) lineno++; 26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( prevc=='\\' ) prevc = 0; 26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else prevc = c; 26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c==0 ){ 26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(ps.filename,ps.tokenlineno, 26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"C code starting on this line is not terminated before the end of the file."); 26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ps.errorcnt++; 26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp; 26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp+1; 26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( isalnum(c) ){ /* Identifiers */ 26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c= *cp)!=0 && (isalnum(c) || c=='_') ) cp++; 26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp; 26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */ 26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp += 3; 26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp; 26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( (c=='/' || c=='|') && isalpha(cp[1]) ){ 26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp += 2; 26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c = *cp)!=0 && (isalnum(c) || c=='_') ) cp++; 26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp; 26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ /* All other (one character) operators */ 26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextcp = cp; 26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *cp; 26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = 0; /* Null terminate the token */ 26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parseonetoken(&ps); /* Parse the token */ 26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = c; /* Restore the buffer */ 26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = nextcp; 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(filebuf); /* Release the buffer after parsing */ 26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gp->rule = ps.firstrule; 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gp->errorcnt = ps.errorcnt; 26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*************************** From the file "plink.c" *********************/ 26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Routines processing configuration follow-set propagation links 26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the LEMON parser generator. 26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct plink *plink_freelist = 0; 26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new plink */ 26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct plink *Plink_new(){ 26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *newlink; 26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( plink_freelist==0 ){ 26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int amt = 100; 26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) ); 26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( plink_freelist==0 ){ 26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unable to allocate memory for a new follow-set propagation link.\n"); 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1]; 26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plink_freelist[amt-1].next = 0; 26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newlink = plink_freelist; 26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plink_freelist = plink_freelist->next; 26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return newlink; 26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a plink to a plink list */ 26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Plink_add(struct plink **plpp, struct config *cfp) 26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *newlink; 26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newlink = Plink_new(); 26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newlink->next = *plpp; 26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *plpp = newlink; 26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newlink->cfp = cfp; 26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Transfer every plink on the list "from" to the list "to" */ 26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Plink_copy(struct plink **to, struct plink *from) 26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *nextpl; 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( from ){ 27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextpl = from->next; 27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from->next = *to; 27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *to = from; 27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from = nextpl; 27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Delete every plink on the list */ 27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Plink_delete(struct plink *plp) 27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct plink *nextpl; 27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( plp ){ 27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextpl = plp->next; 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plp->next = plink_freelist; 27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plink_freelist = plp; 27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plp = nextpl; 27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*********************** From the file "report.c" **************************/ 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Procedures for generating reports and tables in the LEMON parser generator. 27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Generate a filename with the given suffix. Space to hold the 27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** name comes from malloc() and must be freed by the calling 27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** function. 27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE char *file_makename(struct lemon *lemp, const char *suffix) 27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *name; 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cp; 27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 ); 27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( name==0 ){ 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Can't allocate space for a filename.\n"); 27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(name,lemp->filename); 27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = strrchr(name,'.'); 27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp ) *cp = 0; 27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcat(name,suffix); 27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name; 27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Open a file with a name based on the name of the input file, 27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** but with a different (specified) suffix, and return a pointer 27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to the stream */ 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE FILE *file_open( 27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lemon *lemp, 27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *suffix, 27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *mode 27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *fp; 27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->outname ) free(lemp->outname); 27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->outname = file_makename(lemp, suffix); 27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fp = fopen(lemp->outname,mode); 27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( fp==0 && *mode=='w' ){ 27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add files we create to a list, so we can delete them if we fail. This 27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is to keep makefiles from getting confused. We don't include .out files, 27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** though: this is debug information, and you don't want it deleted if there 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** was an error you need to track down. 27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(( *mode=='w' ) && (strcmp(suffix, ".out") != 0)){ 27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **ptr = (const char **) 27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) realloc(made_files, sizeof (const char **) * (made_files_count + 1)); 27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *fname = Strsafe(lemp->outname); 27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ptr == NULL) || (fname == NULL)) { 27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(ptr); 27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_error(); 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) made_files = ptr; 27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) made_files[made_files_count++] = fname; 27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fp; 27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Duplicate the input file without comments and without actions 27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** on rules */ 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Reprint(struct lemon *lemp) 27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; 27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j, maxlen, len, ncolumns, skip; 27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename); 27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxlen = 10; 27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = lemp->symbols[i]; 27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = lemonStrlen(sp->name); 27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( len>maxlen ) maxlen = len; 27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ncolumns = 76/(maxlen+5); 27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ncolumns<1 ) ncolumns = 1; 28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip = (lemp->nsymbol + ncolumns - 1)/ncolumns; 28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<skip; i++){ 28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("//"); 28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=i; j<lemp->nsymbol; j+=skip){ 28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = lemp->symbols[j]; 28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( sp->index==j ); 28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name); 28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("\n"); 28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s",rp->lhs->name); 28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ 28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(" ::="); 28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs; i++){ 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = rp->rhs[i]; 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(" %s", sp->name); 28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==MULTITERMINAL ){ 28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=1; j<sp->nsubsym; j++){ 28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("|%s", sp->subsym[j]->name); 28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ 28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("."); 28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->precsym ) printf(" [%s]",rp->precsym->name); 28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if( rp->code ) printf("\n %s",rp->code); */ 28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("\n"); 28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfigPrint(FILE *fp, struct config *cfp) 28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp = cfp->rp; 28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%s ::=",rp->lhs->name); 28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<=rp->nrhs; i++){ 28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i==cfp->dot ) fprintf(fp," *"); 28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i==rp->nrhs ) break; 28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = rp->rhs[i]; 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp," %s", sp->name); 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==MULTITERMINAL ){ 28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=1; j<sp->nsubsym; j++){ 28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"|%s",sp->subsym[j]->name); 28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define TEST */ 28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Print a set */ 28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void SetPrint(out,set,lemp) 28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILE *out; 28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *set; 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct lemon *lemp; 28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *spacer; 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spacer = ""; 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"%12s[",""); 28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nterminal; i++){ 28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( SetFind(set,i) ){ 28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"%s%s",spacer,lemp->symbols[i]->name); 28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spacer = " "; 28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"]\n"); 28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Print a plink chain */ 28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void PlinkPrint(out,plp,tag) 28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILE *out; 28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct plink *plp; 28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *tag; 28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( plp ){ 28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->statenum); 28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigPrint(out,plp->cfp); 28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"\n"); 28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plp = plp->next; 28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Print an action to the given file descriptor. Return FALSE if 28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** nothing was actually printed. 28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PrintAction(struct action *ap, FILE *fp, int indent){ 28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = 1; 28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( ap->type ){ 28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHIFT: 28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s shift %d",indent,ap->sp->name,ap->x.stp->statenum); 28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case REDUCE: 28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index); 28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ACCEPT: 29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s accept",indent,ap->sp->name); 29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERROR: 29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s error",indent,ap->sp->name); 29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SRCONFLICT: 29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RRCONFLICT: 29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", 29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent,ap->sp->name,ap->x.rp->index); 29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SSCONFLICT: 29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s shift %-3d ** Parsing conflict **", 29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent,ap->sp->name,ap->x.stp->statenum); 29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SH_RESOLVED: 29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( showPrecedenceConflict ){ 29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s shift %-3d -- dropped by precedence", 29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent,ap->sp->name,ap->x.stp->statenum); 29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = 0; 29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RD_RESOLVED: 29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( showPrecedenceConflict ){ 29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"%*s reduce %-3d -- dropped by precedence", 29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent,ap->sp->name,ap->x.rp->index); 29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = 0; 29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NOT_USED: 29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = 0; 29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Generate the "y.output" log file */ 29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReportOutput(struct lemon *lemp) 29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *cfp; 29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap; 29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *fp; 29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fp = file_open(lemp,".out","wb"); 29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( fp==0 ) return; 29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"State %d:\n",stp->statenum); 29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->basisflag ) cfp=stp->bp; 29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else cfp=stp->cfp; 29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( cfp ){ 29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[20]; 29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cfp->dot==cfp->rp->nrhs ){ 29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(buf,"(%d)",cfp->rp->index); 29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp," %5s ",buf); 29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp," "); 29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigPrint(fp,cfp); 29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"\n"); 29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPrint(fp,cfp->fws,lemp); 29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlinkPrint(fp,cfp->fplp,"To "); 29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlinkPrint(fp,cfp->bplp,"From"); 29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->basisflag ) cfp=cfp->bp; 29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else cfp=cfp->next; 29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"\n"); 29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=stp->ap; ap; ap=ap->next){ 29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); 29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp,"\n"); 29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp, "----------------------------------------------------\n"); 29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp, "Symbols:\n"); 29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; 29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = lemp->symbols[i]; 29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp, " %3d: %s", i, sp->name); 29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==NONTERMINAL ){ 29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp, ":"); 29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->lambda ){ 29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp, " <lambda>"); 29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<lemp->nterminal; j++){ 29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->firstset && SetFind(sp->firstset, j) ){ 29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp, " %s", lemp->symbols[j]->name); 29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(fp, "\n"); 29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(fp); 29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Search for the file "name" which is in the same directory as 30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the exacutable */ 30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE char *pathsearch(char *argv0, char *name, int modemask) 30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *pathlist; 30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *pathbufptr; 30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *pathbuf; 30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *path,*cp; 30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c; 30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __WIN32__ 30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = strrchr(argv0,'\\'); 30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = strrchr(argv0,'/'); 30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp ){ 30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *cp; 30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = 0; 30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); 30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( path ) sprintf(path,"%s/%s",argv0,name); 30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = c; 30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pathlist = getenv("PATH"); 30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; 30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 ); 30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); 30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pathbuf != 0) && (path!=0) ){ 30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pathbufptr = pathbuf; 30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(pathbuf, pathlist); 30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( *pathbuf ){ 30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = strchr(pathbuf,':'); 30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)]; 30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *cp; 30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = 0; 30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(path,"%s/%s",pathbuf,name); 30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = c; 30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c==0 ) pathbuf[0] = 0; 30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else pathbuf = &cp[1]; 30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( access(path,modemask)==0 ) break; 30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(pathbufptr); 30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return path; 30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Given an action, compute the integer value for that action 30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** which is to be put in the action table of the generated machine. 30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return negative if no action should be generated. 30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE int compute_action(struct lemon *lemp, struct action *ap) 30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int act; 30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( ap->type ){ 30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SHIFT: act = ap->x.stp->statenum; break; 30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case REDUCE: act = ap->x.rp->index + lemp->nstate; break; 30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERROR: act = lemp->nstate + lemp->nrule; break; 30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break; 30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: act = -1; break; 30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return act; 30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LINESIZE 1000 30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The next cluster of routines are for reading the template file 30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and writing the results to the generated parser */ 30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The first function transfers data from "in" to "out" until 30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a line is seen which begins with "%%". The line number is 30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** tracked. 30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if name!=0, then any word that begin with "Parse" is changed to 30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** begin with *name instead. 30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void tplt_xfer(char *name, FILE *in, FILE *out, int *lineno) 30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, iStart; 30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char line[LINESIZE]; 30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){ 30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*lineno)++; 30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iStart = 0; 30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( name ){ 30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; line[i]; i++){ 30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0 30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (i==0 || !isalpha(line[i-1])) 30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]); 30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"%s",name); 30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += 4; 30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iStart = i+1; 30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"%s",&line[iStart]); 30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The next function finds the template file and opens it, returning 30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a pointer to the opened file. */ 31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE FILE *tplt_open(struct lemon *lemp) 31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char templatename[] = "lempar.c"; 31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[1000]; 31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *in; 31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *tpltname; 31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cp; 31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* first, see if user specified a template filename on the command line. */ 31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_templatename != 0) { 31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( access(user_templatename,004)==-1 ){ 31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", 31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_templatename); 31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in = fopen(user_templatename,"rb"); 31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( in==0 ){ 31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Can't open the template file \"%s\".\n",user_templatename); 31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return in; 31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = strrchr(lemp->filename,'.'); 31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp ){ 31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); 31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(buf,"%s.lt",lemp->filename); 31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( access(buf,004)==0 ){ 31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tpltname = buf; 31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( access(templatename,004)==0 ){ 31345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tpltname = templatename; 31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tpltname = pathsearch(lemp->argv0,templatename,0); 31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( tpltname==0 ){ 31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", 31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) templatename); 31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in = fopen(tpltname,"rb"); 31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( in==0 ){ 31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); 31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return in; 31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Print a #line directive line to the output file. */ 31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void tplt_linedir(FILE *out, int lineno, char *filename) 31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#line %d \"",lineno); 31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( *filename ){ 31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *filename == '\\' ) putc('\\',out); 31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) putc(*filename,out); 31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filename++; 31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"\"\n"); 31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Print a string to the file and keep the linenumber up to date */ 31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void tplt_print(FILE *out, struct lemon *lemp, char *str, int *lineno) 31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( str==0 ) return; 31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( *str ){ 31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) putc(*str,out); 31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *str=='\n' ) (*lineno)++; 31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str++; 31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( str[-1]!='\n' ){ 31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) putc('\n',out); 31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*lineno)++; 31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lemp->nolinenosflag) { 31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); 31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following routine emits code for the destructor for the 31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** symbol sp 31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void emit_destructor_code( 31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *out, 31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp, 31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lemon *lemp, 31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *lineno 31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cp = 0; 31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==TERMINAL ){ 31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = lemp->tokendest; 31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp==0 ) return; 31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"{\n"); (*lineno)++; 32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( sp->destructor ){ 32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = sp->destructor; 32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"{\n"); (*lineno)++; 32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,sp->destLineno,lemp->filename); } 32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( lemp->vardest ){ 32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = lemp->vardest; 32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp==0 ) return; 32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"{\n"); (*lineno)++; 32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( 0 ); /* Cannot happen */ 32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; *cp; cp++){ 32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *cp=='$' && cp[1]=='$' ){ 32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"(yypminor->yy%d)",sp->dtnum); 32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp++; 32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *cp=='\n' ) (*lineno)++; 32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fputc(*cp,out); 32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"\n"); (*lineno)++; 32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lemp->nolinenosflag) { 32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); 32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"}\n"); (*lineno)++; 32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return TRUE (non-zero) if the given symbol has a destructor. 32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int has_destructor(struct symbol *sp, struct lemon *lemp) 32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==TERMINAL ){ 32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = lemp->tokendest!=0; 32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = lemp->vardest!=0 || sp->destructor!=0; 32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Append text to a dynamically allocated string. If zText is 0 then 32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** reset the string to be empty again. Always return the complete text 32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the string (which is overwritten with each call). 32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** n bytes of zText are stored. If n==0 then all of zText up to the first 32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** \000 terminator is stored. zText can contain up to two instances of 32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** %d. The values of p1 and p2 are written into the first and second 32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** %d. 32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If n==-1, then the previous character is overwritten. 32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE char *append_str(const char *zText, int n, int p1, int p2){ 32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char empty[1] = { 0 }; 32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char *z = 0; 32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int alloced = 0; 32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int used = 0; 32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c; 32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zInt[40]; 32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zText==0 ){ 32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used = 0; 32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return z; 32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n<=0 ){ 32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n<0 ){ 32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used += n; 32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( used>=0 ); 32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = lemonStrlen(zText); 32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (int) (n+sizeof(zInt)*2+used) >= alloced ){ 32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alloced = n + sizeof(zInt)*2 + used + 200; 32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = (char *) realloc(z, alloced); 32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z==0 ) return empty; 32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( n-- > 0 ){ 32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *(zText++); 32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='%' && n>0 && zText[0]=='d' ){ 32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(zInt, "%d", p1); 32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p1 = p2; 32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(&z[used], zInt); 32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used += lemonStrlen(&z[used]); 32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zText++; 32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n--; 32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z[used++] = c; 32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z[used] = 0; 32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return z; 32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** zCode is a string that is the action associated with a rule. Expand 32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the symbols in this string so that the refer to elements of the parser 32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** stack. 32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ 33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cp, *xp; 33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char lhsused = 0; /* True if the LHS element has been used */ 33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char used[MAXRHS]; /* True for each RHS element which is used */ 33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs; i++) used[i] = 0; 33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lhsused = 0; 33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->code==0 ){ 33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static char newlinestr[2] = { '\n', '\0' }; 33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->code = newlinestr; 33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->line = rp->ruleline; 33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_str(0,0,0,0); 33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This const cast is wrong but harmless, if we're careful. */ 33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cp=(char *)rp->code; *cp; cp++){ 33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ 33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char saved; 33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); 33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved = *xp; 33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *xp = 0; 33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ 33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); 33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = xp; 33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lhsused = 1; 33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs; i++){ 33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){ 33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp!=rp->code && cp[-1]=='@' ){ 33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the argument is of the form @X then substituted 33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the token number of X, not the value of X */ 33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); 33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = rp->rhs[i]; 33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dtnum; 33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==MULTITERMINAL ){ 33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dtnum = sp->subsym[0]->dtnum; 33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dtnum = sp->dtnum; 33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_str("yymsp[%d].minor.yy%d",0,i-rp->nrhs+1, dtnum); 33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = xp; 33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used[i] = 1; 33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *xp = saved; 33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_str(cp, 1, 0, 0); 33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } /* End loop */ 33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check to make sure the LHS has been used */ 33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->lhsalias && !lhsused ){ 33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(lemp->filename,rp->ruleline, 33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Label \"%s\" for \"%s(%s)\" is never used.", 33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->lhsalias,rp->lhs->name,rp->lhsalias); 33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate destructor code for RHS symbols which are not used in the 33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** reduce code */ 33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<rp->nrhs; i++){ 33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->rhsalias[i] && !used[i] ){ 33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorMsg(lemp->filename,rp->ruleline, 33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Label %s for \"%s(%s)\" is never used.", 33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]); 33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->errorcnt++; 33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( rp->rhsalias[i]==0 ){ 33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( has_destructor(rp->rhs[i],lemp) ){ 33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0, 33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->rhs[i]->index,i-rp->nrhs+1); 33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No destructor defined for this term */ 33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->code ){ 33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = append_str(0,0,0,0); 33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->code = Strsafe(cp?cp:""); 33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code which executes when the rule "rp" is reduced. Write 33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the code to "out". Make sure lineno stays up-to-date. 33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE void emit_code( 33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *out, 33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp, 33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lemon *lemp, 33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *lineno 33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *cp; 33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code to do the reduce action */ 33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->code ){ 34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,rp->line,lemp->filename); } 34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"{%s",rp->code); 34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(cp=rp->code; *cp; cp++){ 34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *cp=='\n' ) (*lineno)++; 34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } /* End loop */ 34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"}\n"); (*lineno)++; 34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); } 34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } /* End if( rp->code ) */ 34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Print the definition of the union used for the parser's data stack. 34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This union contains fields for every possible data type for tokens 34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and nonterminals. In the process of computing and printing this 34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** union, also set the ".dtnum" field of every terminal and nonterminal 34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** symbol. 34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void print_stack_union( 34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *out, /* The output stream */ 34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lemon *lemp, /* The main info structure for this parser */ 34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *plineno, /* Pointer to the line number */ 34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mhflag /* True if generating makeheaders output */ 34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lineno = *plineno; /* The line number of the output */ 34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **types; /* A hash table of datatypes */ 34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int arraysize; /* Size of the "types" array */ 34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxdtlength; /* Maximum length of any ".datatype" field. */ 34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *stddt; /* Standardized name for a datatype */ 34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,j; /* Loop counters */ 34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int hash; /* For hashing the name of a type */ 34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *name; /* Name of the parser */ 34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allocate and initialize types[] and allocate stddt[] */ 34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize = lemp->nsymbol * 2; 34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types = (char**)calloc( arraysize, sizeof(char*) ); 34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<arraysize; i++) types[i] = 0; 34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxdtlength = 0; 34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->vartype ){ 34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxdtlength = lemonStrlen(lemp->vartype); 34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = lemp->symbols[i]; 34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->datatype==0 ) continue; 34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = lemonStrlen(sp->datatype); 34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( len>maxdtlength ) maxdtlength = len; 34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stddt = (char*)malloc( maxdtlength*2 + 1 ); 34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( types==0 || stddt==0 ){ 34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Out of memory.\n"); 34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Build a hash table of datatypes. The ".dtnum" field of each symbol 34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is 34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** used for terminal symbols. If there is no %default_type defined then 34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 0 is also used as the .dtnum value for nonterminals which do not specify 34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a datatype using the %type directive. 34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = lemp->symbols[i]; 34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cp; 34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp==lemp->errsym ){ 34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->dtnum = arraysize+1; 34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){ 34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->dtnum = 0; 34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cp = sp->datatype; 34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cp==0 ) cp = lemp->vartype; 34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = 0; 34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( isspace(*cp) ) cp++; 34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( *cp ) stddt[j++] = *cp++; 34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( j>0 && isspace(stddt[j-1]) ) j--; 34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stddt[j] = 0; 34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->tokentype && strcmp(stddt, lemp->tokentype)==0 ){ 34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->dtnum = 0; 34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash = 0; 34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; stddt[j]; j++){ 34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash = hash*53 + stddt[j]; 34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash = (hash & 0x7fffffff)%arraysize; 34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( types[hash] ){ 34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(types[hash],stddt)==0 ){ 34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->dtnum = hash + 1; 34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash++; 34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( hash>=arraysize ) hash = 0; 34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( types[hash]==0 ){ 34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->dtnum = hash + 1; 34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types[hash] = (char*)malloc( lemonStrlen(stddt)+1 ); 34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( types[hash]==0 ){ 35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Out of memory.\n"); 35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(types[hash],stddt); 35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ 35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = lemp->name ? lemp->name : "Parse"; 35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lineno = *plineno; 35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } 35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sTOKENTYPE %s\n",name, 35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->tokentype?lemp->tokentype:"void*"); lineno++; 35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } 35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"typedef union {\n"); lineno++; 35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," int yyinit;\n"); lineno++; 35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; 35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<arraysize; i++){ 35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( types[i]==0 ) continue; 35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; 35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(types[i]); 35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->errsym->useCnt ){ 35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; 35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(stddt); 35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(types); 35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"} YYMINORTYPE;\n"); lineno++; 35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *plineno = lineno; 35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the name of a C datatype able to represent values between 35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** lwr and upr, inclusive. 35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char *minimum_size_type(int lwr, int upr){ 35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lwr>=0 ){ 35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( upr<=255 ){ 35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "unsigned char"; 35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( upr<65535 ){ 35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "unsigned short int"; 35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "unsigned int"; 35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( lwr>=-127 && upr<=127 ){ 35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "signed char"; 35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( lwr>=-32767 && upr<32767 ){ 35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "short"; 35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "int"; 35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Each state contains a set of token transaction and a set of 35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** nonterminal transactions. Each of these sets makes an instance 35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the following structure. An array of these structures is used 35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to order the creation of entries in the yy_action[] table. 35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct axset { 35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; /* A pointer to a state */ 35615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isTkn; /* True to use tokens. False for non-terminals */ 35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nAction; /* Number of actions */ 35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iOrder; /* Original order of action sets */ 35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Compare to axset structures for sorting purposes 35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int axset_compare(const void *a, const void *b){ 35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct axset *p1 = (struct axset*)a; 35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct axset *p2 = (struct axset*)b; 35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c; 35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = p2->nAction - p1->nAction; 35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c==0 ){ 35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = p2->iOrder - p1->iOrder; 35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( c!=0 || p1==p2 ); 35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return c; 35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write text on "out" that describes the rule "rp". 35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void writeRuleText(FILE *out, struct rule *rp){ 35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"%s ::=", rp->lhs->name); 35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<rp->nrhs; j++){ 35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = rp->rhs[j]; 35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," %s", sp->name); 35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp->type==MULTITERMINAL ){ 35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int k; 35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(k=1; k<sp->nsubsym; k++){ 35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"|%s",sp->subsym[k]->name); 35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Generate C source code for the parser */ 36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReportTable( 36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct lemon *lemp, 36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mhflag /* Output in makeheaders format if true */ 36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *out, *in; 36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char line[LINESIZE]; 36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lineno; 36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap; 36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp; 36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct acttab *pActtab; 36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j, n; 36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *name; 36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mnTknOfst, mxTknOfst; 36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mnNtOfst, mxNtOfst; 36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct axset *ax; 36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in = tplt_open(lemp); 36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( in==0 ) return; 36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = file_open(lemp,".c","wb"); 36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( out==0 ){ 36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(in); 36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lineno = 1; 36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate the include code, if any */ 36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_print(out,lemp,lemp->include,&lineno); 36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( mhflag ){ 36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *name = file_makename(lemp, ".h"); 36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#include \"%s\"\n", name); lineno++; 36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(name); 36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate #defines for all tokens */ 36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( mhflag ){ 36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *prefix; 36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#if INTERFACE\n"); lineno++; 36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->tokenprefix ) prefix = lemp->tokenprefix; 36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else prefix = ""; 36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; i<lemp->nterminal; i++){ 36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); 36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lineno++; 36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#endif\n"); lineno++; 36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate the defines */ 36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYCODETYPE %s\n", 36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) minimum_size_type(0, lemp->nsymbol+1)); lineno++; 36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; 36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYACTIONTYPE %s\n", 36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; 36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->wildcard ){ 36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYWILDCARD %d\n", 36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->wildcard->index); lineno++; 36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_stack_union(out,lemp,&lineno,mhflag); 36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++; 36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->stacksize ){ 36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++; 36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++; 36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#endif\n"); lineno++; 36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( mhflag ){ 36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#if INTERFACE\n"); lineno++; 36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = lemp->name ? lemp->name : "Parse"; 36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->arg && lemp->arg[0] ){ 36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = lemonStrlen(lemp->arg); 36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( i>=1 && isspace(lemp->arg[i-1]) ) i--; 36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; 36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; 36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; 36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", 36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name,lemp->arg,&lemp->arg[i]); lineno++; 36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", 36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name,&lemp->arg[i],&lemp->arg[i]); lineno++; 36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_SDECL\n",name); lineno++; 36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_PDECL\n",name); lineno++; 36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_FETCH\n",name); lineno++; 36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %sARG_STORE\n",name); lineno++; 36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( mhflag ){ 36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#endif\n"); lineno++; 36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; 36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; 36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->errsym->useCnt ){ 36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; 36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; 36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->has_fallback ){ 37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YYFALLBACK 1\n"); lineno++; 37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate the action table and its associates: 37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** yy_action[] A single table containing all actions. 37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** yy_lookahead[] A table containing the lookahead for each entry in 37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** yy_action. Used to detect hash collisions. 37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** yy_shift_ofst[] For each state, the offset into yy_action for 37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** shifting terminals. 37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** yy_reduce_ofst[] For each state, the offset into yy_action for 37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** shifting non-terminals after a reduce. 37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** yy_default[] Default action for each state. 37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute the actions on all states and count them up */ 37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ax = (struct axset *) calloc(lemp->nstate*2, sizeof(ax[0])); 37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ax==0 ){ 37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"malloc failed\n"); 37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ax[i*2].stp = stp; 37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ax[i*2].isTkn = 1; 37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ax[i*2].nAction = stp->nTknAct; 37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ax[i*2+1].stp = stp; 37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ax[i*2+1].isTkn = 0; 37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ax[i*2+1].nAction = stp->nNtAct; 37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mxTknOfst = mnTknOfst = 0; 37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mxNtOfst = mnNtOfst = 0; 37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute the action table. In order to try to keep the size of the 37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** action table to a minimum, the heuristic of placing the largest action 37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sets first is used. 37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate*2; i++) ax[i].iOrder = i; 37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); 37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pActtab = acttab_alloc(); 37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){ 37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = ax[i].stp; 37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ax[i].isTkn ){ 37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=stp->ap; ap; ap=ap->next){ 37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int action; 37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->sp->index>=lemp->nterminal ) continue; 37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action = compute_action(lemp, ap); 37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( action<0 ) continue; 37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) acttab_action(pActtab, ap->sp->index, action); 37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->iTknOfst = acttab_insert(pActtab); 37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( stp->iTknOfst<mnTknOfst ) mnTknOfst = stp->iTknOfst; 37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; 37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=stp->ap; ap; ap=ap->next){ 37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int action; 37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->sp->index<lemp->nterminal ) continue; 37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->sp->index==lemp->nsymbol ) continue; 37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action = compute_action(lemp, ap); 37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( action<0 ) continue; 37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) acttab_action(pActtab, ap->sp->index, action); 37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->iNtOfst = acttab_insert(pActtab); 37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( stp->iNtOfst<mnNtOfst ) mnNtOfst = stp->iNtOfst; 37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; 37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(ax); 37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Output the yy_action table */ 37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = acttab_size(pActtab); 37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define YY_ACTTAB_COUNT (%d)\n", n); lineno++; 37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; 37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0; i<n; i++){ 37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int action = acttab_yyaction(pActtab, i); 37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( action<0 ) action = lemp->nstate + lemp->nrule + 2; 37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==0 ) fprintf(out," /* %5d */ ", i); 37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " %4d,", action); 37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==9 || i==n-1 ){ 37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "\n"); lineno++; 37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = 0; 37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "};\n"); lineno++; 37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Output the yy_lookahead table */ 37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; 37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0; i<n; i++){ 37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int la = acttab_yylookahead(pActtab, i); 37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( la<0 ) la = lemp->nsymbol; 37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==0 ) fprintf(out," /* %5d */ ", i); 37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " %4d,", la); 37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==9 || i==n-1 ){ 37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "\n"); lineno++; 37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = 0; 37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "};\n"); lineno++; 38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Output the yy_shift_ofst[] table */ 38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; 38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = lemp->nstate; 38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; 38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; 38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; 38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; 38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "static const %s yy_shift_ofst[] = {\n", 38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; 38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0; i<n; i++){ 38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ofst; 38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ofst = stp->iTknOfst; 38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; 38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==0 ) fprintf(out," /* %5d */ ", i); 38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " %4d,", ofst); 38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==9 || i==n-1 ){ 38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "\n"); lineno++; 38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = 0; 38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "};\n"); lineno++; 38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Output the yy_reduce_ofst[] table */ 38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; 38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = lemp->nstate; 38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--; 38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++; 38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_REDUCE_MIN (%d)\n", mnNtOfst); lineno++; 38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "#define YY_REDUCE_MAX (%d)\n", mxNtOfst); lineno++; 38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "static const %s yy_reduce_ofst[] = {\n", 38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; 38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0; i<n; i++){ 38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ofst; 38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ofst = stp->iNtOfst; 38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1; 38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==0 ) fprintf(out," /* %5d */ ", i); 38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " %4d,", ofst); 38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==9 || i==n-1 ){ 38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "\n"); lineno++; 38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = 0; 38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "};\n"); lineno++; 38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Output the default action table */ 38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++; 38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = lemp->nstate; 38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0; i<n; i++){ 38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==0 ) fprintf(out," /* %5d */ ", i); 38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " %4d,", stp->iDflt); 38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==9 || i==n-1 ){ 38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "\n"); lineno++; 38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = 0; 38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, "};\n"); lineno++; 38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate the table of fallback tokens. 38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->has_fallback ){ 38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mx = lemp->nterminal - 1; 38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } 38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<=mx; i++){ 38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *p = lemp->symbols[i]; 38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->fallback==0 ){ 38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " 0, /* %10s => nothing */\n", p->name); 38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, 38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->name, p->fallback->name); 38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lineno++; 38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name, in, out, &lineno); 38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate a table containing the symbolic name of every symbol 38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(line,"\"%s\",",lemp->symbols[i]->name); 38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," %-15s",line); 38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } 38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } 38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate a table containing a text string that describes every 39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** rule in the rule set of the grammar. This information is used 39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** when tracing REDUCE actions. 39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ 39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( rp->index==i ); 39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," /* %3d */ \"", i); 39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writeRuleText(out, rp); 39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"\",\n"); lineno++; 39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code which executes every time a symbol is popped from 39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the stack while processing errors or while destroying the parser. 39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (In other words, generate the %destructor actions) 39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->tokendest ){ 39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int once = 1; 39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = lemp->symbols[i]; 39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp==0 || sp->type!=TERMINAL ) continue; 39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( once ){ 39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " /* TERMINAL Destructor */\n"); lineno++; 39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) once = 0; 39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; 39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++); 39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<lemp->nsymbol ){ 39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); 39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," break;\n"); lineno++; 39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->vardest ){ 39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *dflt_sp = 0; 39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int once = 1; 39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = lemp->symbols[i]; 39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp==0 || sp->type==TERMINAL || 39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->index<=0 || sp->destructor!=0 ) continue; 39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( once ){ 39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " /* Default NON-TERMINAL Destructor */\n"); lineno++; 39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) once = 0; 39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; 39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dflt_sp = sp; 39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( dflt_sp!=0 ){ 39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) emit_destructor_code(out,dflt_sp,lemp,&lineno); 39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," break;\n"); lineno++; 39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nsymbol; i++){ 39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp = lemp->symbols[i]; 39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; 39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; 39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Combine duplicate destructors into a single case */ 39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=i+1; j<lemp->nsymbol; j++){ 39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp2 = lemp->symbols[j]; 39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp2 && sp2->type!=TERMINAL && sp2->destructor 39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && sp2->dtnum==sp->dtnum 39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && strcmp(sp->destructor,sp2->destructor)==0 ){ 39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," case %d: /* %s */\n", 39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp2->index, sp2->name); lineno++; 39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp2->destructor = 0; 39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); 39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," break;\n"); lineno++; 39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code which executes whenever the parser stack overflows */ 39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_print(out,lemp,lemp->overflow,&lineno); 39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate the table of rule information 39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Note: This code depends on the fact that rules are number 39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sequentually beginning with 0. 39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++; 39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code which execution during each REDUCE action */ 39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) translate_code(lemp, rp); 39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* First output rules other than the default: rule */ 39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp2; /* Other rules with the same action */ 39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->code==0 ) continue; 39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ 39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," case %d: /* ", rp->index); 39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writeRuleText(out, rp); 39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " */\n"); lineno++; 39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp2=rp->next; rp2; rp2=rp2->next){ 40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp2->code==rp->code ){ 40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," case %d: /* ", rp2->index); 40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writeRuleText(out, rp2); 40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++; 40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp2->code = 0; 40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) emit_code(out,rp,lemp,&lineno); 40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," break;\n"); lineno++; 40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp->code = 0; 40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Finally, output the default: rule. We choose as the default: all 40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** empty actions. */ 40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," default:\n"); lineno++; 40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rp=lemp->rule; rp; rp=rp->next){ 40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->code==0 ) continue; 40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( rp->code[0]=='\n' && rp->code[1]==0 ); 40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," /* (%d) ", rp->index); 40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writeRuleText(out, rp); 40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++; 40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out," break;\n"); lineno++; 40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code which executes if a parse fails */ 40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_print(out,lemp,lemp->failure,&lineno); 40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code which executes when a syntax error occurs */ 40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_print(out,lemp,lemp->error,&lineno); 40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code which executes when the parser accepts its input */ 40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_print(out,lemp,lemp->accept,&lineno); 40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_xfer(lemp->name,in,out,&lineno); 40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Append any addition code the user desires */ 40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tplt_print(out,lemp,lemp->extracode,&lineno); 40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(in); 40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(out); 40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Generate a header file for the parser */ 40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReportHeader(struct lemon *lemp) 40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *out, *in; 40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *prefix; 40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char line[LINESIZE]; 40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char pattern[LINESIZE]; 40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( lemp->tokenprefix ) prefix = lemp->tokenprefix; 40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else prefix = ""; 40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in = file_open(lemp,".h","rb"); 40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( in ){ 40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){ 40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); 40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(line,pattern) ) break; 40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(in); 40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i==lemp->nterminal ){ 40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No change in the file. Don't rewrite it. */ 40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = file_open(lemp,".h","wb"); 40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( out ){ 40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=1; i<lemp->nterminal; i++){ 40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); 40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(out); 40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Reduce the size of the action tables, if possible, by making use 40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of defaults. 40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In this version, we take the most frequent REDUCE action and make 40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** it the default. Except, there is no default if the wildcard token 40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is a possible look-ahead. 40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompressTables(struct lemon *lemp) 40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap, *ap2; 40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rule *rp, *rp2, *rbest; 40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbest, n; 40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int usesWildcard; 40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbest = 0; 40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rbest = 0; 40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usesWildcard = 0; 40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=stp->ap; ap; ap=ap->next){ 41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->type==SHIFT && ap->sp==lemp->wildcard ){ 41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usesWildcard = 1; 41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->type!=REDUCE ) continue; 41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp = ap->x.rp; 41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp->lhsStart ) continue; 41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp==rbest ) continue; 41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 1; 41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap2=ap->next; ap2; ap2=ap2->next){ 41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap2->type!=REDUCE ) continue; 41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rp2 = ap2->x.rp; 41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp2==rbest ) continue; 41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rp2==rp ) n++; 41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n>nbest ){ 41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbest = n; 41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rbest = rp; 41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Do not make a default if the number of rules to default 41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is not at least 1 or if the wildcard token is a possible 41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** lookahead. 41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nbest<1 || usesWildcard ) continue; 41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Combine matching REDUCE actions into a single default */ 41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=stp->ap; ap; ap=ap->next){ 41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->type==REDUCE && ap->x.rp==rbest ) break; 41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( ap ); 41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap->sp = Symbol_new("{default}"); 41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=ap->next; ap; ap=ap->next){ 41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED; 41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->ap = Action_sort(stp->ap); 41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Compare two states for sorting purposes. The smaller state is the 41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** one with the most non-terminal actions. If they have the same number 41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of non-terminal actions, then the smaller is the one with the most 41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** token actions. 41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int stateResortCompare(const void *a, const void *b){ 41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct state *pA = *(const struct state**)a; 41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct state *pB = *(const struct state**)b; 41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; 41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = pB->nNtAct - pA->nNtAct; 41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n==0 ){ 41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = pB->nTknAct - pA->nTknAct; 41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n==0 ){ 41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = pB->statenum - pA->statenum; 41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( n!=0 ); 41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return n; 41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Renumber and resort states so that states with fewer choices 41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** occur at the end. Except, keep state 0 as the first state. 41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResortStates(struct lemon *lemp) 41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *stp; 41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct action *ap; 41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp = lemp->sorted[i]; 41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->nTknAct = stp->nNtAct = 0; 41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->iDflt = lemp->nstate + lemp->nrule; 41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->iTknOfst = NO_OFFSET; 41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->iNtOfst = NO_OFFSET; 41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ap=stp->ap; ap; ap=ap->next){ 41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( compute_action(lemp,ap)>=0 ){ 41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ap->sp->index<lemp->nterminal ){ 41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->nTknAct++; 41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( ap->sp->index<lemp->nsymbol ){ 41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->nNtAct++; 41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stp->iDflt = compute_action(lemp, ap); 41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) qsort(&lemp->sorted[1], lemp->nstate-1, sizeof(lemp->sorted[0]), 41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stateResortCompare); 41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<lemp->nstate; i++){ 41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lemp->sorted[i]->statenum = i; 41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***************** From the file "set.c" ************************************/ 42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set manipulation routines for the LEMON parser generator. 42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int size = 0; 42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Set the set size */ 42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetSize(int n) 42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = n+1; 42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new set */ 42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *SetNew(){ 42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *s; 42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = (char*)calloc( size, 1); 42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( s==0 ){ 42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void memory_error(); 42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_error(); 42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s; 42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Deallocate a set */ 42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetFree(char *s) 42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(s); 42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a new element to the set. Return TRUE if the element was added 42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and FALSE if it was already there. */ 42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SetAdd(char *s, int e) 42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( e>=0 && e<size ); 42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = s[e]; 42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s[e] = 1; 42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !rv; 42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add every element of s2 to s1. Return TRUE if s1 changes. */ 42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SetUnion(char *s1, char *s2) 42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, progress; 42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 0; 42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++){ 42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( s2[i]==0 ) continue; 42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( s1[i]==0 ){ 42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 1; 42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s1[i] = 1; 42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return progress; 42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/********************** From the file "table.c" ****************************/ 42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All code in this file has been automatically generated 42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from a specification in the file 42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "table.q" 42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by the associative array code building program "aagen". 42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Do not edit this file! Instead, edit the specification 42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file, then rerun aagen. 42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Code for processing tables in the LEMON parser generator. 42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE int strhash(const char *x) 42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h = 0; 42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( *x) h = h*13 + *(x++); 42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return h; 42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Works like strdup, sort of. Save a string in malloced memory, but 42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** keep strings in a table so that the same string is not in more 42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** than one place. 42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *Strsafe(const char *y) 42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *z; 42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *cpy; 42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( y==0 ) return 0; 42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = Strsafe_find(y); 42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){ 42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strcpy(cpy,y); 42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = cpy; 42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Strsafe_insert(z); 42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryCheck(z); 42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return z; 42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of the following structure for each 42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** associative array of type "x1". 42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct s_x1 { 42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; /* The number of available slots. */ 43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Must be a power of 2 greater than or */ 43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* equal to 1 */ 43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; /* Number of currently slots filled */ 43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x1node *tbl; /* The data stored here */ 43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x1node **ht; /* Hash table for lookups */ 43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of this structure for every data element 43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in an associative array of type "x1". 43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct s_x1node { 43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *data; /* The data */ 43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x1node *next; /* Next entry with the same hash */ 43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x1node **from; /* Previous link */ 43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} x1node; 43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is only one instance of the array, which is the following */ 43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct s_x1 *x1a; 43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new associative array */ 43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Strsafe_init(){ 43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x1a ) return; 43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1a = (struct s_x1*)malloc( sizeof(struct s_x1) ); 43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x1a ){ 43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1a->size = 1024; 43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1a->count = 0; 43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1a->tbl = (x1node*)malloc( 43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x1node) + sizeof(x1node*))*1024 ); 43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x1a->tbl==0 ){ 43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x1a); 43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1a = 0; 43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1a->ht = (x1node**)&(x1a->tbl[1024]); 43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<1024; i++) x1a->ht[i] = 0; 43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Insert a new record into the array. Return TRUE if successful. 43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Prior data with the same key is NOT overwritten */ 43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Strsafe_insert(const char *data) 43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1node *np; 43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ph; 43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x1a==0 ) return 0; 43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ph = strhash(data); 43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x1a->size-1); 43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x1a->ht[h]; 43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(np->data,data)==0 ){ 43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An existing entry with the same key is found. */ 43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fail because overwrite is not allows. */ 43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x1a->count>=x1a->size ){ 43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Need to make the hash table bigger */ 43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,size; 43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x1 array; 43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.size = size = x1a->size*2; 43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.count = x1a->count; 43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.tbl = (x1node*)malloc( 43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x1node) + sizeof(x1node*))*size ); 43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht = (x1node**)&(array.tbl[size]); 43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++) array.ht[i] = 0; 43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<x1a->count; i++){ 43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1node *oldnp, *newnp; 43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldnp = &(x1a->tbl[i]); 43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = strhash(oldnp->data) & (size-1); 43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp = &(array.tbl[i]); 43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->next = array.ht[h]; 43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->data = oldnp->data; 43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->from = &(array.ht[h]); 43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht[h] = newnp; 43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x1a->tbl); 43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x1a = array; 43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Insert the new data */ 43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x1a->size-1); 43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = &(x1a->tbl[x1a->count++]); 43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->data = data; 43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x1a->ht[h] ) x1a->ht[h]->from = &(np->next); 43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->next = x1a->ht[h]; 43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1a->ht[h] = np; 43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->from = &(x1a->ht[h]); 43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to data assigned to the given key. Return NULL 43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if no such key. */ 43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *Strsafe_find(const char *key) 43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x1node *np; 44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x1a==0 ) return 0; 44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = strhash(key) & (x1a->size-1); 44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x1a->ht[h]; 44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(np->data,key)==0 ) break; 44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return np ? np->data : 0; 44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to the (terminal or nonterminal) symbol "x". 44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Create a new symbol if this is the first time "x" has been seen. 44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol *Symbol_new(const char *x) 44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *sp; 44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = Symbol_find(x); 44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sp==0 ){ 44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = (struct symbol *)calloc(1, sizeof(struct symbol) ); 44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryCheck(sp); 44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->name = Strsafe(x); 44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; 44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->rule = 0; 44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->fallback = 0; 44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->prec = -1; 44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->assoc = UNK; 44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->firstset = 0; 44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->lambda = LEMON_FALSE; 44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->destructor = 0; 44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->destLineno = 0; 44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->datatype = 0; 44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->useCnt = 0; 44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol_insert(sp,sp->name); 44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp->useCnt++; 44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sp; 44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compare two symbols for working purposes 44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Symbols that begin with upper case letters (terminals or tokens) 44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** must sort before symbols that begin with lower case letters 44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (non-terminals). Other than that, the order does not matter. 44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** We find experimentally that leaving the symbols in their original 44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** order (the order they appeared in the grammar file) gives the 44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** smallest parser tables in SQLite. 44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Symbolcmpp(const void *_a, const void *_b) 44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct symbol **a = (const struct symbol **) _a; 44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct symbol **b = (const struct symbol **) _b; 44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); 44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); 44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 ); 44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i1-i2; 44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of the following structure for each 44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** associative array of type "x2". 44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct s_x2 { 44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; /* The number of available slots. */ 44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Must be a power of 2 greater than or */ 44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* equal to 1 */ 44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; /* Number of currently slots filled */ 44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x2node *tbl; /* The data stored here */ 44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x2node **ht; /* Hash table for lookups */ 44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of this structure for every data element 44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in an associative array of type "x2". 44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct s_x2node { 44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *data; /* The data */ 44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *key; /* The key */ 44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x2node *next; /* Next entry with the same hash */ 44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x2node **from; /* Previous link */ 44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} x2node; 44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is only one instance of the array, which is the following */ 44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct s_x2 *x2a; 44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new associative array */ 44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Symbol_init(){ 44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a ) return; 44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); 44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a ){ 44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2a->size = 128; 44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2a->count = 0; 44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2a->tbl = (x2node*)malloc( 44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x2node) + sizeof(x2node*))*128 ); 44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a->tbl==0 ){ 44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x2a); 44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2a = 0; 44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2a->ht = (x2node**)&(x2a->tbl[128]); 45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<128; i++) x2a->ht[i] = 0; 45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Insert a new record into the array. Return TRUE if successful. 45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Prior data with the same key is NOT overwritten */ 45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Symbol_insert(struct symbol *data, const char *key) 45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2node *np; 45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ph; 45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a==0 ) return 0; 45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ph = strhash(key); 45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x2a->size-1); 45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x2a->ht[h]; 45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(np->key,key)==0 ){ 45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An existing entry with the same key is found. */ 45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fail because overwrite is not allows. */ 45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a->count>=x2a->size ){ 45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Need to make the hash table bigger */ 45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,size; 45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x2 array; 45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.size = size = x2a->size*2; 45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.count = x2a->count; 45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.tbl = (x2node*)malloc( 45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x2node) + sizeof(x2node*))*size ); 45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht = (x2node**)&(array.tbl[size]); 45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++) array.ht[i] = 0; 45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<x2a->count; i++){ 45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2node *oldnp, *newnp; 45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldnp = &(x2a->tbl[i]); 45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = strhash(oldnp->key) & (size-1); 45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp = &(array.tbl[i]); 45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->next = array.ht[h]; 45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->key = oldnp->key; 45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->data = oldnp->data; 45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->from = &(array.ht[h]); 45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht[h] = newnp; 45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x2a->tbl); 45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x2a = array; 45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Insert the new data */ 45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x2a->size-1); 45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = &(x2a->tbl[x2a->count++]); 45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->key = key; 45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->data = data; 45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a->ht[h] ) x2a->ht[h]->from = &(np->next); 45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->next = x2a->ht[h]; 45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2a->ht[h] = np; 45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->from = &(x2a->ht[h]); 45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to data assigned to the given key. Return NULL 45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if no such key. */ 45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol *Symbol_find(const char *key) 45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x2node *np; 45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a==0 ) return 0; 45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = strhash(key) & (x2a->size-1); 45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x2a->ht[h]; 45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( strcmp(np->key,key)==0 ) break; 45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return np ? np->data : 0; 45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return the n-th data. Return NULL if n is out of range. */ 45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol *Symbol_Nth(int n) 45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol *data; 45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a && n>0 && n<=x2a->count ){ 45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = x2a->tbl[n-1].data; 45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = 0; 45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return the size of the array */ 45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Symbol_count() 45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x2a ? x2a->count : 0; 45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return an array of pointers to all data in the table. 45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The array is obtained from malloc. Return NULL if memory allocation 45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** problems, or if the array is empty. */ 46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct symbol **Symbol_arrayof() 46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct symbol **array; 46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,size; 46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x2a==0 ) return 0; 46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = x2a->count; 46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = (struct symbol **)calloc(size, sizeof(struct symbol *)); 46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array ){ 46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++) array[i] = x2a->tbl[i].data; 46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return array; 46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compare two configurations */ 46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Configcmp(const char *_a,const char *_b) 46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct config *a = (struct config *) _a; 46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct config *b = (struct config *) _b; 46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x; 46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = a->rp->index - b->rp->index; 46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x==0 ) x = a->dot - b->dot; 46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x; 46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Compare two states */ 46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE int statecmp(struct config *a, struct config *b) 46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){ 46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = a->rp->index - b->rp->index; 46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==0 ) rc = a->dot - b->dot; 46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==0 ){ 46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a ) rc = 1; 46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( b ) rc = -1; 46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Hash a state */ 46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE int statehash(struct config *a) 46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h=0; 46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( a ){ 46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = h*571 + a->rp->index*37 + a->dot; 46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a = a->bp; 46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return h; 46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new state structure */ 46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct state *State_new() 46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *newstate; 46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstate = (struct state *)calloc(1, sizeof(struct state) ); 46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryCheck(newstate); 46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return newstate; 46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of the following structure for each 46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** associative array of type "x3". 46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct s_x3 { 46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; /* The number of available slots. */ 46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Must be a power of 2 greater than or */ 46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* equal to 1 */ 46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; /* Number of currently slots filled */ 46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x3node *tbl; /* The data stored here */ 46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x3node **ht; /* Hash table for lookups */ 46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of this structure for every data element 46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in an associative array of type "x3". 46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct s_x3node { 46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state *data; /* The data */ 46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *key; /* The key */ 46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x3node *next; /* Next entry with the same hash */ 46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x3node **from; /* Previous link */ 46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} x3node; 46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is only one instance of the array, which is the following */ 46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct s_x3 *x3a; 46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new associative array */ 46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void State_init(){ 46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a ) return; 46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); 46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a ){ 46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3a->size = 128; 46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3a->count = 0; 46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3a->tbl = (x3node*)malloc( 46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x3node) + sizeof(x3node*))*128 ); 46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a->tbl==0 ){ 46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x3a); 46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3a = 0; 46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3a->ht = (x3node**)&(x3a->tbl[128]); 46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<128; i++) x3a->ht[i] = 0; 47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Insert a new record into the array. Return TRUE if successful. 47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Prior data with the same key is NOT overwritten */ 47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int State_insert(struct state *data, struct config *key) 47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3node *np; 47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ph; 47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a==0 ) return 0; 47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ph = statehash(key); 47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x3a->size-1); 47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x3a->ht[h]; 47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( statecmp(np->key,key)==0 ){ 47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An existing entry with the same key is found. */ 47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fail because overwrite is not allows. */ 47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a->count>=x3a->size ){ 47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Need to make the hash table bigger */ 47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,size; 47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x3 array; 47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.size = size = x3a->size*2; 47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.count = x3a->count; 47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.tbl = (x3node*)malloc( 47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x3node) + sizeof(x3node*))*size ); 47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht = (x3node**)&(array.tbl[size]); 47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++) array.ht[i] = 0; 47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<x3a->count; i++){ 47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3node *oldnp, *newnp; 47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldnp = &(x3a->tbl[i]); 47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = statehash(oldnp->key) & (size-1); 47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp = &(array.tbl[i]); 47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->next = array.ht[h]; 47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->key = oldnp->key; 47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->data = oldnp->data; 47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->from = &(array.ht[h]); 47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht[h] = newnp; 47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x3a->tbl); 47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x3a = array; 47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Insert the new data */ 47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x3a->size-1); 47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = &(x3a->tbl[x3a->count++]); 47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->key = key; 47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->data = data; 47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a->ht[h] ) x3a->ht[h]->from = &(np->next); 47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->next = x3a->ht[h]; 47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3a->ht[h] = np; 47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->from = &(x3a->ht[h]); 47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to data assigned to the given key. Return NULL 47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if no such key. */ 47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct state *State_find(struct config *key) 47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x3node *np; 47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a==0 ) return 0; 47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = statehash(key) & (x3a->size-1); 47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x3a->ht[h]; 47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( statecmp(np->key,key)==0 ) break; 47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return np ? np->data : 0; 47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return an array of pointers to all data in the table. 47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The array is obtained from malloc. Return NULL if memory allocation 47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** problems, or if the array is empty. */ 47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct state **State_arrayof() 47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct state **array; 47845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,size; 47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x3a==0 ) return 0; 47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = x3a->count; 47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = (struct state **)malloc( sizeof(struct state *)*size ); 47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array ){ 47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++) array[i] = x3a->tbl[i].data; 47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return array; 47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Hash a configuration */ 47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIVATE int confighash(struct config *a) 47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 47975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h=0; 47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = h*571 + a->rp->index*37 + a->dot; 47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return h; 48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of the following structure for each 48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** associative array of type "x4". 48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct s_x4 { 48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; /* The number of available slots. */ 48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Must be a power of 2 greater than or */ 48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* equal to 1 */ 48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; /* Number of currently slots filled */ 48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x4node *tbl; /* The data stored here */ 48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x4node **ht; /* Hash table for lookups */ 48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is one instance of this structure for every data element 48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in an associative array of type "x4". 48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct s_x4node { 48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct config *data; /* The data */ 48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x4node *next; /* Next entry with the same hash */ 48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x4node **from; /* Previous link */ 48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} x4node; 48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* There is only one instance of the array, which is the following */ 48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct s_x4 *x4a; 48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allocate a new associative array */ 48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configtable_init(){ 48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a ) return; 48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); 48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a ){ 48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a->size = 64; 48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a->count = 0; 48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a->tbl = (x4node*)malloc( 48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x4node) + sizeof(x4node*))*64 ); 48355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a->tbl==0 ){ 48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x4a); 48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a = 0; 48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a->ht = (x4node**)&(x4a->tbl[64]); 48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<64; i++) x4a->ht[i] = 0; 48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Insert a new record into the array. Return TRUE if successful. 48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Prior data with the same key is NOT overwritten */ 48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Configtable_insert(struct config *data) 48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4node *np; 48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ph; 48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a==0 ) return 0; 48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ph = confighash(data); 48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x4a->size-1); 48565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x4a->ht[h]; 48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Configcmp((const char *) np->data,(const char *) data)==0 ){ 48595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An existing entry with the same key is found. */ 48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fail because overwrite is not allows. */ 48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a->count>=x4a->size ){ 48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Need to make the hash table bigger */ 48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i,size; 48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct s_x4 array; 48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.size = size = x4a->size*2; 48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.count = x4a->count; 48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.tbl = (x4node*)malloc( 48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sizeof(x4node) + sizeof(x4node*))*size ); 48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht = (x4node**)&(array.tbl[size]); 48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<size; i++) array.ht[i] = 0; 48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<x4a->count; i++){ 48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4node *oldnp, *newnp; 48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldnp = &(x4a->tbl[i]); 48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = confighash(oldnp->data) & (size-1); 48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp = &(array.tbl[i]); 48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->next = array.ht[h]; 48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->data = oldnp->data; 48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newnp->from = &(array.ht[h]); 48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array.ht[h] = newnp; 48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x4a->tbl); 48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *x4a = array; 48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Insert the new data */ 48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = ph & (x4a->size-1); 48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = &(x4a->tbl[x4a->count++]); 48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->data = data; 48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a->ht[h] ) x4a->ht[h]->from = &(np->next); 48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->next = x4a->ht[h]; 48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a->ht[h] = np; 48975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np->from = &(x4a->ht[h]); 48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return a pointer to data assigned to the given key. Return NULL 49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if no such key. */ 49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct config *Configtable_find(struct config *key) 49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h; 49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4node *np; 49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a==0 ) return 0; 49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = confighash(key) & (x4a->size-1); 49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = x4a->ht[h]; 49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( np ){ 49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Configcmp((const char *) np->data,(const char *) key)==0 ) break; 49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np = np->next; 49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return np ? np->data : 0; 49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Remove all data from the table. Pass each data to the function "f" 49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** as it is removed. ("f" may be null to avoid this step.) */ 49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Configtable_clear(int(*f)(struct config *)) 49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x4a==0 || x4a->count==0 ) return; 49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data); 49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<x4a->size; i++) x4a->ht[i] = 0; 49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x4a->count = 0; 49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4929