]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/CodeTools/TianoTools/Pccts/antlr/bits.c
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / CodeTools / TianoTools / Pccts / antlr / bits.c
CommitLineData
878ddf1f 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
44typedef unsigned char SetWordType;\r
45#define BitsPerByte 8\r
46#define BitsPerWord BitsPerByte*sizeof(SetWordType)\r
47\r
48static SetWordType *setwd = NULL;\r
49int setnum = -1;\r
50int wordnum = 0;\r
51\r
52int 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
57void\r
58#ifdef __USE_PROTOS\r
59DumpIntAsChars( FILE *f, char *format, unsigned wd )\r
60#else\r
61DumpIntAsChars( f, format, wd )\r
62FILE *f;\r
63char *format;\r
64unsigned 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
84void\r
85#ifdef __USE_PROTOS\r
86NewSetWd( void )\r
87#else\r
88NewSetWd( )\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
102void\r
103#ifdef __USE_PROTOS\r
104DumpSetWd( void )\r
105#else\r
106DumpSetWd( )\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
114void\r
115#ifdef __USE_PROTOS\r
116DumpSetWdForC( void )\r
117#else\r
118DumpSetWdForC( )\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
140void\r
141#ifdef __USE_PROTOS\r
142DumpSetWdForCC( void )\r
143#else\r
144DumpSetWdForCC( )\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
165void\r
166#ifdef __USE_PROTOS\r
167NewSet( void )\r
168#else\r
169NewSet( )\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
180void\r
181#ifdef __USE_PROTOS\r
182FillSet( set s )\r
183#else\r
184FillSet( s )\r
185set 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
202static set\r
203#ifdef __USE_PROTOS\r
204Efirst( char *rule, ECnode *eclass )\r
205#else\r
206Efirst( rule, eclass )\r
207char *rule;\r
208ECnode *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
236static void\r
237#ifdef __USE_PROTOS\r
238doEclass( char *eclass )\r
239#else\r
240doEclass( eclass )\r
241char *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
314void\r
315#ifdef __USE_PROTOS\r
316ComputeErrorSets( void )\r
317#else\r
318ComputeErrorSets( )\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
332void\r
333#ifdef __USE_PROTOS\r
334ComputeTokSets( void )\r
335#else\r
336ComputeTokSets( )\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
381errNoFL(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
385errNoFL(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
389errNoFL(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
404again:\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
434void\r
435#ifdef __USE_PROTOS\r
436DumpRemainingTokSets(void)\r
437#else\r
438DumpRemainingTokSets()\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
465void\r
466#ifdef __USE_PROTOS\r
467SubstErrorClass( set *f )\r
468#else\r
469SubstErrorClass( f )\r
470set *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
504int\r
505#ifdef __USE_PROTOS\r
506DefErrSet1(int nilOK, set *f, int subst, char *name )\r
507#else\r
508DefErrSet1(nilOK, f, subst, name )\r
509int nilOK;\r
510set *f;\r
511int subst; /* should be substitute error classes? */\r
512char *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
519int\r
520#ifdef __USE_PROTOS\r
521DefErrSet( set *f, int subst, char *name )\r
522#else\r
523DefErrSet( f, subst, name )\r
524set *f;\r
525int subst; /* should be substitute error classes? */\r
526char *name;\r
527#endif\r
528{\r
529 return DefErrSet1(0,f,subst,name);\r
530}\r
531\r
532int\r
533#ifdef __USE_PROTOS\r
534DefErrSetWithSuffix(int nilOK, set *f, int subst, char *name, const char* suffix)\r
535#else\r
536DefErrSetWithSuffix(nilOK, f, subst, name, suffix )\r
537int nilOK;\r
538set *f;\r
539int subst; /* should be substitute error classes? */\r
540char *name;\r
541char *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
550int\r
551#ifdef __USE_PROTOS\r
552DefErrSetForC1(int nilOK, set *f, int subst, char * name, const char * suffix)\r
553#else\r
554DefErrSetForC1(nilOK, f, subst, name, suffix)\r
555int nilOK; /* MR13 */\r
556set *f;\r
557int subst; /* should be substitute error classes? */\r
558char *name;\r
559const 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
576 fprintf(ErrFile, "SetWordType %s%s[%d] = {",\r
577 name,\r
578 suffix,\r
579 NumWords(TokenNum-1)*sizeof(unsigned));\r
580 }\r
581 else {\r
582 fprintf(ErrFile, "SetWordType zzerr%d[%d] = {",\r
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
604int\r
605#ifdef __USE_PROTOS\r
606DefErrSetForC( set *f, int subst, char *name )\r
607#else\r
608DefErrSetForC( f, subst, name )\r
609set *f;\r
610int subst; /* should be substitute error classes? */\r
611char *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
621int\r
622#ifdef __USE_PROTOS\r
623DefErrSetForCC1(int nilOK, set *f, int subst, char *name, const char *suffix )\r
624#else\r
625DefErrSetForCC1(nilOK, f, subst, name, suffix )\r
626int nilOK; /* MR13 */\r
627set *f;\r
628int subst; /* should be substitute error classes? */\r
629char *name;\r
630const 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
644 fprintf(Parser_h, "\tstatic SetWordType %s%s[%d];\n", name, suffix,\r
645 NumWords(TokenNum-1)*sizeof(unsigned));\r
646 fprintf(Parser_c, "SetWordType %s::%s%s[%d] = {",\r
647 CurrentClassName,\r
648 name,\r
649 suffix,\r
650 NumWords(TokenNum-1)*sizeof(unsigned));\r
651 }\r
652 else {\r
653 fprintf(Parser_c, "SetWordType %s::err%d[%d] = {",\r
654 CurrentClassName,\r
655 esetnum,\r
656 NumWords(TokenNum-1)*sizeof(unsigned));\r
657 fprintf(Parser_h, "\tstatic SetWordType err%d[%d];\n", esetnum,\r
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
678int\r
679#ifdef __USE_PROTOS\r
680DefErrSetForCC( set *f, int subst, char *name )\r
681#else\r
682DefErrSetForCC( f, subst, name )\r
683set *f;\r
684int subst; /* should be substitute error classes? */\r
685char *name;\r
686#endif\r
687{\r
688 return DefErrSetForCC1(0,f,subst,name, "_set");\r
689}\r
690\r
691void\r
692#ifdef __USE_PROTOS\r
693GenParser_c_Hdr(void)\r
694#else\r
695GenParser_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
790 fprintf(Parser_c, "%s(ANTLRTokenBuffer *input) : %s(input,%d,%d,%d,%d)\n",\r
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
808void\r
809#ifdef __USE_PROTOS\r
810GenParser_h_Hdr(void)\r
811#else\r
812GenParser_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
865void\r
866#ifdef __USE_PROTOS\r
867GenErrHdr( void )\r
868#else\r
869GenErrHdr( )\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
915 fprintf(ErrFile, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));\r
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
981void\r
982#ifdef __USE_PROTOS\r
983dumpExpr( FILE *f, char *e )\r
984#else\r
985dumpExpr( f, e )\r
986FILE *f;\r
987char *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
1001int\r
1002#ifdef __USE_PROTOS\r
1003isTermEntryTokClass(TermEntry *te)\r
1004#else\r
1005isTermEntryTokClass(te)\r
1006TermEntry *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