aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries
diff options
context:
space:
mode:
authorDavid Walter Seikel2014-01-13 21:20:31 +1000
committerDavid Walter Seikel2014-01-13 21:20:31 +1000
commit1a4e7656617a670b8e17d7ea8cf6f202f97b23b8 (patch)
treec1837bea9deafb88e8f12b8e8d769ab6fde77d50 /libraries
parentRemove LuaJIT source, we can use packaged LuaJIT 2.0 release now. (diff)
downloadSledjHamr-1a4e7656617a670b8e17d7ea8cf6f202f97b23b8.zip
SledjHamr-1a4e7656617a670b8e17d7ea8cf6f202f97b23b8.tar.gz
SledjHamr-1a4e7656617a670b8e17d7ea8cf6f202f97b23b8.tar.bz2
SledjHamr-1a4e7656617a670b8e17d7ea8cf6f202f97b23b8.tar.xz
Update to latest lemon.
Diffstat (limited to 'libraries')
-rw-r--r--libraries/README2
-rw-r--r--libraries/lemon/lemon.c378
2 files changed, 264 insertions, 116 deletions
diff --git a/libraries/README b/libraries/README
index 57f81b3..8ef38d3 100644
--- a/libraries/README
+++ b/libraries/README
@@ -13,6 +13,8 @@ Irrlicht has been slightly modified to get it to use externally created
13GL stuff, and not use their internal copies of bzip, jpeglib, libpng, 13GL stuff, and not use their internal copies of bzip, jpeglib, libpng,
14and zlib. 14and zlib.
15 15
16Lemon is from http://www.hwaci.com/sw/lemon/.
17
16LuaJIT 2.0 has been released for Ubuntu 13.04 and later, try using 18LuaJIT 2.0 has been released for Ubuntu 13.04 and later, try using
17https://launchpad.net/~mwild1/+archive/ppa for 12.04. Not including 19https://launchpad.net/~mwild1/+archive/ppa for 12.04. Not including
18that anymore. 20that anymore.
diff --git a/libraries/lemon/lemon.c b/libraries/lemon/lemon.c
index c3e612b..8dca20c 100644
--- a/libraries/lemon/lemon.c
+++ b/libraries/lemon/lemon.c
@@ -15,7 +15,7 @@
15 15
16#ifndef __WIN32__ 16#ifndef __WIN32__
17# if defined(_WIN32) || defined(WIN32) 17# if defined(_WIN32) || defined(WIN32)
18# define __WIN32__ 18# define __WIN32__
19# endif 19# endif
20#endif 20#endif
21 21
@@ -50,6 +50,107 @@ static char *msort(char*,char**,int(*)(const char*,const char*));
50*/ 50*/
51#define lemonStrlen(X) ((int)strlen(X)) 51#define lemonStrlen(X) ((int)strlen(X))
52 52
53/*
54** Compilers are starting to complain about the use of sprintf() and strcpy(),
55** saying they are unsafe. So we define our own versions of those routines too.
56**
57** There are three routines here: lemon_sprintf(), lemon_vsprintf(), and
58** lemon_addtext(). The first two are replacements for sprintf() and vsprintf().
59** The third is a helper routine for vsnprintf() that adds texts to the end of a
60** buffer, making sure the buffer is always zero-terminated.
61**
62** The string formatter is a minimal subset of stdlib sprintf() supporting only
63** a few simply conversions:
64**
65** %d
66** %s
67** %.*s
68**
69*/
70static void lemon_addtext(
71 char *zBuf, /* The buffer to which text is added */
72 int *pnUsed, /* Slots of the buffer used so far */
73 const char *zIn, /* Text to add */
74 int nIn, /* Bytes of text to add. -1 to use strlen() */
75 int iWidth /* Field width. Negative to left justify */
76){
77 if( nIn<0 ) for(nIn=0; zIn[nIn]; nIn++){}
78 while( iWidth>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth--; }
79 if( nIn==0 ) return;
80 memcpy(&zBuf[*pnUsed], zIn, nIn);
81 *pnUsed += nIn;
82 while( (-iWidth)>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth++; }
83 zBuf[*pnUsed] = 0;
84}
85static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){
86 int i, j, k, c, size;
87 int nUsed = 0;
88 const char *z;
89 char zTemp[50];
90 str[0] = 0;
91 for(i=j=0; (c = zFormat[i])!=0; i++){
92 if( c=='%' ){
93 int iWidth = 0;
94 lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
95 c = zFormat[++i];
96 if( isdigit(c) || (c=='-' && isdigit(zFormat[i+1])) ){
97 if( c=='-' ) i++;
98 while( isdigit(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0';
99 if( c=='-' ) iWidth = -iWidth;
100 c = zFormat[i];
101 }
102 if( c=='d' ){
103 int v = va_arg(ap, int);
104 if( v<0 ){
105 lemon_addtext(str, &nUsed, "-", 1, iWidth);
106 v = -v;
107 }else if( v==0 ){
108 lemon_addtext(str, &nUsed, "0", 1, iWidth);
109 }
110 k = 0;
111 while( v>0 ){
112 k++;
113 zTemp[sizeof(zTemp)-k] = (v%10) + '0';
114 v /= 10;
115 }
116 lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k, iWidth);
117 }else if( c=='s' ){
118 z = va_arg(ap, const char*);
119 lemon_addtext(str, &nUsed, z, -1, iWidth);
120 }else if( c=='.' && memcmp(&zFormat[i], ".*s", 3)==0 ){
121 i += 2;
122 k = va_arg(ap, int);
123 z = va_arg(ap, const char*);
124 lemon_addtext(str, &nUsed, z, k, iWidth);
125 }else if( c=='%' ){
126 lemon_addtext(str, &nUsed, "%", 1, 0);
127 }else{
128 fprintf(stderr, "illegal format\n");
129 exit(1);
130 }
131 j = i+1;
132 }
133 }
134 lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
135 return nUsed;
136}
137static int lemon_sprintf(char *str, const char *format, ...){
138 va_list ap;
139 int rc;
140 va_start(ap, format);
141 rc = lemon_vsprintf(str, format, ap);
142 va_end(ap);
143 return rc;
144}
145static void lemon_strcpy(char *dest, const char *src){
146 while( (*(dest++) = *(src++))!=0 ){}
147}
148static void lemon_strcat(char *dest, const char *src){
149 while( *dest ) dest++;
150 lemon_strcpy(dest, src);
151}
152
153
53/* a few forward declarations... */ 154/* a few forward declarations... */
54struct rule; 155struct rule;
55struct lemon; 156struct lemon;
@@ -653,7 +754,7 @@ void FindRulePrecedences(struct lemon *xp)
653 } 754 }
654 }else if( sp->prec>=0 ){ 755 }else if( sp->prec>=0 ){
655 rp->precsym = rp->rhs[i]; 756 rp->precsym = rp->rhs[i];
656 } 757 }
657 } 758 }
658 } 759 }
659 } 760 }
@@ -711,12 +812,12 @@ void FindFirstSets(struct lemon *lemp)
711 progress += SetAdd(s1->firstset,s2->subsym[j]->index); 812 progress += SetAdd(s1->firstset,s2->subsym[j]->index);
712 } 813 }
713 break; 814 break;
714 }else if( s1==s2 ){ 815 }else if( s1==s2 ){
715 if( s1->lambda==LEMON_FALSE ) break; 816 if( s1->lambda==LEMON_FALSE ) break;
716 }else{ 817 }else{
717 progress += SetUnion(s1->firstset,s2->firstset); 818 progress += SetUnion(s1->firstset,s2->firstset);
718 if( s2->lambda==LEMON_FALSE ) break; 819 if( s2->lambda==LEMON_FALSE ) break;
719 } 820 }
720 } 821 }
721 } 822 }
722 }while( progress ); 823 }while( progress );
@@ -959,8 +1060,8 @@ void FindFollowSets(struct lemon *lemp)
959 if( change ){ 1060 if( change ){
960 plp->cfp->status = INCOMPLETE; 1061 plp->cfp->status = INCOMPLETE;
961 progress = 1; 1062 progress = 1;
962 } 1063 }
963 } 1064 }
964 cfp->status = COMPLETE; 1065 cfp->status = COMPLETE;
965 } 1066 }
966 } 1067 }
@@ -993,7 +1094,7 @@ void FindActions(struct lemon *lemp)
993 ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ 1094 ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */
994 Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); 1095 Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
995 } 1096 }
996 } 1097 }
997 } 1098 }
998 } 1099 }
999 } 1100 }
@@ -1262,11 +1363,11 @@ void Configlist_closure(struct lemon *lemp)
1262 SetAdd(newcfp->fws, xsp->subsym[k]->index); 1363 SetAdd(newcfp->fws, xsp->subsym[k]->index);
1263 } 1364 }
1264 break; 1365 break;
1265 }else{ 1366 }else{
1266 SetUnion(newcfp->fws,xsp->firstset); 1367 SetUnion(newcfp->fws,xsp->firstset);
1267 if( xsp->lambda==LEMON_FALSE ) break; 1368 if( xsp->lambda==LEMON_FALSE ) break;
1268 } 1369 }
1269 } 1370 }
1270 if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); 1371 if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
1271 } 1372 }
1272 } 1373 }
@@ -1367,7 +1468,7 @@ static void handle_D_option(char *z){
1367 fprintf(stderr,"out of memory\n"); 1468 fprintf(stderr,"out of memory\n");
1368 exit(1); 1469 exit(1);
1369 } 1470 }
1370 strcpy(*paz, z); 1471 lemon_strcpy(*paz, z);
1371 for(z=*paz; *z && *z!='='; z++){} 1472 for(z=*paz; *z && *z!='='; z++){}
1372 *z = 0; 1473 *z = 0;
1373} 1474}
@@ -1378,7 +1479,7 @@ static void handle_T_option(char *z){
1378 if( user_templatename==0 ){ 1479 if( user_templatename==0 ){
1379 memory_error(); 1480 memory_error();
1380 } 1481 }
1381 strcpy(user_templatename, z); 1482 lemon_strcpy(user_templatename, z);
1382} 1483}
1383 1484
1384/* The main program. Parse the command line and do it... */ 1485/* The main program. Parse the command line and do it... */
@@ -1447,12 +1548,15 @@ int main(int argc, char **argv)
1447 } 1548 }
1448 1549
1449 /* Count and index the symbols of the grammar */ 1550 /* Count and index the symbols of the grammar */
1450 lem.nsymbol = Symbol_count();
1451 Symbol_new("{default}"); 1551 Symbol_new("{default}");
1552 lem.nsymbol = Symbol_count();
1452 lem.symbols = Symbol_arrayof(); 1553 lem.symbols = Symbol_arrayof();
1453 for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; 1554 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1454 qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), Symbolcmpp); 1555 qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp);
1455 for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; 1556 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1557 while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; }
1558 assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 );
1559 lem.nsymbol = i - 1;
1456 for(i=1; isupper(lem.symbols[i]->name[0]); i++); 1560 for(i=1; isupper(lem.symbols[i]->name[0]); i++);
1457 lem.nterminal = i; 1561 lem.nterminal = i;
1458 1562
@@ -1546,7 +1650,7 @@ int main(int argc, char **argv)
1546/* 1650/*
1547** Return a pointer to the next structure in the linked list. 1651** Return a pointer to the next structure in the linked list.
1548*/ 1652*/
1549#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) 1653#define NEXT(A) (*(char**)(((char*)A)+offset))
1550 1654
1551/* 1655/*
1552** Inputs: 1656** Inputs:
@@ -1940,7 +2044,9 @@ enum e_state {
1940 WAITING_FOR_DESTRUCTOR_SYMBOL, 2044 WAITING_FOR_DESTRUCTOR_SYMBOL,
1941 WAITING_FOR_DATATYPE_SYMBOL, 2045 WAITING_FOR_DATATYPE_SYMBOL,
1942 WAITING_FOR_FALLBACK_ID, 2046 WAITING_FOR_FALLBACK_ID,
1943 WAITING_FOR_WILDCARD_ID 2047 WAITING_FOR_WILDCARD_ID,
2048 WAITING_FOR_CLASS_ID,
2049 WAITING_FOR_CLASS_TOKEN
1944}; 2050};
1945struct pstate { 2051struct pstate {
1946 char *filename; /* Name of the input file */ 2052 char *filename; /* Name of the input file */
@@ -1950,6 +2056,7 @@ struct pstate {
1950 struct lemon *gp; /* Global state vector */ 2056 struct lemon *gp; /* Global state vector */
1951 enum e_state state; /* The state of the parser */ 2057 enum e_state state; /* The state of the parser */
1952 struct symbol *fallback; /* The fallback token */ 2058 struct symbol *fallback; /* The fallback token */
2059 struct symbol *tkclass; /* Token class symbol */
1953 struct symbol *lhs; /* Left-hand side of current rule */ 2060 struct symbol *lhs; /* Left-hand side of current rule */
1954 const char *lhsalias; /* Alias for the LHS */ 2061 const char *lhsalias; /* Alias for the LHS */
1955 int nrhs; /* Number of right-hand side symbols seen */ 2062 int nrhs; /* Number of right-hand side symbols seen */
@@ -1996,7 +2103,7 @@ static void parseonetoken(struct pstate *psp)
1996"There is no prior rule upon which to attach the code \ 2103"There is no prior rule upon which to attach the code \
1997fragment which begins on this line."); 2104fragment which begins on this line.");
1998 psp->errorcnt++; 2105 psp->errorcnt++;
1999 }else if( psp->prevrule->code!=0 ){ 2106 }else if( psp->prevrule->code!=0 ){
2000 ErrorMsg(psp->filename,psp->tokenlineno, 2107 ErrorMsg(psp->filename,psp->tokenlineno,
2001"Code fragment beginning on this line is not the first \ 2108"Code fragment beginning on this line is not the first \
2002to follow the previous rule."); 2109to follow the previous rule.");
@@ -2004,7 +2111,7 @@ to follow the previous rule.");
2004 }else{ 2111 }else{
2005 psp->prevrule->line = psp->tokenlineno; 2112 psp->prevrule->line = psp->tokenlineno;
2006 psp->prevrule->code = &x[1]; 2113 psp->prevrule->code = &x[1];
2007 } 2114 }
2008 }else if( x[0]=='[' ){ 2115 }else if( x[0]=='[' ){
2009 psp->state = PRECEDENCE_MARK_1; 2116 psp->state = PRECEDENCE_MARK_1;
2010 }else{ 2117 }else{
@@ -2097,7 +2204,7 @@ to follow the previous rule.");
2097 "Can't allocate enough memory for this rule."); 2204 "Can't allocate enough memory for this rule.");
2098 psp->errorcnt++; 2205 psp->errorcnt++;
2099 psp->prevrule = 0; 2206 psp->prevrule = 0;
2100 }else{ 2207 }else{
2101 int i; 2208 int i;
2102 rp->ruleline = psp->tokenlineno; 2209 rp->ruleline = psp->tokenlineno;
2103 rp->rhs = (struct symbol**)&rp[1]; 2210 rp->rhs = (struct symbol**)&rp[1];
@@ -2105,7 +2212,7 @@ to follow the previous rule.");
2105 for(i=0; i<psp->nrhs; i++){ 2212 for(i=0; i<psp->nrhs; i++){
2106 rp->rhs[i] = psp->rhs[i]; 2213 rp->rhs[i] = psp->rhs[i];
2107 rp->rhsalias[i] = psp->alias[i]; 2214 rp->rhsalias[i] = psp->alias[i];
2108 } 2215 }
2109 rp->lhs = psp->lhs; 2216 rp->lhs = psp->lhs;
2110 rp->lhsalias = psp->lhsalias; 2217 rp->lhsalias = psp->lhsalias;
2111 rp->nrhs = psp->nrhs; 2218 rp->nrhs = psp->nrhs;
@@ -2117,12 +2224,12 @@ to follow the previous rule.");
2117 rp->next = 0; 2224 rp->next = 0;
2118 if( psp->firstrule==0 ){ 2225 if( psp->firstrule==0 ){
2119 psp->firstrule = psp->lastrule = rp; 2226 psp->firstrule = psp->lastrule = rp;
2120 }else{ 2227 }else{
2121 psp->lastrule->next = rp; 2228 psp->lastrule->next = rp;
2122 psp->lastrule = rp; 2229 psp->lastrule = rp;
2123 } 2230 }
2124 psp->prevrule = rp; 2231 psp->prevrule = rp;
2125 } 2232 }
2126 psp->state = WAITING_FOR_DECL_OR_RULE; 2233 psp->state = WAITING_FOR_DECL_OR_RULE;
2127 }else if( isalpha(x[0]) ){ 2234 }else if( isalpha(x[0]) ){
2128 if( psp->nrhs>=MAXRHS ){ 2235 if( psp->nrhs>=MAXRHS ){
@@ -2131,11 +2238,11 @@ to follow the previous rule.");
2131 x); 2238 x);
2132 psp->errorcnt++; 2239 psp->errorcnt++;
2133 psp->state = RESYNC_AFTER_RULE_ERROR; 2240 psp->state = RESYNC_AFTER_RULE_ERROR;
2134 }else{ 2241 }else{
2135 psp->rhs[psp->nrhs] = Symbol_new(x); 2242 psp->rhs[psp->nrhs] = Symbol_new(x);
2136 psp->alias[psp->nrhs] = 0; 2243 psp->alias[psp->nrhs] = 0;
2137 psp->nrhs++; 2244 psp->nrhs++;
2138 } 2245 }
2139 }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){ 2246 }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){
2140 struct symbol *msp = psp->rhs[psp->nrhs-1]; 2247 struct symbol *msp = psp->rhs[psp->nrhs-1];
2141 if( msp->type!=MULTITERMINAL ){ 2248 if( msp->type!=MULTITERMINAL ){
@@ -2199,24 +2306,24 @@ to follow the previous rule.");
2199 if( strcmp(x,"name")==0 ){ 2306 if( strcmp(x,"name")==0 ){
2200 psp->declargslot = &(psp->gp->name); 2307 psp->declargslot = &(psp->gp->name);
2201 psp->insertLineMacro = 0; 2308 psp->insertLineMacro = 0;
2202 }else if( strcmp(x,"include")==0 ){ 2309 }else if( strcmp(x,"include")==0 ){
2203 psp->declargslot = &(psp->gp->include); 2310 psp->declargslot = &(psp->gp->include);
2204 }else if( strcmp(x,"code")==0 ){ 2311 }else if( strcmp(x,"code")==0 ){
2205 psp->declargslot = &(psp->gp->extracode); 2312 psp->declargslot = &(psp->gp->extracode);
2206 }else if( strcmp(x,"token_destructor")==0 ){ 2313 }else if( strcmp(x,"token_destructor")==0 ){
2207 psp->declargslot = &psp->gp->tokendest; 2314 psp->declargslot = &psp->gp->tokendest;
2208 }else if( strcmp(x,"default_destructor")==0 ){ 2315 }else if( strcmp(x,"default_destructor")==0 ){
2209 psp->declargslot = &psp->gp->vardest; 2316 psp->declargslot = &psp->gp->vardest;
2210 }else if( strcmp(x,"token_prefix")==0 ){ 2317 }else if( strcmp(x,"token_prefix")==0 ){
2211 psp->declargslot = &psp->gp->tokenprefix; 2318 psp->declargslot = &psp->gp->tokenprefix;
2212 psp->insertLineMacro = 0; 2319 psp->insertLineMacro = 0;
2213 }else if( strcmp(x,"syntax_error")==0 ){ 2320 }else if( strcmp(x,"syntax_error")==0 ){
2214 psp->declargslot = &(psp->gp->error); 2321 psp->declargslot = &(psp->gp->error);
2215 }else if( strcmp(x,"parse_accept")==0 ){ 2322 }else if( strcmp(x,"parse_accept")==0 ){
2216 psp->declargslot = &(psp->gp->accept); 2323 psp->declargslot = &(psp->gp->accept);
2217 }else if( strcmp(x,"parse_failure")==0 ){ 2324 }else if( strcmp(x,"parse_failure")==0 ){
2218 psp->declargslot = &(psp->gp->failure); 2325 psp->declargslot = &(psp->gp->failure);
2219 }else if( strcmp(x,"stack_overflow")==0 ){ 2326 }else if( strcmp(x,"stack_overflow")==0 ){
2220 psp->declargslot = &(psp->gp->overflow); 2327 psp->declargslot = &(psp->gp->overflow);
2221 }else if( strcmp(x,"extra_argument")==0 ){ 2328 }else if( strcmp(x,"extra_argument")==0 ){
2222 psp->declargslot = &(psp->gp->arg); 2329 psp->declargslot = &(psp->gp->arg);
@@ -2245,21 +2352,23 @@ to follow the previous rule.");
2245 psp->preccounter++; 2352 psp->preccounter++;
2246 psp->declassoc = NONE; 2353 psp->declassoc = NONE;
2247 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; 2354 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
2248 }else if( strcmp(x,"destructor")==0 ){ 2355 }else if( strcmp(x,"destructor")==0 ){
2249 psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; 2356 psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL;
2250 }else if( strcmp(x,"type")==0 ){ 2357 }else if( strcmp(x,"type")==0 ){
2251 psp->state = WAITING_FOR_DATATYPE_SYMBOL; 2358 psp->state = WAITING_FOR_DATATYPE_SYMBOL;
2252 }else if( strcmp(x,"fallback")==0 ){ 2359 }else if( strcmp(x,"fallback")==0 ){
2253 psp->fallback = 0; 2360 psp->fallback = 0;
2254 psp->state = WAITING_FOR_FALLBACK_ID; 2361 psp->state = WAITING_FOR_FALLBACK_ID;
2255 }else if( strcmp(x,"wildcard")==0 ){ 2362 }else if( strcmp(x,"wildcard")==0 ){
2256 psp->state = WAITING_FOR_WILDCARD_ID; 2363 psp->state = WAITING_FOR_WILDCARD_ID;
2364 }else if( strcmp(x,"token_class")==0 ){
2365 psp->state = WAITING_FOR_CLASS_ID;
2257 }else{ 2366 }else{
2258 ErrorMsg(psp->filename,psp->tokenlineno, 2367 ErrorMsg(psp->filename,psp->tokenlineno,
2259 "Unknown declaration keyword: \"%%%s\".",x); 2368 "Unknown declaration keyword: \"%%%s\".",x);
2260 psp->errorcnt++; 2369 psp->errorcnt++;
2261 psp->state = RESYNC_AFTER_DECL_ERROR; 2370 psp->state = RESYNC_AFTER_DECL_ERROR;
2262 } 2371 }
2263 }else{ 2372 }else{
2264 ErrorMsg(psp->filename,psp->tokenlineno, 2373 ErrorMsg(psp->filename,psp->tokenlineno,
2265 "Illegal declaration keyword: \"%s\".",x); 2374 "Illegal declaration keyword: \"%s\".",x);
@@ -2314,10 +2423,10 @@ to follow the previous rule.");
2314 ErrorMsg(psp->filename,psp->tokenlineno, 2423 ErrorMsg(psp->filename,psp->tokenlineno,
2315 "Symbol \"%s\" has already be given a precedence.",x); 2424 "Symbol \"%s\" has already be given a precedence.",x);
2316 psp->errorcnt++; 2425 psp->errorcnt++;
2317 }else{ 2426 }else{
2318 sp->prec = psp->preccounter; 2427 sp->prec = psp->preccounter;
2319 sp->assoc = psp->declassoc; 2428 sp->assoc = psp->declassoc;
2320 } 2429 }
2321 }else{ 2430 }else{
2322 ErrorMsg(psp->filename,psp->tokenlineno, 2431 ErrorMsg(psp->filename,psp->tokenlineno,
2323 "Can't assign a precedence to \"%s\".",x); 2432 "Can't assign a precedence to \"%s\".",x);
@@ -2347,7 +2456,7 @@ to follow the previous rule.");
2347 for(z=psp->filename, nBack=0; *z; z++){ 2456 for(z=psp->filename, nBack=0; *z; z++){
2348 if( *z=='\\' ) nBack++; 2457 if( *z=='\\' ) nBack++;
2349 } 2458 }
2350 sprintf(zLine, "#line %d ", psp->tokenlineno); 2459 lemon_sprintf(zLine, "#line %d ", psp->tokenlineno);
2351 nLine = lemonStrlen(zLine); 2460 nLine = lemonStrlen(zLine);
2352 n += nLine + lemonStrlen(psp->filename) + nBack; 2461 n += nLine + lemonStrlen(psp->filename) + nBack;
2353 } 2462 }
@@ -2422,6 +2531,40 @@ to follow the previous rule.");
2422 } 2531 }
2423 } 2532 }
2424 break; 2533 break;
2534 case WAITING_FOR_CLASS_ID:
2535 if( !islower(x[0]) ){
2536 ErrorMsg(psp->filename, psp->tokenlineno,
2537 "%%token_class must be followed by an identifier: ", x);
2538 psp->errorcnt++;
2539 psp->state = RESYNC_AFTER_DECL_ERROR;
2540 }else if( Symbol_find(x) ){
2541 ErrorMsg(psp->filename, psp->tokenlineno,
2542 "Symbol \"%s\" already used", x);
2543 psp->errorcnt++;
2544 psp->state = RESYNC_AFTER_DECL_ERROR;
2545 }else{
2546 psp->tkclass = Symbol_new(x);
2547 psp->tkclass->type = MULTITERMINAL;
2548 psp->state = WAITING_FOR_CLASS_TOKEN;
2549 }
2550 break;
2551 case WAITING_FOR_CLASS_TOKEN:
2552 if( x[0]=='.' ){
2553 psp->state = WAITING_FOR_DECL_OR_RULE;
2554 }else if( isupper(x[0]) || ((x[0]=='|' || x[0]=='/') && isupper(x[1])) ){
2555 struct symbol *msp = psp->tkclass;
2556 msp->nsubsym++;
2557 msp->subsym = (struct symbol **) realloc(msp->subsym,
2558 sizeof(struct symbol*)*msp->nsubsym);
2559 if( !isupper(x[0]) ) x++;
2560 msp->subsym[msp->nsubsym-1] = Symbol_new(x);
2561 }else{
2562 ErrorMsg(psp->filename, psp->tokenlineno,
2563 "%%token_class argument \"%s\" should be a token", x);
2564 psp->errorcnt++;
2565 psp->state = RESYNC_AFTER_DECL_ERROR;
2566 }
2567 break;
2425 case RESYNC_AFTER_RULE_ERROR: 2568 case RESYNC_AFTER_RULE_ERROR:
2426/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; 2569/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
2427** break; */ 2570** break; */
@@ -2516,9 +2659,8 @@ void Parse(struct lemon *gp)
2516 filesize = ftell(fp); 2659 filesize = ftell(fp);
2517 rewind(fp); 2660 rewind(fp);
2518 filebuf = (char *)malloc( filesize+1 ); 2661 filebuf = (char *)malloc( filesize+1 );
2519 if( filebuf==0 ){ 2662 if( filesize>100000000 || filebuf==0 ){
2520 ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", 2663 ErrorMsg(ps.filename,0,"Input file too large.");
2521 filesize+1);
2522 gp->errorcnt++; 2664 gp->errorcnt++;
2523 fclose(fp); 2665 fclose(fp);
2524 return; 2666 return;
@@ -2587,12 +2729,12 @@ void Parse(struct lemon *gp)
2587 if( c=='\n' ) lineno++; 2729 if( c=='\n' ) lineno++;
2588 prevc = c; 2730 prevc = c;
2589 cp++; 2731 cp++;
2590 } 2732 }
2591 }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ 2733 }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */
2592 cp = &cp[2]; 2734 cp = &cp[2];
2593 while( (c= *cp)!=0 && c!='\n' ) cp++; 2735 while( (c= *cp)!=0 && c!='\n' ) cp++;
2594 if( c ) lineno++; 2736 if( c ) lineno++;
2595 }else if( c=='\'' || c=='\"' ){ /* String a character literals */ 2737 }else if( c=='\'' || c=='\"' ){ /* String a character literals */
2596 int startchar, prevc; 2738 int startchar, prevc;
2597 startchar = c; 2739 startchar = c;
2598 prevc = 0; 2740 prevc = 0;
@@ -2600,8 +2742,8 @@ void Parse(struct lemon *gp)
2600 if( c=='\n' ) lineno++; 2742 if( c=='\n' ) lineno++;
2601 if( prevc=='\\' ) prevc = 0; 2743 if( prevc=='\\' ) prevc = 0;
2602 else prevc = c; 2744 else prevc = c;
2603 } 2745 }
2604 } 2746 }
2605 } 2747 }
2606 if( c==0 ){ 2748 if( c==0 ){
2607 ErrorMsg(ps.filename,ps.tokenlineno, 2749 ErrorMsg(ps.filename,ps.tokenlineno,
@@ -2716,10 +2858,10 @@ PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
2716 fprintf(stderr,"Can't allocate space for a filename.\n"); 2858 fprintf(stderr,"Can't allocate space for a filename.\n");
2717 exit(1); 2859 exit(1);
2718 } 2860 }
2719 strcpy(name,lemp->filename); 2861 lemon_strcpy(name,lemp->filename);
2720 cp = strrchr(name,'.'); 2862 cp = strrchr(name,'.');
2721 if( cp ) *cp = 0; 2863 if( cp ) *cp = 0;
2722 strcat(name,suffix); 2864 lemon_strcat(name,suffix);
2723 return name; 2865 return name;
2724} 2866}
2725 2867
@@ -2776,11 +2918,13 @@ void Reprint(struct lemon *lemp)
2776 printf(" ::="); 2918 printf(" ::=");
2777 for(i=0; i<rp->nrhs; i++){ 2919 for(i=0; i<rp->nrhs; i++){
2778 sp = rp->rhs[i]; 2920 sp = rp->rhs[i];
2779 printf(" %s", sp->name);
2780 if( sp->type==MULTITERMINAL ){ 2921 if( sp->type==MULTITERMINAL ){
2922 printf(" %s", sp->subsym[0]->name);
2781 for(j=1; j<sp->nsubsym; j++){ 2923 for(j=1; j<sp->nsubsym; j++){
2782 printf("|%s", sp->subsym[j]->name); 2924 printf("|%s", sp->subsym[j]->name);
2783 } 2925 }
2926 }else{
2927 printf(" %s", sp->name);
2784 } 2928 }
2785 /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ 2929 /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */
2786 } 2930 }
@@ -2802,11 +2946,13 @@ void ConfigPrint(FILE *fp, struct config *cfp)
2802 if( i==cfp->dot ) fprintf(fp," *"); 2946 if( i==cfp->dot ) fprintf(fp," *");
2803 if( i==rp->nrhs ) break; 2947 if( i==rp->nrhs ) break;
2804 sp = rp->rhs[i]; 2948 sp = rp->rhs[i];
2805 fprintf(fp," %s", sp->name);
2806 if( sp->type==MULTITERMINAL ){ 2949 if( sp->type==MULTITERMINAL ){
2950 fprintf(fp," %s", sp->subsym[0]->name);
2807 for(j=1; j<sp->nsubsym; j++){ 2951 for(j=1; j<sp->nsubsym; j++){
2808 fprintf(fp,"|%s",sp->subsym[j]->name); 2952 fprintf(fp,"|%s",sp->subsym[j]->name);
2809 } 2953 }
2954 }else{
2955 fprintf(fp," %s", sp->name);
2810 } 2956 }
2811 } 2957 }
2812} 2958}
@@ -2916,7 +3062,7 @@ void ReportOutput(struct lemon *lemp)
2916 while( cfp ){ 3062 while( cfp ){
2917 char buf[20]; 3063 char buf[20];
2918 if( cfp->dot==cfp->rp->nrhs ){ 3064 if( cfp->dot==cfp->rp->nrhs ){
2919 sprintf(buf,"(%d)",cfp->rp->index); 3065 lemon_sprintf(buf,"(%d)",cfp->rp->index);
2920 fprintf(fp," %5s ",buf); 3066 fprintf(fp," %5s ",buf);
2921 }else{ 3067 }else{
2922 fprintf(fp," "); 3068 fprintf(fp," ");
@@ -2981,7 +3127,7 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
2981 c = *cp; 3127 c = *cp;
2982 *cp = 0; 3128 *cp = 0;
2983 path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); 3129 path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
2984 if( path ) sprintf(path,"%s/%s",argv0,name); 3130 if( path ) lemon_sprintf(path,"%s/%s",argv0,name);
2985 *cp = c; 3131 *cp = c;
2986 }else{ 3132 }else{
2987 pathlist = getenv("PATH"); 3133 pathlist = getenv("PATH");
@@ -2990,13 +3136,13 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
2990 path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); 3136 path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
2991 if( (pathbuf != 0) && (path!=0) ){ 3137 if( (pathbuf != 0) && (path!=0) ){
2992 pathbufptr = pathbuf; 3138 pathbufptr = pathbuf;
2993 strcpy(pathbuf, pathlist); 3139 lemon_strcpy(pathbuf, pathlist);
2994 while( *pathbuf ){ 3140 while( *pathbuf ){
2995 cp = strchr(pathbuf,':'); 3141 cp = strchr(pathbuf,':');
2996 if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)]; 3142 if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)];
2997 c = *cp; 3143 c = *cp;
2998 *cp = 0; 3144 *cp = 0;
2999 sprintf(path,"%s/%s",pathbuf,name); 3145 lemon_sprintf(path,"%s/%s",pathbuf,name);
3000 *cp = c; 3146 *cp = c;
3001 if( c==0 ) pathbuf[0] = 0; 3147 if( c==0 ) pathbuf[0] = 0;
3002 else pathbuf = &cp[1]; 3148 else pathbuf = &cp[1];
@@ -3087,9 +3233,9 @@ PRIVATE FILE *tplt_open(struct lemon *lemp)
3087 3233
3088 cp = strrchr(lemp->filename,'.'); 3234 cp = strrchr(lemp->filename,'.');
3089 if( cp ){ 3235 if( cp ){
3090 sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); 3236 lemon_sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename);
3091 }else{ 3237 }else{
3092 sprintf(buf,"%s.lt",lemp->filename); 3238 lemon_sprintf(buf,"%s.lt",lemp->filename);
3093 } 3239 }
3094 if( access(buf,004)==0 ){ 3240 if( access(buf,004)==0 ){
3095 tpltname = buf; 3241 tpltname = buf;
@@ -3240,9 +3386,9 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
3240 while( n-- > 0 ){ 3386 while( n-- > 0 ){
3241 c = *(zText++); 3387 c = *(zText++);
3242 if( c=='%' && n>0 && zText[0]=='d' ){ 3388 if( c=='%' && n>0 && zText[0]=='d' ){
3243 sprintf(zInt, "%d", p1); 3389 lemon_sprintf(zInt, "%d", p1);
3244 p1 = p2; 3390 p1 = p2;
3245 strcpy(&z[used], zInt); 3391 lemon_strcpy(&z[used], zInt);
3246 used += lemonStrlen(&z[used]); 3392 used += lemonStrlen(&z[used]);
3247 zText++; 3393 zText++;
3248 n--; 3394 n--;
@@ -3391,7 +3537,7 @@ void print_stack_union(
3391 int maxdtlength; /* Maximum length of any ".datatype" field. */ 3537 int maxdtlength; /* Maximum length of any ".datatype" field. */
3392 char *stddt; /* Standardized name for a datatype */ 3538 char *stddt; /* Standardized name for a datatype */
3393 int i,j; /* Loop counters */ 3539 int i,j; /* Loop counters */
3394 int hash; /* For hashing the name of a type */ 3540 unsigned hash; /* For hashing the name of a type */
3395 const char *name; /* Name of the parser */ 3541 const char *name; /* Name of the parser */
3396 3542
3397 /* Allocate and initialize types[] and allocate stddt[] */ 3543 /* Allocate and initialize types[] and allocate stddt[] */
@@ -3458,7 +3604,7 @@ void print_stack_union(
3458 break; 3604 break;
3459 } 3605 }
3460 hash++; 3606 hash++;
3461 if( hash>=arraysize ) hash = 0; 3607 if( hash>=(unsigned)arraysize ) hash = 0;
3462 } 3608 }
3463 if( types[hash]==0 ){ 3609 if( types[hash]==0 ){
3464 sp->dtnum = hash + 1; 3610 sp->dtnum = hash + 1;
@@ -3467,7 +3613,7 @@ void print_stack_union(
3467 fprintf(stderr,"Out of memory.\n"); 3613 fprintf(stderr,"Out of memory.\n");
3468 exit(1); 3614 exit(1);
3469 } 3615 }
3470 strcpy(types[hash],stddt); 3616 lemon_strcpy(types[hash],stddt);
3471 } 3617 }
3472 } 3618 }
3473 3619
@@ -3553,9 +3699,11 @@ static void writeRuleText(FILE *out, struct rule *rp){
3553 fprintf(out,"%s ::=", rp->lhs->name); 3699 fprintf(out,"%s ::=", rp->lhs->name);
3554 for(j=0; j<rp->nrhs; j++){ 3700 for(j=0; j<rp->nrhs; j++){
3555 struct symbol *sp = rp->rhs[j]; 3701 struct symbol *sp = rp->rhs[j];
3556 fprintf(out," %s", sp->name); 3702 if( sp->type!=MULTITERMINAL ){
3557 if( sp->type==MULTITERMINAL ){ 3703 fprintf(out," %s", sp->name);
3704 }else{
3558 int k; 3705 int k;
3706 fprintf(out," %s", sp->subsym[0]->name);
3559 for(k=1; k<sp->nsubsym; k++){ 3707 for(k=1; k<sp->nsubsym; k++){
3560 fprintf(out,"|%s",sp->subsym[k]->name); 3708 fprintf(out,"|%s",sp->subsym[k]->name);
3561 } 3709 }
@@ -3856,7 +4004,7 @@ void ReportTable(
3856 /* Generate a table containing the symbolic name of every symbol 4004 /* Generate a table containing the symbolic name of every symbol
3857 */ 4005 */
3858 for(i=0; i<lemp->nsymbol; i++){ 4006 for(i=0; i<lemp->nsymbol; i++){
3859 sprintf(line,"\"%s\",",lemp->symbols[i]->name); 4007 lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name);
3860 fprintf(out," %-15s",line); 4008 fprintf(out," %-15s",line);
3861 if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } 4009 if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; }
3862 } 4010 }
@@ -4021,12 +4169,15 @@ void ReportHeader(struct lemon *lemp)
4021 else prefix = ""; 4169 else prefix = "";
4022 in = file_open(lemp,".h","rb"); 4170 in = file_open(lemp,".h","rb");
4023 if( in ){ 4171 if( in ){
4172 int nextChar;
4024 for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){ 4173 for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){
4025 sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); 4174 lemon_sprintf(pattern,"#define %s%-30s %3d\n",
4175 prefix,lemp->symbols[i]->name,i);
4026 if( strcmp(line,pattern) ) break; 4176 if( strcmp(line,pattern) ) break;
4027 } 4177 }
4178 nextChar = fgetc(in);
4028 fclose(in); 4179 fclose(in);
4029 if( i==lemp->nterminal ){ 4180 if( i==lemp->nterminal && nextChar==EOF ){
4030 /* No change in the file. Don't rewrite it. */ 4181 /* No change in the file. Don't rewrite it. */
4031 return; 4182 return;
4032 } 4183 }
@@ -4034,7 +4185,7 @@ void ReportHeader(struct lemon *lemp)
4034 out = file_open(lemp,".h","wb"); 4185 out = file_open(lemp,".h","wb");
4035 if( out ){ 4186 if( out ){
4036 for(i=1; i<lemp->nterminal; i++){ 4187 for(i=1; i<lemp->nterminal; i++){
4037 fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); 4188 fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i);
4038 } 4189 }
4039 fclose(out); 4190 fclose(out);
4040 } 4191 }
@@ -4232,10 +4383,10 @@ int SetUnion(char *s1, char *s2)
4232** Code for processing tables in the LEMON parser generator. 4383** Code for processing tables in the LEMON parser generator.
4233*/ 4384*/
4234 4385
4235PRIVATE int strhash(const char *x) 4386PRIVATE unsigned strhash(const char *x)
4236{ 4387{
4237 int h = 0; 4388 unsigned h = 0;
4238 while( *x) h = h*13 + *(x++); 4389 while( *x ) h = h*13 + *(x++);
4239 return h; 4390 return h;
4240} 4391}
4241 4392
@@ -4251,7 +4402,7 @@ const char *Strsafe(const char *y)
4251 if( y==0 ) return 0; 4402 if( y==0 ) return 0;
4252 z = Strsafe_find(y); 4403 z = Strsafe_find(y);
4253 if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){ 4404 if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
4254 strcpy(cpy,y); 4405 lemon_strcpy(cpy,y);
4255 z = cpy; 4406 z = cpy;
4256 Strsafe_insert(z); 4407 Strsafe_insert(z);
4257 } 4408 }
@@ -4290,8 +4441,7 @@ void Strsafe_init(){
4290 if( x1a ){ 4441 if( x1a ){
4291 x1a->size = 1024; 4442 x1a->size = 1024;
4292 x1a->count = 0; 4443 x1a->count = 0;
4293 x1a->tbl = (x1node*)malloc( 4444 x1a->tbl = (x1node*)calloc(1024, sizeof(x1node) + sizeof(x1node*));
4294 (sizeof(x1node) + sizeof(x1node*))*1024 );
4295 if( x1a->tbl==0 ){ 4445 if( x1a->tbl==0 ){
4296 free(x1a); 4446 free(x1a);
4297 x1a = 0; 4447 x1a = 0;
@@ -4307,8 +4457,8 @@ void Strsafe_init(){
4307int Strsafe_insert(const char *data) 4457int Strsafe_insert(const char *data)
4308{ 4458{
4309 x1node *np; 4459 x1node *np;
4310 int h; 4460 unsigned h;
4311 int ph; 4461 unsigned ph;
4312 4462
4313 if( x1a==0 ) return 0; 4463 if( x1a==0 ) return 0;
4314 ph = strhash(data); 4464 ph = strhash(data);
@@ -4328,8 +4478,7 @@ int Strsafe_insert(const char *data)
4328 struct s_x1 array; 4478 struct s_x1 array;
4329 array.size = size = x1a->size*2; 4479 array.size = size = x1a->size*2;
4330 array.count = x1a->count; 4480 array.count = x1a->count;
4331 array.tbl = (x1node*)malloc( 4481 array.tbl = (x1node*)calloc(size, sizeof(x1node) + sizeof(x1node*));
4332 (sizeof(x1node) + sizeof(x1node*))*size );
4333 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4482 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4334 array.ht = (x1node**)&(array.tbl[size]); 4483 array.ht = (x1node**)&(array.tbl[size]);
4335 for(i=0; i<size; i++) array.ht[i] = 0; 4484 for(i=0; i<size; i++) array.ht[i] = 0;
@@ -4362,7 +4511,7 @@ int Strsafe_insert(const char *data)
4362** if no such key. */ 4511** if no such key. */
4363const char *Strsafe_find(const char *key) 4512const char *Strsafe_find(const char *key)
4364{ 4513{
4365 int h; 4514 unsigned h;
4366 x1node *np; 4515 x1node *np;
4367 4516
4368 if( x1a==0 ) return 0; 4517 if( x1a==0 ) return 0;
@@ -4404,11 +4553,15 @@ struct symbol *Symbol_new(const char *x)
4404 return sp; 4553 return sp;
4405} 4554}
4406 4555
4407/* Compare two symbols for working purposes 4556/* Compare two symbols for sorting purposes. Return negative,
4557** zero, or positive if a is less then, equal to, or greater
4558** than b.
4408** 4559**
4409** Symbols that begin with upper case letters (terminals or tokens) 4560** Symbols that begin with upper case letters (terminals or tokens)
4410** must sort before symbols that begin with lower case letters 4561** must sort before symbols that begin with lower case letters
4411** (non-terminals). Other than that, the order does not matter. 4562** (non-terminals). And MULTITERMINAL symbols (created using the
4563** %token_class directive) must sort at the very end. Other than
4564** that, the order does not matter.
4412** 4565**
4413** We find experimentally that leaving the symbols in their original 4566** We find experimentally that leaving the symbols in their original
4414** order (the order they appeared in the grammar file) gives the 4567** order (the order they appeared in the grammar file) gives the
@@ -4416,12 +4569,11 @@ struct symbol *Symbol_new(const char *x)
4416*/ 4569*/
4417int Symbolcmpp(const void *_a, const void *_b) 4570int Symbolcmpp(const void *_a, const void *_b)
4418{ 4571{
4419 const struct symbol **a = (const struct symbol **) _a; 4572 const struct symbol *a = *(const struct symbol **) _a;
4420 const struct symbol **b = (const struct symbol **) _b; 4573 const struct symbol *b = *(const struct symbol **) _b;
4421 int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); 4574 int i1 = a->type==MULTITERMINAL ? 3 : a->name[0]>'Z' ? 2 : 1;
4422 int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); 4575 int i2 = b->type==MULTITERMINAL ? 3 : b->name[0]>'Z' ? 2 : 1;
4423 assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 ); 4576 return i1==i2 ? a->index - b->index : i1 - i2;
4424 return i1-i2;
4425} 4577}
4426 4578
4427/* There is one instance of the following structure for each 4579/* There is one instance of the following structure for each
@@ -4456,8 +4608,7 @@ void Symbol_init(){
4456 if( x2a ){ 4608 if( x2a ){
4457 x2a->size = 128; 4609 x2a->size = 128;
4458 x2a->count = 0; 4610 x2a->count = 0;
4459 x2a->tbl = (x2node*)malloc( 4611 x2a->tbl = (x2node*)calloc(128, sizeof(x2node) + sizeof(x2node*));
4460 (sizeof(x2node) + sizeof(x2node*))*128 );
4461 if( x2a->tbl==0 ){ 4612 if( x2a->tbl==0 ){
4462 free(x2a); 4613 free(x2a);
4463 x2a = 0; 4614 x2a = 0;
@@ -4473,8 +4624,8 @@ void Symbol_init(){
4473int Symbol_insert(struct symbol *data, const char *key) 4624int Symbol_insert(struct symbol *data, const char *key)
4474{ 4625{
4475 x2node *np; 4626 x2node *np;
4476 int h; 4627 unsigned h;
4477 int ph; 4628 unsigned ph;
4478 4629
4479 if( x2a==0 ) return 0; 4630 if( x2a==0 ) return 0;
4480 ph = strhash(key); 4631 ph = strhash(key);
@@ -4494,8 +4645,7 @@ int Symbol_insert(struct symbol *data, const char *key)
4494 struct s_x2 array; 4645 struct s_x2 array;
4495 array.size = size = x2a->size*2; 4646 array.size = size = x2a->size*2;
4496 array.count = x2a->count; 4647 array.count = x2a->count;
4497 array.tbl = (x2node*)malloc( 4648 array.tbl = (x2node*)calloc(size, sizeof(x2node) + sizeof(x2node*));
4498 (sizeof(x2node) + sizeof(x2node*))*size );
4499 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4649 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4500 array.ht = (x2node**)&(array.tbl[size]); 4650 array.ht = (x2node**)&(array.tbl[size]);
4501 for(i=0; i<size; i++) array.ht[i] = 0; 4651 for(i=0; i<size; i++) array.ht[i] = 0;
@@ -4530,7 +4680,7 @@ int Symbol_insert(struct symbol *data, const char *key)
4530** if no such key. */ 4680** if no such key. */
4531struct symbol *Symbol_find(const char *key) 4681struct symbol *Symbol_find(const char *key)
4532{ 4682{
4533 int h; 4683 unsigned h;
4534 x2node *np; 4684 x2node *np;
4535 4685
4536 if( x2a==0 ) return 0; 4686 if( x2a==0 ) return 0;
@@ -4604,9 +4754,9 @@ PRIVATE int statecmp(struct config *a, struct config *b)
4604} 4754}
4605 4755
4606/* Hash a state */ 4756/* Hash a state */
4607PRIVATE int statehash(struct config *a) 4757PRIVATE unsigned statehash(struct config *a)
4608{ 4758{
4609 int h=0; 4759 unsigned h=0;
4610 while( a ){ 4760 while( a ){
4611 h = h*571 + a->rp->index*37 + a->dot; 4761 h = h*571 + a->rp->index*37 + a->dot;
4612 a = a->bp; 4762 a = a->bp;
@@ -4655,8 +4805,7 @@ void State_init(){
4655 if( x3a ){ 4805 if( x3a ){
4656 x3a->size = 128; 4806 x3a->size = 128;
4657 x3a->count = 0; 4807 x3a->count = 0;
4658 x3a->tbl = (x3node*)malloc( 4808 x3a->tbl = (x3node*)calloc(128, sizeof(x3node) + sizeof(x3node*));
4659 (sizeof(x3node) + sizeof(x3node*))*128 );
4660 if( x3a->tbl==0 ){ 4809 if( x3a->tbl==0 ){
4661 free(x3a); 4810 free(x3a);
4662 x3a = 0; 4811 x3a = 0;
@@ -4672,8 +4821,8 @@ void State_init(){
4672int State_insert(struct state *data, struct config *key) 4821int State_insert(struct state *data, struct config *key)
4673{ 4822{
4674 x3node *np; 4823 x3node *np;
4675 int h; 4824 unsigned h;
4676 int ph; 4825 unsigned ph;
4677 4826
4678 if( x3a==0 ) return 0; 4827 if( x3a==0 ) return 0;
4679 ph = statehash(key); 4828 ph = statehash(key);
@@ -4693,8 +4842,7 @@ int State_insert(struct state *data, struct config *key)
4693 struct s_x3 array; 4842 struct s_x3 array;
4694 array.size = size = x3a->size*2; 4843 array.size = size = x3a->size*2;
4695 array.count = x3a->count; 4844 array.count = x3a->count;
4696 array.tbl = (x3node*)malloc( 4845 array.tbl = (x3node*)calloc(size, sizeof(x3node) + sizeof(x3node*));
4697 (sizeof(x3node) + sizeof(x3node*))*size );
4698 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4846 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4699 array.ht = (x3node**)&(array.tbl[size]); 4847 array.ht = (x3node**)&(array.tbl[size]);
4700 for(i=0; i<size; i++) array.ht[i] = 0; 4848 for(i=0; i<size; i++) array.ht[i] = 0;
@@ -4729,7 +4877,7 @@ int State_insert(struct state *data, struct config *key)
4729** if no such key. */ 4877** if no such key. */
4730struct state *State_find(struct config *key) 4878struct state *State_find(struct config *key)
4731{ 4879{
4732 int h; 4880 unsigned h;
4733 x3node *np; 4881 x3node *np;
4734 4882
4735 if( x3a==0 ) return 0; 4883 if( x3a==0 ) return 0;
@@ -4751,7 +4899,7 @@ struct state **State_arrayof()
4751 int i,size; 4899 int i,size;
4752 if( x3a==0 ) return 0; 4900 if( x3a==0 ) return 0;
4753 size = x3a->count; 4901 size = x3a->count;
4754 array = (struct state **)malloc( sizeof(struct state *)*size ); 4902 array = (struct state **)calloc(size, sizeof(struct state *));
4755 if( array ){ 4903 if( array ){
4756 for(i=0; i<size; i++) array[i] = x3a->tbl[i].data; 4904 for(i=0; i<size; i++) array[i] = x3a->tbl[i].data;
4757 } 4905 }
@@ -4759,9 +4907,9 @@ struct state **State_arrayof()
4759} 4907}
4760 4908
4761/* Hash a configuration */ 4909/* Hash a configuration */
4762PRIVATE int confighash(struct config *a) 4910PRIVATE unsigned confighash(struct config *a)
4763{ 4911{
4764 int h=0; 4912 unsigned h=0;
4765 h = h*571 + a->rp->index*37 + a->dot; 4913 h = h*571 + a->rp->index*37 + a->dot;
4766 return h; 4914 return h;
4767} 4915}
@@ -4797,8 +4945,7 @@ void Configtable_init(){
4797 if( x4a ){ 4945 if( x4a ){
4798 x4a->size = 64; 4946 x4a->size = 64;
4799 x4a->count = 0; 4947 x4a->count = 0;
4800 x4a->tbl = (x4node*)malloc( 4948 x4a->tbl = (x4node*)calloc(64, sizeof(x4node) + sizeof(x4node*));
4801 (sizeof(x4node) + sizeof(x4node*))*64 );
4802 if( x4a->tbl==0 ){ 4949 if( x4a->tbl==0 ){
4803 free(x4a); 4950 free(x4a);
4804 x4a = 0; 4951 x4a = 0;
@@ -4814,8 +4961,8 @@ void Configtable_init(){
4814int Configtable_insert(struct config *data) 4961int Configtable_insert(struct config *data)
4815{ 4962{
4816 x4node *np; 4963 x4node *np;
4817 int h; 4964 unsigned h;
4818 int ph; 4965 unsigned ph;
4819 4966
4820 if( x4a==0 ) return 0; 4967 if( x4a==0 ) return 0;
4821 ph = confighash(data); 4968 ph = confighash(data);
@@ -4835,8 +4982,7 @@ int Configtable_insert(struct config *data)
4835 struct s_x4 array; 4982 struct s_x4 array;
4836 array.size = size = x4a->size*2; 4983 array.size = size = x4a->size*2;
4837 array.count = x4a->count; 4984 array.count = x4a->count;
4838 array.tbl = (x4node*)malloc( 4985 array.tbl = (x4node*)calloc(size, sizeof(x4node) + sizeof(x4node*));
4839 (sizeof(x4node) + sizeof(x4node*))*size );
4840 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4986 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4841 array.ht = (x4node**)&(array.tbl[size]); 4987 array.ht = (x4node**)&(array.tbl[size]);
4842 for(i=0; i<size; i++) array.ht[i] = 0; 4988 for(i=0; i<size; i++) array.ht[i] = 0;