]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/CodeTools/TianoTools/Pccts/antlr/build.c
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / CodeTools / TianoTools / Pccts / antlr / build.c
diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/build.c b/Tools/CodeTools/TianoTools/Pccts/antlr/build.c
new file mode 100644 (file)
index 0000000..4eb3b02
--- /dev/null
@@ -0,0 +1,813 @@
+/*\r
+ * build.c -- functions associated with building syntax diagrams.\r
+ *\r
+ * SOFTWARE RIGHTS\r
+ *\r
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or\r
+ * company may do whatever they wish with source code distributed with\r
+ * PCCTS or the code generated by PCCTS, including the incorporation of\r
+ * PCCTS, or its output, into commerical software.\r
+ *\r
+ * We encourage users to develop software with PCCTS.  However, we do ask\r
+ * that credit is given to us for developing PCCTS.  By "credit",\r
+ * we mean that if you incorporate our source code into one of your\r
+ * programs (commercial product, research project, or otherwise) that you\r
+ * acknowledge this fact somewhere in the documentation, research report,\r
+ * etc...  If you like PCCTS and have developed a nice tool with the\r
+ * output, please mention that you developed it using PCCTS.  In\r
+ * addition, we ask that this header remain intact in our source code.\r
+ * As long as these guidelines are kept, we expect to continue enhancing\r
+ * this system and expect to make other tools available as they are\r
+ * completed.\r
+ *\r
+ * ANTLR 1.33\r
+ * Terence Parr\r
+ * Parr Research Corporation\r
+ * with Purdue University and AHPCRC, University of Minnesota\r
+ * 1989-2001\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <ctype.h>\r
+#include "pcctscfg.h"\r
+#include "set.h"\r
+#include "syn.h"\r
+#include "hash.h"\r
+#include "generic.h"\r
+#include "dlgdef.h"\r
+\r
+#define SetBlk(g, t, approx, first_set_symbol) {                               \\r
+                       ((Junction *)g.left)->jtype = t;                                                \\r
+                       ((Junction *)g.left)->approx = approx;                                  \\r
+                       ((Junction *)g.left)->pFirstSetSymbol = first_set_symbol;   \\r
+                       ((Junction *)g.left)->end = (Junction *) g.right;               \\r
+                       ((Junction *)g.right)->jtype = EndBlk;}\r
+\r
+/* Add the parameter string 'parm' to the parms field of a block-type junction\r
+ * g.left points to the sentinel node on a block.  i.e. g.left->p1 points to\r
+ * the actual junction with its jtype == some block-type.\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+addParm( Node *p, char *parm )\r
+#else\r
+addParm( p, parm )\r
+Node *p;\r
+char *parm;\r
+#endif\r
+{\r
+       char *q = (char *) malloc( strlen(parm) + 1 );\r
+       require(p!=NULL, "addParm: NULL object\n");\r
+       require(q!=NULL, "addParm: unable to alloc parameter\n");\r
+\r
+       strcpy(q, parm);\r
+       if ( p->ntype == nRuleRef )\r
+       {\r
+               ((RuleRefNode *)p)->parms = q;\r
+       }\r
+       else if ( p->ntype == nJunction )\r
+       {\r
+               ((Junction *)p)->parm = q;      /* only one parameter allowed on subrules */\r
+       }\r
+       else fatal_internal("addParm: invalid node for adding parm");\r
+}\r
+\r
+/*\r
+ * Build an action node for the syntax diagram\r
+ *\r
+ * buildAction(ACTION) ::= --o-->ACTION-->o--\r
+ *\r
+ * Where o is a junction node.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+buildAction( char *action, int file, int line, int is_predicate )\r
+#else\r
+buildAction( action, file, line, is_predicate )\r
+char *action;\r
+int file;\r
+int line;\r
+int is_predicate;\r
+#endif\r
+{\r
+       Junction *j1, *j2;\r
+       Graph g;\r
+       ActionNode *a;\r
+       require(action!=NULL, "buildAction: invalid action");\r
+       \r
+       j1 = newJunction();\r
+       j2 = newJunction();\r
+       a = newActionNode();\r
+       a->action = (char *) malloc( strlen(action)+1 );\r
+       require(a->action!=NULL, "buildAction: cannot alloc space for action\n");\r
+       strcpy(a->action, action);\r
+       j1->p1 = (Node *) a;\r
+       a->next = (Node *) j2;\r
+       a->is_predicate = is_predicate;\r
+\r
+    if (is_predicate) {\r
+        PredEntry   *predEntry;\r
+        char        *t;\r
+        char        *key;\r
+        char        *u;\r
+        int         inverted=0;\r
+\r
+        t=key=(char *)calloc(1,strlen(a->action)+1);\r
+\r
+        for (u=a->action; *u != '\0' ; u++) {\r
+          if (*u != ' ') {\r
+            if (t==key && *u=='!') {\r
+              inverted=!inverted;\r
+            } else {\r
+              *t++=*u;\r
+            };\r
+          };\r
+        };\r
+\r
+        *t='\0';\r
+\r
+\r
+        predEntry=(PredEntry *)hash_get(Pname,key);\r
+        a->predEntry=predEntry;\r
+        if (predEntry != NULL) a->inverted=inverted;\r
+    } else {\r
+/* MR12c */      char  *strStart=a->action;\r
+/* MR12c */      char  *strEnd;\r
+/* MR12c */      strEnd=strStart+strlen(strStart)-1;\r
+/* MR12c */      for ( ; strEnd >= strStart &&  isspace(*strEnd); strEnd--) *strEnd=0;\r
+/* MR12c */      while (*strStart != '\0' && isspace(*strStart)) strStart++;\r
+/* MR12c */      if (ci_strequ(strStart,"nohoist")) {\r
+/* MR12c */        a->noHoist=1;\r
+/* MR12c */      }\r
+       }\r
+\r
+       g.left = (Node *) j1; g.right = (Node *) j2;\r
+       a->file = file;\r
+       a->line = line;\r
+       a->rname = CurRule;     /* MR10 */\r
+       return g;\r
+}\r
+\r
+/*\r
+ * Build a token node for the syntax diagram\r
+ *\r
+ * buildToken(TOKEN) ::= --o-->TOKEN-->o--\r
+ *\r
+ * Where o is a junction node.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+buildToken( char *text )\r
+#else\r
+buildToken( text )\r
+char *text;\r
+#endif\r
+{\r
+       Junction *j1, *j2;\r
+       Graph g;\r
+       TokNode *t;\r
+       require(text!=NULL, "buildToken: invalid token name");\r
+       \r
+       j1 = newJunction();\r
+       j2 = newJunction();\r
+       t = newTokNode();\r
+       t->altstart = CurAltStart;\r
+       if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}\r
+       else {t->label=TRUE; t->token = addTname( text );}\r
+       j1->p1 = (Node *) t;\r
+       t->next = (Node *) j2;\r
+       g.left = (Node *) j1; g.right = (Node *) j2;\r
+       return g;\r
+}\r
+\r
+/*\r
+ * Build a wild-card node for the syntax diagram\r
+ *\r
+ * buildToken(TOKEN) ::= --o-->'.'-->o--\r
+ *\r
+ * Where o is a junction node.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+buildWildCard( char *text )\r
+#else\r
+buildWildCard( text )\r
+char *text;\r
+#endif\r
+{\r
+       Junction *j1, *j2;\r
+       Graph g;\r
+       TokNode *t;\r
+       TCnode *w;\r
+       TermEntry *p;\r
+       require(text!=NULL, "buildWildCard: invalid token name");\r
+       \r
+       j1 = newJunction();\r
+       j2 = newJunction();\r
+       t = newTokNode();\r
+\r
+       /* If the ref a wild card, make a token class for it */\r
+       if ( Tnum(WildCardString) == 0 )\r
+       {\r
+               w = newTCnode;\r
+               w->tok = addTname( WildCardString );\r
+               set_orel(w->tok, &imag_tokens);\r
+               set_orel(w->tok, &tokclasses);\r
+               WildCardToken = w->tok;\r
+               require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,\r
+                               "hash table mechanism is broken");\r
+               p->classname = 1;       /* entry is class name, not token */\r
+               p->tclass = w;          /* save ptr to this tclass def */\r
+               list_add(&tclasses, (char *)w);\r
+       }\r
+       else {\r
+               p=(TermEntry *)hash_get(Tname, WildCardString);\r
+               require( p!= NULL, "hash table mechanism is broken");\r
+               w = p->tclass;\r
+       }\r
+\r
+       t->token = w->tok;\r
+       t->wild_card = 1;\r
+       t->tclass = w;\r
+\r
+       t->altstart = CurAltStart;\r
+       j1->p1 = (Node *) t;\r
+       t->next = (Node *) j2;\r
+       g.left = (Node *) j1; g.right = (Node *) j2;\r
+       return g;\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+setUpperRange(TokNode *t, char *text)\r
+#else\r
+setUpperRange(t, text)\r
+TokNode *t;\r
+char *text;\r
+#endif\r
+{\r
+       require(t!=NULL, "setUpperRange: NULL token node");\r
+       require(text!=NULL, "setUpperRange: NULL token string");\r
+\r
+       if ( *text == '"' ) {t->upper_range = addTexpr( text );}\r
+       else {t->upper_range = addTname( text );}\r
+}\r
+\r
+/*\r
+ * Build a rule reference node of the syntax diagram\r
+ *\r
+ * buildRuleRef(RULE) ::= --o-->RULE-->o--\r
+ *\r
+ * Where o is a junction node.\r
+ *\r
+ * If rule 'text' has been defined already, don't alloc new space to store string.\r
+ * Set r->text to point to old copy in string table.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+buildRuleRef( char *text )\r
+#else\r
+buildRuleRef( text )\r
+char *text;\r
+#endif\r
+{\r
+       Junction *j1, *j2;\r
+       Graph g;\r
+       RuleRefNode *r;\r
+       RuleEntry *p;\r
+       require(text!=NULL, "buildRuleRef: invalid rule name");\r
+       \r
+       j1 = newJunction();\r
+       j2 = newJunction();\r
+       r = newRNode();\r
+       r->altstart = CurAltStart;\r
+       r->assign = NULL;\r
+       if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;\r
+       else r->text = mystrdup( text );\r
+       j1->p1  = (Node *) r;\r
+       r->next = (Node *) j2;\r
+       g.left = (Node *) j1; g.right = (Node *) j2;\r
+       return g;\r
+}\r
+\r
+/*\r
+ * Or two subgraphs into one graph via:\r
+ *\r
+ * Or(G1, G2) ::= --o-G1-o--\r
+ *                  |    ^\r
+ *                                     v    |\r
+ *                  o-G2-o\r
+ *\r
+ * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.\r
+ * If, however, the G1 altnum is 0, make it 1 and then\r
+ * make G2 altnum = G1 altnum + 1.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+Or( Graph g1, Graph g2 )\r
+#else\r
+Or( g1, g2 )\r
+Graph g1;\r
+Graph g2;\r
+#endif\r
+{\r
+       Graph g;\r
+       require(g1.left != NULL, "Or: invalid graph");\r
+       require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");\r
+\r
+       ((Junction *)g1.left)->p2 = g2.left;\r
+       ((Junction *)g2.right)->p1 = g1.right;\r
+       /* set altnums */\r
+       if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;\r
+       ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;\r
+       g.left = g2.left;\r
+       g.right = g1.right;\r
+       return g;\r
+}\r
+\r
+/*\r
+ * Catenate two subgraphs\r
+ *\r
+ * Cat(G1, G2) ::= --o-G1-o-->o-G2-o--\r
+ * Cat(NULL,G2)::= --o-G2-o--\r
+ * Cat(G1,NULL)::= --o-G1-o--\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+Cat( Graph g1, Graph g2 )\r
+#else\r
+Cat( g1, g2 )\r
+Graph g1;\r
+Graph g2;\r
+#endif\r
+{\r
+       Graph g;\r
+       \r
+       if ( g1.left == NULL && g1.right == NULL ) return g2;\r
+       if ( g2.left == NULL && g2.right == NULL ) return g1;\r
+       ((Junction *)g1.right)->p1 = g2.left;\r
+       g.left = g1.left;\r
+       g.right = g2.right;\r
+       return g;\r
+}\r
+\r
+/*\r
+ * Make a subgraph an optional block\r
+ *\r
+ * makeOpt(G) ::= --o-->o-G-o-->o--\r
+ *                      |          ^\r
+ *                                             v           |\r
+ *                                         o-------o\r
+ *\r
+ * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.\r
+ *\r
+ * The node on the far right is added so that every block owns its own\r
+ * EndBlk node.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+makeOpt( Graph g1, int approx, char * pFirstSetSymbol )\r
+#else\r
+makeOpt( g1, approx, pFirstSetSymbol )\r
+Graph g1;\r
+int approx;\r
+char * pFirstSetSymbol;\r
+#endif\r
+{\r
+       Junction *j1,*j2,*p;\r
+       Graph g;\r
+       require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");\r
+\r
+       j1 = newJunction();\r
+       j2 = newJunction();\r
+       ((Junction *)g1.right)->p1 = (Node *) j2;       /* add node to G at end */\r
+\r
+    /*  MR21\r
+     *\r
+     *  There is code in genBlk which recognizes the node created\r
+     *  by emptyAlt() as a special case and bypasses it.  We don't\r
+     *  want this to happen for the optBlk.\r
+     */\r
+\r
+       g = emptyAlt3(); /* MR21 */\r
+       if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;\r
+       ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;\r
+       for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)\r
+               {;}                                                                             /* find last alt */\r
+       p->p2 = g.left;                                                         /* add optional alternative */\r
+       ((Junction *)g.right)->p1 = (Node *)j2;         /* opt alt points to EndBlk */\r
+       g1.right = (Node *)j2;\r
+       SetBlk(g1, aOptBlk, approx, pFirstSetSymbol);\r
+       j1->p1 = g1.left;                                                       /* add generic node in front */\r
+       g.left = (Node *) j1;\r
+       g.right = g1.right;\r
+       return g;\r
+}\r
+\r
+/*\r
+ * Make a graph into subblock\r
+ *\r
+ * makeBlk(G) ::= --o-->o-G-o-->o--\r
+ *\r
+ * The node on the far right is added so that every block owns its own\r
+ * EndBlk node.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+makeBlk( Graph g1, int approx, char * pFirstSetSymbol )\r
+#else\r
+makeBlk( g1, approx, pFirstSetSymbol )\r
+Graph g1;\r
+int approx;\r
+char * pFirstSetSymbol;\r
+#endif\r
+{\r
+       Junction *j,*j2;\r
+       Graph g;\r
+       require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph");\r
+\r
+       j = newJunction();\r
+       j2 = newJunction();\r
+       ((Junction *)g1.right)->p1 = (Node *) j2;       /* add node to G at end */\r
+       g1.right = (Node *)j2;\r
+       SetBlk(g1, aSubBlk, approx, pFirstSetSymbol);\r
+       j->p1 = g1.left;                                                        /* add node in front */\r
+       g.left = (Node *) j;\r
+       g.right = g1.right;\r
+\r
+       return g;\r
+}\r
+\r
+/*\r
+ * Make a subgraph into a loop (closure) block -- (...)*\r
+ *\r
+ * makeLoop(G) ::=       |---|\r
+ *                                          v   |\r
+ *                        --o-->o-->o-G-o-->o--\r
+ *                   |           ^\r
+ *                   v           |\r
+ *                                      o-----------o\r
+ *\r
+ * After making loop, always place generic node out front.  It becomes\r
+ * the start of enclosing block.  The aLoopBlk is the target of the loop.\r
+ *\r
+ * Loop blks have TWO EndBlk nodes--the far right and the node that loops back\r
+ * to the aLoopBlk node.  Node with which we can branch past loop == aLoopBegin and\r
+ * one which is loop target == aLoopBlk.\r
+ * The branch-past (initial) aLoopBegin node has end\r
+ * pointing to the last EndBlk node.  The loop-target node has end==NULL.\r
+ *\r
+ * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+makeLoop( Graph g1, int approx, char * pFirstSetSymbol )\r
+#else\r
+makeLoop( g1, approx, pFirstSetSymbol)\r
+Graph g1;\r
+int approx;\r
+char * pFirstSetSymbol;\r
+#endif\r
+{\r
+       Junction *back, *front, *begin;\r
+       Graph g;\r
+       require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph");\r
+\r
+       back = newJunction();\r
+       front = newJunction();\r
+       begin = newJunction();\r
+       g = emptyAlt3();\r
+       ((Junction *)g1.right)->p2 = g1.left;           /* add loop branch to G */\r
+       ((Junction *)g1.right)->p1 = (Node *) back;     /* add node to G at end */\r
+       ((Junction *)g1.right)->jtype = EndBlk;         /* mark 1st EndBlk node */\r
+       ((Junction *)g1.left)->jtype = aLoopBlk;        /* mark 2nd aLoopBlk node */\r
+       ((Junction *)g1.left)->end = (Junction *) g1.right;\r
+       ((Junction *)g1.left)->lock = makelocks();\r
+       ((Junction *)g1.left)->pred_lock = makelocks();\r
+       g1.right = (Node *) back;\r
+       begin->p1 = (Node *) g1.left;\r
+       g1.left = (Node *) begin;\r
+       begin->p2 = (Node *) g.left;                            /* make bypass arc */\r
+       ((Junction *)g.right)->p1 = (Node *) back;\r
+       SetBlk(g1, aLoopBegin, approx, pFirstSetSymbol);\r
+       front->p1 = g1.left;                                            /* add node to front */\r
+       g1.left = (Node *) front;\r
+\r
+       return g1;\r
+}\r
+\r
+/*\r
+ * Make a subgraph into a plus block -- (...)+ -- 1 or more times\r
+ *\r
+ * makePlus(G) ::=      |---|\r
+ *                                      v   |\r
+ *                        --o-->o-G-o-->o--\r
+ *\r
+ * After making loop, always place generic node out front.  It becomes\r
+ * the start of enclosing block.  The aPlusBlk is the target of the loop.\r
+ *\r
+ * Plus blks have TWO EndBlk nodes--the far right and the node that loops back\r
+ * to the aPlusBlk node.\r
+ *\r
+ * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node.\r
+ */\r
+Graph\r
+#ifdef __USE_PROTOS\r
+makePlus( Graph g1, int approx, char * pFirstSetSymbol)\r
+#else\r
+makePlus( g1, approx, pFirstSetSymbol)\r
+Graph g1;\r
+int approx;\r
+char * pFirstSetSymbol;\r
+#endif\r
+{\r
+       int has_empty_alt_already = 0;\r
+       Graph g;\r
+       Junction *j2, *j3, *first_alt;\r
+       Junction *last_alt=NULL, *p;\r
+       require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph");\r
+\r
+       first_alt = (Junction *)g1.left;\r
+       j2 = newJunction();\r
+       j3 = newJunction();\r
+       if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;\r
+       ((Junction *)g1.right)->p2 = g1.left;           /* add loop branch to G */\r
+       ((Junction *)g1.right)->p1 = (Node *) j2;       /* add node to G at end */\r
+       ((Junction *)g1.right)->jtype = EndBlk;         /* mark 1st EndBlk node */\r
+       g1.right = (Node *) j2;\r
+       SetBlk(g1, aPlusBlk, approx, pFirstSetSymbol);\r
+       ((Junction *)g1.left)->lock = makelocks();\r
+       ((Junction *)g1.left)->pred_lock = makelocks();\r
+       j3->p1 = g1.left;                                                       /* add node to front */\r
+       g1.left = (Node *) j3;\r
+\r
+       /* add an optional branch which is the "exit" branch of loop */\r
+       /* FIRST, check to ensure that there does not already exist\r
+        * an optional path.\r
+        */\r
+       /* find last alt */\r
+       for(p=first_alt; p!=NULL; p=(Junction *)p->p2)\r
+       {\r
+               if ( p->p1->ntype == nJunction &&\r
+                        p->p1!=NULL &&\r
+                        ((Junction *)p->p1)->jtype==Generic &&\r
+                        ((Junction *)p->p1)->p1!=NULL &&\r
+                        ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk )\r
+               {\r
+                       has_empty_alt_already = 1;\r
+               }\r
+               last_alt = p;\r
+       }\r
+       if ( !has_empty_alt_already )\r
+       {\r
+               require(last_alt!=NULL, "last_alt==NULL; bad (..)+");\r
+               g = emptyAlt();\r
+               last_alt->p2 = g.left;\r
+               ((Junction *)g.right)->p1 = (Node *) j2;\r
+\r
+               /* make sure lookahead computation ignores this alt for\r
+               * FIRST("(..)+"); but it's still used for computing the FIRST\r
+               * of each alternative.\r
+               */\r
+               ((Junction *)g.left)->ignore = 1;\r
+       }\r
+\r
+       return g1;\r
+}\r
+\r
+/*\r
+ * Return an optional path:  --o-->o--\r
+ */\r
+\r
+Graph\r
+#ifdef __USE_PROTOS\r
+emptyAlt( void )\r
+#else\r
+emptyAlt( )\r
+#endif\r
+{\r
+       Junction *j1, *j2;\r
+       Graph g;\r
+\r
+       j1 = newJunction();\r
+       j2 = newJunction();\r
+       j1->p1 = (Node *) j2;\r
+       g.left = (Node *) j1;\r
+       g.right = (Node *) j2;\r
+       \r
+       return g;\r
+}\r
+\r
+/*  MR21\r
+ *\r
+ *  There is code in genBlk which recognizes the node created\r
+ *  by emptyAlt() as a special case and bypasses it.  We don't\r
+ *  want this to happen for the optBlk.\r
+ */\r
+\r
+Graph\r
+#ifdef __USE_PROTOS\r
+emptyAlt3( void )\r
+#else\r
+emptyAlt3( )\r
+#endif\r
+{\r
+       Junction *j1, *j2, *j3;\r
+       Graph g;\r
+\r
+       j1 = newJunction();\r
+       j2 = newJunction();\r
+    j3 = newJunction();\r
+       j1->p1 = (Node *) j2;\r
+       j2->p1 = (Node *) j3;\r
+       g.left = (Node *) j1;\r
+       g.right = (Node *) j3;\r
+       \r
+       return g;\r
+}\r
+\r
+/* N o d e  A l l o c a t i o n */\r
+\r
+TokNode *\r
+#ifdef __USE_PROTOS\r
+newTokNode( void )\r
+#else\r
+newTokNode( )\r
+#endif\r
+{\r
+       static TokNode *FreeList = NULL;\r
+       TokNode *p, *newblk;\r
+\r
+       if ( FreeList == NULL )\r
+       {\r
+               newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode));\r
+               if ( newblk == NULL )\r
+                       fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
+               for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++)\r
+               {\r
+                       p->next = (Node *)FreeList;     /* add all new token nodes to FreeList */\r
+                       FreeList = p;\r
+               }\r
+       }\r
+       p = FreeList;\r
+       FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */\r
+       p->next = NULL;                                         /* NULL the ptr we used */\r
+    memset( (char *) p, 0, sizeof(TokNode));        /* MR10 */\r
+       p->ntype = nToken;\r
+       p->rname = CurRule;\r
+       p->file = CurFile;\r
+       p->line = zzline;\r
+       p->altstart = NULL;\r
+\r
+       return p;\r
+}\r
+\r
+RuleRefNode *\r
+#ifdef __USE_PROTOS\r
+newRNode( void )\r
+#else\r
+newRNode( )\r
+#endif\r
+{\r
+       static RuleRefNode *FreeList = NULL;\r
+       RuleRefNode *p, *newblk;\r
+\r
+       if ( FreeList == NULL )\r
+       {\r
+               newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode));\r
+               if ( newblk == NULL )\r
+                       fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
+               for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++)\r
+               {\r
+                       p->next = (Node *)FreeList;     /* add all new rref nodes to FreeList */\r
+                       FreeList = p;\r
+               }\r
+       }\r
+       p = FreeList;\r
+       FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */\r
+       p->next = NULL;                                         /* NULL the ptr we used */\r
+    memset( (char *) p, 0, sizeof(RuleRefNode));        /* MR10 */\r
+       p->ntype = nRuleRef;\r
+       p->rname = CurRule;\r
+       p->file = CurFile;\r
+       p->line = zzline;\r
+       p->astnode = ASTinclude;\r
+       p->altstart = NULL;\r
+       \r
+       return p;\r
+}\r
+\r
+static int junctionSeqNumber=0;         /* MR10 */\r
+\r
+Junction *\r
+#ifdef __USE_PROTOS\r
+newJunction( void )\r
+#else\r
+newJunction( )\r
+#endif\r
+{\r
+       static Junction *FreeList = NULL;\r
+       Junction *p, *newblk;\r
+\r
+       if ( FreeList == NULL )\r
+       {\r
+               newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction));\r
+               if ( newblk == NULL )\r
+                       fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
+               for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++)\r
+               {\r
+                       p->p1 = (Node *)FreeList;       /* add all new Junction nodes to FreeList */\r
+                       FreeList = p;\r
+               }\r
+       }\r
+       p = FreeList;\r
+       FreeList = (Junction *)FreeList->p1;/* remove a Junction node */\r
+       p->p1 = NULL;                                           /* NULL the ptr we used */\r
+    memset( (char *) p, 0, sizeof(Junction));       /* MR10 */\r
+       p->ntype = nJunction;\r
+       p->visited = 0;\r
+       p->jtype = Generic;\r
+       p->rname = CurRule;\r
+       p->file = CurFile;\r
+       p->line = zzline;\r
+       p->exception_label = NULL;\r
+       p->fset = (set *) calloc(CLL_k+1, sizeof(set));\r
+       require(p->fset!=NULL, "cannot allocate fset in newJunction");\r
+    p->seq=++junctionSeqNumber;     /* MR10 */\r
+\r
+       return p;\r
+}\r
+\r
+ActionNode *\r
+#ifdef __USE_PROTOS\r
+newActionNode( void )\r
+#else\r
+newActionNode( )\r
+#endif\r
+{\r
+       static ActionNode *FreeList = NULL;\r
+       ActionNode *p, *newblk;\r
+\r
+       if ( FreeList == NULL )\r
+       {\r
+               newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode));\r
+               if ( newblk == NULL )\r
+                       fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));\r
+               for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++)\r
+               {\r
+                       p->next = (Node *)FreeList;     /* add all new Action nodes to FreeList */\r
+                       FreeList = p;\r
+               }\r
+       }\r
+       p = FreeList;\r
+       FreeList = (ActionNode *)FreeList->next;/* remove an Action node */\r
+    memset( (char *) p, 0, sizeof(ActionNode));     /* MR10 */\r
+       p->ntype = nAction;\r
+       p->next = NULL;                                         /* NULL the ptr we used */\r
+       p->done = 0;\r
+       p->pred_fail = NULL;\r
+       p->guardpred = NULL;\r
+    p->ampersandPred = NULL;\r
+       return p;\r
+}\r
+\r
+/*\r
+ * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion.\r
+ * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs.\r
+ * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes.\r
+ *\r
+ * if ( lock[k]==TRUE ) then we have been here before looking for k tokens\r
+ * of lookahead.\r
+ */\r
+char *\r
+#ifdef __USE_PROTOS\r
+makelocks( void )\r
+#else\r
+makelocks( )\r
+#endif\r
+{\r
+       char *p = (char *) calloc(CLL_k+1, sizeof(char));\r
+       require(p!=NULL, "cannot allocate lock array");\r
+       \r
+       return p;\r
+}\r
+\r
+#if 0\r
+** #ifdef __USE_PROTOS\r
+** void my_memset(char *p,char value,int count)\r
+** #else\r
+** void my_memset(p,value,count)\r
+**   char      *p;\r
+**   char      value;\r
+**   int       count;\r
+** #endif\r
+** {\r
+**    int      i;\r
+**\r
+**    for (i=0; i<count; i++) {\r
+**     p[i]=value;\r
+**   };\r
+** }\r
+#endif\r