]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/CodeTools/Source/Pccts/antlr/build.c
More renames for Tool Packages
[mirror_edk2.git] / Tools / CodeTools / Source / Pccts / antlr / build.c
CommitLineData
878ddf1f 1/*\r
2 * build.c -- functions associated with building syntax diagrams.\r
3 *\r
4 * SOFTWARE RIGHTS\r
5 *\r
6 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r
7 * Set (PCCTS) -- PCCTS is in the public domain. An individual or\r
8 * company may do whatever they wish with source code distributed with\r
9 * PCCTS or the code generated by PCCTS, including the incorporation of\r
10 * PCCTS, or its output, into commerical software.\r
11 *\r
12 * We encourage users to develop software with PCCTS. However, we do ask\r
13 * that credit is given to us for developing PCCTS. By "credit",\r
14 * we mean that if you incorporate our source code into one of your\r
15 * programs (commercial product, research project, or otherwise) that you\r
16 * acknowledge this fact somewhere in the documentation, research report,\r
17 * etc... If you like PCCTS and have developed a nice tool with the\r
18 * output, please mention that you developed it using PCCTS. In\r
19 * addition, we ask that this header remain intact in our source code.\r
20 * As long as these guidelines are kept, we expect to continue enhancing\r
21 * this system and expect to make other tools available as they are\r
22 * completed.\r
23 *\r
24 * ANTLR 1.33\r
25 * Terence Parr\r
26 * Parr Research Corporation\r
27 * with Purdue University and AHPCRC, University of Minnesota\r
28 * 1989-2001\r
29 */\r
30\r
31#include <stdio.h>\r
32#include <stdlib.h>\r
33#include <ctype.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#define SetBlk(g, t, approx, first_set_symbol) { \\r
42 ((Junction *)g.left)->jtype = t; \\r
43 ((Junction *)g.left)->approx = approx; \\r
44 ((Junction *)g.left)->pFirstSetSymbol = first_set_symbol; \\r
45 ((Junction *)g.left)->end = (Junction *) g.right; \\r
46 ((Junction *)g.right)->jtype = EndBlk;}\r
47\r
48/* Add the parameter string 'parm' to the parms field of a block-type junction\r
49 * g.left points to the sentinel node on a block. i.e. g.left->p1 points to\r
50 * the actual junction with its jtype == some block-type.\r
51 */\r
52void\r
53#ifdef __USE_PROTOS\r
54addParm( Node *p, char *parm )\r
55#else\r
56addParm( p, parm )\r
57Node *p;\r
58char *parm;\r
59#endif\r
60{\r
61 char *q = (char *) malloc( strlen(parm) + 1 );\r
62 require(p!=NULL, "addParm: NULL object\n");\r
63 require(q!=NULL, "addParm: unable to alloc parameter\n");\r
64\r
65 strcpy(q, parm);\r
66 if ( p->ntype == nRuleRef )\r
67 {\r
68 ((RuleRefNode *)p)->parms = q;\r
69 }\r
70 else if ( p->ntype == nJunction )\r
71 {\r
72 ((Junction *)p)->parm = q; /* only one parameter allowed on subrules */\r
73 }\r
74 else fatal_internal("addParm: invalid node for adding parm");\r
75}\r
76\r
77/*\r
78 * Build an action node for the syntax diagram\r
79 *\r
80 * buildAction(ACTION) ::= --o-->ACTION-->o--\r
81 *\r
82 * Where o is a junction node.\r
83 */\r
84Graph\r
85#ifdef __USE_PROTOS\r
86buildAction( char *action, int file, int line, int is_predicate )\r
87#else\r
88buildAction( action, file, line, is_predicate )\r
89char *action;\r
90int file;\r
91int line;\r
92int is_predicate;\r
93#endif\r
94{\r
95 Junction *j1, *j2;\r
96 Graph g;\r
97 ActionNode *a;\r
98 require(action!=NULL, "buildAction: invalid action");\r
99 \r
100 j1 = newJunction();\r
101 j2 = newJunction();\r
102 a = newActionNode();\r
103 a->action = (char *) malloc( strlen(action)+1 );\r
104 require(a->action!=NULL, "buildAction: cannot alloc space for action\n");\r
105 strcpy(a->action, action);\r
106 j1->p1 = (Node *) a;\r
107 a->next = (Node *) j2;\r
108 a->is_predicate = is_predicate;\r
109\r
110 if (is_predicate) {\r
111 PredEntry *predEntry;\r
112 char *t;\r
113 char *key;\r
114 char *u;\r
115 int inverted=0;\r
116\r
117 t=key=(char *)calloc(1,strlen(a->action)+1);\r
118\r
119 for (u=a->action; *u != '\0' ; u++) {\r
120 if (*u != ' ') {\r
121 if (t==key && *u=='!') {\r
122 inverted=!inverted;\r
123 } else {\r
124 *t++=*u;\r
125 };\r
126 };\r
127 };\r
128\r
129 *t='\0';\r
130\r
131\r
132 predEntry=(PredEntry *)hash_get(Pname,key);\r
133 a->predEntry=predEntry;\r
134 if (predEntry != NULL) a->inverted=inverted;\r
135 } else {\r
136/* MR12c */ char *strStart=a->action;\r
137/* MR12c */ char *strEnd;\r
138/* MR12c */ strEnd=strStart+strlen(strStart)-1;\r
139/* MR12c */ for ( ; strEnd >= strStart && isspace(*strEnd); strEnd--) *strEnd=0;\r
140/* MR12c */ while (*strStart != '\0' && isspace(*strStart)) strStart++;\r
141/* MR12c */ if (ci_strequ(strStart,"nohoist")) {\r
142/* MR12c */ a->noHoist=1;\r
143/* MR12c */ }\r
144 }\r
145\r
146 g.left = (Node *) j1; g.right = (Node *) j2;\r
147 a->file = file;\r
148 a->line = line;\r
149 a->rname = CurRule; /* MR10 */\r
150 return g;\r
151}\r
152\r
153/*\r
154 * Build a token node for the syntax diagram\r
155 *\r
156 * buildToken(TOKEN) ::= --o-->TOKEN-->o--\r
157 *\r
158 * Where o is a junction node.\r
159 */\r
160Graph\r
161#ifdef __USE_PROTOS\r
162buildToken( char *text )\r
163#else\r
164buildToken( text )\r
165char *text;\r
166#endif\r
167{\r
168 Junction *j1, *j2;\r
169 Graph g;\r
170 TokNode *t;\r
171 require(text!=NULL, "buildToken: invalid token name");\r
172 \r
173 j1 = newJunction();\r
174 j2 = newJunction();\r
175 t = newTokNode();\r
176 t->altstart = CurAltStart;\r
177 if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}\r
178 else {t->label=TRUE; t->token = addTname( text );}\r
179 j1->p1 = (Node *) t;\r
180 t->next = (Node *) j2;\r
181 g.left = (Node *) j1; g.right = (Node *) j2;\r
182 return g;\r
183}\r
184\r
185/*\r
186 * Build a wild-card node for the syntax diagram\r
187 *\r
188 * buildToken(TOKEN) ::= --o-->'.'-->o--\r
189 *\r
190 * Where o is a junction node.\r
191 */\r
192Graph\r
193#ifdef __USE_PROTOS\r
194buildWildCard( char *text )\r
195#else\r
196buildWildCard( text )\r
197char *text;\r
198#endif\r
199{\r
200 Junction *j1, *j2;\r
201 Graph g;\r
202 TokNode *t;\r
203 TCnode *w;\r
204 TermEntry *p;\r
205 require(text!=NULL, "buildWildCard: invalid token name");\r
206 \r
207 j1 = newJunction();\r
208 j2 = newJunction();\r
209 t = newTokNode();\r
210\r
211 /* If the ref a wild card, make a token class for it */\r
212 if ( Tnum(WildCardString) == 0 )\r
213 {\r
214 w = newTCnode;\r
215 w->tok = addTname( WildCardString );\r
216 set_orel(w->tok, &imag_tokens);\r
217 set_orel(w->tok, &tokclasses);\r
218 WildCardToken = w->tok;\r
219 require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,\r
220 "hash table mechanism is broken");\r
221 p->classname = 1; /* entry is class name, not token */\r
222 p->tclass = w; /* save ptr to this tclass def */\r
223 list_add(&tclasses, (char *)w);\r
224 }\r
225 else {\r
226 p=(TermEntry *)hash_get(Tname, WildCardString);\r
227 require( p!= NULL, "hash table mechanism is broken");\r
228 w = p->tclass;\r
229 }\r
230\r
231 t->token = w->tok;\r
232 t->wild_card = 1;\r
233 t->tclass = w;\r
234\r
235 t->altstart = CurAltStart;\r
236 j1->p1 = (Node *) t;\r
237 t->next = (Node *) j2;\r
238 g.left = (Node *) j1; g.right = (Node *) j2;\r
239 return g;\r
240}\r
241\r
242void\r
243#ifdef __USE_PROTOS\r
244setUpperRange(TokNode *t, char *text)\r
245#else\r
246setUpperRange(t, text)\r
247TokNode *t;\r
248char *text;\r
249#endif\r
250{\r
251 require(t!=NULL, "setUpperRange: NULL token node");\r
252 require(text!=NULL, "setUpperRange: NULL token string");\r
253\r
254 if ( *text == '"' ) {t->upper_range = addTexpr( text );}\r
255 else {t->upper_range = addTname( text );}\r
256}\r
257\r
258/*\r
259 * Build a rule reference node of the syntax diagram\r
260 *\r
261 * buildRuleRef(RULE) ::= --o-->RULE-->o--\r
262 *\r
263 * Where o is a junction node.\r
264 *\r
265 * If rule 'text' has been defined already, don't alloc new space to store string.\r
266 * Set r->text to point to old copy in string table.\r
267 */\r
268Graph\r
269#ifdef __USE_PROTOS\r
270buildRuleRef( char *text )\r
271#else\r
272buildRuleRef( text )\r
273char *text;\r
274#endif\r
275{\r
276 Junction *j1, *j2;\r
277 Graph g;\r
278 RuleRefNode *r;\r
279 RuleEntry *p;\r
280 require(text!=NULL, "buildRuleRef: invalid rule name");\r
281 \r
282 j1 = newJunction();\r
283 j2 = newJunction();\r
284 r = newRNode();\r
285 r->altstart = CurAltStart;\r
286 r->assign = NULL;\r
287 if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;\r
288 else r->text = mystrdup( text );\r
289 j1->p1 = (Node *) r;\r
290 r->next = (Node *) j2;\r
291 g.left = (Node *) j1; g.right = (Node *) j2;\r
292 return g;\r
293}\r
294\r
295/*\r
296 * Or two subgraphs into one graph via:\r
297 *\r
298 * Or(G1, G2) ::= --o-G1-o--\r
299 * | ^\r
300 * v |\r
301 * o-G2-o\r
302 *\r
303 * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.\r
304 * If, however, the G1 altnum is 0, make it 1 and then\r
305 * make G2 altnum = G1 altnum + 1.\r
306 */\r
307Graph\r
308#ifdef __USE_PROTOS\r
309Or( Graph g1, Graph g2 )\r
310#else\r
311Or( g1, g2 )\r
312Graph g1;\r
313Graph g2;\r
314#endif\r
315{\r
316 Graph g;\r
317 require(g1.left != NULL, "Or: invalid graph");\r
318 require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");\r
319\r
320 ((Junction *)g1.left)->p2 = g2.left;\r
321 ((Junction *)g2.right)->p1 = g1.right;\r
322 /* set altnums */\r
323 if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;\r
324 ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;\r
325 g.left = g2.left;\r
326 g.right = g1.right;\r
327 return g;\r
328}\r
329\r
330/*\r
331 * Catenate two subgraphs\r
332 *\r
333 * Cat(G1, G2) ::= --o-G1-o-->o-G2-o--\r
334 * Cat(NULL,G2)::= --o-G2-o--\r
335 * Cat(G1,NULL)::= --o-G1-o--\r
336 */\r
337Graph\r
338#ifdef __USE_PROTOS\r
339Cat( Graph g1, Graph g2 )\r
340#else\r
341Cat( g1, g2 )\r
342Graph g1;\r
343Graph g2;\r
344#endif\r
345{\r
346 Graph g;\r
347 \r
348 if ( g1.left == NULL && g1.right == NULL ) return g2;\r
349 if ( g2.left == NULL && g2.right == NULL ) return g1;\r
350 ((Junction *)g1.right)->p1 = g2.left;\r
351 g.left = g1.left;\r
352 g.right = g2.right;\r
353 return g;\r
354}\r
355\r
356/*\r
357 * Make a subgraph an optional block\r
358 *\r
359 * makeOpt(G) ::= --o-->o-G-o-->o--\r
360 * | ^\r
361 * v |\r
362 * o-------o\r
363 *\r
364 * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.\r
365 *\r
366 * The node on the far right is added so that every block owns its own\r
367 * EndBlk node.\r
368 */\r
369Graph\r
370#ifdef __USE_PROTOS\r
371makeOpt( Graph g1, int approx, char * pFirstSetSymbol )\r
372#else\r
373makeOpt( g1, approx, pFirstSetSymbol )\r
374Graph g1;\r
375int approx;\r
376char * pFirstSetSymbol;\r
377#endif\r
378{\r
379 Junction *j1,*j2,*p;\r
380 Graph g;\r
381 require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");\r
382\r
383 j1 = newJunction();\r
384 j2 = newJunction();\r
385 ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */\r
386\r
387 /* MR21\r
388 *\r
389 * There is code in genBlk which recognizes the node created\r
390 * by emptyAlt() as a special case and bypasses it. We don't\r
391 * want this to happen for the optBlk.\r
392 */\r
393\r
394 g = emptyAlt3(); /* MR21 */\r
395 if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;\r
396 ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;\r
397 for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)\r
398 {;} /* find last alt */\r
399 p->p2 = g.left; /* add optional alternative */\r
400 ((Junction *)g.right)->p1 = (Node *)j2; /* opt alt points to EndBlk */\r
401 g1.right = (Node *)j2;\r
402 SetBlk(g1, aOptBlk, approx, pFirstSetSymbol);\r
403 j1->p1 = g1.left; /* add generic node in front */\r
404 g.left = (Node *) j1;\r
405 g.right = g1.right;\r
406 return g;\r
407}\r
408\r
409/*\r
410 * Make a graph into subblock\r
411 *\r
412 * makeBlk(G) ::= --o-->o-G-o-->o--\r
413 *\r
414 * The node on the far right is added so that every block owns its own\r
415 * EndBlk node.\r
416 */\r
417Graph\r
418#ifdef __USE_PROTOS\r
419makeBlk( Graph g1, int approx, char * pFirstSetSymbol )\r
420#else\r
421makeBlk( g1, approx, pFirstSetSymbol )\r
422Graph g1;\r
423int approx;\r
424char * pFirstSetSymbol;\r
425#endif\r
426{\r
427 Junction *j,*j2;\r
428 Graph g;\r
429 require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph");\r
430\r
431 j = newJunction();\r
432 j2 = newJunction();\r
433 ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */\r
434 g1.right = (Node *)j2;\r
435 SetBlk(g1, aSubBlk, approx, pFirstSetSymbol);\r
436 j->p1 = g1.left; /* add node in front */\r
437 g.left = (Node *) j;\r
438 g.right = g1.right;\r
439\r
440 return g;\r
441}\r
442\r
443/*\r
444 * Make a subgraph into a loop (closure) block -- (...)*\r
445 *\r
446 * makeLoop(G) ::= |---|\r
447 * v |\r
448 * --o-->o-->o-G-o-->o--\r
449 * | ^\r
450 * v |\r
451 * o-----------o\r
452 *\r
453 * After making loop, always place generic node out front. It becomes\r
454 * the start of enclosing block. The aLoopBlk is the target of the loop.\r
455 *\r
456 * Loop blks have TWO EndBlk nodes--the far right and the node that loops back\r
457 * to the aLoopBlk node. Node with which we can branch past loop == aLoopBegin and\r
458 * one which is loop target == aLoopBlk.\r
459 * The branch-past (initial) aLoopBegin node has end\r
460 * pointing to the last EndBlk node. The loop-target node has end==NULL.\r
461 *\r
462 * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node.\r
463 */\r
464Graph\r
465#ifdef __USE_PROTOS\r
466makeLoop( Graph g1, int approx, char * pFirstSetSymbol )\r
467#else\r
468makeLoop( g1, approx, pFirstSetSymbol)\r
469Graph g1;\r
470int approx;\r
471char * pFirstSetSymbol;\r
472#endif\r
473{\r
474 Junction *back, *front, *begin;\r
475 Graph g;\r
476 require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph");\r
477\r
478 back = newJunction();\r
479 front = newJunction();\r
480 begin = newJunction();\r
481 g = emptyAlt3();\r
482 ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */\r
483 ((Junction *)g1.right)->p1 = (Node *) back; /* add node to G at end */\r
484 ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */\r
485 ((Junction *)g1.left)->jtype = aLoopBlk; /* mark 2nd aLoopBlk node */\r
486 ((Junction *)g1.left)->end = (Junction *) g1.right;\r
487 ((Junction *)g1.left)->lock = makelocks();\r
488 ((Junction *)g1.left)->pred_lock = makelocks();\r
489 g1.right = (Node *) back;\r
490 begin->p1 = (Node *) g1.left;\r
491 g1.left = (Node *) begin;\r
492 begin->p2 = (Node *) g.left; /* make bypass arc */\r
493 ((Junction *)g.right)->p1 = (Node *) back;\r
494 SetBlk(g1, aLoopBegin, approx, pFirstSetSymbol);\r
495 front->p1 = g1.left; /* add node to front */\r
496 g1.left = (Node *) front;\r
497\r
498 return g1;\r
499}\r
500\r
501/*\r
502 * Make a subgraph into a plus block -- (...)+ -- 1 or more times\r
503 *\r
504 * makePlus(G) ::= |---|\r
505 * v |\r
506 * --o-->o-G-o-->o--\r
507 *\r
508 * After making loop, always place generic node out front. It becomes\r
509 * the start of enclosing block. The aPlusBlk is the target of the loop.\r
510 *\r
511 * Plus blks have TWO EndBlk nodes--the far right and the node that loops back\r
512 * to the aPlusBlk node.\r
513 *\r
514 * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node.\r
515 */\r
516Graph\r
517#ifdef __USE_PROTOS\r
518makePlus( Graph g1, int approx, char * pFirstSetSymbol)\r
519#else\r
520makePlus( g1, approx, pFirstSetSymbol)\r
521Graph g1;\r
522int approx;\r
523char * pFirstSetSymbol;\r
524#endif\r
525{\r
526 int has_empty_alt_already = 0;\r
527 Graph g;\r
528 Junction *j2, *j3, *first_alt;\r
529 Junction *last_alt=NULL, *p;\r
530 require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph");\r
531\r
532 first_alt = (Junction *)g1.left;\r
533 j2 = newJunction();\r
534 j3 = newJunction();\r
535 if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;\r
536 ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */\r
537 ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */\r
538 ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */\r
539 g1.right = (Node *) j2;\r
540 SetBlk(g1, aPlusBlk, approx, pFirstSetSymbol);\r
541 ((Junction *)g1.left)->lock = makelocks();\r
542 ((Junction *)g1.left)->pred_lock = makelocks();\r
543 j3->p1 = g1.left; /* add node to front */\r
544 g1.left = (Node *) j3;\r
545\r
546 /* add an optional branch which is the "exit" branch of loop */\r
547 /* FIRST, check to ensure that there does not already exist\r
548 * an optional path.\r
549 */\r
550 /* find last alt */\r
551 for(p=first_alt; p!=NULL; p=(Junction *)p->p2)\r
552 {\r
553 if ( p->p1->ntype == nJunction &&\r
554 p->p1!=NULL &&\r
555 ((Junction *)p->p1)->jtype==Generic &&\r
556 ((Junction *)p->p1)->p1!=NULL &&\r
557 ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk )\r
558 {\r
559 has_empty_alt_already = 1;\r
560 }\r
561 last_alt = p;\r
562 }\r
563 if ( !has_empty_alt_already )\r
564 {\r
565 require(last_alt!=NULL, "last_alt==NULL; bad (..)+");\r
566 g = emptyAlt();\r
567 last_alt->p2 = g.left;\r
568 ((Junction *)g.right)->p1 = (Node *) j2;\r
569\r
570 /* make sure lookahead computation ignores this alt for\r
571 * FIRST("(..)+"); but it's still used for computing the FIRST\r
572 * of each alternative.\r
573 */\r
574 ((Junction *)g.left)->ignore = 1;\r
575 }\r
576\r
577 return g1;\r
578}\r
579\r
580/*\r
581 * Return an optional path: --o-->o--\r
582 */\r
583\r
584Graph\r
585#ifdef __USE_PROTOS\r
586emptyAlt( void )\r
587#else\r
588emptyAlt( )\r
589#endif\r
590{\r
591 Junction *j1, *j2;\r
592 Graph g;\r
593\r
594 j1 = newJunction();\r
595 j2 = newJunction();\r
596 j1->p1 = (Node *) j2;\r
597 g.left = (Node *) j1;\r
598 g.right = (Node *) j2;\r
599 \r
600 return g;\r
601}\r
602\r
603/* MR21\r
604 *\r
605 * There is code in genBlk which recognizes the node created\r
606 * by emptyAlt() as a special case and bypasses it. We don't\r
607 * want this to happen for the optBlk.\r
608 */\r
609\r
610Graph\r
611#ifdef __USE_PROTOS\r
612emptyAlt3( void )\r
613#else\r
614emptyAlt3( )\r
615#endif\r
616{\r
617 Junction *j1, *j2, *j3;\r
618 Graph g;\r
619\r
620 j1 = newJunction();\r
621 j2 = newJunction();\r
622 j3 = newJunction();\r
623 j1->p1 = (Node *) j2;\r
624 j2->p1 = (Node *) j3;\r
625 g.left = (Node *) j1;\r
626 g.right = (Node *) j3;\r
627 \r
628 return g;\r
629}\r
630\r
631/* N o d e A l l o c a t i o n */\r
632\r
633TokNode *\r
634#ifdef __USE_PROTOS\r
635newTokNode( void )\r
636#else\r
637newTokNode( )\r
638#endif\r
639{\r
640 static TokNode *FreeList = NULL;\r
641 TokNode *p, *newblk;\r
642\r
643 if ( FreeList == NULL )\r
644 {\r
645 newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode));\r
646 if ( newblk == NULL )\r
647 fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
648 for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++)\r
649 {\r
650 p->next = (Node *)FreeList; /* add all new token nodes to FreeList */\r
651 FreeList = p;\r
652 }\r
653 }\r
654 p = FreeList;\r
655 FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */\r
656 p->next = NULL; /* NULL the ptr we used */\r
657 memset( (char *) p, 0, sizeof(TokNode)); /* MR10 */\r
658 p->ntype = nToken;\r
659 p->rname = CurRule;\r
660 p->file = CurFile;\r
661 p->line = zzline;\r
662 p->altstart = NULL;\r
663\r
664 return p;\r
665}\r
666\r
667RuleRefNode *\r
668#ifdef __USE_PROTOS\r
669newRNode( void )\r
670#else\r
671newRNode( )\r
672#endif\r
673{\r
674 static RuleRefNode *FreeList = NULL;\r
675 RuleRefNode *p, *newblk;\r
676\r
677 if ( FreeList == NULL )\r
678 {\r
679 newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode));\r
680 if ( newblk == NULL )\r
681 fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
682 for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++)\r
683 {\r
684 p->next = (Node *)FreeList; /* add all new rref nodes to FreeList */\r
685 FreeList = p;\r
686 }\r
687 }\r
688 p = FreeList;\r
689 FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */\r
690 p->next = NULL; /* NULL the ptr we used */\r
691 memset( (char *) p, 0, sizeof(RuleRefNode)); /* MR10 */\r
692 p->ntype = nRuleRef;\r
693 p->rname = CurRule;\r
694 p->file = CurFile;\r
695 p->line = zzline;\r
696 p->astnode = ASTinclude;\r
697 p->altstart = NULL;\r
698 \r
699 return p;\r
700}\r
701\r
702static int junctionSeqNumber=0; /* MR10 */\r
703\r
704Junction *\r
705#ifdef __USE_PROTOS\r
706newJunction( void )\r
707#else\r
708newJunction( )\r
709#endif\r
710{\r
711 static Junction *FreeList = NULL;\r
712 Junction *p, *newblk;\r
713\r
714 if ( FreeList == NULL )\r
715 {\r
716 newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction));\r
717 if ( newblk == NULL )\r
718 fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
719 for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++)\r
720 {\r
721 p->p1 = (Node *)FreeList; /* add all new Junction nodes to FreeList */\r
722 FreeList = p;\r
723 }\r
724 }\r
725 p = FreeList;\r
726 FreeList = (Junction *)FreeList->p1;/* remove a Junction node */\r
727 p->p1 = NULL; /* NULL the ptr we used */\r
728 memset( (char *) p, 0, sizeof(Junction)); /* MR10 */\r
729 p->ntype = nJunction;\r
730 p->visited = 0;\r
731 p->jtype = Generic;\r
732 p->rname = CurRule;\r
733 p->file = CurFile;\r
734 p->line = zzline;\r
735 p->exception_label = NULL;\r
736 p->fset = (set *) calloc(CLL_k+1, sizeof(set));\r
737 require(p->fset!=NULL, "cannot allocate fset in newJunction");\r
738 p->seq=++junctionSeqNumber; /* MR10 */\r
739\r
740 return p;\r
741}\r
742\r
743ActionNode *\r
744#ifdef __USE_PROTOS\r
745newActionNode( void )\r
746#else\r
747newActionNode( )\r
748#endif\r
749{\r
750 static ActionNode *FreeList = NULL;\r
751 ActionNode *p, *newblk;\r
752\r
753 if ( FreeList == NULL )\r
754 {\r
755 newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode));\r
756 if ( newblk == NULL )\r
757 fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
758 for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++)\r
759 {\r
760 p->next = (Node *)FreeList; /* add all new Action nodes to FreeList */\r
761 FreeList = p;\r
762 }\r
763 }\r
764 p = FreeList;\r
765 FreeList = (ActionNode *)FreeList->next;/* remove an Action node */\r
766 memset( (char *) p, 0, sizeof(ActionNode)); /* MR10 */\r
767 p->ntype = nAction;\r
768 p->next = NULL; /* NULL the ptr we used */\r
769 p->done = 0;\r
770 p->pred_fail = NULL;\r
771 p->guardpred = NULL;\r
772 p->ampersandPred = NULL;\r
773 return p;\r
774}\r
775\r
776/*\r
777 * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion.\r
778 * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs.\r
779 * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes.\r
780 *\r
781 * if ( lock[k]==TRUE ) then we have been here before looking for k tokens\r
782 * of lookahead.\r
783 */\r
784char *\r
785#ifdef __USE_PROTOS\r
786makelocks( void )\r
787#else\r
788makelocks( )\r
789#endif\r
790{\r
791 char *p = (char *) calloc(CLL_k+1, sizeof(char));\r
792 require(p!=NULL, "cannot allocate lock array");\r
793 \r
794 return p;\r
795}\r
796\r
797#if 0\r
798** #ifdef __USE_PROTOS\r
799** void my_memset(char *p,char value,int count)\r
800** #else\r
801** void my_memset(p,value,count)\r
802** char *p;\r
803** char value;\r
804** int count;\r
805** #endif\r
806** {\r
807** int i;\r
808**\r
809** for (i=0; i<count; i++) {\r
810** p[i]=value;\r
811** };\r
812** }\r
813#endif\r