aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/lemon/lemon.c
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/lemon/lemon.c
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 '')
-rw-r--r--libraries/lemon/lemon.c378
1 files changed, 262 insertions, 116 deletions
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;