]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/CCode/Source/Pccts/antlr/misc.c
Retiring the ANT/JAVA build and removing the older EDK II packages that required...
[mirror_edk2.git] / Tools / CCode / Source / Pccts / antlr / misc.c
diff --git a/Tools/CCode/Source/Pccts/antlr/misc.c b/Tools/CCode/Source/Pccts/antlr/misc.c
deleted file mode 100644 (file)
index 3f58da3..0000000
+++ /dev/null
@@ -1,1864 +0,0 @@
-/*\r
- * misc.c\r
- *\r
- * Manage tokens, regular expressions.\r
- * Print methods for debugging\r
- * Compute follow lists onto tail ends of rules.\r
- *\r
- * The following functions are visible:\r
- *\r
- *             int             addTname(char *);               Add token name\r
- *             int             addTexpr(char *);               Add token expression\r
- *             int             Tnum(char *);                   Get number of expr/token\r
- *             void    Tklink(char *, char *); Link a name with an expression\r
- *             int             hasAction(expr);                Does expr already have action assigned?\r
- *             void    setHasAction(expr);             Indicate that expr now has an action\r
- *             Entry   *newEntry(char *,int);  Create new table entry with certain size\r
- *             void    list_add(ListNode **list, char *e)\r
- *      void    list_free(ListNode **list, int freeData);   *** MR10 ***\r
- *             void    list_apply(ListNode *list, void (*f)())\r
- *             void    lexclass(char *m);              switch to new/old lexical class\r
- *             void    lexmode(int i);                 switch to old lexical class i\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 "pcctscfg.h"\r
-#include "set.h"\r
-#include "syn.h"\r
-#include "hash.h"\r
-#include "generic.h"\r
-#include "dlgdef.h"\r
-#include <ctype.h>\r
-\r
-static int tsize=TSChunk;              /* size of token str arrays */\r
-\r
-static void\r
-#ifdef __USE_PROTOS\r
-RemapForcedTokensInSyntaxDiagram(Node *);\r
-#else\r
-RemapForcedTokensInSyntaxDiagram();\r
-#endif\r
-\r
-                               /* T o k e n  M a n i p u l a t i o n */\r
-\r
-/*\r
- * add token 't' to the TokenStr/Expr array.  Make more room if necessary.\r
- * 't' is either an expression or a token name.\r
- *\r
- * There is only one TokenStr array, but multiple ExprStr's.  Therefore,\r
- * for each lex class (element of lclass) we must extend the ExprStr array.\r
- * ExprStr's and TokenStr are always all the same size.\r
- *\r
- * Also, there is a Texpr hash table for each automaton.\r
- */\r
-static void\r
-#ifdef __USE_PROTOS\r
-Ttrack( char *t )\r
-#else\r
-Ttrack( t )\r
-char *t;\r
-#endif\r
-{\r
-       if ( TokenNum >= tsize )        /* terminal table overflow? */\r
-       {\r
-               char **p;\r
-               int i, more, j;\r
-\r
-               more = TSChunk * (1 + ((TokenNum-tsize) / TSChunk));\r
-               tsize += more;\r
-               TokenStr = (char **) realloc((char *)TokenStr, tsize*sizeof(char *));\r
-               require(TokenStr != NULL, "Ttrack: can't extend TokenStr");\r
-               for (i=0; i<NumLexClasses; i++)\r
-               {\r
-                       lclass[i].exprs = (char **)\r
-                                                         realloc((char *)lclass[i].exprs, tsize*sizeof(char *));\r
-                       require(lclass[i].exprs != NULL, "Ttrack: can't extend ExprStr");\r
-                       for (p= &lclass[i].exprs[tsize-more],j=1; j<=more; j++) *p++ = NULL;\r
-               }\r
-               for (p= &TokenStr[tsize-more],i=1; i<=more; i++) *p++ = NULL;\r
-               lexmode( CurrentLexClass ); /* reset ExprStr in case table moved */\r
-       }\r
-       /* note: we use the actual ExprStr/TokenStr array\r
-        * here as TokenInd doesn't exist yet\r
-        */\r
-       if ( *t == '"' ) ExprStr[TokenNum] = t;\r
-       else TokenStr[TokenNum] = t;\r
-}\r
-\r
-static Expr *\r
-#ifdef __USE_PROTOS\r
-newExpr( char *e )\r
-#else\r
-newExpr( e )\r
-char *e;\r
-#endif\r
-{\r
-       Expr *p = (Expr *) calloc(1, sizeof(Expr));\r
-       require(p!=NULL, "newExpr: cannot alloc Expr node");\r
-\r
-       p->expr = e;\r
-       p->lclass = CurrentLexClass;\r
-       return p;\r
-}\r
-\r
-/* switch to lexical class/mode m.  This amounts to creating a new\r
- * lex mode if one does not already exist and making ExprStr point\r
- * to the correct char string array.  We must also switch Texpr tables.\r
- *\r
- * BTW, we need multiple ExprStr arrays because more than one automaton\r
- * may have the same label for a token, but with different expressions.\r
- * We need to track an expr for each automaton.  If we disallowed this\r
- * feature, only one ExprStr would be required.\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-lexclass( char *m )\r
-#else\r
-lexclass( m )\r
-char *m;\r
-#endif\r
-{\r
-       int i;\r
-       TermEntry *p;\r
-       static char EOFSTR[] = "\"@\"";\r
-\r
-       if ( hash_get(Tname, m) != NULL )\r
-       {\r
-               warn(eMsg1("lexclass name conflicts with token/errclass label '%s'",m));\r
-       }\r
-       /* does m already exist? */\r
-       i = LexClassIndex(m);\r
-       if ( i != -1 ) {lexmode(i); return;}\r
-       /* must make new one */\r
-       NumLexClasses++;\r
-       CurrentLexClass = NumLexClasses-1;\r
-       require(NumLexClasses<=MaxLexClasses, "number of allowable lexclasses exceeded\nIncrease MaxLexClasses in generic.h and recompile all C files");\r
-       lclass[CurrentLexClass].classnum = m;\r
-       lclass[CurrentLexClass].exprs = (char **) calloc(tsize, sizeof(char *));\r
-       require(lclass[CurrentLexClass].exprs!=NULL,\r
-                       "lexclass: cannot allocate ExprStr");\r
-       lclass[CurrentLexClass].htable = newHashTable();\r
-       ExprStr = lclass[CurrentLexClass].exprs;\r
-       Texpr = lclass[CurrentLexClass].htable;\r
-       /* define EOF for each automaton */\r
-       p = newTermEntry( EOFSTR );\r
-       p->token = EofToken;    /* couldn't have remapped tokens yet, use EofToken */\r
-       hash_add(Texpr, EOFSTR, (Entry *)p);\r
-       list_add(&ExprOrder, (void *)newExpr(EOFSTR));\r
-       /* note: we use the actual ExprStr array\r
-        * here as TokenInd doesn't exist yet\r
-        */\r
-       ExprStr[EofToken] = EOFSTR;\r
-}\r
-\r
-void\r
-#ifdef __USE_PROTOS\r
-lexmode( int i )\r
-#else\r
-lexmode( i )\r
-int i;\r
-#endif\r
-{\r
-       require(i<NumLexClasses, "lexmode: invalid mode");\r
-       ExprStr = lclass[i].exprs;\r
-       Texpr = lclass[i].htable;\r
-       CurrentLexClass = i;\r
-}\r
-\r
-/* return index into lclass array of lexical class. return -1 if nonexistent */\r
-int\r
-#ifdef __USE_PROTOS\r
-LexClassIndex( char *cl )\r
-#else\r
-LexClassIndex( cl )\r
-char *cl;\r
-#endif\r
-{\r
-       int i;\r
-\r
-       for (i=0; i<NumLexClasses; i++)\r
-       {\r
-               if ( strcmp(lclass[i].classnum, cl) == 0 ) return i;\r
-       }\r
-       return -1;\r
-}\r
-\r
-int\r
-#ifdef __USE_PROTOS\r
-hasAction( char *expr )\r
-#else\r
-hasAction( expr )\r
-char *expr;\r
-#endif\r
-{\r
-       TermEntry *p;\r
-       require(expr!=NULL, "hasAction: invalid expr");\r
-\r
-       p = (TermEntry *) hash_get(Texpr, expr);\r
-       require(p!=NULL, eMsg1("hasAction: expr '%s' doesn't exist",expr));\r
-       return (p->action!=NULL);\r
-}\r
-\r
-void\r
-#ifdef __USE_PROTOS\r
-setHasAction( char *expr, char *action )\r
-#else\r
-setHasAction( expr, action )\r
-char *expr;\r
-char *action;\r
-#endif\r
-{\r
-       TermEntry *p;\r
-       require(expr!=NULL, "setHasAction: invalid expr");\r
-\r
-       p = (TermEntry *) hash_get(Texpr, expr);\r
-       require(p!=NULL, eMsg1("setHasAction: expr '%s' doesn't exist",expr));\r
-       p->action = action;\r
-}\r
-\r
-ForcedToken *\r
-#ifdef __USE_PROTOS\r
-newForcedToken(char *token, int tnum)\r
-#else\r
-newForcedToken(token, tnum)\r
-char *token;\r
-int tnum;\r
-#endif\r
-{\r
-       ForcedToken *ft = (ForcedToken *) calloc(1, sizeof(ForcedToken));\r
-       require(ft!=NULL, "out of memory");\r
-       ft->token = token;\r
-       ft->tnum = tnum;\r
-       return ft;\r
-}\r
-\r
-/*\r
- * Make a token indirection array that remaps token numbers and then walk\r
- * the appropriate symbol tables and SynDiag to change token numbers\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-RemapForcedTokens(void)\r
-#else\r
-RemapForcedTokens()\r
-#endif\r
-{\r
-       ListNode *p;\r
-       ForcedToken *q;\r
-       int max_token_number=0;     /* MR9 23-Sep-97 Removed "unsigned" */\r
-       int i;\r
-\r
-       if ( ForcedTokens == NULL ) return;\r
-\r
-       /* find max token num */\r
-       for (p = ForcedTokens->next; p!=NULL; p=p->next)\r
-       {\r
-               q = (ForcedToken *) p->elem;\r
-               if ( q->tnum > max_token_number ) max_token_number = q->tnum;\r
-       }\r
-       fprintf(stderr, "max token number is %d\n", max_token_number);\r
-\r
-       /* make token indirection array */\r
-       TokenInd = (int *) calloc(max_token_number+1, sizeof(int));\r
-       LastTokenCounted = TokenNum;\r
-       TokenNum = max_token_number+1;\r
-       require(TokenInd!=NULL, "RemapForcedTokens: cannot allocate TokenInd");\r
-\r
-       /* fill token indirection array and change token id htable ; swap token indices */\r
-       for (i=1; i<TokenNum; i++) TokenInd[i] = i;\r
-       for (p = ForcedTokens->next; p!=NULL; p=p->next)\r
-       {\r
-               TermEntry *te;\r
-               int old_pos, t;\r
-\r
-               q = (ForcedToken *) p->elem;\r
-               fprintf(stderr, "%s forced to %d\n", q->token, q->tnum);\r
-               te = (TermEntry *) hash_get(Tname, q->token);\r
-               require(te!=NULL, "RemapForcedTokens: token not in hash table");\r
-               old_pos = te->token;\r
-               fprintf(stderr, "Before: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);\r
-               fprintf(stderr, "Before: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);\r
-               q = (ForcedToken *) p->elem;\r
-               t = TokenInd[old_pos];\r
-               TokenInd[old_pos] = q->tnum;\r
-               TokenInd[q->tnum] = t;\r
-               te->token = q->tnum;            /* update token type id symbol table */\r
-               fprintf(stderr, "After: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);\r
-               fprintf(stderr, "After: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);\r
-\r
-               /* Change the token number in the sym tab entry for the exprs\r
-                * at the old position of the token id and the target position\r
-                */\r
-               /* update expr at target (if any) of forced token id */\r
-               if ( q->tnum < TokenNum )       /* is it a valid position? */\r
-               {\r
-                       for (i=0; i<NumLexClasses; i++)\r
-                       {\r
-                               if ( lclass[i].exprs[q->tnum]!=NULL )\r
-                               {\r
-                                       /* update the symbol table for this expr */\r
-                                       TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[q->tnum]);\r
-                                       require(e!=NULL, "RemapForcedTokens: expr not in hash table");\r
-                                       e->token = old_pos;\r
-                                       fprintf(stderr, "found expr '%s' at target %d in lclass[%d]; changed to %d\n",\r
-                                                       lclass[i].exprs[q->tnum], q->tnum, i, old_pos);\r
-                               }\r
-                       }\r
-               }\r
-               /* update expr at old position (if any) of forced token id */\r
-               for (i=0; i<NumLexClasses; i++)\r
-               {\r
-                       if ( lclass[i].exprs[old_pos]!=NULL )\r
-                       {\r
-                               /* update the symbol table for this expr */\r
-                               TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[old_pos]);\r
-                               require(e!=NULL, "RemapForcedTokens: expr not in hash table");\r
-                               e->token = q->tnum;\r
-                               fprintf(stderr, "found expr '%s' for id %s in lclass[%d]; changed to %d\n",\r
-                                               lclass[i].exprs[old_pos], q->token, i, q->tnum);\r
-                       }\r
-               }\r
-       }\r
-\r
-       /* Update SynDiag */\r
-       RemapForcedTokensInSyntaxDiagram((Node *)SynDiag);\r
-}\r
-\r
-static void\r
-#ifdef __USE_PROTOS\r
-RemapForcedTokensInSyntaxDiagram(Node *p)\r
-#else\r
-RemapForcedTokensInSyntaxDiagram(p)\r
-Node *p;\r
-#endif\r
-{\r
-       Junction *j = (Junction *) p;\r
-       RuleRefNode *r = (RuleRefNode *) p;\r
-       TokNode *t = (TokNode *)p;\r
-\r
-       if ( p==NULL ) return;\r
-       require(p->ntype>=1 && p->ntype<=NumNodeTypes,  "Remap...: invalid diagram node");\r
-       switch ( p->ntype )\r
-       {\r
-               case nJunction :\r
-                       if ( j->visited ) return;\r
-                       if ( j->jtype == EndRule ) return;\r
-                       j->visited = TRUE;\r
-                       RemapForcedTokensInSyntaxDiagram( j->p1 );\r
-                       RemapForcedTokensInSyntaxDiagram( j->p2 );\r
-                       j->visited = FALSE;\r
-                       return;\r
-               case nRuleRef :\r
-                       RemapForcedTokensInSyntaxDiagram( r->next );\r
-                       return;\r
-               case nToken :\r
-                       if ( t->remapped ) return;      /* we've been here before */\r
-                       t->remapped = 1;\r
-                       fprintf(stderr, "remapping %d to %d\n", t->token, TokenInd[t->token]);\r
-                       t->token = TokenInd[t->token];\r
-                       RemapForcedTokensInSyntaxDiagram( t->next );\r
-                       return;\r
-               case nAction :\r
-                       RemapForcedTokensInSyntaxDiagram( ((ActionNode *)p)->next );\r
-                       return;\r
-               default :\r
-                       fatal_internal("invalid node type");\r
-       }\r
-}\r
-\r
-/*\r
- * Add a token name.  Return the token number associated with it.  If it already\r
- * exists, then return the token number assigned to it.\r
- *\r
- * Track the order in which tokens are found so that the DLG output maintains\r
- * that order.  It also lets us map token numbers to strings.\r
- */\r
-int\r
-#ifdef __USE_PROTOS\r
-addTname( char *token )\r
-#else\r
-addTname( token )\r
-char *token;\r
-#endif\r
-{\r
-       TermEntry *p;\r
-       require(token!=NULL, "addTname: invalid token name");\r
-\r
-       if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;\r
-       p = newTermEntry( token );\r
-       Ttrack( p->str );\r
-       p->token = TokenNum++;\r
-       hash_add(Tname, token, (Entry *)p);\r
-       return p->token;\r
-}\r
-\r
-/* This is the same as addTname except we force the TokenNum to be tnum.\r
- * We don't have to use the Forced token stuff as no tokens will have\r
- * been defined with #tokens when this is called.  This is only called\r
- * when a #tokdefs meta-op is used.\r
- */\r
-int\r
-#ifdef __USE_PROTOS\r
-addForcedTname( char *token, int tnum )\r
-#else\r
-addForcedTname( token, tnum )\r
-char *token;\r
-int tnum;\r
-#endif\r
-{\r
-       TermEntry *p;\r
-       require(token!=NULL, "addTname: invalid token name");\r
-\r
-       if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;\r
-       p = newTermEntry( token );\r
-       Ttrack( p->str );\r
-       p->token = tnum;\r
-       hash_add(Tname, token, (Entry *)p);\r
-       return p->token;\r
-}\r
-\r
-/*\r
- * Add a token expr.  Return the token number associated with it.  If it already\r
- * exists, then return the token number assigned to it.\r
- */\r
-int\r
-#ifdef __USE_PROTOS\r
-addTexpr( char *expr )\r
-#else\r
-addTexpr( expr )\r
-char *expr;\r
-#endif\r
-{\r
-       TermEntry *p;\r
-       require(expr!=NULL, "addTexpr: invalid regular expression");\r
-\r
-       if ( (p=(TermEntry *)hash_get(Texpr, expr)) != NULL ) return p->token;\r
-       p = newTermEntry( expr );\r
-       Ttrack( p->str );\r
-       /* track the order in which they occur */\r
-       list_add(&ExprOrder, (void *)newExpr(p->str));\r
-       p->token = TokenNum++;\r
-       hash_add(Texpr, expr, (Entry *)p);\r
-       return p->token;\r
-}\r
-\r
-/* return the token number of 'term'.  Return 0 if no 'term' exists */\r
-int\r
-#ifdef __USE_PROTOS\r
-Tnum( char *term )\r
-#else\r
-Tnum( term )\r
-char *term;\r
-#endif\r
-{\r
-       TermEntry *p;\r
-       require(term!=NULL, "Tnum: invalid terminal");\r
-       \r
-       if ( *term=='"' ) p = (TermEntry *) hash_get(Texpr, term);\r
-       else p = (TermEntry *) hash_get(Tname, term);\r
-       if ( p == NULL ) return 0;\r
-       else return p->token;\r
-}\r
-\r
-/* associate a Name with an expr.  If both have been already assigned\r
- * token numbers, then an error is reported.  Add the token or expr\r
- * that has not been added if no error.  This 'represents' the #token\r
- * ANTLR pseudo-op.  If both have not been defined, define them both\r
- * linked to same token number.\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-Tklink( char *token, char *expr )\r
-#else\r
-Tklink( token, expr )\r
-char *token;\r
-char *expr;\r
-#endif\r
-{\r
-       TermEntry *p, *q;\r
-       require(token!=NULL && expr!=NULL, "Tklink: invalid token name and/or expr");\r
-\r
-       p = (TermEntry *) hash_get(Tname, token);\r
-       q = (TermEntry *) hash_get(Texpr, expr);\r
-       if ( p != NULL && q != NULL )   /* both defined */\r
-       {\r
-               warn( eMsg2("token name %s and rexpr %s already defined; ignored",\r
-                                       token, expr) );\r
-               return;\r
-       }\r
-       if ( p==NULL && q==NULL )               /* both not defined */\r
-       {\r
-               int t = addTname( token );\r
-               q = newTermEntry( expr );\r
-               hash_add(Texpr, expr, (Entry *)q);\r
-               q->token = t;\r
-               /* note: we use the actual ExprStr array\r
-                * here as TokenInd doesn't exist yet\r
-                */\r
-               ExprStr[t] = q->str;\r
-               /* track the order in which they occur */\r
-               list_add(&ExprOrder, (void *)newExpr(q->str));\r
-               return;\r
-       }\r
-       if ( p != NULL )                                /* one is defined, one is not */\r
-       {\r
-               q = newTermEntry( expr );\r
-               hash_add(Texpr, expr, (Entry *)q);\r
-               q->token = p->token;\r
-               ExprStr[p->token] = q->str;     /* both expr and token str defined now */\r
-               list_add(&ExprOrder, (void *)newExpr(q->str));\r
-       }\r
-       else                                                    /* trying to associate name with expr here*/\r
-       {\r
-               p = newTermEntry( token );\r
-               hash_add(Tname, token, (Entry *)p);\r
-               p->token = q->token;\r
-               TokenStr[p->token] = p->str;/* both expr and token str defined now */\r
-       }\r
-}\r
-\r
-/*\r
- * Given a string, this function allocates and returns a pointer to a\r
- * hash table record of size 'sz' whose "str" pointer is reset to a position\r
- * in the string table.\r
- */\r
-Entry *\r
-#ifdef __USE_PROTOS\r
-newEntry( char *text, int sz )\r
-#else\r
-newEntry( text, sz )\r
-char *text;\r
-int sz;\r
-#endif\r
-{\r
-       Entry *p;\r
-       require(text!=NULL, "new: NULL terminal");\r
-       \r
-       if ( (p = (Entry *) calloc(1,sz)) == 0 )\r
-       {\r
-               fatal_internal("newEntry: out of memory for terminals\n");\r
-               exit(PCCTS_EXIT_FAILURE);\r
-       }\r
-       p->str = mystrdup(text);\r
-       \r
-       return(p);\r
-}\r
-\r
-/*\r
- * add an element to a list.\r
- *\r
- * Any non-empty list has a sentinel node whose 'elem' pointer is really\r
- * a pointer to the last element.  (i.e. length(list) = #elemIn(list)+1).\r
- * Elements are appended to the list.\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-list_add( ListNode **list, void *e )\r
-#else\r
-list_add( list, e )\r
-ListNode **list;\r
-void *e;\r
-#endif\r
-{\r
-       ListNode *p, *tail;\r
-       require(e!=NULL, "list_add: attempting to add NULL list element");\r
-\r
-       p = newListNode;\r
-       require(p!=NULL, "list_add: cannot alloc new list node");\r
-       p->elem = e;\r
-       if ( *list == NULL )\r
-       {\r
-               ListNode *sentinel = newListNode;\r
-               require(sentinel!=NULL, "list_add: cannot alloc sentinel node");\r
-               *list=sentinel;\r
-               sentinel->next = p;\r
-               sentinel->elem = (char *)p;             /* set tail pointer */\r
-       }\r
-       else                                                            /* find end of list */\r
-       {\r
-               tail = (ListNode *) (*list)->elem;      /* get tail pointer */\r
-               tail->next = p;\r
-               (*list)->elem = (char *) p;             /* reset tail */\r
-       }\r
-}\r
-\r
-/* MR10 list_free() frees the ListNode elements in the list       */\r
-/* MR10   if freeData then free the data elements of the list too */\r
-\r
-void\r
-#ifdef __USE_PROTOS\r
-list_free(ListNode **list,int freeData)\r
-#else\r
-list_free(list,freeData)\r
-  ListNode      **list;\r
-  int           freeData;\r
-#endif\r
-{\r
-       ListNode *p;\r
-    ListNode *next;\r
-\r
-       if (list == NULL) return;\r
-    if (*list == NULL) return;\r
-       for (p=*list; p != NULL; p=next) {\r
-      next=p->next;\r
-      if (freeData && p->elem != NULL) {\r
-        free( (char *) p->elem);\r
-      };\r
-      free( (char *) p);\r
-    };\r
-    *list=NULL;\r
-}\r
-\r
-void\r
-#ifdef __USE_PROTOS\r
-list_apply( ListNode *list, void (*f)(void *) )\r
-#else\r
-list_apply( list, f )\r
-ListNode *list;\r
-void (*f)();\r
-#endif\r
-{\r
-       ListNode *p;\r
-       require(f!=NULL, "list_apply: NULL function to apply");\r
-\r
-       if ( list == NULL ) return;\r
-       for (p = list->next; p!=NULL; p=p->next) (*f)( p->elem );\r
-}\r
-\r
-/* MR27 */\r
-\r
-#ifdef __USE_PROTOS\r
-int list_search_cstring(ListNode *list, char * cstring)\r
-#else\r
-int list_search_cstring(list, cstring)\r
-  ListNode * list;\r
-  char * cstring;\r
-#endif\r
-{\r
-       ListNode *p;\r
-       if (list == NULL ) return 0;\r
-       for (p = list->next; p!=NULL; p=p->next) {\r
-               if (p->elem == NULL) continue;\r
-               if (0 == strcmp((char *) p->elem , cstring)) return 1;\r
-       }\r
-       return 0;\r
-}\r
-\r
-                       /* F O L L O W  C y c l e  S t u f f */\r
-               \r
-/* make a key based upon (rulename, computation, k value).\r
- * Computation values are 'i'==FIRST, 'o'==FOLLOW.\r
- */\r
-\r
-/* MR10  Make the key all characters so it can be read easily   */\r
-/* MR10    by a simple dump program.  Also, separates           */\r
-/* MR10   'o' and 'i' from rule name                            */\r
-\r
-char *\r
-#ifdef __USE_PROTOS\r
-Fkey( char *rule, int computation, int k )\r
-#else\r
-Fkey( rule, computation, k )\r
-char *rule;\r
-int computation;\r
-int k;\r
-#endif\r
-{\r
-       static char key[MaxRuleName+2+2+1];                                 /* MR10 */\r
-       int i;\r
-       \r
-       if ( k > 99 )                                                       /* MR10 */\r
-               fatal("k>99 is too big for this implementation of ANTLR!\n");   /* MR10 */\r
-       if ( (i=strlen(rule)) > MaxRuleName )                               /* MR10 */\r
-               fatal( eMsgd("rule name > max of %d\n", MaxRuleName) );         /* MR10 */\r
-       strcpy(key,rule);\r
-\r
-/* MR10 */     key[i]='*';\r
-/* MR10 */     key[i+1] = (char) computation; /* MR20 G. Hobbelt */\r
-/* MR10 */     if (k < 10) {\r
-/* MR10 */       key[i+2] = (char) ( '0' + k);\r
-/* MR10 */      key[i+3] = '\0';\r
-/* MR10 */     } else {\r
-/* MR10 */       key[i+2] = (char) ( '0' + k/10);\r
-/* MR10 */       key[i+3] = (char) ( '0' + k % 10);\r
-/* MR10 */       key[i+4] = '\0';\r
-/* MR10 */     };\r
-\r
-       return key;\r
-}\r
-\r
-/* Push a rule onto the kth FOLLOW stack */\r
-void\r
-#ifdef __USE_PROTOS\r
-FoPush( char *rule, int k )\r
-#else\r
-FoPush( rule, k )\r
-char *rule;\r
-int k;\r
-#endif\r
-{\r
-       RuleEntry *r;\r
-       require(rule!=NULL, "FoPush: tried to push NULL rule");\r
-       require(k<=CLL_k,       "FoPush: tried to access non-existent stack");\r
-\r
-       /*fprintf(stderr, "FoPush(%s)\n", rule);*/\r
-       r = (RuleEntry *) hash_get(Rname, rule);\r
-       if ( r == NULL ) {fatal_internal( eMsg1("rule %s must be defined but isn't", rule) );}\r
-       if ( FoStack[k] == NULL )               /* Does the kth stack exist yet? */\r
-       {\r
-               /*fprintf(stderr, "allocating FoStack\n");*/\r
-               FoStack[k] = (int *) calloc(FoStackSize, sizeof(int));\r
-               require(FoStack[k]!=NULL, "FoPush: cannot allocate FOLLOW stack\n");\r
-       }\r
-       if ( FoTOS[k] == NULL )\r
-       {\r
-               FoTOS[k]=FoStack[k];\r
-               *(FoTOS[k]) = r->rulenum;\r
-       }\r
-       else\r
-       {\r
-#ifdef MEMCHK\r
-               require(valid(FoStack[k]), "FoPush: invalid FoStack");\r
-#endif\r
-               if ( FoTOS[k] >= &(FoStack[k][FoStackSize-1]) )\r
-                       fatal( eMsgd("exceeded max depth of FOLLOW recursion (%d)\n",\r
-                                               FoStackSize) );\r
-               require(FoTOS[k]>=FoStack[k],\r
-                               eMsg1("FoPush: FoStack stack-ptr is playing out of its sandbox",\r
-                                         rule));\r
-               ++(FoTOS[k]);\r
-               *(FoTOS[k]) = r->rulenum;\r
-       }\r
-       {\r
-               /*\r
-****           int *p;\r
-****           fprintf(stderr, "FoStack[k=%d]:\n", k);\r
-****           for (p=FoStack[k]; p<=FoTOS[k]; p++)\r
-****           {\r
-****                   fprintf(stderr, "\t%s\n", RulePtr[*p]->rname);\r
-****           }\r
-               */\r
-       }\r
-}\r
-\r
-/* Pop one rule off of the FOLLOW stack.  TOS ptr is NULL if empty. */\r
-void\r
-#ifdef __USE_PROTOS\r
-FoPop( int k )\r
-#else\r
-FoPop( k )\r
-int k;\r
-#endif\r
-{\r
-       require(k<=CLL_k, "FoPop: tried to access non-existent stack");\r
-       /*fprintf(stderr, "FoPop\n");*/\r
-       require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),\r
-                       "FoPop: FoStack stack-ptr is playing out of its sandbox");\r
-       if ( FoTOS[k] == FoStack[k] ) FoTOS[k] = NULL;\r
-       else (FoTOS[k])--;\r
-}\r
-\r
-/* Compute FOLLOW cycle.\r
- * Mark all FOLLOW sets for rules in cycle as incomplete.\r
- * Then, save cycle on the cycle list (Cycles) for later resolution.\r
- * The Cycle is stored in the form:\r
- *             (head of cycle==croot, rest of rules in cycle==cyclicDep)\r
- *\r
- * e.g. (Fo means "FOLLOW of", "-->" means requires or depends on)\r
- *\r
- *             Fo(x)-->Fo(a)-->Fo(b)-->Fo(c)-->Fo(x)\r
- *                                                                                ^----Infinite recursion (cycle)\r
- *\r
- * the cycle would be: x -> {a,b,c} or stored as (x,{a,b,c}).  Fo(x) depends\r
- * on the FOLLOW of a,b, and c.  The root of a cycle is always complete after\r
- * Fo(x) finishes.  Fo(a,b,c) however are not.  It turns out that all rules\r
- * in a FOLLOW cycle have the same FOLLOW set.\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-RegisterCycle( char *rule, int k )\r
-#else\r
-RegisterCycle( rule, k )\r
-char *rule;\r
-int k;\r
-#endif\r
-{\r
-       CacheEntry *f;\r
-       Cycle *c;\r
-       int *p;\r
-       RuleEntry *r;\r
-       require(rule!=NULL, "RegisterCycle: tried to register NULL rule");\r
-       require(k<=CLL_k,       "RegisterCycle: tried to access non-existent stack");\r
-\r
-       /*fprintf(stderr, "RegisterCycle(%s)\n", rule);*/\r
-       /* Find cycle start */\r
-       r = (RuleEntry *) hash_get(Rname, rule);\r
-       require(r!=NULL,eMsg1("rule %s must be defined but isn't", rule));\r
-       require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),\r
-                       eMsg1("RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox",\r
-                                 rule));\r
-/***   if ( FoTOS[k]<FoStack[k]||FoTOS[k]>&(FoStack[k][FoStackSize-1]) )\r
-****   {\r
-****           fprintf(stderr, "RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox\n",\r
-****                                           rule);\r
-****           fprintf(stderr, "RegisterCycle: sp==0x%x out of bounds 0x%x...0x%x\n",\r
-****                                           FoTOS[k], FoStack[k], &(FoStack[k][FoStackSize-1]));\r
-****           exit(PCCTS_EXIT_FAILURE);\r
-****   }\r
-****/\r
-\r
-#ifdef MEMCHK\r
-       require(valid(FoStack[k]), "RegisterCycle: invalid FoStack");\r
-#endif\r
-       for (p=FoTOS[k]; *p != r->rulenum && p >= FoStack[k]; --p) {;}\r
-       require(p>=FoStack[k], "RegisterCycle: FoStack is screwed up beyond belief");\r
-       if ( p == FoTOS[k] ) return;    /* don't worry about cycles to oneself */\r
-       \r
-       /* compute cyclic dependents (rules in cycle except head) */\r
-       c = newCycle;\r
-       require(c!=NULL, "RegisterCycle: couldn't alloc new cycle");\r
-       c->cyclicDep = empty;\r
-       c->croot = *p++;                /* record root of cycle */\r
-       for (; p<=FoTOS[k]; p++)\r
-       {\r
-               /* Mark all dependent rules as incomplete */\r
-               f = (CacheEntry *) hash_get(Fcache, Fkey(RulePtr[*p]->rname,'o',k));\r
-               if ( f==NULL )\r
-               {\r
-                       f = newCacheEntry( Fkey(RulePtr[*p]->rname,'o',k) );\r
-                       hash_add(Fcache, Fkey(RulePtr[*p]->rname,'o',k), (Entry *)f);\r
-               }\r
-               f->incomplete = TRUE;\r
-               \r
-               set_orel(*p, &(c->cyclicDep)); /* mark rule as dependent of croot */\r
-       }\r
-       list_add(&(Cycles[k]), (void *)c);\r
-}\r
-\r
-/* make all rules in cycle complete\r
- *\r
- * while ( some set has changed ) do\r
- *             for each cycle do\r
- *                     if degree of FOLLOW set for croot > old degree then\r
- *                             update all FOLLOW sets for rules in cyclic dependency\r
- *                             change = TRUE\r
- *                     endif\r
- *             endfor\r
- * endwhile\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-ResolveFoCycles( int k )\r
-#else\r
-ResolveFoCycles( k )\r
-int k;\r
-#endif\r
-{\r
-       ListNode *p, *q;\r
-       Cycle *c;\r
-       int changed = 1;\r
-       CacheEntry *f,*g;\r
-       int r;\r
-/*  int i;  */  /* MR10 not useful */\r
-       unsigned d;\r
-\r
-    unsigned    *cursor;        /* MR10 */\r
-    unsigned    *origin;        /* MR10 */\r
-       \r
-       /*fprintf(stderr, "Resolving following cycles for %d\n", k);*/\r
-       while ( changed )\r
-       {\r
-               changed = 0;\r
-/* MR10 i = 0;  */\r
-               for (p = Cycles[k]->next; p!=NULL; p=p->next)\r
-               {\r
-                       c = (Cycle *) p->elem;\r
-                       /*fprintf(stderr, "cycle %d: %s -->", i++, RulePtr[c->croot]->rname);*/\r
-                       /*s_fprT(stderr, c->cyclicDep);*/\r
-                       /*fprintf(stderr, "\n");*/\r
-                       f = (CacheEntry *)\r
-                                       hash_get(Fcache, Fkey(RulePtr[c->croot]->rname,'o',k));\r
-                       require(f!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[c->croot]->rname) );\r
-                       if ( (d=set_deg(f->fset)) > c->deg )\r
-                       {\r
-                               /*fprintf(stderr, "Fo(%s) has changed\n", RulePtr[c->croot]->rname);*/\r
-                               changed = 1;\r
-                               c->deg = d;             /* update cycle FOLLOW set degree */\r
-\r
-/* MR10 */      origin=set_pdq(c->cyclicDep);\r
-/* MR10 */      for (cursor=origin; *cursor != nil; cursor++) {\r
-/* MR10 */         r=*cursor;\r
-\r
-/********              while ( !set_nil(c->cyclicDep) ) {      *****/\r
-/********                                      r = set_int(c->cyclicDep);  *****/\r
-/********                                      set_rm(r, c->cyclicDep);    *****/\r
-\r
-                                       /*fprintf(stderr, "updating Fo(%s)\n", RulePtr[r]->rname);*/\r
-                                       g = (CacheEntry *)\r
-                                                       hash_get(Fcache, Fkey(RulePtr[r]->rname,'o',k));\r
-                                       require(g!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[r]->rname) );\r
-                                       set_orin(&(g->fset), f->fset);\r
-                                       g->incomplete = FALSE;\r
-                               }\r
-/* MR10 */      free( (char *) origin);\r
-/* MR10 */      origin=NULL;\r
-                       }\r
-               }\r
-/* MR10 - this if statement appears to be meaningless since i is always 0 */\r
-/* MR10                if ( i == 1 ) changed = 0;      */ /* if only 1 cycle, no need to repeat */\r
-       }\r
-       /* kill Cycle list */\r
-       for (q = Cycles[k]->next; q != NULL; q=p)\r
-       {\r
-               p = q->next;\r
-               set_free( ((Cycle *)q->elem)->cyclicDep );\r
-               free((char *)q);\r
-       }\r
-       free( (char *)Cycles[k] );\r
-       Cycles[k] = NULL;\r
-}\r
-\r
-\r
-                       /* P r i n t i n g  S y n t a x  D i a g r a m s */\r
-\r
-static void\r
-#ifdef __USE_PROTOS\r
-pBlk( Junction *q, int btype )\r
-#else\r
-pBlk( q, btype )\r
-Junction *q;\r
-int btype;\r
-#endif\r
-{\r
-       int k,a;\r
-       Junction *alt, *p;\r
-\r
-       q->end->pvisited = TRUE;\r
-       if ( btype == aLoopBegin )\r
-       {\r
-               require(q->p2!=NULL, "pBlk: invalid ()* block");\r
-               PRINT(q->p1);\r
-               alt = (Junction *)q->p2;\r
-               PRINT(alt->p1);\r
-               if ( PrintAnnotate )\r
-               {\r
-                       printf(" /* Opt ");\r
-                       k = 1;\r
-                       while ( !set_nil(alt->fset[k]) )\r
-                       {\r
-                               s_fprT(stdout, alt->fset[k]);\r
-                               if ( k++ == CLL_k ) break;\r
-                               if ( !set_nil(alt->fset[k]) ) printf(", ");\r
-                       }\r
-                       printf(" */\n");\r
-               }\r
-               return;\r
-       }\r
-       for (a=1,alt=q; alt != NULL; alt= (Junction *) alt->p2, a++)\r
-       {\r
-               if ( alt->p1 != NULL ) PRINT(alt->p1);\r
-               if ( PrintAnnotate )\r
-               {\r
-                       printf( " /* [%d] ", alt->altnum);\r
-                       k = 1;\r
-                       while ( !set_nil(alt->fset[k]) )\r
-                       {\r
-                               s_fprT(stdout, alt->fset[k]);\r
-                               if ( k++ == CLL_k ) break;\r
-                               if ( !set_nil(alt->fset[k]) ) printf(", ");\r
-                       }\r
-                       if ( alt->p2 == NULL && btype == aOptBlk )\r
-                               printf( " (optional branch) */\n");\r
-                       else printf( " */\n");\r
-               }\r
-\r
-               /* ignore implied empty alt of Plus blocks */\r
-               if ( alt->p2 != NULL && ((Junction *)alt->p2)->ignore ) break;\r
-\r
-               if ( alt->p2 != NULL && !(((Junction *)alt->p2)->p2==NULL && btype == aOptBlk) )\r
-               {\r
-                       if ( pLevel == 1 )\r
-                       {\r
-                               printf("\n");\r
-                               if ( a+1==pAlt1 || a+1==pAlt2 ) printf("=>");\r
-                               printf("\t");\r
-                       }\r
-                       else printf(" ");\r
-                       printf("|");\r
-                       if ( pLevel == 1 )\r
-                       {\r
-                               p = (Junction *) ((Junction *)alt->p2)->p1;\r
-                               while ( p!=NULL )\r
-                               {\r
-                                       if ( p->ntype==nAction )\r
-                                       {\r
-                                               p=(Junction *)((ActionNode *)p)->next;\r
-                                               continue;\r
-                                       }\r
-                                       if ( p->ntype!=nJunction )\r
-                                       {\r
-                                               break;\r
-                                       }\r
-                                       if ( p->jtype==EndBlk || p->jtype==EndRule )\r
-                                       {\r
-                                               p = NULL;\r
-                                               break;\r
-                                       }\r
-                                       p = (Junction *)p->p1;\r
-                               }\r
-                               if ( p==NULL ) printf("\n\t");  /* Empty alt? */\r
-                       }\r
-               }\r
-       }\r
-       q->end->pvisited = FALSE;\r
-}\r
-\r
-/* How to print out a junction */\r
-void\r
-#ifdef __USE_PROTOS\r
-pJunc( Junction *q )\r
-#else\r
-pJunc( q )\r
-Junction *q;\r
-#endif\r
-{\r
-       int dum_k;\r
-       int doing_rule;\r
-       require(q!=NULL, "pJunc: NULL node");\r
-       require(q->ntype==nJunction, "pJunc: not junction");\r
-       \r
-       if ( q->pvisited == TRUE ) return;\r
-       q->pvisited = TRUE;\r
-       switch ( q->jtype )\r
-       {\r
-               case aSubBlk :\r
-                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);\r
-                       if ( q->end->p1 != NULL && ((Junction *)q->end->p1)->ntype==nJunction &&\r
-                                ((Junction *)q->end->p1)->jtype == EndRule ) doing_rule = 1;\r
-                       else doing_rule = 0;\r
-                       pLevel++;\r
-                       if ( pLevel==1 )\r
-                       {\r
-                               if ( pAlt1==1 ) printf("=>");\r
-                               printf("\t");\r
-                       }\r
-                       else printf(" ");\r
-                       if ( doing_rule )\r
-                       {\r
-                               if ( pLevel==1 ) printf(" ");\r
-                               pBlk(q,q->jtype);\r
-                       }\r
-                       else {\r
-                               printf("(");\r
-                               if ( pLevel==1 ) printf(" ");\r
-                               pBlk(q,q->jtype);\r
-                               if ( pLevel>1 ) printf(" ");\r
-                               printf(")");\r
-                       }\r
-                       if ( q->guess ) printf("?");\r
-                       pLevel--;\r
-                       if ( PrintAnnotate ) freeBlkFsets(q);\r
-                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);\r
-                       break;\r
-               case aOptBlk :\r
-                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);\r
-                       pLevel++;\r
-                       if ( pLevel==1 )\r
-                       {\r
-                               if ( pAlt1==1 ) printf("=>");\r
-                               printf("\t");\r
-                       }\r
-                       else printf(" ");\r
-                       printf("{");\r
-                       if ( pLevel==1 ) printf(" ");\r
-                       pBlk(q,q->jtype);\r
-                       if ( pLevel>1 ) printf(" ");\r
-                       else printf("\n\t");\r
-                       printf("}");\r
-                       pLevel--;\r
-                       if ( PrintAnnotate ) freeBlkFsets(q);\r
-                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);\r
-                       break;\r
-               case aLoopBegin :\r
-                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);\r
-                       pLevel++;\r
-                       if ( pLevel==1 )\r
-                       {\r
-                               if ( pAlt1==1 ) printf("=>");\r
-                               printf("\t");\r
-                       }\r
-                       else printf(" ");\r
-                       printf("(");\r
-                       if ( pLevel==1 ) printf(" ");\r
-                       pBlk(q,q->jtype);\r
-                       if ( pLevel>1 ) printf(" ");\r
-                       else printf("\n\t");\r
-                       printf(")*");\r
-                       pLevel--;\r
-                       if ( PrintAnnotate ) freeBlkFsets(q);\r
-                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);\r
-                       break;\r
-               case aLoopBlk :\r
-                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);\r
-                       pBlk(q,q->jtype);\r
-                       if ( PrintAnnotate ) freeBlkFsets(q);\r
-                       break;\r
-               case aPlusBlk :\r
-                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);\r
-                       pLevel++;\r
-                       if ( pLevel==1 )\r
-                       {\r
-                               if ( pAlt1==1 ) printf("=>");\r
-                               printf("\t");\r
-                       }\r
-                       else printf(" ");\r
-                       printf("(");\r
-                       if ( pLevel==1 ) printf(" ");\r
-                       pBlk(q,q->jtype);\r
-                       if ( pLevel>1 ) printf(" ");\r
-                       printf(")+");\r
-                       pLevel--;\r
-                       if ( PrintAnnotate ) freeBlkFsets(q);\r
-                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);\r
-                       break;\r
-               case EndBlk :\r
-                       break;\r
-               case RuleBlk :\r
-                       printf( "\n%s :\n", q->rname);\r
-                       PRINT(q->p1);\r
-                       if ( q->p2 != NULL ) PRINT(q->p2);\r
-                       break;\r
-               case Generic :\r
-                       if ( q->p1 != NULL ) PRINT(q->p1);\r
-                       q->pvisited = FALSE;\r
-                       if ( q->p2 != NULL ) PRINT(q->p2);\r
-                       break;\r
-               case EndRule :\r
-                       printf( "\n\t;\n");\r
-                       break;\r
-       }\r
-       q->pvisited = FALSE;\r
-}\r
-\r
-/* How to print out a rule reference node */\r
-void\r
-#ifdef __USE_PROTOS\r
-pRuleRef( RuleRefNode *p )\r
-#else\r
-pRuleRef( p )\r
-RuleRefNode *p;\r
-#endif\r
-{\r
-       require(p!=NULL, "pRuleRef: NULL node");\r
-       require(p->ntype==nRuleRef, "pRuleRef: not rule ref node");\r
-       \r
-       printf( " %s", p->text);\r
-       PRINT(p->next);\r
-}\r
-\r
-/* How to print out a terminal node */\r
-void\r
-#ifdef __USE_PROTOS\r
-pToken( TokNode *p )\r
-#else\r
-pToken( p )\r
-TokNode *p;\r
-#endif\r
-{\r
-       require(p!=NULL, "pToken: NULL node");\r
-       require(p->ntype==nToken, "pToken: not token node");\r
-\r
-       if ( p->wild_card ) printf(" .");\r
-       printf( " %s", TerminalString(p->token));\r
-       PRINT(p->next);\r
-}\r
-\r
-/* How to print out a terminal node */\r
-void\r
-#ifdef __USE_PROTOS\r
-pAction( ActionNode *p )\r
-#else\r
-pAction( p )\r
-ActionNode *p;\r
-#endif\r
-{\r
-       require(p!=NULL, "pAction: NULL node");\r
-       require(p->ntype==nAction, "pAction: not action node");\r
-       \r
-       PRINT(p->next);\r
-}\r
-\r
-                                       /* F i l l  F o l l o w  L i s t s */\r
-\r
-/*\r
- * Search all rules for all rule reference nodes, q to rule, r.\r
- * Add q->next to follow list dangling off of rule r.\r
- * i.e.\r
- *\r
- *             r: -o-R-o-->o--> Ptr to node following rule r in another rule\r
- *                                     |\r
- *                                     o--> Ptr to node following another reference to r.\r
- *\r
- * This is the data structure employed to avoid FOLLOW set computation.  We\r
- * simply compute the FIRST (reach) of the EndRule Node which follows the\r
- * list found at the end of all rules which are referenced elsewhere.  Rules\r
- * not invoked by other rules have no follow list (r->end->p1==NULL).\r
- * Generally, only start symbols are not invoked by another rule.\r
- *\r
- * Note that this mechanism also gives a free cross-reference mechanism.\r
- *\r
- * The entire syntax diagram is layed out like this:\r
- *\r
- * SynDiag\r
- *     |\r
- *     v\r
- *     o-->R1--o\r
- *     |\r
- *     o-->R2--o\r
- *     |\r
- *     ...\r
- *     |\r
- *     o-->Rn--o\r
- *\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-FoLink( Node *p )\r
-#else\r
-FoLink( p )\r
-Node *p;\r
-#endif\r
-{\r
-       RuleEntry *q;\r
-       Junction *j = (Junction *) p;\r
-       RuleRefNode *r = (RuleRefNode *) p;\r
-\r
-       if ( p==NULL ) return;\r
-       require(p->ntype>=1 && p->ntype<=NumNodeTypes,\r
-                       eMsgd("FoLink: invalid diagram node: ntype==%d",p->ntype));\r
-       switch ( p->ntype )\r
-       {\r
-               case nJunction :\r
-                       if ( j->fvisited ) return;\r
-                       if ( j->jtype == EndRule ) return;\r
-                       j->fvisited = TRUE;\r
-                       FoLink( j->p1 );\r
-                       FoLink( j->p2 );\r
-/* MR14 */\r
-/* MR14 */  /* Need to determine whether the guess block is an         */\r
-/* MR14 */  /* of the form (alpha)? beta before follow sets are        */\r
-/* MR14 */  /* computed.  This is necessary to solve problem           */\r
-/* MR14 */  /* of doing follow on the alpha of an (alpha)? beta block. */\r
-/* MR14 */\r
-/* MR14 */  /* This is performed by analysis_point as a side-effect.   */\r
-/* MR14 */\r
-/* MR14 */\r
-/* MR14 */  if (j->jtype == aSubBlk && j->guess) {\r
-/* MR14 */    Junction *ignore;\r
-/* MR14 */    ignore=analysis_point(j);\r
-/* MR14 */  }\r
-/* MR14 */\r
-                       return;\r
-               case nRuleRef :\r
-                       if ( r->linked ) return;\r
-                       q = (RuleEntry *) hash_get(Rname, r->text);\r
-                       if ( q == NULL )\r
-                       {\r
-                               warnFL( eMsg1("rule %s not defined",r->text), FileStr[r->file], r->line );\r
-                       }\r
-                       else\r
-                       {\r
-                               if ( r->parms!=NULL && RulePtr[q->rulenum]->pdecl==NULL )\r
-                               {\r
-                                       warnFL( eMsg1("rule %s accepts no parameter(s)", r->text),\r
-                                                       FileStr[r->file], r->line );\r
-                               }\r
-                               if ( r->parms==NULL && RulePtr[q->rulenum]->pdecl!=NULL )\r
-                               {\r
-                                       warnFL( eMsg1("rule %s requires parameter(s)", r->text),\r
-                                                       FileStr[r->file], r->line );\r
-                               }\r
-                               if ( r->assign!=NULL && RulePtr[q->rulenum]->ret==NULL )\r
-                               {\r
-                                       warnFL( eMsg1("rule %s yields no return value(s)", r->text),\r
-                                                       FileStr[r->file], r->line );\r
-                               }\r
-                               if ( r->assign==NULL && RulePtr[q->rulenum]->ret!=NULL )\r
-                               {\r
-                                       warnFL( eMsg1("rule %s returns a value(s)", r->text),\r
-                                                       FileStr[r->file], r->line );\r
-                               }\r
-                               if ( !r->linked )\r
-                               {\r
-                                       addFoLink(      r->next, r->rname, RulePtr[q->rulenum] );\r
-                                       r->linked = TRUE;\r
-                               }\r
-                       }\r
-                       FoLink( r->next );\r
-                       return;\r
-               case nToken :\r
-                       FoLink( ((TokNode *)p)->next );\r
-                       return;\r
-               case nAction :\r
-                       FoLink( ((ActionNode *)p)->next );\r
-                       return;\r
-               default :\r
-                       fatal_internal("invalid node type");\r
-       }\r
-}\r
-\r
-/*\r
- * Add a reference to the end of a rule.\r
- *\r
- * 'r' points to the RuleBlk node in a rule.  r->end points to the last node\r
- * (EndRule jtype) in a rule.\r
- *\r
- * Initial:\r
- *             r->end -->      o\r
- *\r
- * After:\r
- *             r->end -->      o-->o--> Ptr to node following rule r in another rule\r
- *                                             |\r
- *                                             o--> Ptr to node following another reference to r.\r
- *\r
- * Note that the links are added to the head of the list so that r->end->p1\r
- * always points to the most recently added follow-link.  At the end, it should\r
- * point to the last reference found in the grammar (starting from the 1st rule).\r
- */\r
-void\r
-#ifdef __USE_PROTOS\r
-addFoLink( Node *p, char *rname, Junction *r )\r
-#else\r
-addFoLink( p, rname, r )\r
-Node *p;\r
-char *rname;\r
-Junction *r;\r
-#endif\r
-{\r
-       Junction *j;\r
-       require(r!=NULL,                                "addFoLink: incorrect rule graph");\r
-       require(r->end!=NULL,                   "addFoLink: incorrect rule graph");\r
-       require(r->end->jtype==EndRule, "addFoLink: incorrect rule graph");\r
-       require(p!=NULL,                                "addFoLink: NULL FOLLOW link");\r
-\r
-       j = newJunction();\r
-       j->rname = rname;                       /* rname on follow links point to target rule */\r
-       j->p1 = p;                                      /* link to other rule */\r
-       j->p2 = (Node *) r->end->p1;/* point to head of list */\r
-       r->end->p1 = (Node *) j;        /* reset head to point to new node */\r
-}\r
-\r
-void\r
-#ifdef __USE_PROTOS\r
-GenCrossRef( Junction *p )\r
-#else\r
-GenCrossRef( p )\r
-Junction *p;\r
-#endif\r
-{\r
-       set a;\r
-       Junction *j;\r
-       RuleEntry *q;\r
-       unsigned e;\r
-       require(p!=NULL, "GenCrossRef: why are you passing me a null grammar?");\r
-\r
-       printf("Cross Reference:\n\n");\r
-       a = empty;\r
-       for (; p!=NULL; p = (Junction *)p->p2)\r
-       {\r
-               printf("Rule %20s referenced by {", p->rname);\r
-               /* make a set of rules for uniqueness */\r
-               for (j = (Junction *)(p->end)->p1; j!=NULL; j = (Junction *)j->p2)\r
-               {\r
-                       q = (RuleEntry *) hash_get(Rname, j->rname);\r
-                       require(q!=NULL, "GenCrossRef: FoLinks are screwed up");\r
-                       set_orel(q->rulenum, &a);\r
-               }\r
-               for (; !set_nil(a); set_rm(e, a))\r
-               {\r
-                       e = set_int(a);\r
-                       printf(" %s", RulePtr[e]->rname);\r
-               }\r
-               printf(" }\n");\r
-       }\r
-       set_free( a );\r
-}\r
-\r
-/*\r
-   The single argument is a pointer to the start of an element of a\r
-   C++ style function prototypet list.  Given a pointer to the start of\r
-   an formal we must locate the comma (or the end of the string)\r
-   and locate the datatype, formal name, and initial value expression.\r
-\r
-   The function returns a pointer to the character following the comma\r
-   which terminates the formal declaration, or a pointer to the end of\r
-   the string if none was found.\r
-\r
-   I thought we were parsing specialists, how come I'm doing this by\r
-   hand written code ?\r
-\r
-   Examples of input:\r
\r
-        Foo f,\r
-        Foo f = Foo(1),\r
-        Foo f = Foo(1,2),\r
-        Foo f = &farray[1,2],\r
-        Foo f = ",",\r
-        Foo f = ',',\r
-        TFoo<int,char> f = TFoo<int,char>(1,2),\r
-\r
-   A non-zero value for nesting indicates a problem matching '(' and ')',\r
-   '[' and ']', '<' and '>', '{' and '}', or improperly terminated string\r
-   or character literal.\r
-\r
-*/\r
-\r
-\r
-/*\r
- *  Don't care if it is a valid string literal or not, just find the end\r
- *  Start with pointer to leading "\""\r
- */\r
-\r
-#ifdef __USE_PROTOS\r
-char * skipStringLiteral(char *pCurrent)\r
-#else\r
-char * skipStringLiteral(pCurrent)\r
-char *pCurrent;\r
-#endif\r
-{\r
-  char *p = pCurrent;\r
-  if (*p == 0) return p;\r
-  require (*p == '\"', "skipStringLiteral")\r
-  p++;\r
-  for (p = p; *p != 0; p++) {\r
-    if (*p == '\\') {\r
-      p++;\r
-      if (*p == 0) break;\r
-      p++;\r
-    }\r
-    if (*p == '\"') {\r
-      p++;\r
-      break;\r
-    }\r
-  }\r
-  return p;\r
-}\r
-\r
-/*\r
- *  Don't care if it is a valid character literal or not, just find the end\r
- *  Start with pointer to leading "'"\r
- */\r
-\r
-#ifdef __USE_PROTOS\r
-char * skipCharLiteral(char *pStart)\r
-#else\r
-char * skipCharLiteral(pStart)\r
- char *pStart;\r
-#endif\r
-{\r
-  char *p = pStart;\r
-  if (*p == 0) return p;\r
-  require (*p == '\'', "skipCharLiteral")\r
-  p++;\r
-  for (p = p; *p != 0; p++) {\r
-    if (*p == '\\') {\r
-      p++;\r
-      if (*p == 0) break;\r
-      p++;\r
-    }\r
-    if (*p == '\'') {\r
-      p++;\r
-      break;\r
-    }\r
-  }\r
-  return p;\r
-}\r
-\r
-#ifdef __USE_PROTOS\r
-char * skipSpaces(char *pStart)\r
-#else\r
-char * skipSpaces(pStart)\r
-char * pStart;\r
-#endif\r
-{\r
-  char *p = pStart;\r
-  while (*p != 0 && isspace(*p)) p++;\r
-  return p;\r
-}\r
-\r
-#ifdef __USE_PROTOS\r
-char * skipToSeparatorOrEqualSign(char *pStart, int *pNest)\r
-#else\r
-char * skipToSeparatorOrEqualSign(pStart, pNest)\r
-char *pStart;\r
-int *pNest;\r
-#endif\r
-{\r
-  char *p = pStart;\r
-  \r
-  int nest = 0;\r
-\r
-  *pNest = (-1);\r
-\r
-  while (*p != 0) {\r
-    switch (*p) {\r
-\r
-      case '(' :\r
-      case '[' :\r
-      case '<' :\r
-      case '{' :\r
-        nest++;\r
-        p++;\r
-        break;\r
-\r
-      case ')' :\r
-      case ']' :\r
-      case '>' :\r
-      case '}' :\r
-        nest--;\r
-        p++;\r
-        break;\r
-      \r
-      case '"' :\r
-        p = skipStringLiteral(p);\r
-        break;\r
-  \r
-      case '\'' :\r
-        p = skipCharLiteral(p);\r
-        break;\r
-\r
-      case '\\':\r
-        p++;\r
-        if (*p == 0) goto EXIT;\r
-        p++;\r
-        break;\r
-\r
-      case ',':\r
-      case '=':\r
-        if (nest == 0) goto EXIT;\r
-               p++;\r
-        break;\r
-\r
-      default:\r
-        p++;\r
-    }\r
-  }\r
-EXIT:\r
-  *pNest = nest;\r
-  return p;\r
-}\r
-\r
-#ifdef __USE_PROTOS\r
-char * skipToSeparator(char *pStart, int *pNest)\r
-#else\r
-char * skipToSeparator(pStart, pNest)\r
-char *pStart;\r
-int *pNest;\r
-#endif\r
-{\r
-  char * p = pStart;\r
-  for ( ; ; ) {\r
-    p = skipToSeparatorOrEqualSign(p, pNest);\r
-    if (*pNest != 0) return p;\r
-    if (*p == ',') return p;\r
-    if (*p == 0) return p;\r
-       p++;\r
-  }\r
-}\r
-\r
-/* skip to just past the "=" separating the declaration from the initialization value */\r
-\r
-#ifdef __USE_PROTOS\r
-char * getInitializer(char *pStart)\r
-#else\r
-char * getInitializer(pStart)\r
-char * pStart;\r
-#endif\r
-{\r
-       char *p;\r
-       char *pDataType;\r
-       char *pSymbol;\r
-       char *pEqualSign;\r
-       char *pValue;\r
-       char *pSeparator;\r
-       int nest = 0;\r
-\r
-       require(pStart!=NULL, "getInitializer: invalid string"); \r
-\r
-       p = endFormal(pStart,\r
-                             &pDataType,\r
-                                 &pSymbol,\r
-                                 &pEqualSign,\r
-                                 &pValue,\r
-                                 &pSeparator,\r
-                                 &nest);\r
-    if (nest != 0) return NULL;\r
-    if (pEqualSign == NULL) return NULL;\r
-    if (pValue == NULL) return NULL;\r
-       return strBetween(pValue, NULL, pSeparator);\r
-}\r
-\r
-/*\r
-   Examines the string from pStart to pEnd-1.\r
-   If the string has 0 length or is entirely white space\r
-   returns 1.  Otherwise 0.\r
-*/\r
-\r
-#ifdef __USE_PROTOS\r
-int isWhiteString(const char *pStart, const char *pEnd)\r
-#else\r
-int isWhiteString(pStart, pEnd)\r
-const char *pStart;\r
-const char *pEnd;\r
-#endif\r
-{\r
-  const char *p;\r
-  for (p = pStart; p < pEnd; p++) {\r
-    if (! isspace(*p)) return 0;\r
-  }\r
-  return 1;\r
-}\r
-\r
-/*\r
-   This replaces HasComma() which couldn't distinguish\r
-\r
-        foo ["a,b"]\r
-\r
-   from:\r
-\r
-        foo[a,b]\r
-\r
-*/\r
-\r
-#ifdef __USE_PROTOS\r
-int hasMultipleOperands(char *pStart)\r
-#else\r
-int hasMultipleOperands(pStart)\r
-char *pStart;\r
-#endif\r
-{\r
-  char *p = pStart;\r
-  int nest = 0;\r
-\r
-  p = skipSpaces(p);\r
-  if (*p == 0) return 0;\r
-  p = skipToSeparator(p, &nest);\r
-  if (nest == 0 && *p == ',') return 1;\r
-  return 0;\r
-}\r
-\r
-\r
-#define MAX_STR_BETWEEN_WORK_AREA 1000\r
-\r
-static char strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA];\r
-\r
-\r
-/*\r
-       strBetween(pStart, pNext, pStop)\r
-\r
-    Creates a null terminated string by copying the text between two pointers\r
-       to a work area.  The start of the string is pStart.  The end of the string\r
-       is the character before pNext, or if pNext is null then the character before\r
-       pStop.  Trailing spaces are not included in the copy operation.\r
-       \r
-       This is used when a string contains several parts.  The pNext part may be\r
-       optional.  The pStop will stop the scan when the optional part is not present\r
-       (is a null pointer).\r
-*/\r
-\r
-#ifdef __USE_PROTOS\r
-char *strBetween(char *pStart, char *pNext, char *pStop)\r
-#else\r
-char *strBetween(pStart, pNext, pStop)\r
-char *pStart;\r
-char *pNext;\r
-char *pStop;\r
-#endif\r
-{\r
-  char *p;\r
-  char *q = strBetweenWorkArea;\r
-  const char *pEnd;\r
-\r
-  pEnd = (pNext != NULL) ? pNext : pStop;\r
-\r
-  require (pEnd != NULL, "pEnd == NULL");\r
-  require (pEnd >= pStart, "pEnd < pStart");\r
-  for (pEnd--; pEnd >= pStart; pEnd--) { /* MR31 */\r
-       if (! isspace(*pEnd)) break;\r
-  }\r
-  for (p = pStart;\r
-       p <= pEnd && q < &strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA-2];\r
-          p++, q++) {\r
-        *q = *p;\r
-  }\r
-  *q = 0;\r
-  return strBetweenWorkArea;\r
-}\r
-\r
-/*\r
-   function     Returns pointer to character following separator at\r
-   value        which to continue search for next formal.  If at the\r
-                end of the string a pointer to the null byte at the\r
-                end of the string is returned.\r
-\r
-   pStart       Pointer to the starting position of the formal list\r
-\r
-                This may be the middle of a longer string, for example\r
-                when looking for the end of formal #3 starting from\r
-                the middle of the complete formal list.\r
-\r
-   ppDataType   Returns a pointer to the start of the data type in the\r
-                formal. Example: pointer to "Foo".\r
-\r
-   ppSymbol     Returns a pointer to the start of the formal symbol.\r
-                Example: pointer to "f".\r
-\r
-   ppEqualSign  Returns a pointer to the equal sign separating the\r
-                formal symbol from the initial value.  If there is \r
-                no "=" then this will be NULL.\r
-\r
-   ppValue      Returns a pointer to the initial value part of the\r
-                formal declaration.  Example: pointer to "&farray[1,2]"\r
-\r
-   ppSeparator  Returns a pointer to the character which terminated the\r
-                scan.  This should be a pointer to a comma or a null\r
-                byte which terminates the string.\r
-\r
-   pNest        Returns the nesting level when a separator was found.\r
-                This is non-zero for any kind of error.  This is zero\r
-                for a successful parse of this portion of the formal\r
-                list.\r
-\r
-*/ \r
\r
-#ifdef __USE_PROTOS\r
-char * endFormal(char *pStart,\r
-                 char **ppDataType,\r
-                 char **ppSymbol,\r
-                 char **ppEqualSign,\r
-                 char **ppValue,\r
-                 char **ppSeparator,\r
-                 int *pNest)\r
-#else\r
-char * endFormal(pStart,\r
-                            ppDataType,\r
-                                ppSymbol,\r
-                                ppEqualSign,\r
-                                ppValue,\r
-                                ppSeparator,\r
-                                pNest)\r
-char *pStart;\r
-char **ppDataType;\r
-char **ppSymbol;\r
-char **ppEqualSign;\r
-char **ppValue;\r
-char **ppSeparator;\r
-int *pNest;\r
-\r
-#endif\r
-{\r
-  char *p = pStart;\r
-  char *q;\r
-\r
-  *ppDataType = NULL;\r
-  *ppSymbol = NULL;\r
-  *ppEqualSign = NULL;\r
-  *ppValue = NULL;\r
-  *ppSeparator = NULL;\r
-\r
-  *pNest = 0;\r
-\r
-  /* The first non-blank is the start of the datatype */\r
-\r
-  p = skipSpaces(p);\r
-  if (*p == 0) goto EXIT;\r
-  *ppDataType = p;\r
-\r
-  /* We are not looking for the symbol, we are looking\r
-     for the separator that follows the symbol.  Then\r
-     we'll back up.\r
-   \r
-     Search for the ',' or '=" or null terminator.\r
-   */\r
-\r
-  p = skipToSeparatorOrEqualSign(p, pNest);\r
-\r
-  if (*pNest != 0) goto EXIT;\r
-\r
-  /*\r
-     Work backwards to find start of symbol\r
-     Skip spaces between the end of symbol and separator\r
-     Assume that there are no spaces in the formal, but\r
-     there is a space preceding the formal\r
-  */\r
-\r
-  for (q = &p[-1]; q >= *ppDataType; q--) {\r
-    if (! isspace(*q)) break;\r
-  }\r
-  if (q < *ppDataType) goto EXIT;\r
-\r
-  /*\r
-     MR26 Handle things like: IIR_Bool (IIR_Decl::*constraint)()\r
-     Backup until we hit the end of a symbol string, then find the\r
-     start of the symbol string.  This wont' work for functions\r
-     with prototypes, but works for the most common cases.  For\r
-     others, use typedef names.\r
-   */\r
-\r
-/* MR26 */  for (q = q; q >= *ppDataType; q--) {\r
-/* MR26 */    if (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$') break;\r
-/* MR26 */  }\r
-/* MR26 */  if (q < *ppDataType) goto EXIT;\r
-\r
-  for (q = q; q >= *ppDataType; q--) {\r
-    if ( ! (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$')) break;\r
-  }\r
-\r
-  *ppSymbol = &q[1];\r
-\r
-  if (*p == ',' || *p == 0) {\r
-    *ppSeparator = p;\r
-    goto EXIT;\r
-  }\r
-\r
-  *ppEqualSign = p;\r
-  p = skipSpaces(++p);\r
-  *ppValue = p;\r
-  if (*p == 0) goto EXIT;\r
-\r
-\r
-  while (*p != 0 && *pNest == 0 && *p != ',') {\r
-      p = skipToSeparator(p, pNest);\r
-  }\r
-  if (*pNest == 0) *ppSeparator = p;\r
-\r
-EXIT:\r
-  if (*p == ',') p++;\r
-  return p;\r
-}\r