]>
Commit | Line | Data |
---|---|---|
30fdf114 LG |
1 | /* bits.c -- manage creation and output of bit sets used by the parser.\r |
2 | *\r | |
3 | * SOFTWARE RIGHTS\r | |
4 | *\r | |
5 | * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r | |
6 | * Set (PCCTS) -- PCCTS is in the public domain. An individual or\r | |
7 | * company may do whatever they wish with source code distributed with\r | |
8 | * PCCTS or the code generated by PCCTS, including the incorporation of\r | |
9 | * PCCTS, or its output, into commerical software.\r | |
10 | *\r | |
11 | * We encourage users to develop software with PCCTS. However, we do ask\r | |
12 | * that credit is given to us for developing PCCTS. By "credit",\r | |
13 | * we mean that if you incorporate our source code into one of your\r | |
14 | * programs (commercial product, research project, or otherwise) that you\r | |
15 | * acknowledge this fact somewhere in the documentation, research report,\r | |
16 | * etc... If you like PCCTS and have developed a nice tool with the\r | |
17 | * output, please mention that you developed it using PCCTS. In\r | |
18 | * addition, we ask that this header remain intact in our source code.\r | |
19 | * As long as these guidelines are kept, we expect to continue enhancing\r | |
20 | * this system and expect to make other tools available as they are\r | |
21 | * completed.\r | |
22 | *\r | |
23 | * ANTLR 1.33\r | |
24 | * Terence Parr\r | |
25 | * Parr Research Corporation\r | |
26 | * with Purdue University and AHPCRC, University of Minnesota\r | |
27 | * 1989-2001\r | |
28 | */\r | |
29 | \r | |
30 | #include <stdio.h>\r | |
31 | #include <stdlib.h>\r | |
32 | #include <ctype.h>\r | |
33 | #include <assert.h>\r | |
34 | #include "pcctscfg.h"\r | |
35 | #include "set.h"\r | |
36 | #include "syn.h"\r | |
37 | #include "hash.h"\r | |
38 | #include "generic.h"\r | |
39 | #include "dlgdef.h"\r | |
40 | \r | |
41 | /* char is only thing that is pretty much always known == 8 bits\r | |
42 | * This allows output of antlr (set stuff, anyway) to be androgynous (portable)\r | |
43 | */\r | |
44 | typedef unsigned char SetWordType;\r | |
45 | #define BitsPerByte 8\r | |
46 | #define BitsPerWord BitsPerByte*sizeof(SetWordType)\r | |
47 | \r | |
48 | static SetWordType *setwd = NULL;\r | |
49 | int setnum = -1;\r | |
50 | int wordnum = 0;\r | |
51 | \r | |
52 | int esetnum = 0;\r | |
53 | \r | |
54 | /* Used to convert native wordsize, which ANTLR uses (via set.c) to manipulate sets,\r | |
55 | to bytes that are most portable size-wise.\r | |
56 | */\r | |
57 | void\r | |
58 | #ifdef __USE_PROTOS\r | |
59 | DumpIntAsChars( FILE *f, char *format, unsigned wd )\r | |
60 | #else\r | |
61 | DumpIntAsChars( f, format, wd )\r | |
62 | FILE *f;\r | |
63 | char *format;\r | |
64 | unsigned wd;\r | |
65 | #endif\r | |
66 | {\r | |
67 | int i;\r | |
68 | /* uses max of 32 bit unsigned integer for the moment */\r | |
69 | static unsigned long byte_mask[sizeof(unsigned long)] =\r | |
70 | { 0xFF, 0xFF00UL, 0xFF0000UL, 0xFF000000UL }; /* MR20 G. Hobbelt */\r | |
71 | /* 0xFF00000000, 0xFF0000000000, 0xFF000000000000, 0xFF00000000000000 };*/\r | |
72 | \r | |
73 | /* for each byte in the word */\r | |
74 | assert(sizeof(unsigned) <= 4); /* M20 G. Hobbelt Sanity check */\r | |
75 | for (i=0; i<sizeof(unsigned); i++)\r | |
76 | {\r | |
77 | /* mask out the ith byte and shift down to the first 8 bits */\r | |
78 | fprintf(f, format, (wd&byte_mask[i])>>(i*BitsPerByte));\r | |
79 | if ( i<sizeof(unsigned)-1) fprintf(f, ",");\r | |
80 | }\r | |
81 | }\r | |
82 | \r | |
83 | /* Create a new setwd (ignoring [Ep] token on end) */\r | |
84 | void\r | |
85 | #ifdef __USE_PROTOS\r | |
86 | NewSetWd( void )\r | |
87 | #else\r | |
88 | NewSetWd( )\r | |
89 | #endif\r | |
90 | {\r | |
91 | SetWordType *p;\r | |
92 | \r | |
93 | if ( setwd == NULL )\r | |
94 | {\r | |
95 | setwd = (SetWordType *) calloc(TokenNum, sizeof(SetWordType));\r | |
96 | require(setwd!=NULL, "NewSetWd: cannot alloc set wd\n");\r | |
97 | }\r | |
98 | for (p = setwd; p<&(setwd[TokenNum]); p++) {*p=0;}\r | |
99 | wordnum++;\r | |
100 | }\r | |
101 | \r | |
102 | void\r | |
103 | #ifdef __USE_PROTOS\r | |
104 | DumpSetWd( void )\r | |
105 | #else\r | |
106 | DumpSetWd( )\r | |
107 | #endif\r | |
108 | {\r | |
109 | if ( GenCC ) DumpSetWdForCC();\r | |
110 | else DumpSetWdForC();\r | |
111 | }\r | |
112 | \r | |
113 | /* Dump the current setwd to ErrFile. 0..MaxTokenVal */\r | |
114 | void\r | |
115 | #ifdef __USE_PROTOS\r | |
116 | DumpSetWdForC( void )\r | |
117 | #else\r | |
118 | DumpSetWdForC( )\r | |
119 | #endif\r | |
120 | {\r | |
121 | int i,c=1;\r | |
122 | \r | |
123 | if ( setwd==NULL ) return;\r | |
124 | fprintf(DefFile, "extern SetWordType setwd%d[];\n", wordnum);\r | |
125 | fprintf(ErrFile,\r | |
126 | "SetWordType setwd%d[%d] = {", wordnum, TokenNum-1);\r | |
127 | for (i=0; i<TokenNum-1; i++)\r | |
128 | {\r | |
129 | DAWDLE;\r | |
130 | if ( i!=0 ) fprintf(ErrFile, ",");\r | |
131 | if ( c == 8 ) {fprintf(ErrFile, "\n\t"); c=1;} else c++;\r | |
132 | fprintf(ErrFile, "0x%x", setwd[i]);\r | |
133 | }\r | |
134 | fprintf(ErrFile, "};\n");\r | |
135 | }\r | |
136 | \r | |
137 | /* Dump the current setwd to Parser.C file. 0..MaxTokenVal;\r | |
138 | * Only used if -CC on.\r | |
139 | */\r | |
140 | void\r | |
141 | #ifdef __USE_PROTOS\r | |
142 | DumpSetWdForCC( void )\r | |
143 | #else\r | |
144 | DumpSetWdForCC( )\r | |
145 | #endif\r | |
146 | {\r | |
147 | int i,c=1;\r | |
148 | \r | |
149 | if ( setwd==NULL ) return;\r | |
150 | fprintf(Parser_h, "\tstatic SetWordType setwd%d[%d];\n", wordnum, TokenNum-1);\r | |
151 | fprintf(Parser_c,\r | |
152 | "SetWordType %s::setwd%d[%d] = {", CurrentClassName, wordnum,\r | |
153 | TokenNum-1);\r | |
154 | for (i=0; i<TokenNum-1; i++)\r | |
155 | {\r | |
156 | DAWDLE;\r | |
157 | if ( i!=0 ) fprintf(Parser_c, ",");\r | |
158 | if ( c == 8 ) {fprintf(Parser_c, "\n\t"); c=1;} else c++;\r | |
159 | fprintf(Parser_c, "0x%x", setwd[i]);\r | |
160 | }\r | |
161 | fprintf(Parser_c, "};\n");\r | |
162 | }\r | |
163 | \r | |
164 | /* Make a new set. Dump old setwd and create new setwd if current setwd is full */\r | |
165 | void\r | |
166 | #ifdef __USE_PROTOS\r | |
167 | NewSet( void )\r | |
168 | #else\r | |
169 | NewSet( )\r | |
170 | #endif\r | |
171 | {\r | |
172 | setnum++;\r | |
173 | if ( setnum==BitsPerWord ) /* is current setwd full? */\r | |
174 | {\r | |
175 | DumpSetWd(); NewSetWd(); setnum = 0;\r | |
176 | }\r | |
177 | }\r | |
178 | \r | |
179 | /* s is a set of tokens. Turn on bit at each token position in set 'setnum' */\r | |
180 | void\r | |
181 | #ifdef __USE_PROTOS\r | |
182 | FillSet( set s )\r | |
183 | #else\r | |
184 | FillSet( s )\r | |
185 | set s;\r | |
186 | #endif\r | |
187 | {\r | |
188 | SetWordType mask=(((unsigned)1)<<setnum);\r | |
189 | unsigned int e;\r | |
190 | \r | |
191 | while ( !set_nil(s) )\r | |
192 | {\r | |
193 | e = set_int(s);\r | |
194 | set_rm(e, s);\r | |
195 | setwd[e] |= mask;\r | |
196 | }\r | |
197 | }\r | |
198 | \r | |
199 | /* E r r o r C l a s s S t u f f */\r | |
200 | \r | |
201 | /* compute the FIRST of a rule for the error class stuff */\r | |
202 | static set\r | |
203 | #ifdef __USE_PROTOS\r | |
204 | Efirst( char *rule, ECnode *eclass )\r | |
205 | #else\r | |
206 | Efirst( rule, eclass )\r | |
207 | char *rule;\r | |
208 | ECnode *eclass;\r | |
209 | #endif\r | |
210 | {\r | |
211 | set rk, a;\r | |
212 | Junction *r;\r | |
213 | RuleEntry *q = (RuleEntry *) hash_get(Rname, rule);\r | |
214 | \r | |
215 | if ( q == NULL )\r | |
216 | {\r | |
217 | warnNoFL(eMsg2("undefined rule '%s' referenced in errclass '%s'; ignored",\r | |
218 | rule, TokenString(eclass->tok)));\r | |
219 | return empty;\r | |
220 | }\r | |
221 | r = RulePtr[q->rulenum];\r | |
222 | r->end->halt = TRUE; /* don't let reach fall off end of rule here */\r | |
223 | rk = empty;\r | |
224 | REACH(r, 1, &rk, a);\r | |
225 | r->end->halt = FALSE;\r | |
226 | return a;\r | |
227 | }\r | |
228 | \r | |
229 | /*\r | |
230 | * scan the list of tokens/eclasses/nonterminals filling the new eclass\r | |
231 | * with the set described by the list. Note that an eclass can be\r | |
232 | * quoted to allow spaces etc... However, an eclass must not conflict\r | |
233 | * with a reg expr found elsewhere. The reg expr will be taken over\r | |
234 | * the eclass name.\r | |
235 | */\r | |
236 | static void\r | |
237 | #ifdef __USE_PROTOS\r | |
238 | doEclass( char *eclass )\r | |
239 | #else\r | |
240 | doEclass( eclass )\r | |
241 | char *eclass;\r | |
242 | #endif\r | |
243 | {\r | |
244 | TermEntry *q;\r | |
245 | ECnode *p;\r | |
246 | TCnode *tcnode;\r | |
247 | ListNode *e;\r | |
248 | unsigned int t;\r | |
249 | unsigned deg=0;\r | |
250 | set a;\r | |
251 | require(eclass!=NULL, "doEclass: NULL eset");\r | |
252 | \r | |
253 | p = (ECnode *) eclass;\r | |
254 | lexmode(p->lexclass); /* switch to lexclass where errclass is defined */\r | |
255 | p->eset = empty;\r | |
256 | for (e = (p->elist)->next; e!=NULL; e=e->next)\r | |
257 | {\r | |
258 | q = NULL; /* MR23 */\r | |
259 | \r | |
260 | if ( islower( *((char *)e->elem) ) ) /* is it a rule ref? (alias FIRST request) */\r | |
261 | {\r | |
262 | a = Efirst((char *)e->elem, p);\r | |
263 | set_orin(&p->eset, a);\r | |
264 | deg += set_deg(a);\r | |
265 | set_free( a );\r | |
266 | continue;\r | |
267 | }\r | |
268 | else if ( *((char *)e->elem)=='"' )\r | |
269 | {\r | |
270 | t = 0;\r | |
271 | q = (TermEntry *) hash_get(Texpr, (char *) e->elem);\r | |
272 | if ( q == NULL )\r | |
273 | {\r | |
274 | /* if quoted and not an expr look for eclass name */\r | |
275 | q = (TermEntry *) hash_get(Tname, *((char **)&(e->elem))=StripQuotes((char *)e->elem));\r | |
276 | if ( q != NULL ) t = q->token;\r | |
277 | }\r | |
278 | else t = q->token;\r | |
279 | }\r | |
280 | else /* labelled token/eclass/tokclass */\r | |
281 | {\r | |
282 | q = (TermEntry *) hash_get(Tname, (char *)e->elem);\r | |
283 | if ( q != NULL )\r | |
284 | {\r | |
285 | if ( strcmp((char *)e->elem, TokenString(p->tok))==0 )\r | |
286 | {\r | |
287 | warnNoFL(eMsg1("self-referential error class '%s'; ignored",\r | |
288 | (char *)e->elem));\r | |
289 | continue;\r | |
290 | }\r | |
291 | else\r | |
292 | t = q->token;\r | |
293 | }\r | |
294 | else t=0;\r | |
295 | }\r | |
296 | if ( t!=0 )\r | |
297 | {\r | |
298 | if (isTermEntryTokClass(q)) { /* MR23 */\r | |
299 | tcnode = q->tclass; /* MR23 */\r | |
300 | set_orin(&p->eset, tcnode->tset); /* MR23 */\r | |
301 | deg = set_deg(p->eset); /* MR23 */\r | |
302 | } /* MR23 */\r | |
303 | else {\r | |
304 | set_orel(t, &p->eset);\r | |
305 | deg++;\r | |
306 | }\r | |
307 | }\r | |
308 | else warnNoFL(eMsg2("undefined token '%s' referenced in errclass '%s'; ignored",\r | |
309 | (char *)e->elem, TokenString(p->tok)));\r | |
310 | }\r | |
311 | p->setdeg = deg;\r | |
312 | }\r | |
313 | \r | |
314 | void\r | |
315 | #ifdef __USE_PROTOS\r | |
316 | ComputeErrorSets( void )\r | |
317 | #else\r | |
318 | ComputeErrorSets( )\r | |
319 | #endif\r | |
320 | {\r | |
321 | #ifdef __cplusplus\r | |
322 | list_apply(eclasses, (void (*)(void *)) doEclass);\r | |
323 | #else\r | |
324 | #ifdef __USE_PROTOS\r | |
325 | list_apply(eclasses, (void (*)(void *)) doEclass);\r | |
326 | #else\r | |
327 | list_apply(eclasses, doEclass);\r | |
328 | #endif\r | |
329 | #endif\r | |
330 | }\r | |
331 | \r | |
332 | void\r | |
333 | #ifdef __USE_PROTOS\r | |
334 | ComputeTokSets( void )\r | |
335 | #else\r | |
336 | ComputeTokSets( )\r | |
337 | #endif\r | |
338 | {\r | |
339 | ListNode *t, *e = NULL, *e1, *e2;\r | |
340 | int something_changed;\r | |
341 | int i;\r | |
342 | TCnode *p;\r | |
343 | TermEntry *q, *q1, *q2;\r | |
344 | \r | |
345 | if ( tclasses == NULL ) return;\r | |
346 | \r | |
347 | /* turn lists of token/tokclass references into sets */\r | |
348 | for (t = tclasses->next; t!=NULL; t=t->next)\r | |
349 | {\r | |
350 | p = (TCnode *) t->elem;\r | |
351 | \r | |
352 | /* if wild card, then won't have entries in tclass, assume all_tokens */\r | |
353 | if ( p->tok == WildCardToken )\r | |
354 | {\r | |
355 | p->tset = set_dup(all_tokens);\r | |
356 | continue;\r | |
357 | }\r | |
358 | \r | |
359 | lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */\r | |
360 | p->tset = empty;\r | |
361 | \r | |
362 | /* instantiate all tokens/token_classes into the tset */\r | |
363 | for (e = (p->tlist)->next; e!=NULL; e=e->next)\r | |
364 | {\r | |
365 | char *tokstr;\r | |
366 | tokstr = (char *)e->elem;\r | |
367 | if ( *tokstr == '"' ) {\r | |
368 | q = (TermEntry *) hash_get(Texpr, tokstr);\r | |
369 | require(q!=NULL, "ComputeTokSets: no token def");\r | |
370 | set_orel(q->token, &p->tset);\r | |
371 | } else if (tokstr[0] == '.') {\r | |
372 | e1=e->next;\r | |
373 | e2=e1->next;\r | |
374 | e=e2;\r | |
375 | q1= (TermEntry *) hash_get(Tname, (char *)e1->elem);\r | |
376 | require(q1!=NULL, "ComputeTokSets: no token def");\r | |
377 | q2= (TermEntry *) hash_get(Tname, (char *)e2->elem);\r | |
378 | require(q2!=NULL, "ComputeTokSets: no token def");\r | |
379 | \r | |
380 | if (set_el(q1->token,imag_tokens)) {\r | |
381 | errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s",\r | |
382 | TokenString(p->tok),(char *)e1->elem) );\r | |
383 | }\r | |
384 | if (set_el(q2->token,imag_tokens)) {\r | |
385 | errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s",\r | |
386 | TokenString(p->tok),(char *)e2->elem) );\r | |
387 | }\r | |
388 | if (q1->token > q2->token) {\r | |
389 | errNoFL(eMsg3("for #tokclass %s %s..%s - first token number > second token number",\r | |
390 | TokenString(p->tok),(char *)e1->elem,(char *)e2->elem) );\r | |
391 | for (i=q2->token; i<=q1->token; i++) { set_orel(i, &p->tset); }\r | |
392 | } else {\r | |
393 | for (i=q1->token; i<=q2->token; i++) { set_orel(i, &p->tset); }\r | |
394 | }\r | |
395 | } else {\r | |
396 | q = (TermEntry *) hash_get(Tname, tokstr);\r | |
397 | require(q!=NULL, "ComputeTokSets: no token def");\r | |
398 | set_orel(q->token, &p->tset);\r | |
399 | }\r | |
400 | }\r | |
401 | }\r | |
402 | \r | |
403 | /* Go thru list of tokclasses again looking for tokclasses in sets */\r | |
404 | again:\r | |
405 | something_changed = 0;\r | |
406 | for (t = tclasses->next; t!=NULL; t=t->next)\r | |
407 | {\r | |
408 | set tcl;\r | |
409 | p = (TCnode *) t->elem;\r | |
410 | tcl = set_and(p->tset, tokclasses);\r | |
411 | if ( !set_nil(tcl) )\r | |
412 | {\r | |
413 | int tk;\r | |
414 | /* replace refs to tokclasses with the associated set of tokens */\r | |
415 | something_changed = 1;\r | |
416 | while ( !set_nil(tcl) )\r | |
417 | {\r | |
418 | tk = set_int(tcl); /* grab one of the tok class refs */\r | |
419 | set_rm(tk, tcl);\r | |
420 | if ( p->tok != tk ) /* tokclass ref to yourself? */\r | |
421 | {\r | |
422 | q = (TermEntry *) hash_get(Tname, TokenString(tk));\r | |
423 | require(q!=NULL, "#tokclass not in hash table");\r | |
424 | set_orin(&p->tset, q->tclass->tset);\r | |
425 | }\r | |
426 | set_rm(tk, p->tset); /* remove ref that we replaced */\r | |
427 | }\r | |
428 | }\r | |
429 | set_free(tcl);\r | |
430 | }\r | |
431 | if ( something_changed ) goto again;\r | |
432 | }\r | |
433 | \r | |
434 | void\r | |
435 | #ifdef __USE_PROTOS\r | |
436 | DumpRemainingTokSets(void)\r | |
437 | #else\r | |
438 | DumpRemainingTokSets()\r | |
439 | #endif\r | |
440 | {\r | |
441 | TCnode *p;\r | |
442 | ListNode *t;\r | |
443 | \r | |
444 | /* Go thru tclasses (for the last time) and dump the sets not dumped\r | |
445 | * during code gen; yes, this is a bogus way to do this, but ComputeTokSets()\r | |
446 | * can't dump the defs as the error file and tok file has not been created\r | |
447 | * yet etc...\r | |
448 | */\r | |
449 | if ( tclasses==NULL ) return;\r | |
450 | for (t = tclasses->next; t!=NULL; t=t->next)\r | |
451 | {\r | |
452 | unsigned e;\r | |
453 | p = (TCnode *) t->elem;\r | |
454 | if ( p->dumped ) continue;\r | |
455 | e = DefErrSet(&(p->tset), 0, TokenString(p->tok));\r | |
456 | p->dumped = 1;\r | |
457 | p->setnum = e;\r | |
458 | }\r | |
459 | }\r | |
460 | \r | |
461 | \r | |
462 | /* replace a subset of an error set with an error class name if a subset is found\r | |
463 | * repeat process until no replacements made\r | |
464 | */\r | |
465 | void\r | |
466 | #ifdef __USE_PROTOS\r | |
467 | SubstErrorClass( set *f )\r | |
468 | #else\r | |
469 | SubstErrorClass( f )\r | |
470 | set *f;\r | |
471 | #endif\r | |
472 | {\r | |
473 | int max, done = 0;\r | |
474 | ListNode *p;\r | |
475 | ECnode *ec, *maxclass = NULL;\r | |
476 | set a;\r | |
477 | require(f!=NULL, "SubstErrorClass: NULL eset");\r | |
478 | \r | |
479 | if ( eclasses == NULL ) return;\r | |
480 | while ( !done )\r | |
481 | {\r | |
482 | max = 0;\r | |
483 | maxclass = NULL;\r | |
484 | for (p=eclasses->next; p!=NULL; p=p->next) /* chk all error classes */\r | |
485 | {\r | |
486 | ec = (ECnode *) p->elem;\r | |
487 | if ( ec->setdeg > max )\r | |
488 | {\r | |
489 | if ( set_sub(ec->eset, *f) || set_equ(ec->eset, *f) )\r | |
490 | {maxclass = ec; max=ec->setdeg;}\r | |
491 | }\r | |
492 | }\r | |
493 | if ( maxclass != NULL ) /* if subset found, replace with token */\r | |
494 | {\r | |
495 | a = set_dif(*f, maxclass->eset);\r | |
496 | set_orel((unsigned)maxclass->tok, &a);\r | |
497 | set_free(*f);\r | |
498 | *f = a;\r | |
499 | }\r | |
500 | else done = 1;\r | |
501 | }\r | |
502 | }\r | |
503 | \r | |
504 | int\r | |
505 | #ifdef __USE_PROTOS\r | |
506 | DefErrSet1(int nilOK, set *f, int subst, char *name )\r | |
507 | #else\r | |
508 | DefErrSet1(nilOK, f, subst, name )\r | |
509 | int nilOK;\r | |
510 | set *f;\r | |
511 | int subst; /* should be substitute error classes? */\r | |
512 | char *name;\r | |
513 | #endif\r | |
514 | {\r | |
515 | if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, "_set");\r | |
516 | else return DefErrSetForC1(nilOK, f, subst, name, "_set");\r | |
517 | }\r | |
518 | \r | |
519 | int\r | |
520 | #ifdef __USE_PROTOS\r | |
521 | DefErrSet( set *f, int subst, char *name )\r | |
522 | #else\r | |
523 | DefErrSet( f, subst, name )\r | |
524 | set *f;\r | |
525 | int subst; /* should be substitute error classes? */\r | |
526 | char *name;\r | |
527 | #endif\r | |
528 | {\r | |
529 | return DefErrSet1(0,f,subst,name);\r | |
530 | }\r | |
531 | \r | |
532 | int\r | |
533 | #ifdef __USE_PROTOS\r | |
534 | DefErrSetWithSuffix(int nilOK, set *f, int subst, char *name, const char* suffix)\r | |
535 | #else\r | |
536 | DefErrSetWithSuffix(nilOK, f, subst, name, suffix )\r | |
537 | int nilOK;\r | |
538 | set *f;\r | |
539 | int subst; /* should be substitute error classes? */\r | |
540 | char *name;\r | |
541 | char *suffix;\r | |
542 | #endif\r | |
543 | {\r | |
544 | if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, suffix );\r | |
545 | else return DefErrSetForC1(nilOK, f, subst, name, suffix);\r | |
546 | }\r | |
547 | \r | |
548 | /* Define a new error set. WARNING...set-implementation dependent.\r | |
549 | */\r | |
550 | int\r | |
551 | #ifdef __USE_PROTOS\r | |
552 | DefErrSetForC1(int nilOK, set *f, int subst, char * name, const char * suffix)\r | |
553 | #else\r | |
554 | DefErrSetForC1(nilOK, f, subst, name, suffix)\r | |
555 | int nilOK; /* MR13 */\r | |
556 | set *f;\r | |
557 | int subst; /* should be substitute error classes? */\r | |
558 | char *name;\r | |
559 | const char *suffix;\r | |
560 | #endif\r | |
561 | {\r | |
562 | unsigned *p, *endp;\r | |
563 | int e=1;\r | |
564 | \r | |
565 | if (!nilOK) require(!set_nil(*f), "DefErrSetForC1: nil set to dump?");\r | |
566 | \r | |
567 | if ( subst ) SubstErrorClass(f);\r | |
568 | p = f->setword;\r | |
569 | endp = &(f->setword[f->n]);\r | |
570 | esetnum++;\r | |
571 | if ( name!=NULL )\r | |
572 | fprintf(DefFile, "extern SetWordType %s%s[];\n", name, suffix);\r | |
573 | else\r | |
574 | fprintf(DefFile, "extern SetWordType zzerr%d[];\n", esetnum);\r | |
575 | if ( name!=NULL ) {\r | |
8230d45b | 576 | fprintf(ErrFile, "SetWordType %s%s[%lu] = {",\r |
30fdf114 LG |
577 | name,\r |
578 | suffix,\r | |
579 | NumWords(TokenNum-1)*sizeof(unsigned));\r | |
580 | }\r | |
581 | else {\r | |
8230d45b | 582 | fprintf(ErrFile, "SetWordType zzerr%d[%lu] = {",\r |
30fdf114 LG |
583 | esetnum,\r |
584 | NumWords(TokenNum-1)*sizeof(unsigned));\r | |
585 | }\r | |
586 | while ( p < endp )\r | |
587 | {\r | |
588 | if ( e > 1 ) fprintf(ErrFile, ", ");\r | |
589 | DumpIntAsChars(ErrFile, "0x%x", *p++);\r | |
590 | if ( e == 3 )\r | |
591 | {\r | |
592 | DAWDLE;\r | |
593 | if ( p < endp ) fprintf(ErrFile, ",");\r | |
594 | fprintf(ErrFile, "\n\t");\r | |
595 | e=1;\r | |
596 | }\r | |
597 | else e++;\r | |
598 | }\r | |
599 | fprintf(ErrFile, "};\n");\r | |
600 | \r | |
601 | return esetnum;\r | |
602 | }\r | |
603 | \r | |
604 | int\r | |
605 | #ifdef __USE_PROTOS\r | |
606 | DefErrSetForC( set *f, int subst, char *name )\r | |
607 | #else\r | |
608 | DefErrSetForC( f, subst, name )\r | |
609 | set *f;\r | |
610 | int subst; /* should be substitute error classes? */\r | |
611 | char *name;\r | |
612 | #endif\r | |
613 | {\r | |
614 | return DefErrSetForC1(0,f,subst,name, "_set");\r | |
615 | }\r | |
616 | \r | |
617 | /* Define a new error set. WARNING...set-implementation dependent;\r | |
618 | * Only used when -CC on.\r | |
619 | */\r | |
620 | \r | |
621 | int\r | |
622 | #ifdef __USE_PROTOS\r | |
623 | DefErrSetForCC1(int nilOK, set *f, int subst, char *name, const char *suffix )\r | |
624 | #else\r | |
625 | DefErrSetForCC1(nilOK, f, subst, name, suffix )\r | |
626 | int nilOK; /* MR13 */\r | |
627 | set *f;\r | |
628 | int subst; /* should be substitute error classes? */\r | |
629 | char *name;\r | |
630 | const char *suffix;\r | |
631 | #endif\r | |
632 | {\r | |
633 | unsigned *p, *endp;\r | |
634 | int e=1;\r | |
635 | \r | |
636 | if (!nilOK) require(!set_nil(*f), "DefErrSetForCC1: nil set to dump?");\r | |
637 | \r | |
638 | if ( subst ) SubstErrorClass(f);\r | |
639 | p = f->setword;\r | |
640 | endp = &(f->setword[f->n]);\r | |
641 | esetnum++;\r | |
642 | \r | |
643 | if ( name!=NULL ) {\r | |
8230d45b | 644 | fprintf(Parser_h, "\tstatic SetWordType %s%s[%lu];\n", name, suffix,\r |
30fdf114 | 645 | NumWords(TokenNum-1)*sizeof(unsigned));\r |
8230d45b | 646 | fprintf(Parser_c, "SetWordType %s::%s%s[%lu] = {",\r |
30fdf114 LG |
647 | CurrentClassName,\r |
648 | name,\r | |
649 | suffix,\r | |
650 | NumWords(TokenNum-1)*sizeof(unsigned));\r | |
651 | }\r | |
652 | else {\r | |
8230d45b | 653 | fprintf(Parser_c, "SetWordType %s::err%d[%lu] = {",\r |
30fdf114 LG |
654 | CurrentClassName,\r |
655 | esetnum,\r | |
656 | NumWords(TokenNum-1)*sizeof(unsigned));\r | |
8230d45b | 657 | fprintf(Parser_h, "\tstatic SetWordType err%d[%lu];\n", esetnum,\r |
30fdf114 LG |
658 | NumWords(TokenNum-1)*sizeof(unsigned));\r |
659 | }\r | |
660 | \r | |
661 | while ( p < endp )\r | |
662 | {\r | |
663 | if ( e > 1 ) fprintf(Parser_c, ", ");\r | |
664 | DumpIntAsChars(Parser_c, "0x%x", *p++);\r | |
665 | if ( e == 3 )\r | |
666 | {\r | |
667 | if ( p < endp ) fprintf(Parser_c, ",");\r | |
668 | fprintf(Parser_c, "\n\t");\r | |
669 | e=1;\r | |
670 | }\r | |
671 | else e++;\r | |
672 | }\r | |
673 | fprintf(Parser_c, "};\n");\r | |
674 | \r | |
675 | return esetnum;\r | |
676 | }\r | |
677 | \r | |
678 | int\r | |
679 | #ifdef __USE_PROTOS\r | |
680 | DefErrSetForCC( set *f, int subst, char *name )\r | |
681 | #else\r | |
682 | DefErrSetForCC( f, subst, name )\r | |
683 | set *f;\r | |
684 | int subst; /* should be substitute error classes? */\r | |
685 | char *name;\r | |
686 | #endif\r | |
687 | {\r | |
688 | return DefErrSetForCC1(0,f,subst,name, "_set");\r | |
689 | }\r | |
690 | \r | |
691 | void\r | |
692 | #ifdef __USE_PROTOS\r | |
693 | GenParser_c_Hdr(void)\r | |
694 | #else\r | |
695 | GenParser_c_Hdr()\r | |
696 | #endif\r | |
697 | {\r | |
698 | int i,j;\r | |
699 | TermEntry *te;\r | |
700 | char * hasAkaName = NULL; /* MR23 */\r | |
701 | \r | |
702 | hasAkaName = (char *) malloc(TokenNum+1); /* MR23 */\r | |
703 | require(hasAkaName!=NULL, "Cannot alloc hasAkaName\n"); /* MR23 */\r | |
704 | for (i = 0; i < TokenNum; i++) hasAkaName[i]='0'; /* MR23 */\r | |
705 | hasAkaName[TokenNum] = 0; /* MR23 */\r | |
706 | \r | |
707 | fprintf(Parser_c, "/*\n");\r | |
708 | fprintf(Parser_c, " * %s: P a r s e r S u p p o r t\n", CurrentClassName);\r | |
709 | fprintf(Parser_c, " *\n");\r | |
710 | fprintf(Parser_c, " * Generated from:");\r | |
711 | for (i=0; i<NumFiles; i++) fprintf(Parser_c, " %s", FileStr[i]);\r | |
712 | fprintf(Parser_c, "\n");\r | |
713 | fprintf(Parser_c, " *\n");\r | |
714 | fprintf(Parser_c, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");\r | |
715 | fprintf(Parser_c, " * Parr Research Corporation\n");\r | |
716 | fprintf(Parser_c, " * with Purdue University Electrical Engineering\n");\r | |
717 | fprintf(Parser_c, " * with AHPCRC, University of Minnesota\n");\r | |
718 | fprintf(Parser_c, " * ANTLR Version %s\n", Version);\r | |
719 | fprintf(Parser_c, " */\n\n");\r | |
720 | \r | |
721 | if ( FirstAction != NULL ) dumpAction(FirstAction,Parser_c, 0, -1, 0, 1); /* MR11 MR15b */\r | |
722 | \r | |
723 | fprintf(Parser_c, "#define ANTLR_VERSION %s\n", VersionDef);\r | |
724 | \r | |
725 | fprintf(Parser_c, "#include \"pcctscfg.h\"\n");\r | |
726 | fprintf(Parser_c, "#include \"pccts_stdio.h\"\n");\r | |
727 | fprintf(Parser_c, "#define ANTLR_SUPPORT_CODE\n");\r | |
728 | if ( UserTokenDefsFile != NULL )\r | |
729 | fprintf(Parser_c, "#include %s\n", UserTokenDefsFile);\r | |
730 | else\r | |
731 | fprintf(Parser_c, "#include \"%s\"\n", DefFileName);\r | |
732 | \r | |
733 | fprintf(Parser_c, "#include \"%s.h\"\n\n", CurrentClassName);\r | |
734 | \r | |
735 | fprintf(Parser_c, "const ANTLRChar *%s::tokenName(int tok) ", /* MR1 */\r | |
736 | CurrentClassName); /* MR1 */\r | |
737 | fprintf(Parser_c, " { return _token_tbl[tok]; }\n"); /* MR1 */ /* MR10 */\r | |
738 | /* Dump a Parser::tokens for each automaton */\r | |
739 | fprintf(Parser_c, "\nconst ANTLRChar *%s::_token_tbl[]={\n",\r | |
740 | CurrentClassName); /* MR20 */\r | |
741 | fprintf(Parser_c, "\t/* 00 */\t\"Invalid\"");\r | |
742 | \r | |
743 | for (i=1; i<TokenNum-1; i++)\r | |
744 | {\r | |
745 | DAWDLE;\r | |
746 | if ( i == EpToken ) continue;\r | |
747 | /* remapped to invalid token? */\r | |
748 | if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )\r | |
749 | {\r | |
750 | fprintf(Parser_c, ",\n\t/* %02d */\t\"invalid\"", i);\r | |
751 | continue;\r | |
752 | }\r | |
753 | if ( TokenString(i) != NULL ) {\r | |
754 | te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */\r | |
755 | if (te == NULL || te->akaString == NULL) { /* MR11 */\r | |
756 | fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));\r | |
757 | } else {\r | |
758 | hasAkaName[i] = '1'; /* MR23 */\r | |
759 | fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */\r | |
760 | }\r | |
761 | }\r | |
762 | else\r | |
763 | {\r | |
764 | /* look in all lexclasses for the reg expr */\r | |
765 | for (j=0; j<NumLexClasses; j++)\r | |
766 | {\r | |
767 | lexmode(j);\r | |
768 | if ( ExprString(i) != NULL )\r | |
769 | {\r | |
770 | fprintf(Parser_c, ",\n\t/* %02d */\t", i);\r | |
771 | dumpExpr(Parser_c, ExprString(i));\r | |
772 | break;\r | |
773 | }\r | |
774 | }\r | |
775 | if ( j>=NumLexClasses )\r | |
776 | {\r | |
777 | if ( UserDefdTokens )\r | |
778 | {\r | |
779 | fprintf(Parser_c, ",\n\t/* %02d */\t\"\"", i);\r | |
780 | }\r | |
781 | else\r | |
782 | fatal_internal(eMsgd("No label or expr for token %d",i));\r | |
783 | }\r | |
784 | }\r | |
785 | }\r | |
786 | fprintf(Parser_c, "\n};\n");\r | |
787 | \r | |
788 | /* Build constructors */\r | |
789 | fprintf(Parser_c, "\n%s::", CurrentClassName);\r | |
8230d45b | 790 | fprintf(Parser_c, "%s(ANTLRTokenBuffer *input) : %s(input,%d,%d,%d,%lu)\n",\r |
30fdf114 LG |
791 | CurrentClassName,\r |
792 | (BaseClassName == NULL ? "ANTLRParser" : BaseClassName),\r | |
793 | OutputLL_k,\r | |
794 | FoundGuessBlk,\r | |
795 | DemandLookahead,\r | |
796 | NumWords(TokenNum-1)*sizeof(unsigned));\r | |
797 | fprintf(Parser_c, "{\n");\r | |
798 | fprintf(Parser_c, "\ttoken_tbl = _token_tbl;\n");\r | |
799 | if (TraceGen) {\r | |
800 | fprintf(Parser_c, "\ttraceOptionValueDefault=1;\t\t// MR10 turn trace ON\n");\r | |
801 | } else {\r | |
802 | fprintf(Parser_c, "\ttraceOptionValueDefault=0;\t\t// MR10 turn trace OFF\n");\r | |
803 | };\r | |
804 | fprintf(Parser_c, "}\n\n");\r | |
805 | free ( (void *) hasAkaName);\r | |
806 | }\r | |
807 | \r | |
808 | void\r | |
809 | #ifdef __USE_PROTOS\r | |
810 | GenParser_h_Hdr(void)\r | |
811 | #else\r | |
812 | GenParser_h_Hdr()\r | |
813 | #endif\r | |
814 | {\r | |
815 | int i;\r | |
816 | \r | |
817 | fprintf(Parser_h, "/*\n");\r | |
818 | fprintf(Parser_h, " * %s: P a r s e r H e a d e r \n", CurrentClassName);\r | |
819 | fprintf(Parser_h, " *\n");\r | |
820 | fprintf(Parser_h, " * Generated from:");\r | |
821 | for (i=0; i<NumFiles; i++) fprintf(Parser_h, " %s", FileStr[i]);\r | |
822 | fprintf(Parser_h, "\n");\r | |
823 | fprintf(Parser_h, " *\n");\r | |
824 | fprintf(Parser_h, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");\r | |
825 | fprintf(Parser_h, " * Parr Research Corporation\n");\r | |
826 | fprintf(Parser_h, " * with Purdue University Electrical Engineering\n");\r | |
827 | fprintf(Parser_h, " * with AHPCRC, University of Minnesota\n");\r | |
828 | fprintf(Parser_h, " * ANTLR Version %s\n", Version);\r | |
829 | fprintf(Parser_h, " */\n\n");\r | |
830 | \r | |
831 | if ( FirstAction != NULL ) dumpAction( FirstAction, Parser_h, 0, -1, 0, 1); /* MR11 MR15b */\r | |
832 | \r | |
833 | fprintf(Parser_h, "#ifndef %s_h\n", CurrentClassName);\r | |
834 | fprintf(Parser_h, "#define %s_h\n\n", CurrentClassName);\r | |
835 | \r | |
836 | fprintf(Parser_h, "#ifndef ANTLR_VERSION\n");\r | |
837 | fprintf(Parser_h, "#define ANTLR_VERSION %s\n",VersionDef);\r | |
838 | fprintf(Parser_h, "#endif\n\n");\r | |
839 | \r | |
840 | if ( GenAST ) fprintf(Parser_h, "class ASTBase;\n");\r | |
841 | if (TraceGen) {\r | |
842 | fprintf(Parser_h,"#ifndef zzTRACE_RULES\n"); /* MR20 */\r | |
843 | fprintf(Parser_h,"#define zzTRACE_RULES\n"); /* MR20 */\r | |
844 | fprintf(Parser_h,"#endif\n"); /* MR22 */\r | |
845 | };\r | |
846 | fprintf(Parser_h, "#include \"%s\"\n\n", APARSER_H);\r | |
847 | \r | |
848 | if ( HdrAction != NULL ) dumpAction( HdrAction, Parser_h, 0, -1, 0, 1);\r | |
849 | \r | |
850 | /* MR10 */ if (ClassDeclStuff == NULL) {\r | |
851 | /* MR10 */ fprintf(Parser_h, "class %s : public ANTLRParser {\n", CurrentClassName);\r | |
852 | /* MR10 */ } else {\r | |
853 | /* MR10 */ fprintf(Parser_h, "class %s %s {\n",CurrentClassName,ClassDeclStuff);\r | |
854 | /* MR10 */ };\r | |
855 | \r | |
856 | fprintf(Parser_h, "public:\n"); /* MR1 */\r | |
857 | fprintf(Parser_h, "\tstatic const ANTLRChar *tokenName(int tk);\n");/* MR1 */\r | |
858 | fprintf(Parser_h, "\tenum { SET_SIZE = %i };\n",TokenNum-1); /* MR21 */\r | |
859 | fprintf(Parser_h, "protected:\n");\r | |
860 | fprintf(Parser_h, "\tstatic const ANTLRChar *_token_tbl[];\n"); /* MR20 */\r | |
861 | fprintf(Parser_h, "private:\n");\r | |
862 | }\r | |
863 | \r | |
864 | /* Currently, this is only used in !GenCC mode */\r | |
865 | void\r | |
866 | #ifdef __USE_PROTOS\r | |
867 | GenErrHdr( void )\r | |
868 | #else\r | |
869 | GenErrHdr( )\r | |
870 | #endif\r | |
871 | {\r | |
872 | int i, j;\r | |
873 | TermEntry *te;\r | |
874 | \r | |
875 | fprintf(ErrFile, "/*\n");\r | |
876 | fprintf(ErrFile, " * A n t l r S e t s / E r r o r F i l e H e a d e r\n");\r | |
877 | fprintf(ErrFile, " *\n");\r | |
878 | fprintf(ErrFile, " * Generated from:");\r | |
879 | for (i=0; i<NumFiles; i++) fprintf(ErrFile, " %s", FileStr[i]);\r | |
880 | fprintf(ErrFile, "\n");\r | |
881 | fprintf(ErrFile, " *\n");\r | |
882 | fprintf(ErrFile, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");\r | |
883 | fprintf(ErrFile, " * Parr Research Corporation\n");\r | |
884 | fprintf(ErrFile, " * with Purdue University Electrical Engineering\n");\r | |
885 | fprintf(ErrFile, " * With AHPCRC, University of Minnesota\n");\r | |
886 | fprintf(ErrFile, " * ANTLR Version %s\n", Version);\r | |
887 | fprintf(ErrFile, " */\n\n");\r | |
888 | \r | |
889 | if ( FirstAction != NULL ) dumpAction( FirstAction, ErrFile, 0, -1, 0, 1); /* MR11 MR15b */\r | |
890 | \r | |
891 | fprintf(ErrFile, "#define ANTLR_VERSION %s\n", VersionDef);\r | |
892 | \r | |
893 | fprintf(ErrFile, "#include \"pcctscfg.h\"\n");\r | |
894 | fprintf(ErrFile, "#include \"pccts_stdio.h\"\n");\r | |
895 | if ( strcmp(ParserName, DefaultParserName)!=0 )\r | |
896 | fprintf(ErrFile, "#define %s %s\n", DefaultParserName, ParserName);\r | |
897 | if ( strcmp(ParserName, DefaultParserName)!=0 )\r | |
898 | fprintf(ErrFile, "#include \"%s\"\n", RemapFileName);\r | |
899 | if ( HdrAction != NULL ) dumpAction( HdrAction, ErrFile, 0, -1, 0, 1 );\r | |
900 | if ( FoundGuessBlk )\r | |
901 | {\r | |
902 | fprintf(ErrFile, "#define ZZCAN_GUESS\n");\r | |
903 | fprintf(ErrFile, "#include \"pccts_setjmp.h\"\n");\r | |
904 | }\r | |
905 | if (TraceGen) {\r | |
906 | fprintf(ErrFile,"#ifndef zzTRACE_RULES\n"); /* MR20 */\r | |
907 | fprintf(ErrFile,"#define zzTRACE_RULES\n"); /* MR20 */\r | |
908 | fprintf(ErrFile,"#endif\n"); /* MR22 */\r | |
909 | };\r | |
910 | \r | |
911 | if ( OutputLL_k > 1 ) fprintf(ErrFile, "#define LL_K %d\n", OutputLL_k);\r | |
912 | #ifdef DUM\r | |
913 | if ( LexGen ) fprintf(ErrFile, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));\r | |
914 | #endif\r | |
8230d45b | 915 | fprintf(ErrFile, "#define zzSET_SIZE %lu\n", NumWords(TokenNum-1)*sizeof(unsigned));\r |
30fdf114 LG |
916 | if ( DemandLookahead ) fprintf(ErrFile, "#define DEMAND_LOOK\n");\r |
917 | fprintf(ErrFile, "#include \"antlr.h\"\n");\r | |
918 | if ( GenAST ) fprintf(ErrFile, "#include \"ast.h\"\n");\r | |
919 | \r | |
920 | if ( UserDefdTokens ) fprintf(ErrFile, "#include %s\n", UserTokenDefsFile);\r | |
921 | /* still need this one as it has the func prototypes */\r | |
922 | fprintf(ErrFile, "#include \"%s\"\n", DefFileName);\r | |
923 | fprintf(ErrFile, "#include \"dlgdef.h\"\n");\r | |
924 | fprintf(ErrFile, "#include \"err.h\"\n\n");\r | |
925 | \r | |
926 | /* Dump a zztokens for each automaton */\r | |
927 | if ( strcmp(ParserName, DefaultParserName)!=0 )\r | |
928 | {\r | |
929 | fprintf(ErrFile, "ANTLRChar *%s_zztokens[%d]={\n", ParserName, TokenNum-1);\r | |
930 | }\r | |
931 | else\r | |
932 | {\r | |
933 | fprintf(ErrFile, "ANTLRChar *zztokens[%d]={\n", TokenNum-1);\r | |
934 | }\r | |
935 | fprintf(ErrFile, "\t/* 00 */\t\"Invalid\"");\r | |
936 | for (i=1; i<TokenNum-1; i++)\r | |
937 | {\r | |
938 | DAWDLE;\r | |
939 | if ( i == EpToken ) continue;\r | |
940 | /* remapped to invalid token? */\r | |
941 | if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )\r | |
942 | {\r | |
943 | fprintf(ErrFile, ",\n\t/* %02d */\t\"invalid\"", i);\r | |
944 | continue;\r | |
945 | }\r | |
946 | if ( TokenString(i) != NULL ) {\r | |
947 | te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */\r | |
948 | if (te == NULL || te->akaString == NULL) { /* MR11 */\r | |
949 | fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));\r | |
950 | } else {\r | |
951 | fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */\r | |
952 | }\r | |
953 | }\r | |
954 | else\r | |
955 | {\r | |
956 | /* look in all lexclasses for the reg expr */\r | |
957 | for (j=0; j<NumLexClasses; j++)\r | |
958 | {\r | |
959 | lexmode(j);\r | |
960 | if ( ExprString(i) != NULL )\r | |
961 | {\r | |
962 | fprintf(ErrFile, ",\n\t/* %02d */\t", i);\r | |
963 | dumpExpr(ErrFile, ExprString(i));\r | |
964 | break;\r | |
965 | }\r | |
966 | }\r | |
967 | if ( j>=NumLexClasses )\r | |
968 | {\r | |
969 | if ( UserDefdTokens )\r | |
970 | {\r | |
971 | fprintf(ErrFile, ",\n\t/* %02d */\t\"\"", i);\r | |
972 | }\r | |
973 | else\r | |
974 | fatal_internal(eMsgd("No label or expr for token %d",i));\r | |
975 | }\r | |
976 | }\r | |
977 | }\r | |
978 | fprintf(ErrFile, "\n};\n");\r | |
979 | }\r | |
980 | \r | |
981 | void\r | |
982 | #ifdef __USE_PROTOS\r | |
983 | dumpExpr( FILE *f, char *e )\r | |
984 | #else\r | |
985 | dumpExpr( f, e )\r | |
986 | FILE *f;\r | |
987 | char *e;\r | |
988 | #endif\r | |
989 | {\r | |
990 | while ( *e!='\0' )\r | |
991 | {\r | |
992 | if ( *e=='\\' && *(e+1)=='\\' )\r | |
993 | {putc('\\', f); putc('\\', f); e+=2;}\r | |
994 | else if ( *e=='\\' && *(e+1)=='"' )\r | |
995 | {putc('\\', f); putc('"', f); e+=2;}\r | |
996 | else if ( *e=='\\' ) {putc('\\', f); putc('\\', f); e++;}\r | |
997 | else {putc(*e, f); e++;}\r | |
998 | }\r | |
999 | }\r | |
1000 | \r | |
1001 | int\r | |
1002 | #ifdef __USE_PROTOS\r | |
1003 | isTermEntryTokClass(TermEntry *te)\r | |
1004 | #else\r | |
1005 | isTermEntryTokClass(te)\r | |
1006 | TermEntry *te;\r | |
1007 | #endif\r | |
1008 | {\r | |
1009 | ListNode *t;\r | |
1010 | TCnode *p;\r | |
1011 | TermEntry *q;\r | |
1012 | char *tokstr;\r | |
1013 | \r | |
1014 | if (tclasses == NULL) return 0;\r | |
1015 | \r | |
1016 | for (t = tclasses->next; t!=NULL; t=t->next)\r | |
1017 | {\r | |
1018 | p = (TCnode *) t->elem;\r | |
1019 | tokstr = TokenString(p->tok);\r | |
1020 | lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */\r | |
1021 | q = (TermEntry *) hash_get(Tname, tokstr);\r | |
1022 | if (q == te) return 1;\r | |
1023 | }\r | |
1024 | return 0;\r | |
1025 | }\r |