]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c
Check In tool source code based on Build tool project revision r1655.
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / Pccts / antlr / gen.c
diff --git a/BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c b/BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c
new file mode 100644 (file)
index 0000000..368a96b
--- /dev/null
@@ -0,0 +1,4797 @@
+/*\r
+ * gen.c\r
+ *\r
+ * Generate C code (ANSI, K&R, C++)\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 NumExprPerLine 4\r
+static int on1line=0;\r
+static set tokensRefdInBlock;\r
+\r
+                                       /* T r a n s l a t i o n  T a b l e s */\r
+\r
+/* C_Trans[node type] == pointer to function that knows how to translate that node. */\r
+#ifdef __cplusplus\r
+void (*C_Trans[NumNodeTypes+1])(...) = {\r
+       NULL,\r
+       NULL,                                   /* See next table.\r
+Junctions have many types */\r
+       (void (*)(...)) genRuleRef,\r
+       (void (*)(...)) genToken,\r
+       (void (*)(...)) genAction\r
+ };\r
+#else\r
+void (*C_Trans[NumNodeTypes+1])() = {\r
+       NULL,\r
+       NULL,                                   /* See next table.\r
+Junctions have many types */\r
+       genRuleRef,\r
+       genToken,\r
+       genAction\r
+ };\r
+#endif\r
+\r
+/* C_JTrans[Junction type] == pointer to function that knows how to translate that\r
+ * kind of junction node.\r
+ */\r
+#ifdef __cplusplus\r
+void (*C_JTrans[NumJuncTypes+1])(...) = {\r
+       NULL,\r
+       (void (*)(...)) genSubBlk,\r
+       (void (*)(...)) genOptBlk,\r
+       (void (*)(...)) genLoopBlk,\r
+       (void (*)(...)) genEndBlk,\r
+       (void (*)(...)) genRule,\r
+       (void (*)(...)) genJunction,\r
+       (void (*)(...)) genEndRule,\r
+       (void (*)(...)) genPlusBlk,\r
+       (void (*)(...)) genLoopBegin\r
+ };\r
+#else\r
+void (*C_JTrans[NumJuncTypes+1])() = {\r
+       NULL,\r
+       genSubBlk,\r
+       genOptBlk,\r
+       genLoopBlk,\r
+       genEndBlk,\r
+       genRule,\r
+       genJunction,\r
+       genEndRule,\r
+       genPlusBlk,\r
+       genLoopBegin\r
+ };\r
+#endif\r
+\r
+#define PastWhiteSpace(s)      while (*(s) == ' ' || *(s) == '\t') {s++;}\r
+\r
+static int tabs = 0;\r
+\r
+/* MR6 Got tired of text running off page when using standard tab stops */\r
+\r
+#define TAB { int i;                                                                   \\r
+             if (TabWidth==0) {                                                        \\r
+                for (i=0; i<tabs; i++) fputc('\t', output);                            \\r
+             } else {                                                                  \\r
+                for (i=0; i<tabs*TabWidth; i++) fputc(' ',output);                     \\r
+             };                                                                        \\r
+           }\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+tab( void )\r
+#else\r
+tab( )\r
+#endif\r
+TAB\r
+\r
+#ifdef __USE_PROTOS\r
+static char *tokenFollowSet(TokNode *);\r
+static ActionNode *findImmedAction( Node * );\r
+static void dumpRetValAssign(char *, char *, RuleRefNode *);           /* MR30 */\r
+static void dumpAfterActions(FILE *output);\r
+static set ComputeErrorSet(Junction *, int, int);\r
+static void makeErrorClause(Junction *, set, int, int);\r
+static void DumpFuncHeader( Junction *, RuleEntry * );\r
+static int has_guess_block_as_first_item(Junction *);\r
+static int genExprSets(set *, int);\r
+static void genExprTree( Tree *t, int k );\r
+static void genExprTreeOriginal( Tree *t, int k );                  /* MR10 */\r
+static char * findOuterHandlerLabel(ExceptionGroup *eg);            /* MR7 */\r
+static void OutLineInfo(FILE *file,int line,char *fileName);        /* MR14 */\r
+#else\r
+static char *tokenFollowSet();\r
+static ActionNode *findImmedAction();\r
+static void dumpRetValAssign();\r
+static void dumpAfterActions();\r
+static set ComputeErrorSet();\r
+static void makeErrorClause();\r
+static void DumpFuncHeader();\r
+static int has_guess_block_as_first_item();\r
+static int genExprSets();\r
+static void genExprTree();\r
+static void genExprTreeOriginal();                                  /* MR10 */\r
+static char * findOuterHandlerLabel();                              /* MR7 */\r
+static void OutLineInfo();                                          /* MR14 */\r
+#endif\r
+\r
+#define gen(s)                 {tab(); fprintf(output, s);}\r
+#define gen1(s,a)              {tab(); fprintf(output, s,a);}\r
+#define gen2(s,a,b)            {tab(); fprintf(output, s,a,b);}\r
+#define gen3(s,a,b,c)  {tab(); fprintf(output, s,a,b,c);}\r
+#define gen4(s,a,b,c,d)        {tab(); fprintf(output, s,a,b,c,d);}\r
+#define gen5(s,a,b,c,d,e)      {tab(); fprintf(output, s,a,b,c,d,e);}\r
+#define gen6(s,a,b,c,d,e,f)    {tab(); fprintf(output, s,a,b,c,d,e,f);}\r
+#define gen7(s,a,b,c,d,e,f,g)  {tab(); fprintf(output, s,a,b,c,d,e,f,g);}\r
+\r
+#define _gen(s)                        {fprintf(output, s);}\r
+#define _gen1(s,a)             {fprintf(output, s,a);}\r
+#define _gen2(s,a,b)   {fprintf(output, s,a,b);}\r
+#define _gen3(s,a,b,c) {fprintf(output, s,a,b,c);}\r
+#define _gen4(s,a,b,c,d){fprintf(output, s,a,b,c,d);}\r
+#define _gen5(s,a,b,c,d,e){fprintf(output, s,a,b,c,d,e);}\r
+#define _gen6(s,a,b,c,d,e,f){fprintf(output, s,a,b,c,d,e,f);}\r
+#define _gen7(s,a,b,c,d,e,f,g){fprintf(output, s,a,b,c,d,e,f,g);}\r
+\r
+\r
+/* MR11 a convenient place to set a break point */\r
+\r
+#ifdef __USE_PROTOS\r
+void MR_break(void) \r
+#else\r
+void MR_break() \r
+#endif\r
+{\r
+  return;\r
+}\r
+\r
+/* MR10 genTraceOut(Junction *)      */\r
+\r
+#ifdef __USE_PROTOS\r
+static void genTraceOut(Junction *q)\r
+#else\r
+static void genTraceOut(q)\r
+  Junction  *q;\r
+#endif\r
+{\r
+  if ( TraceGen ) {\r
+               if ( GenCC ) {gen1("zzTRACEOUT(\"%s\");\n", q->rname);}\r
+               else gen1("zzTRACEOUT((ANTLRChar *)\"%s\");\n", q->rname);\r
+  }\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+warn_about_using_gk_option(void)\r
+#else\r
+warn_about_using_gk_option()\r
+#endif\r
+{\r
+       static int warned_already=0;\r
+\r
+       if ( !DemandLookahead || warned_already ) return;\r
+       warned_already = 1;\r
+       warnNoFL("-gk option could cause trouble for <<...>>? predicates");\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+freeBlkFsets( Junction *q )\r
+#else\r
+freeBlkFsets( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       int i;\r
+       Junction *alt;\r
+       require(q!=NULL, "freeBlkFsets: invalid node");\r
+\r
+       for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )\r
+       {\r
+               for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]);\r
+       }\r
+}\r
+\r
+/*\r
+ * Generate a local variable allocation for each token references\r
+ * in this block.\r
+ */\r
+static void\r
+#ifdef __USE_PROTOS\r
+genTokenPointers( Junction *q )\r
+#else\r
+genTokenPointers( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       /* Rule refs are counted and can be referenced, but their\r
+        * value is not set to anything useful ever.\r
+        *\r
+     * The ptrs are to be named _tij where i is the current level\r
+        * and j is the element number within an alternative.\r
+        */\r
+       int first=1, t=0;\r
+       set a;\r
+       tokensRefdInBlock = q->tokrefs;\r
+\r
+       if ( set_deg(q->tokrefs) == 0 ) return;\r
+       a = set_dup(q->tokrefs);\r
+       gen("ANTLRTokenPtr ");\r
+       for (; !set_nil(a); set_rm(t, a))\r
+       {\r
+               t = set_int(a);\r
+               if ( first ) first = 0;\r
+               else _gen(",");\r
+               if ( !DontCopyTokens ) _gen2("_tv%d%d,", BlkLevel, t);\r
+               _gen2("_t%d%d", BlkLevel, t);\r
+               if ( !DontCopyTokens ) {_gen2("= &_tv%d%d", BlkLevel, t);}\r
+               else _gen("=NULL");\r
+       }\r
+       _gen(";\n");\r
+       set_free(a);\r
+}\r
+\r
+static int\r
+#ifdef __USE_PROTOS\r
+hasDefaultException(ExceptionGroup *eg)\r
+#else\r
+hasDefaultException(eg)\r
+ExceptionGroup *eg;\r
+#endif\r
+{\r
+    ListNode *q;\r
+\r
+    for (q = eg->handlers->next; q!=NULL; q=q->next)\r
+    {\r
+        ExceptionHandler *eh = (ExceptionHandler *)q->elem;\r
+        if ( strcmp("default", eh->signalname)==0 ) {\r
+            return 1;\r
+        }\r
+    }\r
+    return 0;\r
+}\r
+static void\r
+#ifdef __USE_PROTOS\r
+dumpException(ExceptionGroup *eg, int no_default_case)\r
+#else\r
+dumpException(eg, no_default_case)\r
+ExceptionGroup *eg;\r
+int no_default_case;\r
+#endif\r
+{\r
+    char    *outerLabel;                                             /* MR7 */\r
+    int     altHandler=0;                                            /* MR7 */\r
+    int     namedHandler=0;                                          /* MR7 */\r
+\r
+    outerLabel=findOuterHandlerLabel(eg);                            /* MR7 */\r
+\r
+    if (eg->label != NULL) {                                         /* MR7 */\r
+      namedHandler=1;                                                /* MR7 */\r
+    } else if (eg->forRule) {                                        /* MR7 */\r
+      /* nothing */                                                  /* MR20 */\r
+    } else {                                                         /* MR7 */\r
+      altHandler=1;                                                  /* MR7 */\r
+    };                                                               /* MR7 */\r
+\r
+#if 0\r
+**     if (! eg->used) {                                             /* MR7 */\r
+**             warnFL("exception group never used",                         /* MR7 */\r
+**             FileStr[eg->altstart->file],eg->altstart->line);      /* MR7 */\r
+**     };                                                            /* MR7 */\r
+#endif\r
+\r
+    if (namedHandler) {                                              /* MR7 */\r
+         gen1("switch ( _signal ) {  /* [%s] */\n",eg->label);          /* MR7 */\r
+    } else {                                                         /* MR7 */\r
+         gen("switch ( _signal ) {\n");                                 /* MR7 */\r
+      gen("case NoSignal: break;  /* MR7 */\n");                     /* MR7 */\r
+    };                                                               /* MR7 */\r
+       {\r
+               ListNode *q;\r
+               for (q = eg->handlers->next; q!=NULL; q=q->next)\r
+               {\r
+                       ExceptionHandler *eh = (ExceptionHandler *)q->elem;\r
+                       if ( strcmp("default", eh->signalname)==0 ) {\r
+                               gen("default :\n");\r
+                               tabs++;\r
+                               dumpAction(eh->action, output, tabs, -1, 1, 1);\r
+                gen("_signal=NoSignal;  /* MR7 */\n");                  /* MR7 */\r
+                gen("break;  /* MR7 */\n");                             /* MR7 */\r
+                               tabs--;\r
+                               gen("}\n");\r
+\r
+                /* copied from later code in dumpException */        /* MR7 */\r
+\r
+                if (namedHandler) {                                  /* MR7 */\r
+                  gen("if (_signal != NoSignal)");                   /* MR7 */\r
+                  _gen1(" goto %s_handler;  /* MR7 */\n",outerLabel);/* MR7 */\r
+                } else if (altHandler) {                             /* MR7 */\r
+                  gen1("goto %s_handler;  /* MR7 */\n",outerLabel);  /* MR7 */\r
+                };\r
+                               return;\r
+                       }\r
+                       gen1("case %s :\n", eh->signalname);\r
+                       tabs++;\r
+                       if ( eh->action != NULL )\r
+                       {\r
+                               dumpAction(eh->action, output, tabs, -1, 1, 1);\r
+                gen("break;  /* MR7 */\n");                          /* MR7 */\r
+                       }\r
+                       tabs--;\r
+               }\r
+       }\r
+       if ( no_default_case ) return;\r
+\r
+       gen("default :\n");\r
+    tabs++;                                                         /* MR7 */\r
+    gen("break;  /* MR7 */\n");                                     /* MR7 */\r
+    tabs--;                                                         /* MR7 */\r
+\r
+       tabs++;\r
+/***** gen("*_retsignal = _signal;\n"); *****/\r
+\r
+       tabs--;\r
+       gen("}\n");\r
+\r
+    if (namedHandler) {                                             /* MR7 */\r
+      gen("if (_signal != NoSignal)");                              /* MR7 */\r
+      _gen1(" goto %s_handler;  /* MR7 */\n",outerLabel);           /* MR7 */\r
+    } else if (altHandler) {                                        /* MR7 */\r
+      gen1("goto %s_handler;  /* MR7 */\n",outerLabel);             /* MR7 */\r
+    };\r
+\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+dumpExceptions(ListNode *list)\r
+#else\r
+dumpExceptions(list)\r
+ListNode *list;\r
+#endif\r
+{\r
+       ListNode *p;\r
+\r
+       for (p = list->next; p!=NULL; p=p->next)\r
+       {\r
+               ExceptionGroup *eg = (ExceptionGroup *) p->elem;\r
+               _gen2("%s%s_handler:\n",\r
+                         eg->label==NULL?"":eg->label,\r
+                         eg->altID==NULL?"":eg->altID);\r
+               if ( eg->altID!=NULL ) dumpException(eg, 0);\r
+               else {\r
+                       /* This must be the rule exception handler */\r
+                       dumpException(eg, 1);\r
+                       if ( !hasDefaultException(eg) )\r
+            {\r
+                gen("default :\n");\r
+                tabs++;\r
+                gen("zzdflthandlers(_signal,_retsignal);\n");\r
+                tabs--;\r
+                gen("}\n");\r
+            }\r
+               }\r
+       }\r
+}\r
+\r
+/* For each element label that is found in a rule, generate a unique\r
+ * Attribute (and AST pointer if GenAST) variable.\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genElementLabels(ListNode *list)\r
+#else\r
+genElementLabels(list)\r
+ListNode *list;\r
+#endif\r
+{\r
+       int first=1;\r
+       ListNode *p;\r
+\r
+       if ( GenCC ) {gen("ANTLRTokenPtr");}\r
+       else {gen("Attrib");}\r
+       for (p = list->next; p!=NULL; p=p->next)\r
+       {\r
+               char *ep = (char *)p->elem;\r
+               if ( first ) first = 0;\r
+               else _gen(",");\r
+               if ( GenCC ) {_gen1(" %s=NULL",ep);}\r
+               else {_gen1(" %s",ep);}\r
+       }\r
+       _gen(";\n");\r
+\r
+       if ( !GenAST ) return;\r
+\r
+       first = 1;\r
+       gen("AST");\r
+       for (p = list->next; p!=NULL; p=p->next)\r
+       {\r
+               char *ep = (char *)p->elem;\r
+               if ( first ) first = 0;\r
+               else _gen(",");\r
+               _gen1(" *%s_ast=NULL",ep);\r
+       }\r
+       _gen(";\n");\r
+}\r
+\r
+/*\r
+ * Generate a local variable allocation for each token or rule reference\r
+ * in this block.\r
+ */\r
+static void\r
+#ifdef __USE_PROTOS\r
+genASTPointers( Junction *q )\r
+#else\r
+genASTPointers( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       int first=1, t;\r
+       set a;\r
+\r
+       a = set_or(q->tokrefs, q->rulerefs);\r
+       if ( set_deg(a) > 0 )\r
+       {\r
+               gen("AST ");\r
+               for (; !set_nil(a); set_rm(t, a))\r
+               {\r
+                       t = set_int(a);\r
+                       if ( first ) first = 0;\r
+                       else _gen(",");\r
+                       _gen2("*_ast%d%d=NULL", BlkLevel, t);\r
+               }\r
+               set_free(a);\r
+       }\r
+       _gen(";\n");\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+BLOCK_Head( void )\r
+#else\r
+BLOCK_Head( )\r
+#endif\r
+{\r
+       gen("{\n");\r
+       tabs++;\r
+       if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel);\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+BLOCK_Tail( void )\r
+#else\r
+BLOCK_Tail( )\r
+#endif\r
+{\r
+       if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel);\r
+       if ( !GenCC ) gen("}\n");\r
+       tabs--;\r
+       gen("}\n");\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+BLOCK_Preamble( Junction *q )\r
+#else\r
+BLOCK_Preamble( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       ActionNode *a;\r
+       Junction *begin;\r
+\r
+       BLOCK_Head();\r
+       if ( GenCC ) genTokenPointers(q);\r
+       if ( GenCC&&GenAST ) genASTPointers(q);\r
+       if ( q->jtype == aPlusBlk ) gen("int zzcnt=1;\n");\r
+       if ( q->parm != NULL && !q->predparm ) gen1("zzaPush(%s);\n", q->parm)\r
+       else if ( !GenCC ) gen("zzMake0;\n");\r
+       if ( !GenCC ) gen("{\n");\r
+       if ( q->jtype == aLoopBegin ) begin = (Junction *) ((Junction *)q->p1);\r
+       else begin = q;\r
+       if ( has_guess_block_as_first_item(begin) )\r
+       {\r
+               gen("zzGUESS_BLOCK\n");\r
+       }\r
+       if ( q->jtype == aLoopBegin )\r
+               a = findImmedAction( ((Junction *)q->p1)->p1 ); /* look at aLoopBlk */\r
+       else\r
+               a = findImmedAction( q->p1 );\r
+       if ( a!=NULL && !a->is_predicate) {\r
+/* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1);\r
+                  a->done = 1; /* remove action. We have already handled it */\r
+       }\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genCombinedPredTreeContextOrig( Predicate *p )\r
+#else\r
+genCombinedPredTreeContextOrig( p )\r
+Predicate *p;\r
+#endif\r
+{\r
+       static set *ctx=NULL;           /* genExprSets() is destructive, make copy*/\r
+       require(p!=NULL, "can't make context tree for NULL pred tree");\r
+\r
+#ifdef DBG_PRED\r
+       fprintf(stderr, "enter genCombinedPredTreeContextOrig(%s,0x%x) with sets:\n", p->expr, p);\r
+       s_fprT(stderr, p->scontext[1]);\r
+       fprintf(stderr, "\n");\r
+#endif\r
+       if ( p->down == NULL )\r
+       {\r
+/***   if ( p->k>1 && p->tcontext!=NULL ) ***/\r
+               if ( p->tcontext!=NULL )\r
+               {\r
+                       _gen("(");\r
+                       genExprTree(p->tcontext, 1);\r
+                       _gen(")");\r
+               }\r
+/***   else if ( p->k==1 && set_deg(p->scontext[1])>0 ) ***/\r
+               else if ( set_deg(p->scontext[1])>0 )\r
+               {\r
+                       if ( ctx==NULL ) ctx = (set *)calloc(CLL_k+1, sizeof(set));\r
+                       require(ctx!=NULL, "ctx cannot allocate");\r
+                       ctx[0]=empty;\r
+                       ctx[1]=set_dup(p->scontext[1]);\r
+                       _gen("(");\r
+                       genExprSets(&(ctx[0]), p->k);\r
+                       _gen(")");\r
+                       set_free(ctx[1]);\r
+               }\r
+               else if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) {\r
+                       fatal_internal("pred tree is orphan OR or AND list");\r
+               }\r
+               else {\r
+            if (! HoistPredicateContext) {\r
+              _gen(" 1 /* no context: prc is off */ ");\r
+            } else {\r
+              fatal_internal("pred tree context is empty");\r
+            };\r
+               }\r
+               return;\r
+       }\r
+\r
+/* MR10 - make AND just like OR */\r
+\r
+       if ( p->expr == PRED_AND_LIST )\r
+       {\r
+        Predicate *list = p->down;\r
+        for (; list!=NULL; list=list->right)\r
+        {\r
+            genCombinedPredTreeContextOrig(list);\r
+                        if ( list->right!=NULL ) _gen("|| /* MR10 was wrong */ ");\r
+        };\r
+               return;\r
+       }\r
+\r
+       if ( p->expr == PRED_OR_LIST )\r
+       {\r
+        Predicate *list = p->down;\r
+        for (; list!=NULL; list=list->right)\r
+        {\r
+           genCombinedPredTreeContextOrig(list);\r
+           if ( list->right!=NULL ) _gen("||");\r
+        };\r
+        return;\r
+     };\r
+\r
+       fatal("pred tree is really wacked");\r
+}\r
+\r
+/* [genCombinedPredTreeContext] */\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genCombinedPredTreeContext( Predicate *p )\r
+#else\r
+genCombinedPredTreeContext( p )\r
+Predicate *p;\r
+#endif\r
+{\r
+  Tree  *t;\r
+  int   predDepth=0;\r
+\r
+  if (0 && ! MR_usingPredNames && ! MRhoisting) {\r
+    genCombinedPredTreeContextOrig(p);\r
+  } else {\r
+/* MR13 */    MR_pred_depth(p,&predDepth);\r
+/* MR13 */    if (predDepth == 1) {\r
+/* MR13 */\r
+/* MR13 */      set   scontext[2];\r
+/* MR13 */      scontext[0]=empty;\r
+/* MR13 */      scontext[1]=MR_compute_pred_set(p);\r
+/* MR13 */      if (set_nil(scontext[1])) {\r
+/* MR13 */        _gen(" 1 /* MR12 no context (-prc off) */ ");\r
+/* MR13 */      } else {\r
+/* MR13 */        _gen("(");\r
+/* MR13 */        genExprSets(&scontext[0], 1);\r
+/* MR13 */        set_free(scontext[1]);\r
+/* MR13 */        _gen(")");\r
+/* MR13 */      };\r
+\r
+    } else {\r
+      t=MR_compute_pred_tree_context(p);\r
+      if (t == NULL) {\r
+        _gen(" 1 /* MR12 no context (-prc off) */ ");\r
+      } else {\r
+        _gen("(");\r
+        genExprTree(t, 1);\r
+        Tfree(t);   /* MR10 */\r
+        _gen(")");\r
+      };\r
+    };\r
+  };\r
+}\r
+\r
+/* [genPredTreeGate] */\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genPredTreeGate( Predicate *p, int in_and_expr )\r
+#else\r
+genPredTreeGate( p, in_and_expr )\r
+Predicate *p;\r
+int in_and_expr;\r
+#endif\r
+{\r
+       if ( in_and_expr )\r
+       {\r
+               _gen("!(");\r
+               genCombinedPredTreeContext(p);\r
+               _gen(")||");\r
+               if ( p->down!=NULL ) _gen("\n");\r
+       }\r
+       else\r
+       {\r
+               _gen("(");\r
+               genCombinedPredTreeContext(p);\r
+               _gen(")&&");\r
+               if ( p->down!=NULL ) _gen("\n");\r
+       }\r
+}\r
+\r
+#ifdef __USE_PROTOS\r
+void genPredEntry(Predicate *p,int outer)\r
+#else\r
+void genPredEntry(p,outer)\r
+  Predicate     *p;\r
+  int           outer;\r
+#endif\r
+{\r
+    int         inverted=0;\r
+    Predicate   *q;\r
+    int         localOuter=outer;\r
+    int         needRP=0;\r
+\r
+    if (p == NULL) return;\r
+\r
+    if (p->predEntry != NULL && p->predEntry->predLiteral != NULL) {\r
+      if (p->inverted != p->predEntry->pred->inverted) {\r
+        _gen("! /* inverted pred */ (");\r
+        needRP=1;\r
+      } else {\r
+        if (!localOuter) _gen("(");\r
+        needRP=1;\r
+      };\r
+      dumpAction(p->predEntry->predLiteral,output,0,p->source->file,p->source->line,0);\r
+      if (needRP) _gen(")");\r
+      return;\r
+    };\r
+\r
+    inverted=p->inverted;\r
+\r
+    if (inverted) {\r
+      _gen(" ! /* inverted pred */ (");\r
+      localOuter=1;\r
+    };\r
+\r
+    if (p->expr == PRED_OR_LIST) {\r
+      if (!localOuter) _gen("(");\r
+      for (q=p->down; q != NULL ; q=q->right) {\r
+        genPredEntry(q,0);\r
+        if (q->right != NULL) _gen(" || ");\r
+      };\r
+      if (!localOuter) _gen(")");\r
+    } else if (p->expr == PRED_AND_LIST) {\r
+      if (!localOuter) _gen("(");\r
+      for (q=p->down; q != NULL ; q=q->right) {\r
+        genPredEntry(q,0);\r
+        if (q->right != NULL) _gen(" && ");\r
+      };\r
+      if (!localOuter) _gen(")");\r
+    } else {\r
+      if (!localOuter) _gen("(");\r
+      require (p->source != NULL,"predEntry->source == NULL");\r
+      require (p->source->inverted == 0,"dumpPredEntry p->source->inverted != 0");\r
+      dumpAction(p->source->action,output,0,p->source->file,p->source->line,0);\r
+      if (!localOuter) _gen(")");\r
+    };\r
+\r
+    if (inverted) {\r
+        _gen(")");\r
+    }\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+dumpPredAction(ActionNode *anode,\r
+                    char *s,FILE *output,int tabs,int file,int line,int final_newline)\r
+#else\r
+dumpPredAction(anode,\r
+                    s,output,tabs,file,line,final_newline)\r
+\r
+    ActionNode  *anode;\r
+    char        *s;\r
+    FILE        *output;\r
+    int         tabs;\r
+    int         file;\r
+    int         line;\r
+    int         final_newline;\r
+#endif\r
+{\r
+    PredEntry   *predEntry=anode->predEntry;\r
+    int         inverted=anode->inverted;\r
+    Predicate   *workPred;\r
+\r
+    if (predEntry == NULL) {\r
+\r
+      /* inline predicate literal */\r
+\r
+      require(inverted == 0,"dumpPredAction action->inverted");\r
+         dumpAction(s,output,tabs,file,line,final_newline);\r
+\r
+    } else {\r
+\r
+      /* a reference to a predicate - possibly with an inverted source */\r
+\r
+      if (predEntry->predLiteral != NULL) {\r
+        if (inverted) _gen("! /* inverted pred */ (");\r
+        dumpAction(predEntry->predLiteral,output,0,anode->file,anode->line,0);\r
+        if (inverted) _gen(")");\r
+      } else {\r
+        workPred=predicate_dup(predEntry->pred);\r
+        if (inverted) workPred->inverted=!workPred->inverted;\r
+        genPredEntry(workPred,1);\r
+        predicate_free(workPred);\r
+      };\r
+    };\r
+}\r
+\r
+/* [genPred] */\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genPred(Predicate *p, Node *j,int suppress_sva)\r
+#else\r
+genPred(p,j,suppress_sva)\r
+    Predicate   *p;\r
+    Node        *j;\r
+    int         suppress_sva;\r
+#endif\r
+{\r
+       if ( FoundException && !suppress_sva) {_gen("(_sva=(");}    /* MR11 suppress_sva */\r
+       else {_gen("(");}\r
+       if ( GenLineInfo && j->file != -1 ) _gen("\n");\r
+    if (p->source != NULL && p->source->ampersandPred != NULL) {\r
+      if (p->source->ampersandPred->k == 1) {\r
+\r
+            set     ctx[2];\r
+\r
+                       ctx[0]=empty;\r
+                       ctx[1]=set_dup(p->source->ampersandPred->scontext[1]);\r
+\r
+                       _gen("(");\r
+                       genExprSets(&(ctx[0]), p->k);\r
+                       _gen(") && ");\r
+                       set_free(ctx[1]);\r
+      } else {\r
+        _gen("( ");\r
+        genExprTree(p->source->ampersandPred->tcontext,1);\r
+               _gen(" ) && ");\r
+      };\r
+    };\r
+\r
+    dumpPredAction((ActionNode *)p->source,\r
+                p->expr, output, 0, -1 /*indicates no line info*/, j->line, 0);\r
+\r
+       if ( FoundException && !suppress_sva)   /* MR11 suppress_sva */\r
+         {_gen("),_sva)");}    /* MR10 - get red of "meant ==" messages */\r
+       else {_gen(")");}\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+MR_distinctORcontextOpt(Predicate *p,Node *j,int in_and_expr)\r
+#else\r
+MR_distinctORcontextOpt(p,j,in_and_expr)\r
+    Predicate   *p;\r
+    Node        *j;\r
+    int         in_and_expr;\r
+#endif\r
+{\r
+    Predicate   *q;\r
+\r
+    _gen(" /* MR10 Distinct OR context optimization */ \n");\r
+\r
+    if (in_and_expr) {\r
+      gen("zzpf=0,\n");\r
+      for (q=p->down; q != NULL; q=q->right) {\r
+        gen("(  ");\r
+        genCombinedPredTreeContext(q);\r
+        _gen(" && (zzpf=1, ");\r
+        genPred(q,j,0);\r
+        _gen("  )) ||\n");\r
+      };\r
+      gen("!zzpf)");\r
+    } else {\r
+      require (0,\r
+            "MR_distinctORcontextOpt: can't get here when using MR_predSimplify");\r
+#if 0\r
+**      for (q=p->down; q != NULL; q=q->right) {\r
+**        gen("(  ");\r
+**        genCombinedPredTreeContext(q);\r
+**        _gen(" && ");\r
+**        genPred(q,j);\r
+**        if (q->right != NULL) {\r
+**          _gen("  ) ||\n");\r
+**        };\r
+**      };\r
+**      gen(")");\r
+#endif\r
+   };\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genPredTreeOrig( Predicate *p, Node *j, int in_and_expr )\r
+#else\r
+genPredTreeOrig( p, j, in_and_expr )\r
+Predicate *p;\r
+Node *j;\r
+int in_and_expr;\r
+#endif\r
+{\r
+\r
+/* MR10 */  int     allHaveContext=1;\r
+/* MR10 */  int     noneHaveContext=1;\r
+\r
+/* MR10 */  MR_predContextPresent(p,&allHaveContext,&noneHaveContext);\r
+\r
+       if ( ! noneHaveContext )                  /* MR10 context guards ignored when -prc off */\r
+       {\r
+               _gen("(");\r
+               genPredTreeGate(p, in_and_expr);\r
+       }\r
+\r
+       /* if leaf node, just gen predicate */\r
+\r
+       if ( p->down==NULL )\r
+       {\r
+               genPred(p,j,0);\r
+               if ( ! noneHaveContext ) _gen(")");   /* MR10 context guards ignored when -prc off */\r
+               return;\r
+       }\r
+\r
+       /* if AND list, do both preds (only two possible) */\r
+       if ( p->expr == PRED_AND_LIST )\r
+       {\r
+#if 0\r
+**             _gen("(");\r
+**             genPredTreeOrig(p->down, j, 1);\r
+**             _gen("&&");\r
+**             genPredTreeOrig(p->down->right, j, 1);\r
+**             _gen(")");\r
+**             if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */\r
+**             return;\r
+#endif\r
+        /* MR11 - make it work with AND with more than two children - like OR */\r
+\r
+               Predicate *list;\r
+               _gen("(");\r
+               list = p->down;\r
+               for (; list!=NULL; list=list->right)\r
+               {\r
+                       genPredTreeOrig(list, j, 1);\r
+                       if ( list->right!=NULL ) _gen("&&");\r
+               }\r
+               _gen(")");\r
+               if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */\r
+               return;\r
+    };\r
+\r
+       if ( p->expr == PRED_OR_LIST )\r
+       {\r
+               Predicate *list;\r
+               _gen("(");\r
+               list = p->down;\r
+               for (; list!=NULL; list=list->right)\r
+               {\r
+                       genPredTreeOrig(list, j, 0);\r
+                       if ( list->right!=NULL ) _gen("||");\r
+               }\r
+               _gen(")");\r
+               if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */\r
+               return;\r
+       }\r
+\r
+       fatal_internal("genPredTreeOrig: predicate tree is wacked");\r
+}\r
+\r
+#if 0\r
+**   Predicate member dummyPredDepth is no longer used in MR10\r
+**     but we might need it again in the future\r
+**\r
+**   if (MRhoisting) {\r
+**     if ( !noneHaveContext &&\r
+**          ! in_and_expr &&\r
+**          p->source != NULL &&\r
+**          p->source->dummyPredicateDepth > 0 &&\r
+**          p->down == NULL) {\r
+**             _gen("(");\r
+**             genCombinedPredTreeContext(p);\r
+**             _gen("  )\n");\r
+**             return;\r
+**     };\r
+**   };\r
+#endif\r
+\r
+/* [genPredTree] */\r
+\r
+/* in_and_expr\r
+\r
+   what to do if the context is wrong\r
+   what to do if the context is correct but the predicate is false\r
+\r
+   remember: if the context is wrong it's the same as if the\r
+             predicate is true as far as enabling an alternative\r
+\r
+        Consider (AND p q r)\r
+\r
+        if in an ... && ... expression then you don't want\r
+        the entire predicate chain to fail just because the\r
+        context for one component is wrong: so return true\r
+\r
+        Consider (OR p q r)\r
+\r
+        if in an ... || ... expression then you don't want\r
+        the entire predicate chain to succeed just because\r
+        the context for one component is correct when the\r
+        corresponding test is false: so return false when\r
+        the context is correct but the test is false.\r
+*/\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genPredTree( Predicate *p, Node *j, int in_and_expr, int suppress_sva )\r
+#else\r
+genPredTree( p, j, in_and_expr, suppress_sva)\r
+  Predicate     *p;\r
+  Node          *j;\r
+  int           in_and_expr;\r
+  int           suppress_sva;\r
+#endif\r
+{\r
+\r
+    int         allHaveContext=1;\r
+    int         noneHaveContext=1;\r
+    Tree        *groupTree;\r
+    Tree        *oneTree;\r
+    Predicate   *q;\r
+    int         identicalORcontextOptimization=0;\r
+    int         identicalANDcontextOptimization=0;\r
+\r
+    if (0 && !MR_usingPredNames && !MRhoisting) {\r
+      genPredTreeOrig(p,j,in_and_expr);\r
+      return;\r
+    };\r
+\r
+    MR_predContextPresent(p,&allHaveContext,&noneHaveContext);\r
+\r
+       if ( ! noneHaveContext ) {                 /* MR10 context guards ignored when -prc off */\r
+\r
+      _gen("(");\r
+\r
+            /* MR10 optimize OR predicates which are all leaves */\r
+\r
+      if (p->expr == PRED_OR_LIST && MR_allPredLeaves(p->down)) {\r
+        groupTree=MR_compute_pred_tree_context(p);\r
+        for (q=p->down ; q != NULL ; q=q->right) {\r
+          oneTree=MR_compute_pred_tree_context(q);\r
+          if (! MR_tree_equ(groupTree,oneTree)) {\r
+            Tfree(oneTree);\r
+            break;\r
+          };\r
+          Tfree(oneTree);\r
+        };\r
+        Tfree(groupTree);\r
+        if (q == NULL) {\r
+          _gen("/* MR10 individual OR gates suppressed when all predicates are leaves");\r
+          _gen(" with identical context */\n");\r
+          genPredTreeGate(p,in_and_expr);   /* use the parent's in_and_expr for this gate */\r
+          identicalORcontextOptimization=1;\r
+        } else {\r
+          MR_distinctORcontextOpt(p,j,in_and_expr);\r
+          return;\r
+        };\r
+      } else if (p->expr == PRED_AND_LIST && MR_allPredLeaves(p->down)) {\r
+\r
+            /* MR12 optimize AND predicates which are all leaves */\r
+\r
+        groupTree=MR_compute_pred_tree_context(p);\r
+        for (q=p->down ; q != NULL ; q=q->right) {\r
+          oneTree=MR_compute_pred_tree_context(q);\r
+          if (! MR_tree_equ(groupTree,oneTree)) {\r
+            Tfree(oneTree);\r
+            break;\r
+          };\r
+          Tfree(oneTree);\r
+        };\r
+        Tfree(groupTree);\r
+        if (q == NULL) {\r
+          _gen("/* MR12 individual AND gates suppressed when all predicates are leaves");\r
+          _gen(" with identical context */\n");\r
+          genPredTreeGate(p,in_and_expr);   /* use the parent's in_and_expr for this gate */\r
+          identicalANDcontextOptimization=1;\r
+        } else {\r
+          genPredTreeGate(p, in_and_expr);\r
+        };\r
+      } else {\r
+           genPredTreeGate(p, in_and_expr);\r
+      };\r
+       }\r
+\r
+       /* if leaf node, just gen predicate */\r
+\r
+       if ( p->down==NULL )\r
+       {\r
+               genPred(p,j,suppress_sva);\r
+               if ( ! noneHaveContext ) _gen(")");   /* MR10 context guards ignored when -prc off */\r
+               return;\r
+       }\r
+\r
+       /* if AND list, do both preds (only two possible) */\r
+    /* MR10    not any more ! */\r
+\r
+       if ( p->expr == PRED_AND_LIST )\r
+       {\r
+               Predicate *list;\r
+               _gen("(");\r
+               list = p->down;\r
+        for (; list != NULL; list=list->right) {\r
+          if (identicalANDcontextOptimization) {\r
+            genPred(list, j,suppress_sva);\r
+          } else {\r
+                   genPredTree(list, j, 1, suppress_sva);  /* in and context */\r
+          };\r
+          if ( list->right!=NULL ) _gen("&&");\r
+        };\r
+               _gen(")");\r
+               if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */\r
+               return;\r
+       }\r
+\r
+       if ( p->expr == PRED_OR_LIST )\r
+       {\r
+               Predicate *list;\r
+               _gen("(");\r
+               list = p->down;\r
+               for (; list!=NULL; list=list->right)\r
+               {\r
+            if (identicalORcontextOptimization) {\r
+                 genPred(list, j,suppress_sva);\r
+            } else {\r
+                     genPredTree(list, j, 0, suppress_sva);\r
+            };\r
+                       if ( list->right!=NULL ) _gen("||");\r
+               }\r
+               _gen(")");\r
+               if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */\r
+               return;\r
+       }\r
+\r
+       fatal_internal("predicate tree is wacked");\r
+}\r
+\r
+/* [genPredTreeMainXX] */\r
+\r
+Predicate *     /* MR10 */\r
+#ifdef __USE_PROTOS\r
+genPredTreeMainXX( Predicate *p, Node *j ,int in_and_expr)\r
+#else\r
+genPredTreeMainXX( p, j ,in_and_expr)\r
+    Predicate   *p;\r
+    Node        *j;\r
+    int         in_and_expr;\r
+#endif\r
+{\r
+\r
+    int     allHaveContext=1;\r
+    int     noneHaveContext=1;\r
+\r
+#if 0\r
+    fprintf(stderr,"Pred before\n");\r
+    dumppred(p);\r
+    fprintf(stderr,"\n");\r
+    fprintf(stderr,"Pred after\n");\r
+    dumppred(p);\r
+    fprintf(stderr,"\n");\r
+#endif\r
+\r
+    p=MR_predSimplifyALL(p);    /* MR10 */\r
+\r
+    require (MR_predicate_context_completed(p),"predicate context is not complete");\r
+\r
+    MR_cleanup_pred_trees(p);   /* MR10 */\r
+\r
+    MR_predContextPresent(p,&allHaveContext,&noneHaveContext);\r
+    if (!noneHaveContext & !allHaveContext) {\r
+      warnFL("predicate contains elements both with and without context",\r
+                FileStr[j->file],j->line);\r
+    };\r
+\r
+    if (InfoP) {\r
+       _gen("\n#if 0\n\n");\r
+       MR_dumpPred(p,1);\r
+       _gen("#endif\n");\r
+    };\r
+       genPredTree(p,j,in_and_expr,0);\r
+    return p;\r
+}\r
+\r
+Predicate *     /* MR10 */\r
+#ifdef __USE_PROTOS\r
+genPredTreeMain( Predicate *p, Node *j)\r
+#else\r
+genPredTreeMain( p, j)\r
+    Predicate   *p;\r
+    Node        *j;\r
+#endif\r
+{\r
+  return genPredTreeMainXX(p,j,1);\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+genExprTreeOriginal( Tree *t, int k )\r
+#else\r
+genExprTreeOriginal( t, k )\r
+Tree *t;\r
+int k;\r
+#endif\r
+{\r
+       require(t!=NULL, "genExprTreeOriginal: NULL tree");\r
+       \r
+       if ( t->token == ALT )\r
+       {\r
+               _gen("("); genExprTreeOriginal(t->down, k); _gen(")");\r
+               if ( t->right!=NULL )\r
+               {\r
+                       _gen("||");\r
+                       on1line++;\r
+                       if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }\r
+                       _gen("("); genExprTreeOriginal(t->right, k); _gen(")");\r
+               }\r
+               return;\r
+       }\r
+       if ( t->down!=NULL ) _gen("(");\r
+       _gen1("LA(%d)==",k);\r
+       if ( TokenString(t->token) == NULL ) _gen1("%d", t->token)\r
+       else _gen1("%s", TokenString(t->token));\r
+       if ( t->down!=NULL )\r
+       {\r
+               _gen("&&");\r
+               on1line++;\r
+               if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }\r
+               _gen("("); genExprTreeOriginal(t->down, k+1); _gen(")");\r
+       }\r
+       if ( t->down!=NULL ) _gen(")");\r
+       if ( t->right!=NULL )\r
+       {\r
+               _gen("||");\r
+               on1line++;\r
+               if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }\r
+               _gen("("); genExprTreeOriginal(t->right, k); _gen(")");\r
+       }\r
+}\r
+\r
+#ifdef __USE_PROTOS\r
+static void MR_LAtokenString(int k,int token)\r
+#else\r
+static void MR_LAtokenString(k,token)\r
+  int   k;\r
+  int   token;\r
+#endif\r
+{\r
+    char    *ts;\r
+\r
+    ts=TokenString(token);\r
+    if (ts == NULL) {\r
+      _gen2(" LA(%d)==%d",k,token);\r
+    } else {\r
+      _gen2(" LA(%d)==%s",k,ts);\r
+    };\r
+}\r
+\r
+\r
+#ifdef __USE_PROTOS\r
+static int MR_countLeaves(Tree *t)\r
+#else\r
+static int MR_countLeaves(t)\r
+  Tree  *t;\r
+#endif\r
+{\r
+  if (t == NULL) return 0;\r
+  if (t->token == ALT) {\r
+    return MR_countLeaves(t->down)+MR_countLeaves(t->right);\r
+  } else {\r
+    return 1+MR_countLeaves(t->down)+MR_countLeaves(t->right);\r
+  };\r
+}\r
+\r
+#ifdef __USE_PROTOS\r
+static void MR_genOneLine(Tree *tree,int k)\r
+#else\r
+static void MR_genOneLine(tree,k)\r
+  Tree      *tree;\r
+  int       k;\r
+#endif\r
+{\r
+    if (tree == NULL) return;\r
+    if (tree->token == ALT) {\r
+       MR_genOneLine(tree->down,k);\r
+    } else {\r
+       MR_LAtokenString(k,tree->token);\r
+       if (tree->down != NULL &&\r
+           tree->down->right == NULL) {\r
+          _gen(" &&");\r
+          MR_genOneLine(tree->down,k+1);\r
+       } else if (tree->down != NULL) {\r
+         _gen(" && (");\r
+         MR_genOneLine(tree->down,k+1);\r
+         _gen(")");\r
+       };\r
+    };\r
+    if (tree->right != NULL) {\r
+      _gen(" ||");\r
+      MR_genOneLine(tree->right,k);\r
+    };\r
+}\r
+\r
+static int across;\r
+static int depth;\r
+static int lastkonline;\r
+\r
+#ifdef __USE_PROTOS\r
+static void MR_genMultiLine(Tree *tree,int k)\r
+#else\r
+static void MR_genMultiLine(tree,k)\r
+  Tree  *tree;\r
+  int   k;\r
+#endif\r
+{\r
+    int     i;\r
+\r
+    if (tree == NULL) return;\r
+    if (tree->token == ALT) {\r
+      MR_genMultiLine(tree,k);\r
+    } else {\r
+      MR_LAtokenString(k,tree->token);\r
+      lastkonline=k;\r
+      across++;\r
+      if (tree->down != NULL && tree->down->right == NULL) {\r
+        if (across > 3) {\r
+          _gen("\n");\r
+          across=0;\r
+          lastkonline=0;\r
+          for (i=0 ; i < depth+k ; i++) _gen("   ");\r
+          _gen("&&");\r
+        } else {\r
+          _gen(" &&");\r
+        };\r
+        MR_genMultiLine(tree->down,k+1);\r
+      } else if (tree->down != NULL) {\r
+        _gen("\n");\r
+        lastkonline=0;\r
+        across=0;\r
+        for (i=0 ; i < depth+k ; i++) _gen("   ");\r
+        _gen("&& (");\r
+        MR_genMultiLine(tree->down,k+1);\r
+        _gen(")");\r
+      };\r
+    };\r
+    if (tree->right != NULL) {\r
+      if (k < lastkonline) {\r
+        _gen("\n");\r
+        across=0;\r
+        lastkonline=0;\r
+        for (i=0; i < depth+k-1 ; i++) _gen("   ");\r
+        _gen("||");\r
+      } else if (across > 3 ) {\r
+        _gen("\n");\r
+        across=0;\r
+        lastkonline=0;\r
+        for (i=0; i < depth+k ; i++) _gen("   ");\r
+        _gen("||");\r
+      } else {\r
+        _gen(" ||");\r
+      };\r
+      MR_genMultiLine(tree->right,k);\r
+    };\r
+}\r
+\r
+#ifdef __USE_PROTOS\r
+static void genExprTree(Tree *tree,int k)\r
+#else\r
+static void genExprTree(tree,k)\r
+  Tree  *tree;\r
+  int   k;\r
+#endif\r
+{\r
+    int     count;\r
+\r
+#if 0\r
+    /* MR20 THM This was probably an error.\r
+            The routine should probably reference that static \r
+            "across" and this declaration hides it.\r
+    */\r
+\r
+    int     across;\r
+#endif\r
+  \r
+    require (tree != NULL,"genExprTree: tree is NULL");\r
+    require (k > 0,"genExprTree: k <= 0");\r
+\r
+    if (0 && !MRhoisting) {   /* MR11 make new version standard */\r
+      genExprTreeOriginal(tree,k);\r
+    } else {\r
+      count=MR_countLeaves(tree);\r
+      if (count < 5) {\r
+        MR_genOneLine(tree,k);\r
+      } else {\r
+        _gen("\n");\r
+        across=0;\r
+        depth=0;\r
+        lastkonline=0;\r
+        MR_genMultiLine(tree,k);\r
+        _gen("\n");\r
+      };\r
+    };\r
+}\r
+\r
+\r
+/*\r
+ * Generate LL(k) type expressions of the form:\r
+ *\r
+ *              (LA(1) == T1 || LA(1) == T2 || ... || LA(1) == Tn) &&\r
+ *              (LA(2) == T1 || LA(2) == T2 || ... || LA(2) == Tn) &&\r
+ *                     .....\r
+ *              (LA(k) == T1 || LA(k) == T2 || ... || LA(k) == Tn)\r
+ *\r
+ * If GenExprSetsOpt generate:\r
+ *\r
+ *             (setwdi[LA(1)]&(1<<j)) && (setwdi[LA(2)]&(1<<j)) ...\r
+ *\r
+ * where n is set_deg(expr) and Ti is some random token and k is the last nonempty\r
+ * set in fset <=CLL_k.\r
+ * k=1..CLL_k where CLL_k >= 1.\r
+ *\r
+ * This routine is visible only to this file and cannot answer a TRANS message.\r
+ *\r
+ */\r
+\r
+/*  [genExpr] */\r
+\r
+static int\r
+#ifdef __USE_PROTOS\r
+genExpr( Junction *j )\r
+#else\r
+genExpr( j )\r
+Junction *j;\r
+#endif\r
+{\r
+       int max_k;\r
+\r
+       /* if full LL(k) is sufficient, then don't use approximate (-ck) lookahead\r
+        * from CLL_k..LL_k\r
+        */\r
+       {\r
+               int limit;\r
+               if ( j->ftree!=NULL ) limit = LL_k;\r
+               else limit = CLL_k;\r
+               max_k = genExprSets(j->fset, limit);\r
+       }\r
+\r
+       /* Do tests for real tuples from other productions that conflict with\r
+        * artificial tuples generated by compression (using sets of tokens\r
+        * rather than k-trees).\r
+        */\r
+       if ( j->ftree != NULL )\r
+       {\r
+               _gen(" && !("); genExprTree(j->ftree, 1); _gen(")");\r
+       }\r
+\r
+       if ( ParseWithPredicates && j->predicate!=NULL )\r
+       {\r
+               Predicate *p = j->predicate;\r
+               warn_about_using_gk_option();\r
+               _gen("&&");\r
+               j->predicate=genPredTreeMain(p, (Node *)j);     /* MR10 */\r
+       }\r
+\r
+       return max_k;\r
+}\r
+\r
+static int\r
+#ifdef __USE_PROTOS\r
+genExprSets( set *fset, int limit )\r
+#else\r
+genExprSets( fset, limit )\r
+set *fset;\r
+int limit;\r
+#endif\r
+{\r
+       int k = 1;\r
+       int max_k = 0;\r
+       unsigned *e, *g, firstTime=1;\r
+\r
+    if (set_nil(fset[1])) {\r
+      _gen(" 0 /* MR13 empty set expression  - undefined rule ? infinite left recursion ? */ ");\r
+      MR_BadExprSets++;\r
+    };\r
+\r
+       if ( GenExprSetsOpt )\r
+       {\r
+               while ( k <= limit && !set_nil(fset[k]) )   /* MR11 */\r
+               {\r
+                       if ( set_deg(fset[k])==1 )      /* too simple for a set? */\r
+                       {\r
+                               int e;\r
+                               _gen1("(LA(%d)==",k);\r
+                               e = set_int(fset[k]);\r
+                               if ( TokenString(e) == NULL ) _gen1("%d)", e)\r
+                               else _gen1("%s)", TokenString(e));\r
+                       }\r
+                       else\r
+                       {\r
+                               NewSet();\r
+                               FillSet( fset[k] );\r
+                               _gen3("(setwd%d[LA(%d)]&0x%x)", wordnum, k, 1<<setnum);\r
+                       }\r
+                       if ( k>max_k ) max_k = k;\r
+                       if ( k == CLL_k ) break;\r
+                       k++;\r
+                       if ( k<=limit && !set_nil(fset[k]) ) _gen(" && ");  /* MR11 */\r
+                       on1line++;\r
+                       if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }\r
+               }\r
+               return max_k;\r
+       }\r
+\r
+       while ( k<= limit &&  !set_nil(fset[k]) )       /* MR11 */\r
+       {\r
+               if ( (e=g=set_pdq(fset[k])) == NULL ) fatal_internal("genExpr: cannot allocate IF expr pdq set");\r
+               for (; *e!=nil; e++)\r
+               {\r
+                       if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; }\r
+                       on1line++;\r
+                       if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }\r
+                       _gen1("LA(%d)==",k);\r
+                       if ( TokenString(*e) == NULL ) _gen1("%d", *e)\r
+                       else _gen1("%s", TokenString(*e));\r
+               }\r
+               free( (char *)g );\r
+               _gen(")");\r
+               if ( k>max_k ) max_k = k;\r
+               if ( k == CLL_k ) break;\r
+               k++;\r
+               if ( k <= limit && !set_nil(fset[k]) ) { firstTime=1; _gen(" && "); }   /* MR11 */\r
+               on1line++;\r
+               if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }\r
+       }\r
+       return max_k;\r
+}\r
+\r
+/*\r
+ * Generate code for any type of block.  If the last alternative in the block is\r
+ * empty (not even an action) don't bother doing it.  This permits us to handle\r
+ * optional and loop blocks as well.\r
+ *\r
+ * Only do this block, return after completing the block.\r
+ * This routine is visible only to this file and cannot answer a TRANS message.\r
+ */\r
+static set\r
+#ifdef __USE_PROTOS\r
+genBlk( Junction *q, int jtype, int *max_k, int *need_right_curly, int * lastAltEmpty /* MR23 */)\r
+#else\r
+genBlk( q, jtype, max_k, need_right_curly, lastAltEmpty /* MR23 */)\r
+Junction *q;\r
+int jtype;\r
+int *max_k;\r
+int *need_right_curly;\r
+int *lastAltEmpty; /* MR23 */\r
+#endif\r
+{\r
+       set f;\r
+       Junction *alt;\r
+       int a_guess_in_block = 0;\r
+       require(q!=NULL,                                "genBlk: invalid node");\r
+       require(q->ntype == nJunction,  "genBlk: not junction");\r
+       *need_right_curly=0;\r
+       *lastAltEmpty = 0;              /* MR23 */\r
+       if ( q->p2 == NULL )    /* only one alternative?  Then don't need if */\r
+       {       \r
+               if (first_item_is_guess_block((Junction *)q->p1)!=NULL )\r
+               {\r
+            if (jtype != aLoopBlk && jtype != aOptBlk && jtype != aPlusBlk) {\r
+                         warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line);\r
+            };\r
+                   gen("zzGUESS\n");   /* guess anyway to make output code consistent */\r
+/* MR10 disable */  /**** gen("if ( !zzrv )\n"); ****/\r
+/* MR10 */          gen("if ( !zzrv ) {\n"); tabs++; (*need_right_curly)++;\r
+        };\r
+               TRANS(q->p1);\r
+               return empty;           /* no decision to be made-->no error set */\r
+       }\r
+\r
+       f = First(q, 1, jtype, max_k);\r
+       for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )\r
+       {\r
+               if ( alt->p2 == NULL )                                  /* chk for empty alt */\r
+               {       \r
+                       Node *p = alt->p1;\r
+                       if ( p->ntype == nJunction )\r
+                       {\r
+                               /* we have empty alt */\r
+/* MR23\r
+   There is a conflict between giving good error information for non-exceptions\r
+   and making life easy for those using parser exception handling.  Consider:\r
+\r
+         r: { A } b;\r
+                b: B;\r
+                \r
+                  with input "C"\r
+\r
+   Before MR21 the error message would be "expecting B - found C".  After MR21\r
+   the error message would be "expcect A, B - found C".  This was good, but it\r
+   caused problems for those using parser exceptions because the reference to\r
+   B was generated inside the {...} where B really wasn't part of the block.\r
+\r
+   In MR23 this has been changed for the case where exceptions are in use to\r
+   not generate the extra check in the tail of the {A} block.\r
+*/\r
+\r
+\r
+/* MR23 */     if (isEmptyAlt( ((Junction *)p)->p1, (Node *)q->end)) {\r
+/* MR23 */      *lastAltEmpty = 1;\r
+/* MR23 */             if (FoundException) {\r
+/* MR23 */                     /* code to restore state if a prev alt didn't follow guess */\r
+/* MR23 */                     if ( a_guess_in_block && jtype != aPlusBlk) {\r
+/* MR23 */                             gen("if ( !zzrv ) zzGUESS_DONE; /* MR28 */\n");\r
+/* MR23 */                     }\r
+/* MR23 */                     break;\r
+/* MR23 */             };\r
+/* MR28 */      if (jtype == aPlusBlk) {\r
+/* MR28 */          break;\r
+/* MR28 */      }\r
+/* MR23 */     }\r
+               }\r
+       } /* end of for loop on alt */\r
+\r
+/* MR10 */        if (alt->p2 == NULL &&\r
+/* MR10 */               ( q->jtype == aSubBlk || q->jtype == RuleBlk) ) {\r
+/* MR10 */          if (first_item_is_guess_block(alt)) {\r
+/* MR10 */               warnFL("(...)? as last alternative of block is unnecessary",\r
+/* MR10 */                                FileStr[alt->file],alt->line);\r
+/* MR10 */          };\r
+/* MR10 */        };\r
+\r
+               if ( alt != q ) gen("else ")\r
+               else\r
+               {\r
+                       if ( DemandLookahead ) {\r
+                               if ( !GenCC ) {gen1("LOOK(%d);\n", *max_k);}\r
+                               else gen1("look(%d);\n", *max_k);\r
+                       }\r
+               }\r
+\r
+               if ( alt!=q )\r
+               {\r
+                       _gen("{\n");\r
+                       tabs++;\r
+                       (*need_right_curly)++;\r
+                       /* code to restore state if a prev alt didn't follow guess */\r
+                       if ( a_guess_in_block )\r
+                               gen("if ( !zzrv ) zzGUESS_DONE;\n");\r
+               }\r
+               if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL )\r
+               {\r
+                       a_guess_in_block = 1;\r
+                       gen("zzGUESS\n");\r
+               }\r
+               gen("if ( ");\r
+               if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && ");\r
+               genExpr(alt);\r
+               _gen(" ) ");\r
+               _gen("{\n");\r
+               tabs++;\r
+               TRANS(alt->p1);\r
+               --tabs;\r
+               gen("}\n");\r
+/* MR10 */        if (alt->p2 == NULL) {\r
+/* MR10 */          if (first_item_is_guess_block(alt)) {\r
+/* MR10 */            gen("/* MR10 */ else {\n");\r
+/* MR10 */            tabs++;\r
+/* MR10 */               (*need_right_curly)++;\r
+/* MR10 */               /* code to restore state if a prev alt didn't follow guess */\r
+/* MR10 */            gen("/* MR10 */ if ( !zzrv ) zzGUESS_DONE;\n");\r
+/* MR10 */            gen("/* MR10 */ if (0) {}     /* last alternative of block is guess block */\n");\r
+/* MR10 */          };\r
+/* MR10 */        };\r
+       }\r
+       return f;\r
+}\r
+\r
+static int\r
+#ifdef __USE_PROTOS\r
+has_guess_block_as_first_item( Junction *q )\r
+#else\r
+has_guess_block_as_first_item( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       Junction *alt;\r
+\r
+       for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )\r
+       {\r
+               if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static int\r
+#ifdef __USE_PROTOS\r
+has_guess_block_as_last_item( Junction *q )\r
+#else\r
+has_guess_block_as_last_item( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       Junction *alt;\r
+\r
+    if (q == NULL) return 0;\r
+       for (alt=q; alt->p2 != NULL && !( (Junction *) alt->p2)->ignore; alt= (Junction *) alt->p2 ) {};\r
+    return first_item_is_guess_block( (Junction *) alt->p1) != NULL;\r
+}\r
+\r
+/* MR30 See description of first_item_is_guess_block for background */\r
+\r
+Junction *\r
+#ifdef __USE_PROTOS\r
+first_item_is_guess_block_extra(Junction *q )\r
+#else\r
+first_item_is_guess_block_extra(q)\r
+Junction *q;\r
+#endif\r
+{\r
+       while ( q!=NULL &&\r
+            (  ( q->ntype==nAction ) ||\r
+               ( q->ntype==nJunction &&\r
+                    (q->jtype==Generic || q->jtype == aLoopBlk) \r
+               )\r
+            )\r
+          )\r
+       {\r
+               if ( q->ntype==nJunction ) q = (Junction *)q->p1;\r
+               else q = (Junction *) ((ActionNode *)q)->next;\r
+       }\r
+\r
+       if ( q==NULL ) return NULL;\r
+       if ( q->ntype!=nJunction ) return NULL;\r
+       if ( q->jtype!=aSubBlk ) return NULL;\r
+       if ( !q->guess ) return NULL;\r
+\r
+       return q;\r
+}\r
+\r
+/* return NULL if 1st item of alt is NOT (...)? block; else return ptr to aSubBlk node\r
+ * of (...)?;  This function ignores actions and predicates.\r
+ */\r
+\r
+Junction *\r
+#ifdef __USE_PROTOS\r
+first_item_is_guess_block( Junction *q )\r
+#else\r
+first_item_is_guess_block( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       Junction * qOriginal = q;       /* DEBUG */\r
+\r
+    /* MR14  Couldn't find aSubBlock which was a guess block when it lay\r
+             behind aLoopBlk.  The aLoopBlk only appear in conjunction with\r
+             aLoopBegin, but the routine didn't know that.  I think.\r
+\r
+       MR14a Added extra parentheses to clarify precedence\r
+\r
+          MR30  This appears to have been a mistake.  The First set was then\r
+                computed incorrectly for:\r
+\r
+                                       r : ( (A)? B\r
+                                           | C\r
+                                               )*\r
+                        \r
+                        The routine analysis_point was seeing the guess block when\r
+                        it was still analyzing the loopBegin block.  As a consequence,\r
+                        when it looked for the analysis_point it was processing the B, but\r
+                        skipping over the C alternative altogether because it thought\r
+                        it was looking at a guess block, not realizing there was a loop\r
+                        block in front of the loopBegin.\r
+\r
+             loopBegin  loopBlk  subBlk/guess  A  G  EB  G  B EB EB  EB  ER\r
+                           |          |          |                     ^   ^\r
+                               |                  |                                |   |\r
+                |          +-> G  C G ----------------------+   |\r
+                |                                               |\r
+                               +--- G G G -------------------------------------+\r
+    \r
+                        Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu).\r
+\r
+               MR30  This is still more complicated.  This fix caused ambiguity messages\r
+               to be reported for "( (A B)? )* A B" but not for "( (A B)? )+".  Why is\r
+               there a difference when these are outwardly identical ?  It is because the\r
+               start of a (...)* block is represented by two nodes: a loopBegin block\r
+               followed by a loopBlock whereas the start of a (...)+ block is\r
+               represented as a single node: a plusBlock.  So if first_item_is_guess_block\r
+               is called when the current node is a loopBegin it starts with the\r
+               loop block rather than the the sub block which follows the loop block.\r
+               However, we can't just skip past the loop block because some routines\r
+               depend on the old implementation.  So, we provide a new implementation\r
+               which does skip the loopBlock.  However, which should be called when ?\r
+               I'm not sure, but my guess is that first_item_is_guess_block_extra (the\r
+               new one) should only be called for the ambiguity routines.\r
+\r
+    */\r
+\r
+       while ( q!=NULL &&\r
+            (  ( q->ntype==nAction ) ||\r
+               ( q->ntype==nJunction &&\r
+                    (q->jtype==Generic /*** || q->jtype == aLoopBlk ***/ ) /*** MR30 Undo MR14 change ***/\r
+               )\r
+            )\r
+          )\r
+       {\r
+               if ( q->ntype==nJunction ) q = (Junction *)q->p1;\r
+               else q = (Junction *) ((ActionNode *)q)->next;\r
+       }\r
+\r
+       if ( q==NULL ) return NULL;\r
+       if ( q->ntype!=nJunction ) return NULL;\r
+       if ( q->jtype!=aSubBlk ) return NULL;\r
+       if ( !q->guess ) return NULL;\r
+\r
+       return q;\r
+}\r
+\r
+/* MR1                                                                                     */\r
+/* MR1  10-Apr-97 MR1 Routine to stringize failed semantic predicates msgs  */\r
+/* MR1                                                                                 */\r
+\r
+#define STRINGIZEBUFSIZE 1024\r
+\r
+static char stringizeBuf[STRINGIZEBUFSIZE];\r
+char *\r
+#ifdef __USE_PROTOS\r
+stringize(char * s)\r
+#else\r
+stringize(s)\r
+char *s;\r
+#endif\r
+\r
+{\r
+  char         *p;\r
+  char         *stop;\r
+\r
+  p=stringizeBuf;\r
+  stop=&stringizeBuf[1015];\r
+\r
+  if (s != 0) {\r
+    while (*s != 0) {\r
+      if (p >= stop) {\r
+       goto stringizeStop;\r
+      } else if (*s == '\n') {\r
+        *p++='\\';\r
+        *p++='n';\r
+        *p++='\\';\r
+       *p++=*s++;\r
+      } else if (*s == '\\') {\r
+       *p++=*s;\r
+       *p++=*s++;\r
+      } else if (*s == '\"') {\r
+        *p++='\\';\r
+       *p++=*s++;\r
+        while (*s != 0) {\r
+          if (p >= stop) {\r
+            goto stringizeStop;\r
+         } else if (*s == '\n') {\r
+           *p++='\\';\r
+           *p++=*s++;\r
+         } else if (*s == '\\') {\r
+           *p++=*s++;\r
+           *p++=*s++;\r
+         } else if (*s == '\"') {\r
+           *p++='\\';\r
+           *p++=*s++;\r
+           break;\r
+         } else {\r
+           *p++=*s++;\r
+          };\r
+        };\r
+      } else if (*s == '\'') {\r
+       *p++=*s++;\r
+        while (*s != 0) {\r
+          if (p >= stop) {\r
+            goto stringizeStop;\r
+         } else if (*s == '\'') {\r
+           *p++=*s++;\r
+           break;\r
+         } else if (*s == '\\') {\r
+           *p++=*s++;\r
+           *p++=*s++;\r
+         } else if (*s == '\"') {\r
+           *p++='\\';\r
+           *p++=*s++;\r
+           break;\r
+         } else {\r
+           *p++=*s++;\r
+          };\r
+        };\r
+      } else {\r
+        *p++=*s++;\r
+      };\r
+    };\r
+  };\r
+  goto stringizeExit;\r
+stringizeStop:\r
+  *p++='.';            \r
+  *p++='.';            \r
+  *p++='.';            \r
+stringizeExit:\r
+  *p=0;\r
+  return stringizeBuf;\r
+}\r
+\r
+#ifdef __USE_PROTOS\r
+int isNullAction(char *s)\r
+#else\r
+int isNullAction(s)\r
+  char  *s;\r
+#endif\r
+{\r
+  char  *p;\r
+  for (p=s; *p != '\0' ; p++) {\r
+    if (*p != ';' && *p !=' ') return 0;\r
+  };\r
+  return 1;\r
+}\r
+/* MR1                                                                                                     */\r
+/* MR1 End of Routine to stringize code for failed predicates msgs         */\r
+/* MR1                                                                                 */\r
+\r
+/* Generate an action.  Don't if action is NULL which means that it was already\r
+ * handled as an init action.\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genAction( ActionNode *p )\r
+#else\r
+genAction( p )\r
+ActionNode *p;\r
+#endif\r
+{\r
+       require(p!=NULL,                        "genAction: invalid node and/or rule");\r
+       require(p->ntype==nAction,      "genAction: not action");\r
+\r
+       if ( !p->done )  /* MR10 */ /* MR11 */\r
+       {\r
+               if ( p->is_predicate)\r
+               {\r
+                       if ( p->guardpred != NULL )\r
+                       {\r
+                Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */\r
+                gen("if (!");\r
+                               guardDup=genPredTreeMain(guardDup, (Node *)p);\r
+                predicate_free(guardDup);\r
+                       }\r
+/* MR10 */  else if (p->ampersandPred != NULL) {\r
+/* MR10 */      gen("if (!");\r
+/* MR10 */      p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p);\r
+/* MR10 */  }\r
+                       else\r
+                       {\r
+                               gen("if (!(");\r
+                               /* make sure that '#line n' is on front of line */\r
+                               if ( GenLineInfo && p->file != -1 ) _gen("\n");\r
+                               dumpPredAction(p,p->action, output, 0, p->file, p->line, 0);\r
+                               _gen(")");\r
+                       }\r
+\r
+/* MR23 Change failed predicate macro to have three arguments:\r
+\r
+        macro arg 1: The stringized predicate itself\r
+        macro arg 2: 0 => no user-defined error action\r
+                     1 => user-defined error action\r
+        macro arg 3: The user-defined error action\r
+\r
+   This gives the user more control of the error action.\r
+*/\r
+                       tabs++;\r
+                       gen3(") {zzfailed_pred(\"%s\",%s, { %s } );}\n",         /* MR23 */\r
+                                       stringize(p->action),                            /* MR23 */\r
+                    (p->pred_fail == NULL ?                          /* MR23/MR27 */\r
+                               "0 /* report */" : "1 /* user action */"),   /* MR23/MR27 */\r
+                    (p->pred_fail == NULL ?                          /* MR23 */\r
+                        "0; /* no user action */" : p->pred_fail));  /* MR23 */\r
+                       tabs--;\r
+               }\r
+               else    /* not a predicate */\r
+               {\r
+            if (! isNullAction(p->action) && !p->noHoist) {\r
+                         if ( FoundGuessBlk ) {\r
+                               if ( GenCC ) {\r
+                  gen("if ( !guessing ) {\n");\r
+                } else {\r
+                                 gen("zzNON_GUESS_MODE {\n");\r
+                };\r
+              };\r
+                         dumpActionPlus(p, p->action, output, tabs, p->file, p->line, 1); /* MR21 */\r
+                         if ( FoundGuessBlk ) gen("}\n");\r
+            };\r
+               }\r
+       }\r
+       TRANS(p->next)\r
+}\r
+\r
+/*\r
+ *             if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in\r
+ *             else pass addr of temp root ptr (&_ast) (don't zzlink it in).\r
+ *\r
+ *             if ! modifies rule-ref, then never link it in and never pass zzSTR.\r
+ *             Always pass address of temp root ptr.\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genRuleRef( RuleRefNode *p )\r
+#else\r
+genRuleRef( p )\r
+RuleRefNode *p;\r
+#endif\r
+{\r
+       Junction *q;\r
+       char *handler_id = "";\r
+       RuleEntry *r, *r2;\r
+       char *parm = "", *exsig = "";\r
+\r
+    int     genRuleRef_emittedGuessGuard=0;     /* MR10 */\r
+\r
+       require(p!=NULL,                        "genRuleRef: invalid node and/or rule");\r
+       require(p->ntype==nRuleRef, "genRuleRef: not rule reference");\r
+       \r
+       if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )\r
+               handler_id = p->altstart->exception_label;\r
+\r
+       r = (RuleEntry *) hash_get(Rname, p->text);\r
+       if ( r == NULL )\r
+       {\r
+               warnFL( eMsg1("rule %s not defined",\r
+                                         p->text), FileStr[p->file], p->line );\r
+               return;\r
+       }\r
+\r
+/* MR8 5-Aug-97     Reported by S.Bochnak@microtool.com.pl                  */\r
+/*                  Don't do assign when no return values declared          */\r
+/*                  Move definition of q up and use it to guard p->assign   */\r
+\r
+       q = RulePtr[r->rulenum];        /* find definition of ref'd rule */  /* MR8 */\r
+\r
+       r2 = (RuleEntry *) hash_get(Rname, p->rname);\r
+       if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}\r
+\r
+    OutLineInfo(output,p->line,FileStr[p->file]);\r
+\r
+       if ( GenCC && GenAST ) {\r
+               gen("_ast = NULL;\n");\r
+       }\r
+\r
+       if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) {      /* MR8 */\r
+               if ( GenCC ) {\r
+          gen("if ( !guessing ) {\n");\r
+        } else {\r
+          gen("zzNON_GUESS_MODE {\n");\r
+        };\r
+        tabs++;                                                      /* MR11 */\r
+        genRuleRef_emittedGuessGuard=1;                              /* MR11 */\r
+    };\r
+\r
+       if ( FoundException ) exsig = "&_signal";\r
+\r
+       tab();\r
+       if ( GenAST )\r
+       {\r
+               if ( GenCC ) {\r
+/****                  if ( r2->noAST || p->astnode==ASTexclude )\r
+****/\r
+                       {\r
+/****                          _gen("_ast = NULL;\n");\r
+****/\r
+                               parm = "&_ast";\r
+                       }\r
+/*** we always want to set just a pointer now, then set correct\r
+pointer after\r
+\r
+                       else {\r
+                               _gen("_astp =\r
+(_tail==NULL)?(&_sibling):(&(_tail->_right));\n");\r
+                               parm = "_astp";\r
+                       }\r
+****/\r
+               }\r
+               else {\r
+                       if ( r2->noAST || p->astnode==ASTexclude )\r
+                       {\r
+                               _gen("_ast = NULL; ");\r
+                               parm = "&_ast";\r
+                       }\r
+                       else parm = "zzSTR";\r
+               }\r
+               if ( p->assign!=NULL && q->ret!=NULL )                       /* MR8 */\r
+               {\r
+                       if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */\r
+                       else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);\r
+               }\r
+               if ( FoundException ) {\r
+                       _gen5("%s%s(%s,&_signal%s%s); ",\r
+                                 RulePrefix,\r
+                                 p->text,\r
+                                 parm,\r
+                                 (p->parms!=NULL)?",":"",\r
+                                 (p->parms!=NULL)?p->parms:"");\r
+                       if ( p->ex_group!=NULL ) {\r
+                               _gen("\n");\r
+                               gen("if (_signal) {\n");\r
+                               tabs++;\r
+                               dumpException(p->ex_group, 0);\r
+                               tabs--;\r
+                               gen("}");\r
+                       }\r
+                       else {\r
+                               _gen1("if (_signal) goto %s_handler;", handler_id);\r
+                       }\r
+               }\r
+               else {\r
+                       _gen5("%s%s(%s%s%s);",\r
+                                 RulePrefix,\r
+                                 p->text,\r
+                                 parm,\r
+                                 (p->parms!=NULL)?",":"",\r
+                                 (p->parms!=NULL)?p->parms:"");\r
+               }\r
+               if ( GenCC && (r2->noAST || p->astnode==ASTexclude) )\r
+               {\r
+                       /* rule has a ! or element does */\r
+                       /* still need to assign to #i so we can play with it */\r
+                       _gen("\n");\r
+                       gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum);\r
+               }\r
+               else if ( !r2->noAST && p->astnode == ASTinclude )\r
+               {\r
+                       /* rule doesn't have a ! and neither does element */\r
+/* MR10 */  if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {\r
+/* MR10 */    _gen("\n");\r
+/* MR10 */    if (GenCC) gen ("if (!guessing) {    /* MR10 */")\r
+/* MR10 */          else gen ("if (!zzguessing) {    /* MR10 */\n");\r
+/* MR10 */    tabs++;\r
+/* MR10 */  };\r
+                       if ( GenCC ) {\r
+                               _gen("\n");\r
+                               gen("if ( _tail==NULL ) _sibling = _ast; else _tail->setRight(_ast);\n");\r
+                               gen2("_ast%d%d = (AST *)_ast;\n", BlkLevel-1, p->elnum);\r
+                               tab();\r
+                       }\r
+                       else _gen(" ");\r
+            if ( GenCC ) {\r
+                _gen("ASTBase::"); }\r
+                else _gen("zz");\r
+                       _gen("link(_root, &_sibling, &_tail);");\r
+\r
+/* MR10 */  if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {     /* MR10 */\r
+/* MR10 */    _gen("\n");\r
+/* MR10 */    tabs--;\r
+/* MR10 */    if (GenCC) gen ("};    /* MR10 */")\r
+/* MR10 */          else gen ("};    /* MR10 */");\r
+/* MR10 */  };\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if ( p->assign!=NULL && q->ret!=NULL )                       /* MR8 */\r
+               {\r
+                       if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */\r
+                       else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);\r
+               }\r
+               if ( FoundException ) {\r
+                       _gen4("%s%s(&_signal%s%s); ",\r
+                                 RulePrefix,\r
+                                 p->text,\r
+                                 (p->parms!=NULL)?",":"",\r
+                                 (p->parms!=NULL)?p->parms:"");\r
+                       if ( p->ex_group!=NULL ) {\r
+                               _gen("\n");\r
+                               gen("if (_signal) {\n");\r
+                               tabs++;\r
+                               dumpException(p->ex_group, 0);\r
+                               tabs--;\r
+                               gen("}");\r
+                       }\r
+                       else {\r
+                               _gen1("if (_signal) goto %s_handler;", handler_id);\r
+                       }\r
+               }\r
+               else {\r
+                       _gen3("%s%s(%s);",\r
+                                 RulePrefix,\r
+                                 p->text,\r
+                                 (p->parms!=NULL)?p->parms:"");\r
+               }\r
+               if ( p->assign!=NULL && q->ret!=NULL ) _gen("\n");           /* MR8 */\r
+       }\r
+\r
+       if ( p->assign!=NULL && q->ret!=NULL) {                          /* MR8 */\r
+               if ( hasMultipleOperands(p->assign) )                        /* MR23 */\r
+               {\r
+                       _gen("\n");\r
+                       dumpRetValAssign(p->assign, q->ret, p);                  /* MR30 */\r
+                       _gen("}");\r
+               }\r
+       }\r
+       _gen("\n");\r
+\r
+       /* Handle element labels now */\r
+       if ( p->el_label!=NULL )\r
+       {\r
+               if ( GenAST )\r
+               {\r
+                       if ( GenCC ) {\r
+                               gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum);\r
+                       }\r
+                       else {gen1("%s_ast = zzastCur;\n", p->el_label);}\r
+               }\r
+               else if (!GenCC ) {\r
+                       gen1("%s = zzaCur;\n", p->el_label);\r
+        }\r
+       }\r
+\r
+       if ( FoundGuessBlk && p->assign!=NULL && q->ret!=NULL ) {       /* MR8 */\r
+               /* in guessing mode, don't branch to handler upon error */\r
+        tabs--;                                                     /* MR11 */\r
+               gen("} else {\n");\r
+        tabs++;                                                     /* MR11 */\r
+               if ( FoundException ) {\r
+                       gen6("%s%s(%s%s&_signal%s%s);\n",\r
+                                RulePrefix,\r
+                                p->text,\r
+                                parm,\r
+                 (*parm!='\0')?",":"",\r
+                 (p->parms!=NULL)?",":"",\r
+                                (p->parms!=NULL)?p->parms:"");\r
+               }\r
+               else {\r
+                       gen5("%s%s(%s%s%s);\n",\r
+                                RulePrefix,\r
+                                p->text,\r
+                                parm,\r
+                                (p->parms!=NULL && *parm!='\0')?",":"",\r
+                                (p->parms!=NULL)?p->parms:"");\r
+               }\r
+        tabs--;                                                     /* MR11 */\r
+               gen("}\n");\r
+       }\r
+       TRANS(p->next)\r
+}\r
+\r
+/*\r
+ * Generate code to match a token.\r
+ *\r
+ * Getting the next token is tricky.  We want to ensure that any action\r
+ * following a token is executed before the next GetToken();\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genToken( TokNode *p )\r
+#else\r
+genToken( p )\r
+TokNode *p;\r
+#endif\r
+{\r
+       RuleEntry *r;\r
+       char *handler_id = "";\r
+       ActionNode *a;\r
+       char *set_name;\r
+       char *set_nameErrSet;\r
+       int complement;\r
+       int ast_label_in_action = 0;    /* MR27 */\r
+       int pushedCmodeAST = 0;                 /* MR27 */\r
+\r
+       require(p!=NULL,                        "genToken: invalid node and/or rule");\r
+       require(p->ntype==nToken,       "genToken: not token");\r
+       if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )\r
+               handler_id = p->altstart->exception_label;\r
+\r
+       r = (RuleEntry *) hash_get(Rname, p->rname);\r
+       if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}\r
+\r
+/*\r
+ * MR27 Has the element label been referenced as an AST (with the # operator) ?\r
+ *      If so, then we'll want to build the AST even though the user has used\r
+ *      the ! operator.\r
+ */\r
+/* MR27 */     if (GenAST && p->el_label != NULL) {\r
+/* MR27 */             ast_label_in_action = list_search_cstring(r->ast_labels_in_actions,\r
+/* MR27 */                                                       p->el_label);\r
+/* MR27 */     }\r
+       \r
+    OutLineInfo(output,p->line,FileStr[p->file]);\r
+\r
+       if ( !set_nil(p->tset) )        /* implies '.', ~Tok, or tokenclass */\r
+       {\r
+               unsigned e;\r
+               unsigned eErrSet = 0;\r
+               set b;\r
+               set bErrSet;                                    /* MR23 */\r
+               b = set_dup(p->tset);\r
+               bErrSet = set_dup(p->tset);         /* MR23 */\r
+               complement = p->complement; /* MR23 */\r
+               if ( p->tclass!=NULL  && complement == 0 /* MR23 */) { /* token class not complemented*/\r
+                       static char buf[MaxRuleName+20];            /* MR23 */\r
+                       static char bufErrSet[MaxRuleName+20];  /* MR23 */\r
+                       if ( p->tclass->dumped ) {\r
+                               e = p->tclass->setnum;\r
+                               eErrSet = p->tclass->setnumErrSet;\r
+                       }\r
+                       else {\r
+                               e = DefErrSet(&b, 0, TokenString(p->token));\r
+                               eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errset");\r
+                               p->tclass->dumped = 1;  /* indicate set has been created */\r
+                               p->tclass->setnum = e;\r
+                               p->tclass->setnumErrSet = eErrSet;                                      /* MR23 */\r
+                       }\r
+                       sprintf(buf, "%s_set", TokenString(p->token));\r
+                       sprintf(bufErrSet, "%s_errset", TokenString(p->token)); /* MR23 */\r
+                       set_name = buf;\r
+                       set_nameErrSet = bufErrSet;                                                             /* MR23 */\r
+               }\r
+\r
+               /* MR23 - Forgot about the case of ~TOKCLASS. */\r
+\r
+               else if ( p->tclass!=NULL  && complement != 0 /* MR23 */)\r
+               {\r
+                       static char buf[MaxRuleName+20];            /* MR23 */\r
+                       static char bufErrSet[MaxRuleName+20];  /* MR23 */\r
+                       if ( p->tclass->dumpedComplement ) {\r
+                               e = p->tclass->setnumComplement;\r
+                               eErrSet = p->tclass->setnumErrSetComplement;\r
+                       }\r
+                       else {\r
+                               e = DefErrSetWithSuffix(0, &b, 0, TokenString(p->token), "_setbar");\r
+                               eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errsetbar");\r
+                               p->tclass->dumpedComplement = 1;        /* indicate set has been created */\r
+                               p->tclass->setnumComplement = e;\r
+                               p->tclass->setnumErrSetComplement = eErrSet;                                    /* MR23 */\r
+                       }\r
+                       sprintf(buf, "%s_setbar", TokenString(p->token));\r
+                       sprintf(bufErrSet, "%s_errsetbar", TokenString(p->token));      /* MR23 */\r
+                       set_name = buf;\r
+                       set_nameErrSet = bufErrSet;                                                             /* MR23 */\r
+               }\r
+               else {                                  /* wild card */\r
+                       static char buf[sizeof("zzerr")+10];\r
+                       static char bufErrSet[sizeof("zzerr")+10];\r
+                       int n = DefErrSet( &b, 0, NULL );\r
+                       int nErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, NULL, "_set");\r
+                       if ( GenCC ) sprintf(buf, "err%d", n);\r
+                       else sprintf(buf, "zzerr%d", n);\r
+                       if ( GenCC ) sprintf(bufErrSet, "err%d", nErrSet);\r
+                       else sprintf(bufErrSet, "zzerr%d", nErrSet);\r
+                       set_name = buf;\r
+                       set_nameErrSet = bufErrSet;\r
+               }\r
+\r
+               if ( !FoundException ) {\r
+/* MR23 */             gen2("zzsetmatch(%s, %s);", set_name, set_nameErrSet);\r
+               }\r
+               else if ( p->ex_group==NULL ) {\r
+            if ( p->use_def_MT_handler )\r
+                gen3("zzsetmatch_wdfltsig(%s,(ANTLRTokenType)%d,%s);",\r
+                     set_name,\r
+                     p->token,\r
+                     tokenFollowSet(p))\r
+            else\r
+                gen2("zzsetmatch_wsig(%s, %s_handler);",\r
+                     set_name,\r
+                     handler_id);\r
+               }\r
+               else\r
+               {\r
+                       gen1("if ( !_setmatch_wsig(%s) ) {\n", set_name);\r
+                       tabs++;\r
+/* MR6 */      if (FoundGuessBlk) {\r
+/* MR6 */        if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}\r
+/* MR6 */        else gen("if ( zzguessing ) goto fail;\n");\r
+/* MR6 */      };\r
+                       gen("_signal=MismatchedToken;\n");\r
+                       dumpException(p->ex_group, 0);\r
+                       tabs--;\r
+                       gen("}\n");\r
+               }\r
+               set_free(b);\r
+               set_free(bErrSet);\r
+       }\r
+       else if ( TokenString(p->token)!=NULL )\r
+       {\r
+               if ( FoundException ) {\r
+                       if ( p->use_def_MT_handler )\r
+                               gen2("zzmatch_wdfltsig(%s,%s);",TokenString(p->token),tokenFollowSet(p))\r
+                       else if ( p->ex_group==NULL )\r
+                       {\r
+                               gen2("zzmatch_wsig(%s, %s_handler);",\r
+                                        TokenString(p->token),\r
+                                        handler_id);\r
+                       }\r
+                       else\r
+                       {\r
+/* MR6 */              if (GenCC) {\r
+/* MR6 */                gen1("if ( !_match_wsig(%s) ) {\n", TokenString(p->token));\r
+/* MR6 */              } else {\r
+/* MR6 */                gen1("if ( !_zzmatch_wsig(%s) ) {\n", TokenString(p->token));\r
+/* MR6 */              };\r
+                               tabs++;\r
+/* MR6 */              if (FoundGuessBlk) {\r
+/* MR6 */                if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}\r
+/* MR6 */                else gen("if ( zzguessing ) goto fail;\n");\r
+/* MR6 */              };\r
+                               gen("_signal=MismatchedToken;\n");\r
+                               dumpException(p->ex_group, 0);\r
+                               tabs--;\r
+                               gen("}\n");\r
+                       }\r
+               }\r
+               else gen1("zzmatch(%s);", TokenString(p->token));\r
+       }\r
+       else {\r
+        if ( FoundException ) {\r
+            if ( p->use_def_MT_handler )\r
+                               gen2("zzmatch_wdfltsig((ANTLRTokenType)%d,%s);",\r
+                                        p->token,tokenFollowSet(p))\r
+            else\r
+                gen2("zzmatch_wsig(%d,%s_handler);",p->token,handler_id);\r
+        }\r
+               else {gen1("zzmatch(%d);", p->token);}\r
+       }\r
+\r
+       a = findImmedAction( p->next );\r
+       /* generate the token labels */\r
+       if ( GenCC && p->elnum>0 )\r
+       {\r
+               /* If building trees in C++, always gen the LT() assigns */\r
+               if ( set_el(p->elnum, tokensRefdInBlock) || GenAST )\r
+               {\r
+/* MR10 */     if ( FoundGuessBlk ) {\r
+/* MR10 */    gen("\n");\r
+/* MR10 */    if (p->label_used_in_semantic_pred) {\r
+/* MR10 */             gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);  /* MR10 */\n", BlkLevel-1, p->elnum);\r
+/* MR10 */    } else {\r
+/* MR10 */             gen("if ( !guessing ) {\n"); tab();\r
+/* MR10 */             _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);\n", BlkLevel-1, p->elnum);\r
+/* MR10 */      gen("}\n");\r
+/* MR10 */    };\r
+/* MR10 */  } else {\r
+/* MR10 */       _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);", BlkLevel-1, p->elnum);\r
+/* MR10 */  };\r
+/* MR10 */\r
+               }\r
+\r
+/*\r
+ *  MR23 labase is never used in the C++ runtime library.\r
+ *       and this code is generated only in C++ mode\r
+ */\r
+\r
+/***           if ( LL_k>1 )                                    / * MR23 disabled */\r
+/***                   if ( !DemandLookahead ) _gen(" labase++;");  / * MR23 disabled */\r
+/***           _gen("\n");                                      / * MR23 disabled */\r
+/***           tab();                                           / * MR23 disabled */\r
+       }\r
+       if ( GenAST )\r
+       {\r
+               if ( FoundGuessBlk &&\r
+                               (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) )\r
+               {\r
+                       if ( GenCC ) {_gen("if ( !guessing ) {\n"); tab();}\r
+                       else {_gen("zzNON_GUESS_MODE {\n"); tab();}\r
+               }\r
+\r
+/* MR27 addition when labels referenced when operator ! used */\r
+\r
+               pushedCmodeAST = 0; /* MR27 */\r
+               if (ast_label_in_action && (p->astnode == ASTexclude || r->noAST)) {\r
+                       _gen("\n");\r
+                       if (GenCC) {\r
+/* MR13 */      if (NewAST) {\r
+/* MR13 */         gen4("_ast%d%d = newAST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);\r
+/* MR13 */      } else {\r
+/* MR13 */         gen4("_ast%d%d = new AST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);\r
+/* MR13 */      }\r
+                       }\r
+                       else {\r
+                               pushedCmodeAST = 1;\r
+                               gen("zzastPush(zzmk_ast(zzastnew(),zzaCur)); /* MR27 */");\r
+                       }\r
+               }\r
+\r
+/* end MR27 addition for labels referenced when operator ! used */\r
+\r
+               if (!r->noAST )\r
+               {\r
+                       if (GenCC && !(p->astnode == ASTexclude) ) {\r
+                               _gen("\n");\r
+/* MR13 */      if (NewAST) {\r
+/* MR13 */         gen4("_ast%d%d = newAST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);\r
+/* MR13 */      } else {\r
+/* MR13 */         gen4("_ast%d%d = new AST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);\r
+/* MR13 */      }\r
+                               tab();\r
+                       }\r
+                       if ( GenCC && !(p->astnode == ASTexclude) )\r
+                               {_gen2("_ast%d%d->", BlkLevel-1, p->elnum);}\r
+                       else _gen(" ");\r
+                       if ( p->astnode==ASTchild ) {\r
+                               if ( !GenCC ) _gen("zz");\r
+                               _gen("subchild(_root, &_sibling, &_tail);");\r
+                       }\r
+                       else if ( p->astnode==ASTroot ) {\r
+                               if ( !GenCC ) _gen("zz");\r
+                               _gen("subroot(_root, &_sibling, &_tail);");\r
+                       }\r
+                       if ( GenCC && !(p->astnode == ASTexclude) ) {\r
+                               _gen("\n");\r
+                               tab();\r
+                       }\r
+               }\r
+               else if ( !GenCC ) {\r
+                       if (! pushedCmodeAST) _gen(" zzastDPush;");\r
+               }\r
+               if ( FoundGuessBlk &&\r
+                               (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) )\r
+                       {gen("}\n"); tab();}\r
+       }\r
+\r
+       /* Handle element labels now */\r
+       if ( p->el_label!=NULL )\r
+       {\r
+        int     done_NON_GUESSMODE=0;\r
+\r
+               _gen("\n");\r
+\r
+/* MR10 */    /* do Attrib / Token ptr for token label used in semantic pred */\r
+/* MR10 */    /* for these cases do assign even in guess mode                */\r
+/* MR10 */\r
+/* MR10 */    if (p->label_used_in_semantic_pred) {\r
+/* MR10 */      if ( GenCC ) {\r
+/* MR10 */        if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {\r
+/* MR10 */          gen3("%s = _t%d%d;", p->el_label, BlkLevel-1, p->elnum);\r
+/* MR10 */        } else {\r
+/* MR10 */          gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label);\r
+/* MR10 */        };\r
+/* MR10 */      } else {\r
+/* MR10 */               gen1("%s = zzaCur;", p->el_label);\r
+/* MR10 */      };\r
+/* MR10 */      if (FoundGuessBlk) _gen("  /* MR10 */");\r
+/* MR10 */      _gen("\n");\r
+/* MR10 */    };\r
+\r
+               /* Do Attrib / Token ptr */\r
+\r
+/* MR10 */  if (! p->label_used_in_semantic_pred) {\r
+/* MR10 */\r
+/* MR10 */      if ( FoundGuessBlk ) {\r
+/* MR10 */        if (! done_NON_GUESSMODE) {\r
+/* MR10 */          done_NON_GUESSMODE=1;\r
+/* MR10 */          if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();}\r
+/* MR10 */          else {gen("zzNON_GUESS_MODE {\n"); tab();}\r
+/* MR10 */        };\r
+/* MR10 */      };\r
+/* MR10 */\r
+/* MR10 */      if ( GenCC ) {\r
+/* MR10 */        if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {\r
+/* MR10 */          gen3("%s = _t%d%d;\n", p->el_label, BlkLevel-1, p->elnum);\r
+/* MR10 */        } else {\r
+/* MR10 */          gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label);\r
+/* MR10 */        };\r
+/* MR10 */      } else {\r
+/* MR10 */        gen1("%s = zzaCur;\n", p->el_label);\r
+/* MR10 */      };\r
+/* MR10 */  };\r
+\r
+               /* Do AST ptr */\r
+\r
+               if (GenAST && (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST) )) /* MR27 */\r
+               {\r
+\r
+/* MR10 */      if ( FoundGuessBlk ) {\r
+/* MR10 */        if (! done_NON_GUESSMODE) {\r
+/* MR10 */          done_NON_GUESSMODE=1;\r
+/* MR10 */          if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();}\r
+/* MR10 */          else {gen("zzNON_GUESS_MODE {\n"); tab();}\r
+/* MR10 */        };\r
+/* MR10 */      };\r
+\r
+                       if ( GenCC ) {\r
+                               gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum);\r
+                       }\r
+                       else {gen1("%s_ast = zzastCur;\n", p->el_label);}\r
+               }\r
+\r
+/* MR10 */  if (done_NON_GUESSMODE) {\r
+/* MR10 */    gen("}\n"); tab();\r
+/* MR10 */  };\r
+\r
+       }\r
+\r
+       /* Handle any actions immediately following action */\r
+       if ( a != NULL )  /* MR10 */ /* MR11 */\r
+    {\r
+       /* delay next token fetch until after action */\r
+               _gen("\n");\r
+               if ( a->is_predicate)\r
+               {\r
+#if 0\r
+/* Disabled in MR30 ************************************************************\r
+   And moved into genAction\r
+   *****************************************************************************\r
+*/\r
\r
+           gen("if (!(");\r
+\r
+                       /* make sure that '#line n' is on front of line */  /* MR14 */\r
+                       if ( GenLineInfo && p->file != -1 ) _gen("\n");     /* MR14 */\r
+                       dumpPredAction(a,a->action, output, 0, a->file, a->line, 0);\r
+\r
+/* MR23 Change failed predicate macro to have three arguments:\r
+\r
+        macro arg 1: The stringized predicate itself\r
+        macro arg 2: 0 => no user-defined error action\r
+                     1 => user-defined error action\r
+        macro arg 3: The user-defined error action\r
+\r
+   This gives the user more control of the error action.\r
+*/\r
+                       _gen(")) \n");\r
+                       tabs++;\r
+                       gen3(" {zzfailed_pred(\"%s\",%s,{ %s } );}\n",           /* MR23 */\r
+                                       stringize(a->action),                            /* MR23 */\r
+                    (a->pred_fail == NULL ?                          /* MR23/MR27 */\r
+                               "0 /* report */" : "1 /* user action */"),   /* MR23/MR27 */\r
+                    (a->pred_fail == NULL ?                          /* MR23 */\r
+                        "0; /* no user action */" : a->pred_fail));  /* MR23 */\r
+                       tabs--;\r
+/* Disabled in MR30 ************************************************************\r
+   And moved into genAction\r
+   *****************************************************************************\r
+*/\r
+#endif\r
+               }\r
+               else    /* MR9 a regular action - not a predicate action */\r
+               {\r
+\r
+/* MR23: Search an action which is not a predicate for LT(i),\r
+         LA(i), or LATEXT(i) in order to warn novice users that\r
+         it refers to the previous matched token, not the next\r
+         one.  This is different than the case for semantic\r
+         predicates.\r
+*/\r
+                                 \r
+/* MR23 */    if (GenCC) {\r
+/* MR23 */         if (strstr(a->action, "LT(") != NULL) LTinTokenAction = 1;\r
+/* MR23 */    }\r
+/* MR23 */    else {\r
+/* MR23 */      if (strstr(a->action, "LA(") != NULL) LTinTokenAction = 1;            \r
+/* MR23 */      if (strstr(a->action, "LATEXT(") != NULL) LTinTokenAction = 1;\r
+/* MR23 */    }\r
+\r
+                       if ( FoundGuessBlk ) {\r
+                               if ( GenCC ) {gen("if ( !guessing ) {\n");}\r
+                               else gen("zzNON_GUESS_MODE {\n");\r
+                       }\r
+                       dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); /* MR21 */\r
+                       if ( FoundGuessBlk ) gen("}\n");\r
+                       a->done = 1; /* MR30 */\r
+               }\r
+/***    a->done = 1;  MR30 Moved up into then branch for true actions, but not predicates ***/\r
+               if ( !DemandLookahead ) {\r
+                       if ( GenCC ) {\r
+                               if ( FoundException && p->use_def_MT_handler ) gen("if (!_signal)");\r
+                               _gen(" consume();")\r
+                if ( FoundException && p->use_def_MT_handler )\r
+                    _gen(" _signal=NoSignal;");\r
+                _gen("\n");\r
+                       }\r
+            else\r
+            {\r
+                if ( FoundException && p->use_def_MT_handler ) _gen("if (!_signal)");\r
+                                       _gen(" zzCONSUME;\n");\r
+                if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");\r
+                _gen("\n");\r
+            }\r
+               }\r
+               else gen("\n");\r
+               if (a->done) {                  /* MR30 */\r
+                       TRANS( a->next );   /* MR30 */\r
+               }                                               /* MR30 */\r
+               else {                                  /* MR30 */\r
+                       TRANS( p->next );       /* MR30 */\r
+               }                                               /* MR30 */\r
+       }\r
+       else\r
+       {\r
+        if ( !DemandLookahead ) {\r
+                       if ( GenCC ) {\r
+                               if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");\r
+                               _gen(" consume();")\r
+                               if (FoundException&&p->use_def_MT_handler) _gen(" _signal=NoSignal;");\r
+                               _gen("\n");\r
+                       }\r
+                       else {\r
+                               if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");\r
+                               _gen(" zzCONSUME;");\r
+                               if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");\r
+                               _gen("\n");\r
+                       }\r
+               }\r
+               else _gen("\n");\r
+               TRANS(p->next);\r
+       }\r
+}\r
+\r
+/*  MR21\r
+ *\r
+ *  There was a bug in the code generation for {...} which causes it\r
+ *  to omit the optional tokens from the error messages.  The easiest\r
+ *  way to fix this was to make the opt block look like a sub block:\r
+ *\r
+ *          { a | b | c }\r
+ *\r
+ *  becomes (internally):\r
+ *\r
+ *          ( a | b | c | )\r
+ *\r
+ *  The code for genOptBlk is now identical to genSubBlk except for\r
+ *  cosmetic changes.\r
+ */\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genOptBlk( Junction *q )\r
+#else\r
+genOptBlk( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       int max_k;\r
+       set f;\r
+       int need_right_curly;\r
+       set savetkref;\r
+       int lastAltEmpty;                       /* MR23 */\r
+       savetkref = tokensRefdInBlock;\r
+       require(q->ntype == nJunction,  "genOptBlk: not junction");\r
+       require(q->jtype == aOptBlk,    "genOptBlk: not opt block");\r
+\r
+    OutLineInfo(output,q->line,FileStr[q->file]);\r
+       BLOCK_Preamble(q);\r
+       BlkLevel++;\r
+    BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */\r
+       f = genBlk(q, aOptBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);\r
+/* MR23\r
+   Bypass error clause generation when exceptions are used in {...} block \r
+   See multi-line note in genBlk near call to isEmptyAlt.\r
+*/\r
+       if (! FoundException) {\r
+           if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}\r
+       }\r
+       else {\r
+               gen("/* MR23 skip error clause for {...} when exceptions in use */\n");\r
+       }\r
+       { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }\r
+       freeBlkFsets(q);\r
+       --BlkLevel;\r
+       BLOCK_Tail();\r
+\r
+       if ( q->guess )\r
+       {\r
+               gen("zzGUESS_DONE\n");\r
+       }\r
+\r
+       /* must duplicate if (alpha)?; one guesses (validates), the\r
+        * second pass matches */\r
+       if ( q->guess && analysis_point(q)==q )\r
+       {\r
+        OutLineInfo(output,q->line,FileStr[q->file]);\r
+               BLOCK_Preamble(q);\r
+               BlkLevel++;\r
+               f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);\r
+               if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}\r
+               { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }\r
+               freeBlkFsets(q);\r
+               --BlkLevel;\r
+               BLOCK_Tail();\r
+       }\r
+\r
+       tokensRefdInBlock = savetkref;\r
+       if (q->end->p1 != NULL) TRANS(q->end->p1);\r
+}\r
+\r
+/*\r
+ * Generate code for a loop blk of form:\r
+ *\r
+ *                              |---|\r
+ *                              v   |\r
+ *                        --o-G-o-->o--\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genLoopBlk( Junction *begin, Junction *q, Junction *start, int max_k )\r
+#else\r
+genLoopBlk( begin, q, start, max_k )\r
+Junction *begin;\r
+Junction *q;\r
+Junction *start;       /* where to start generating code from */\r
+int max_k;\r
+#endif\r
+{\r
+       set         f;\r
+       int         need_right_curly;\r
+       set         savetkref;\r
+    Junction    *guessBlock;    /* MR10 */\r
+    int         singleAlt;      /* MR10 */\r
+       int                     lastAltEmpty;   /* MR23 */\r
+\r
+       savetkref = tokensRefdInBlock;\r
+       require(q->ntype == nJunction,  "genLoopBlk: not junction");\r
+       require(q->jtype == aLoopBlk,   "genLoopBlk: not loop block");\r
+\r
+       if ( q->visited ) return;\r
+       q->visited = TRUE;\r
+\r
+    /* first_item_is_guess_block doesn't care what kind of node it is */\r
+\r
+    guessBlock=first_item_is_guess_block( (Junction *) q->p1);  /* MR10 */\r
+    singleAlt=q->p2==NULL;                                      /* MR10 */\r
+\r
+       if (singleAlt && !guessBlock)       /* MR10 */ /* only one alternative? */\r
+       {\r
+               if ( DemandLookahead ) {\r
+                       if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}\r
+                       else gen1("look(%d);\n", max_k);\r
+               }\r
+               gen("while ( ");\r
+               if ( begin!=NULL ) genExpr(begin);\r
+               else genExpr(q);\r
+               /* if no predicates have been hoisted for this single alt (..)*\r
+                * do so now\r
+                */\r
+        require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");\r
+               if ( ParseWithPredicates && begin->predicate==NULL )\r
+               {\r
+                       Predicate *a = MR_find_predicates_and_supp((Node *)q->p1);\r
+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");\r
+\r
+                       if ( a!=NULL )\r
+                       {\r
+                               _gen("&&");\r
+                               a=genPredTreeMain(a, (Node *)q);    /* MR10 */\r
+                       }\r
+/* MR10 */  if (MRhoisting) {\r
+/* MR10 */    predicate_free(a);\r
+/* MR10 */  };\r
+               }\r
+               _gen(" ) {\n");\r
+               tabs++;\r
+               TRANS(q->p1);\r
+               if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);\r
+               if ( DemandLookahead ) {\r
+                       if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}\r
+                       else gen1("look(%d);\n", max_k);\r
+               }\r
+               --tabs;\r
+               gen("}\n");\r
+               freeBlkFsets(q);\r
+               q->visited = FALSE;\r
+               tokensRefdInBlock = savetkref;\r
+               return;\r
+       }\r
+       gen("for (;;) {\n");        /* MR20 G. Hobbelt */\r
+       tabs++;\r
+/* MR6                                                                                 */\r
+/* MR6            "begin" can never be null when called from genLoopBegin      */\r
+/* MR6     because q==(Junction *)begin->p1 and we know q is valid     */\r
+/* MR6                                                                                         */\r
+/* MR6    from genLoopBegin:                                                           */\r
+/* MR6                                                                                             */\r
+/* MR6          if ( LL_k>1 && !set_nil(q->fset[2]) )                          */\r
+/* MR6            genLoopBlk( q, (Junction *)q->p1, q, max_k );            */\r
+/* MR6         else genLoopBlk( q, (Junction *)q->p1, NULL, max_k );   */\r
+/* MR6                                                                                         */\r
+       if ( begin!=NULL )\r
+       {\r
+               if ( DemandLookahead )\r
+               {\r
+                       if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}\r
+                       else gen1("look(%d);\n", max_k);\r
+               }\r
+               /* The bypass arc of the (...)* predicts what to do when you fail, but\r
+                * ONLY after having tested the loop start expression.  To avoid this,\r
+                * we simply break out of the (...)* loop when we find something that\r
+                * is not in the prediction of the loop (all alts thereof).\r
+                */\r
+               gen("if ( !(");\r
+\r
+/***   TJP says: It used to use the prediction expression for the bypass arc\r
+       of the (...)*.  HOWEVER, if a non LL^1(k) decision was found, this\r
+       thing would miss the ftree stored in the aLoopBegin node and generate\r
+       an LL^1(k) decision anyway.\r
+\r
+ ***           genExpr((Junction *)begin->p2);\r
+ ***/\r
+\r
+            genExpr((Junction *)begin);\r
+            _gen(")) break;\n");\r
+\r
+       }\r
+\r
+       /* generate code for terminating loop (this is optional branch) */\r
+\r
+       f = genBlk(q, aLoopBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);\r
+       set_free(f);\r
+       freeBlkFsets(q);\r
+\r
+       /* generate code for terminating loop (this is optional branch) */\r
+\r
+/* MR6                                                                                                     */\r
+/* MR6  30-May-97 Bug reported by Manuel Ornato                                            */\r
+/* MR6            A definite bug involving the exit from a loop block   */\r
+/* MR6                   In 1.23 and later versions (including 1.33) Instead       */\r
+/* MR6              exiting the block and reporting a syntax error the  */\r
+/* MR6             code loops forever.                                                 */\r
+/* MR6           Looking at 1.20 which generates proper code it is not */\r
+/* MR6             clear which of two changes should be undone.            */\r
+/* MR6           This is my best guess.                                    */\r
+/* MR6           From earlier MR6 note we know that begin can never be     */\r
+/* MR6             null when genLoopBlk called from genLoopBegin           */\r
+/* MR6 */\r
+/* MR6 */ if ( begin==NULL) {\r
+/* MR6 */   /* code for exiting loop "for sure" */\r
+/* MR6 */   gen("/* Suppressed by MR6 */ /*** else break; ***/\n");\r
+/* MR6 */ };\r
+\r
+/* MR10 */if (singleAlt && guessBlock) {\r
+/* MR10 */  tabs--;\r
+/* MR6 */   gen("} else break; /* MR6 code for exiting loop \"for sure\" */\n");\r
+/* MR10 */  need_right_curly--;\r
+/* MR10 */ } else {\r
+/* MR6 */   gen("else break; /* MR6 code for exiting loop \"for sure\" */\n");\r
+/* MR10 */ };\r
+\r
+       { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }\r
+       if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);\r
+       --tabs;\r
+       gen("}\n");\r
+       q->visited = FALSE;\r
+       tokensRefdInBlock = savetkref;\r
+}\r
+\r
+/*\r
+ * Generate code for a loop blk of form:\r
+ *\r
+ *                                      |---|\r
+ *                                          v   |\r
+ *                        --o-->o-->o-G-o-->o--\r
+ *                   |           ^\r
+ *                   v           |\r
+ *                                      o-----------o\r
+ *\r
+ * q->end points to the last node (far right) in the blk.\r
+ *\r
+ * Note that q->end->jtype must be 'EndBlk'.\r
+ *\r
+ * Generate code roughly of the following form:\r
+ *\r
+ *     do {\r
+ *             ... code for alternatives ...\r
+ *  } while ( First Set of aLoopBlk );\r
+ *\r
+ *     OR if > 1 alternative\r
+ *\r
+ *     do {\r
+ *             ... code for alternatives ...\r
+ *             else break;\r
+ *  } while ( 1 );\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genLoopBegin( Junction *q )\r
+#else\r
+genLoopBegin( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       set f;\r
+       int i;\r
+       int max_k;\r
+       set savetkref;\r
+       savetkref = tokensRefdInBlock;\r
+       require(q!=NULL,                                "genLoopBegin: invalid node and/or rule");\r
+       require(q->ntype == nJunction,  "genLoopBegin: not junction");\r
+       require(q->jtype == aLoopBegin, "genLoopBegin: not loop block");\r
+       require(q->p2!=NULL,                    "genLoopBegin: invalid Loop Graph");\r
+\r
+    OutLineInfo(output,q->line,FileStr[q->file]);\r
+\r
+       BLOCK_Preamble(q);\r
+       BlkLevel++;\r
+    BlockPreambleOption(q,q->pFirstSetSymbol);       /* MR21 */\r
+       f = First(q, 1, aLoopBegin, &max_k);\r
+       /* If not simple LL(1), must specify to start at LoopBegin, not LoopBlk */\r
+       if ( LL_k>1 && !set_nil(q->fset[2]) )\r
+               genLoopBlk( q, (Junction *)q->p1, q, max_k );\r
+       else genLoopBlk( q, (Junction *)q->p1, NULL, max_k );\r
+\r
+       for (i=1; i<=CLL_k; i++) set_free(q->fset[i]);\r
+       for (i=1; i<=CLL_k; i++) set_free(((Junction *)q->p2)->fset[i]);\r
+       --BlkLevel;\r
+       BLOCK_Tail();\r
+       set_free(f);\r
+       tokensRefdInBlock = savetkref;\r
+/* MR21 */     if (MR_BlkErr) {\r
+/* MR21 */             set f, fArray[2];\r
+/* MR21 */             f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ );\r
+/* MR21 */      fArray[0]= empty;\r
+/* MR21 */             fArray[1]= set_dup(f);\r
+/* MR21 */      gen("if (");\r
+/* MR21 */      genExprSets(fArray,1);  /* note: destroys set arguments */\r
+/* MR21 */      _gen(") { /* MR21 option -mrblksynerr */\n");\r
+/* MR21 */      tabs++;\r
+/* MR21 */      tab();\r
+/* MR21 */      _gen("/* nothing */ }\n");\r
+/* MR21 */      tab();\r
+/* MR21 */      makeErrorClause(q,f,1,0 /* use plus block bypass ? */ );  /* frees set */\r
+/* MR21 */      tabs--;\r
+/* MR21 */     };\r
+       if (q->end->p1 != NULL) TRANS(q->end->p1);\r
+}\r
+\r
+/*\r
+ * Generate code for a loop blk of form:\r
+ *\r
+ *                                      |---|\r
+ *                                      v   |\r
+ *                            --o-G-o-->o--\r
+ *\r
+ * q->end points to the last node (far right) in the blk.\r
+ * Note that q->end->jtype must be 'EndBlk'.\r
+ *\r
+ * Generate code roughly of the following form:\r
+ *\r
+ *     do {\r
+ *             ... code for alternatives ...\r
+ *  } while ( First Set of aPlusBlk );\r
+ *\r
+ *     OR if > 1 alternative\r
+ *\r
+ *     do {\r
+ *             ... code for alternatives ...\r
+ *             else if not 1st time through, break;\r
+ *  } while ( 1 );\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genPlusBlk( Junction *q )\r
+#else\r
+genPlusBlk( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       int         max_k;\r
+       set         f;\r
+       int         need_right_curly;\r
+       int                     lastAltEmpty;   /* MR23 */\r
+       set         savetkref;\r
+    Junction    *guessBlock;    /* MR10 */\r
+    int         singleAlt;      /* MR10 */\r
+\r
+       savetkref = tokensRefdInBlock;\r
+       require(q!=NULL,                                "genPlusBlk: invalid node and/or rule");\r
+       require(q->ntype == nJunction,  "genPlusBlk: not junction");\r
+       require(q->jtype == aPlusBlk,   "genPlusBlk: not Plus block");\r
+       require(q->p2 != NULL,                  "genPlusBlk: not a valid Plus block");\r
+\r
+       if ( q->visited ) return;\r
+       q->visited = TRUE;\r
+    OutLineInfo(output,q->line,FileStr[q->file]);\r
+       BLOCK_Preamble(q);\r
+       BlkLevel++;\r
+\r
+    BlockPreambleOption((Junction *)q, q->pFirstSetSymbol);       /* MR21 */\r
+    \r
+    /* first_item_is_guess_block  doesn't care what kind of node it is */\r
+\r
+    guessBlock=first_item_is_guess_block( (Junction *)q->p1);   /* MR10 */\r
+\r
+       /* if the ignore flag is set on the 2nd alt and that alt is empty,\r
+        * then it is the implied optional alternative that we added for (...)+\r
+        * and, hence, only 1 alt.\r
+        */\r
+\r
+/* MR10  Reported by Pulkkinen Esa (esap@cs.tut.fi)\r
+ *       Outer code for guess blocks ignored when there is only one alt\r
+ *         for a (...)+ block.\r
+ *       Force use of regular code rather than "optimized" code for that case\r
+ */\r
+\r
+    singleAlt=( ( (Junction *) q->p2)->p2 == NULL) &&\r
+                 ( ( (Junction *) q->p2)->ignore );                    /* only one alternative? */\r
+\r
+    if (singleAlt && !guessBlock)   /* MR10 */\r
+       {\r
+\r
+               Predicate *a=NULL;\r
+               /* if the only alt has a semantic predicate, hoist it; must test before\r
+                * entering loop.\r
+                */\r
+               if ( ParseWithPredicates )\r
+               {\r
+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");\r
+                       a = MR_find_predicates_and_supp((Node *)q);\r
+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");\r
+\r
+                       if ( a!=NULL ) {\r
+                               gen("if (");\r
+                               a=genPredTreeMain(a, (Node *)q);    /* MR10 */\r
+                               _gen(") {\n");\r
+                       }\r
+               }\r
+               gen("do {\n");\r
+               tabs++;\r
+               TRANS(q->p1);\r
+               if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);\r
+               f = First(q, 1, aPlusBlk, &max_k);\r
+               if ( DemandLookahead ) {\r
+                       if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}\r
+                       else gen1("look(%d);\n", max_k);\r
+               }\r
+               --tabs;\r
+               gen("} while ( ");\r
+               if ( q->parm!=NULL && q->predparm ) _gen1("(%s) && ", q->parm);\r
+               genExpr(q);\r
+               if ( ParseWithPredicates && a!=NULL )\r
+               {\r
+            if (! MR_comparePredicates(q->predicate,a)) {\r
+                       _gen("&&");\r
+                       a=genPredTreeMain(a, (Node *)q);    /* MR10 */\r
+            };\r
+               }\r
+               _gen(" );\n");\r
+               if ( ParseWithPredicates && a!=NULL ) gen("}\n");\r
+               --BlkLevel;\r
+               BLOCK_Tail();\r
+               q->visited = FALSE;\r
+               freeBlkFsets(q);\r
+               set_free(f);\r
+               tokensRefdInBlock = savetkref;\r
+/* MR21 */     if (MR_BlkErr) {\r
+/* MR21 */             set f, fArray[2];\r
+/* MR21 */             f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ );\r
+/* MR21 */      fArray[0]= empty;\r
+/* MR21 */             fArray[1]= set_dup(f);\r
+/* MR21 */      gen("if (");\r
+/* MR21 */      genExprSets(fArray,1);  /* note: destroys set arguments */\r
+/* MR21 */      _gen(") { /* MR21 option -mrblksynerr */\n");\r
+/* MR21 */      tabs++;\r
+/* MR21 */      tab();\r
+/* MR21 */      _gen("/* nothing */ }\n");\r
+/* MR21 */      tab();\r
+/* MR21 */      makeErrorClause(q,f,1,1 /* use plus block bypass ? */ );  /* frees set */\r
+/* MR21 */      tabs--;\r
+/* MR21 */     };\r
+               if (q->end->p1 != NULL) TRANS(q->end->p1);\r
+/* MR10 */  if (MRhoisting) {\r
+/* MR10 */    predicate_free(a);\r
+/* MR10 */  };\r
+               return;\r
+       }\r
+       gen("do {\n");\r
+       tabs++;\r
+       f = genBlk(q, aPlusBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);\r
+/* MR6                                                                                         */\r
+/* MR6 Sinan Karasu    (sinan@tardis.ds.boeing.com)                    */\r
+/* MR6    Failed to turn off guess mode when leaving block             */\r
+/* MR6                                                                                         */\r
+/* MR6  */ if ( has_guess_block_as_last_item(q) ) {\r
+/* MR10 */   gen("/* MR10 ()+ */ else {\n");\r
+/* MR10 */   tabs++;\r
+/* MR10 */   need_right_curly++;\r
+/* MR10 */   gen("/* MR10 ()+ */ if ( !zzrv ) zzGUESS_DONE;\n");\r
+/* MR6  */   gen("/* MR10 ()+ */ if ( zzcnt > 1 ) break;\n");\r
+/* MR10 */ } else {\r
+/* MR10 */   gen("/* MR10 ()+ */ else {\n");\r
+/* MR10 */   tabs++;\r
+/* MR10 */   need_right_curly++;\r
+/* MR10 */   gen("if ( zzcnt > 1 ) break;\n");\r
+/* MR10 */ };\r
+\r
+/* MR21 */     if (MR_BlkErr && 1 >= max_k) {\r
+/* MR21 */             set f;\r
+/* MR21 */             f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ );\r
+/* MR21 */      tabs++;\r
+/* MR21 */      tab();\r
+/* MR21 */      makeErrorClause(q,f,1,0 /* use plus block bypass ? */ );  /* frees set */\r
+/* MR21 */      tabs--;\r
+/* MR21 */     }\r
+/* MR21 */  else {\r
+                               tab();\r
+                makeErrorClause(q,f,max_k,1 /* use plus block bypass ? */);\r
+                                                                                   /* MR21 I think this generates the wrong set ? */\r
+                                            /* MR21 because it includes the plus block bypass ? */\r
+                                                                                   /* MR21 but I'm afraid to change it without additional checking */\r
+            }\r
+\r
+       { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }\r
+       freeBlkFsets(q);\r
+       gen("zzcnt++;");\r
+       if ( !GenCC ) _gen1(" zzLOOP(zztasp%d);", BlkLevel-1);\r
+       _gen("\n");\r
+       if ( DemandLookahead ) {\r
+               if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}\r
+               else gen1("look(%d);\n", max_k);\r
+       }\r
+       --tabs;\r
+       if ( q->parm!=NULL && q->predparm ) {gen1("} while (%s);\n", q->parm);}\r
+       else gen("} while ( 1 );\n");\r
+       --BlkLevel;\r
+       BLOCK_Tail();\r
+       q->visited = FALSE;\r
+       tokensRefdInBlock = savetkref;\r
+/* MR21 */     if (MR_BlkErr) {\r
+/* MR21 */             set f, fArray[2];\r
+/* MR21 */             f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ );\r
+/* MR21 */      fArray[0]= empty;\r
+/* MR21 */             fArray[1]= set_dup(f);\r
+/* MR21 */      gen("if (");\r
+/* MR21 */      genExprSets(fArray,1);  /* note: destroys set arguments */\r
+/* MR21 */      _gen(") { /* MR21 option -mrblksynerr */\n");\r
+/* MR21 */      tabs++;\r
+/* MR21 */      tab();\r
+/* MR21 */      _gen("/* nothing */ }\n");\r
+/* MR21 */      tab();\r
+/* MR21 */      makeErrorClause(q,f,1,1 /* use plus block bypass ? */ );  /* frees set */\r
+/* MR21 */      tabs--;\r
+/* MR21 */     };\r
+       if (q->end->p1 != NULL) TRANS(q->end->p1);\r
+}\r
+\r
+/*\r
+ * Generate code for a sub blk of alternatives of form:\r
+ *\r
+ *                            --o-G1--o--\r
+ *                                      |     ^\r
+ *                                      v    /|\r
+ *                              o-G2-o|\r
+ *                                      |     ^\r
+ *                                      v     |\r
+ *                                ..........\r
+ *                                      |     ^\r
+ *                                      v    /\r
+ *                              o-Gn-o\r
+ *\r
+ * q points to the 1st junction of blk (upper-left).\r
+ * q->end points to the last node (far right) in the blk.\r
+ * Note that q->end->jtype must be 'EndBlk'.\r
+ * The last node in every alt points to q->end.\r
+ *\r
+ * Generate code of the following form:\r
+ *     if ( First(G1) ) {\r
+ *             ...code for G1...\r
+ *     }\r
+ *     else if ( First(G2) ) {\r
+ *             ...code for G2...\r
+ *     }\r
+ *     ...\r
+ *     else {\r
+ *             ...code for Gn...\r
+ *     }\r
+ */\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genSubBlk( Junction *q )\r
+#else\r
+genSubBlk( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       int max_k;\r
+       set f;\r
+       int need_right_curly;\r
+       int lastAltEmpty;               /* MR23 */\r
+       set savetkref;\r
+       savetkref = tokensRefdInBlock;\r
+       require(q->ntype == nJunction,  "genSubBlk: not junction");\r
+       require(q->jtype == aSubBlk,    "genSubBlk: not subblock");\r
+\r
+    OutLineInfo(output,q->line,FileStr[q->file]);\r
+       BLOCK_Preamble(q);\r
+       BlkLevel++;\r
+    BlockPreambleOption(q,q->pFirstSetSymbol);       /* MR21 */\r
+       f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);\r
+\r
+/* MR23\r
+   Bypass error clause generation when exceptions are used in a sub block\r
+   in which the last alternative is epsilon.  Example: "(A | B | )". \r
+   See multi-line note in genBlk near call to isEmptyAlt.\r
+*/\r
+       if (FoundException && lastAltEmpty) {\r
+               gen("/* MR23 skip error clause for (...| epsilon) when exceptions in use */\n");\r
+       }\r
+       else {\r
+               if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}\r
+       }\r
+    \r
+       { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }\r
+       freeBlkFsets(q);\r
+       --BlkLevel;\r
+       BLOCK_Tail();\r
+\r
+       if ( q->guess )\r
+       {\r
+               gen("zzGUESS_DONE\n");\r
+       }\r
+\r
+       /* must duplicate if (alpha)?; one guesses (validates), the\r
+        * second pass matches */\r
+       if ( q->guess && analysis_point(q)==q )\r
+       {\r
+        OutLineInfo(output,q->line,FileStr[q->file]);\r
+               BLOCK_Preamble(q);\r
+               BlkLevel++;\r
+               f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);\r
+               if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */);}\r
+               { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }\r
+               freeBlkFsets(q);\r
+               --BlkLevel;\r
+               BLOCK_Tail();\r
+       }\r
+\r
+       tokensRefdInBlock = savetkref;\r
+       if (q->end->p1 != NULL) TRANS(q->end->p1);\r
+}\r
+\r
+static int TnodesAllocatedPrevRule=0;\r
+\r
+/*\r
+ * Generate code for a rule.\r
+ *\r
+ *             rule--> o-->o-Alternatives-o-->o\r
+ * Or,\r
+ *             rule--> o-->o-Alternative-o-->o\r
+ *\r
+ * The 1st junction is a RuleBlk.  The second can be a SubBlk or just a junction\r
+ * (one alternative--no block), the last is EndRule.\r
+ * The second to last is EndBlk if more than one alternative exists in the rule.\r
+ *\r
+ * To get to the init-action for a rule, we must bypass the RuleBlk,\r
+ * and possible SubBlk.\r
+ * Mark any init-action as generated so genBlk() does not regenerate it.\r
+ */\r
+void\r
+#ifdef __USE_PROTOS\r
+genRule( Junction *q )\r
+#else\r
+genRule( q )\r
+Junction *q;\r
+#endif\r
+{\r
+\r
+       const char * returnValueInitializer;\r
+\r
+do {    /* MR10     Change recursion into iteration         */\r
+\r
+       int max_k;\r
+       set follow, rk, f;\r
+       ActionNode *a;\r
+       RuleEntry *r;\r
+       int lastAltEmpty;               /* MR23 */\r
+       static int file = -1;\r
+       int need_right_curly;\r
+       require(q->ntype == nJunction,  "genRule: not junction");\r
+       require(q->jtype == RuleBlk,    "genRule: not rule");\r
+\r
+/* MR14 */    require (MR_BackTraceStack.count == 0,"-alpha MR_BackTraceStack.count != 0");\r
+/* MR14 */    MR_pointerStackReset(&MR_BackTraceStack);\r
+/* MR14 */    if (AlphaBetaTrace) MR_MaintainBackTrace=1;\r
+\r
+    CurRule=q->rname;                               /* MR11 */\r
+\r
+       r = (RuleEntry *) hash_get(Rname, q->rname);\r
+       if ( r == NULL ) warnNoFL("Rule hash table is screwed up beyond belief");\r
+       if ( q->file != file )          /* open new output file if need to */\r
+       {\r
+/* MR6                                                                                 */\r
+/* MR6  Simpler to debug when output goes to stdout rather than a file         */\r
+/* MR6                                                                                 */\r
+/* MR6 */      if (UseStdout) {\r
+/* MR6 */        output = stdout;\r
+/* MR6 */      } else {\r
+/* MR6 */        if ( output != NULL) fclose( output );\r
+/* MR6 */        output = fopen(OutMetaName(outname(FileStr[q->file])), "w");\r
+/* MR6 */      };\r
+               require(output != NULL, "genRule: can't open output file");\r
+\r
+#ifdef SPECIAL_FOPEN\r
+       special_fopen_actions(OutMetaName(outname(FileStr[q->file]))); /* MR1 */\r
+#endif\r
+               if ( file == -1 ) genHdr1(q->file);\r
+               else genHdr(q->file);\r
+               file = q->file;\r
+       }\r
+\r
+    if (InfoM) {\r
+      fprintf(stderr,"    rule %s\n",q->rname);\r
+      fflush(output);\r
+    };\r
+\r
+#if 0\r
+    if (strcmp(q->rname,"***debug***") == 0) {\r
+      fprintf(stderr,"***debug*** %s reached\n",q->rname);\r
+      MR_break();\r
+    };\r
+#endif\r
+\r
+       DumpFuncHeader(q,r);\r
+       tabs++;\r
+\r
+       /* MR23 \r
+          \r
+          If there is a single return value then it can be initialized in \r
+          the declaration using assignment syntax.  If there are multiple\r
+          return values then antlr creates a struct and initialization takes\r
+          place element by element for each element of the struct.  For\r
+       multiple elements the initialization is by assignment so we have\r
+       to wait until all declarations are done before emitting that code -\r
+       because of restrictions in C which don't exist in C++.\r
+\r
+       In the past (before MR23) the only kind of initialization was\r
+          the PURIFY macro which was just a memset() of 0.  Now we allow\r
+          the user to specify an initial value.  PURIFY is still used in C\r
+          mode because C does not have constructors.  However, PURIFY is\r
+          not used in C++ mode because it might overwrite information created\r
+          by elements which have their own ctor.\r
+       \r
+       */\r
+\r
+       if ( q->ret!=NULL )\r
+       {\r
+               if ( hasMultipleOperands(q->ret) )                         /* MR23 */\r
+               {\r
+\r
+            /* Emit initialization code later. */\r
+\r
+                       gen1("struct _rv%d _retv;\n",r->rulenum);\r
+               }\r
+               else\r
+               {\r
+            /* Emit initialization code now. */\r
+\r
+                       tab();\r
+                       DumpType(q->ret, output);\r
+            returnValueInitializer = getInitializer(q->ret);\r
+            if (returnValueInitializer == NULL) {                  /* MR23 */\r
+                       gen(" _retv;\n");                                   /* MR1 MR3 */\r
+            }                                                      /* MR23 */\r
+            else {                                                 /* MR23 */\r
+                gen1(" _retv = %s;\n", returnValueInitializer);    /* MR23 */\r
+            }                                                      /* MR23 */\r
+               }\r
+       }\r
+\r
+    OutLineInfo(output,q->line,FileStr[q->file]);\r
+\r
+    if (InfoM) {\r
+      fflush(output);\r
+    };\r
+\r
+       gen("zzRULE;\n");\r
+       if ( FoundException )\r
+       {\r
+               gen("int _sva=1;\n");\r
+       }\r
+       if ( GenCC && GenAST )\r
+               gen("ASTBase *_ast = NULL, *_sibling = NULL, *_tail = NULL;\n");\r
+       if ( GenCC ) genTokenPointers(q);\r
+       if ( GenCC&&GenAST ) genASTPointers(q);\r
+       if ( q->el_labels!=NULL ) genElementLabels(q->el_labels);\r
+       if ( FoundException ) gen("int _signal=NoSignal;\n");\r
+\r
+       if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel);\r
+\r
+/* MR10 */  /* move zzTRACEIN to before init action */\r
+\r
+/* MR10 */     if ( TraceGen ) {\r
+/* MR10 */             if ( GenCC ) {gen1("zzTRACEIN(\"%s\");\n", q->rname);}\r
+/* MR10 */             else gen1("zzTRACEIN((ANTLRChar *)\"%s\");\n", q->rname);\r
+/* MR10 */     }\r
+\r
+/* MR7      Moved PURIFY() to after all local variables have been declared */\r
+/* MR7      so that the generated code is valid C as well as C++           */\r
+/* MR7        Jan Mikkelsen 10-June-1997                                   */\r
+\r
+\r
+     /*\r
+       MR23    Do the PURIFY macro only for C mode.\r
+               C++ users should use constructors or initialization expressions.\r
+     */\r
+\r
+       if ( q->ret != NULL )                                            /* MR7 */\r
+       {                                                                /* MR7 */\r
+               if (hasMultipleOperands(q->ret)) {                           /* MR23 */\r
+                       if (PURIFY == TRUE) {\r
+                gen1("PCCTS_PURIFY(_retv,sizeof(struct _rv%d))\n",r->rulenum); /* MR23 */\r
+            }\r
+        }                                                            /* MR7 */\r
+               else {                                                       /* MR7 */\r
+\r
+                       /* MR23\r
+                          If there were only one return value operand and\r
+                          it had an initializer then it would have been\r
+                          initiailized in the declaration.\r
+                       */\r
+\r
+                       returnValueInitializer = getInitializer(q->ret);         /* MR23 */\r
+                       if (returnValueInitializer == NULL) {                    /* MR23 */\r
+                       if (PURIFY == TRUE) {\r
+                               gen("PCCTS_PURIFY(_retv,sizeof(");               /* MR23 */\r
+                               DumpType(q->ret, output);                        /* MR7 */\r
+                                       gen("))\n");                                     /* MR7 */\r
+                               }\r
+                       }                                                        /* MR23 */\r
+               }                                                            /* MR7 */\r
+\r
+        if (hasMultipleOperands(q->ret)) {                           /* MR23 */\r
+          DumpInitializers(output, r, q->ret);                       /* MR23 */\r
+        }\r
+\r
+       }\r
+       if ( !GenCC ) gen("zzMake0;\n");\r
+       if ( FoundException ) gen("*_retsignal = NoSignal;\n");\r
+\r
+       if ( !GenCC ) gen("{\n");\r
+\r
+       if ( has_guess_block_as_first_item((Junction *)q->p1) )\r
+       {\r
+               gen("zzGUESS_BLOCK\n");\r
+       }\r
+\r
+       /* L o o k  F o r  I n i t  A c t i o n */\r
+       if ( ((Junction *)q->p1)->jtype == aSubBlk )\r
+               a = findImmedAction( ((Junction *)q->p1)->p1 );\r
+       else\r
+               a = findImmedAction( q->p1 );   /* only one alternative in rule */\r
+       if ( a!=NULL && !a->is_predicate)\r
+       {\r
+ /* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1);\r
+                   a->done = 1;        /* ignore action. We have already handled it */\r
+       }\r
+\r
+       BlkLevel++;\r
+       q->visited = TRUE;                              /* mark RULE as visited for FIRST/FOLLOW */\r
+    BlockPreambleOption((Junction *)q->p1, NULL);   /* MR21 */\r
+       f = genBlk((Junction *)q->p1, RuleBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);\r
+       if ( q->p1 != NULL )\r
+               if ( ((Junction *)q->p1)->p2 != NULL )\r
+                       {tab(); makeErrorClause((Junction *)q->p1,f,max_k,0 /* use plus block bypass ? */);}\r
+       { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }\r
+       freeBlkFsets((Junction *)q->p1);\r
+       q->visited = FALSE;\r
+       --BlkLevel;\r
+       if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel);\r
+\r
+    genTraceOut(q);\r
+\r
+       if ( q->ret!=NULL ) gen("return _retv;\n") else gen("return;\n");\r
+       /* E r r o r  R e c o v e r y */\r
+       NewSet();\r
+       rk = empty;\r
+\r
+/* MR14 */    if (r->dontComputeErrorSet) {\r
+/* MR14 */      follow=empty;\r
+              } else {\r
+                MR_pointerStackReset(&MR_BackTraceStack);   /* MR14 */\r
+                MR_ErrorSetComputationActive=1;\r
+                REACH(q->end, 1, &rk, follow);\r
+                MR_ErrorSetComputationActive=0;\r
+                require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0");\r
+              }\r
+\r
+  FillSet( follow );\r
+       set_free( follow );\r
+\r
+  /* MR20 G. Hobbelt \r
+     Isn't it so that "fail:" is ONLY referenced when:\r
+\r
+        !FoundException || FoundGuessBlk ?\r
+\r
+     Therefore add the "if" around this piece of code generation...\r
+\r
+     Should guessing mode also use _handler label instead of "fail"\r
+     when exception handling is active? gen can automatically put \r
+     "if (guessing)" there so as to skip all kinds of user code.\r
+\r
+   */\r
+\r
+       if ( !FoundException || FoundGuessBlk )  /* MR20 G. Hobbelt */\r
+  {                                          /* MR20 G. Hobbelt */\r
+       _gen("fail:\n");\r
+       if ( !GenCC ) gen("zzEXIT(zztasp1);\n");\r
+       if ( FoundGuessBlk ) {\r
+               if ( !GenCC ) {gen("if ( zzguessing ) zzGUESS_FAIL;\n");}\r
+               else gen("if ( guessing ) zzGUESS_FAIL;\n");\r
+       }\r
+       if ( q->erraction!=NULL )\r
+               dumpAction(q->erraction, output, tabs, q->file, q->line, 1);\r
+       if ( GenCC )\r
+       {\r
+               gen1("syn(zzBadTok, %s, zzMissSet, zzMissTok, zzErrk);\n",\r
+                        r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup);\r
+       }\r
+       else\r
+       {\r
+               gen1("zzsyn(zzMissText, zzBadTok, %s, zzMissSet, zzMissTok, zzErrk, zzBadText);\n",\r
+                        r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup);\r
+       }\r
+       gen3("%sresynch(setwd%d, 0x%x);\n", GenCC?"":"zz", wordnum, 1<<setnum);\r
+\r
+       if ( q->ret!=NULL ) {\r
+      genTraceOut(q);\r
+      gen("return _retv;\n");\r
+    } else if ( q->exceptions!=NULL ) {\r
+      genTraceOut(q);\r
+      gen("return;\n");\r
+    } else if (!FoundException) {       /* MR10 */\r
+      genTraceOut(q);                   /* MR10 */\r
+    };\r
+\r
+  }                                        /* MR20 G. Hobbelt */\r
+\r
+       if ( !GenCC ) gen("}\n");\r
+\r
+       /* Gen code for exception handlers */\r
+    /* make sure each path out contains genTraceOut() */\r
+\r
+       if ( q->exceptions!=NULL )\r
+       {\r
+\r
+               gen("/* exception handlers */\n");\r
+\r
+               dumpExceptions(q->exceptions);\r
+\r
+        if ( !r->has_rule_exception )\r
+        {\r
+            _gen("_handler:\n");\r
+            gen("zzdflthandlers(_signal,_retsignal);\n");\r
+        }\r
+/*  MR20 G. Gobbelt   The label "adios" is never referenced */\r
+\r
+#if 0\r
+       _gen("_adios:\n");\r
+#endif\r
+    if ( q->ret!=NULL ) {\r
+            genTraceOut(q);\r
+            gen("return _retv;\n");\r
+        }\r
+               else {\r
+            genTraceOut(q);\r
+            gen("return;\n");\r
+        }\r
+       }\r
+       else if ( FoundException )\r
+       {\r
+      _gen("_handler:\n");\r
+      gen("zzdflthandlers(_signal,_retsignal);\n");\r
+\r
+/* MR1                                                                      */\r
+/* MR1  7-Apr-97 Fix suggested by: John Bair (jbair@iftime.com)            */\r
+/* MR1                                                                                             */\r
+\r
+         if ( q->ret != NULL) {                                                     /* MR1 */\r
+            genTraceOut(q);                                          /* MR10 */\r
+            gen("return _retv;\n");                                             /* MR1 */\r
+      } else {                                                                      /* MR1 */\r
+            genTraceOut(q);                                          /* MR10 */\r
+            gen("return;\n")    ;                                                   /* MR1 */\r
+      };                                                                                    /* MR1 */\r
+       }\r
+\r
+       tabs--;\r
+       gen("}\n");\r
+\r
+/* MR10     Tired of looking at stacks that are as deep as the number of    */\r
+/* MR10       rules.  Changes recursion to iteration.                       */\r
+\r
+    MR_releaseResourcesUsedInRule( (Node *) q );      /* MR10 */\r
+\r
+    if (InfoT) {\r
+      fprintf(output,"\n/* tnodes created for rule %s:  %d */\n",\r
+                q->rname, (TnodesAllocated-TnodesAllocatedPrevRule) );\r
+    };\r
+\r
+    TnodesAllocatedPrevRule=TnodesAllocated;\r
+\r
+    if (q->p2 == NULL) dumpAfterActions( output );\r
+    q=(Junction *)q->p2;\r
+    require(q==NULL || q->jtype==RuleBlk,"RuleBlk p2 does not point to another RuleBlk");\r
+\r
+} while (q != NULL);\r
+\r
+/**** The old code                           ****/\r
+/****  if ( q->p2 != NULL ) {TRANS(q->p2);} ****/ /* generate code for next rule too */\r
+/****  else dumpAfterActions( output );     ****/\r
+\r
+}\r
+\r
+\r
+/* This is for the function definition, not the declaration. */\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+DumpFuncHeader( Junction *q, RuleEntry *r )\r
+#else\r
+DumpFuncHeader( q, r )\r
+Junction *q;\r
+RuleEntry *r;\r
+#endif\r
+{\r
+/*                                                                                                         */\r
+/*  MR1 10-Apr-97  MR1  Simplify insertion of commas in function header     */\r
+/*                                                                                                         */\r
+       int     needComma;                                                                       /* MR1 */\r
+\r
+\r
+       /* A N S I */\r
+       _gen("\n");\r
+       if ( q->ret!=NULL )\r
+       {\r
+               if ( hasMultipleOperands(q->ret) )                            /* MR23 */\r
+               {\r
+                       if (GenCC) gen2("%s::_rv%d\n", CurrentClassName, r->rulenum)\r
+                       else gen1("struct _rv%d\n",r->rulenum);\r
+               }\r
+               else\r
+               {\r
+                       DumpType(q->ret, output);\r
+                       gen("\n");\r
+               }\r
+       }\r
+       else\r
+       {\r
+               _gen("void\n");\r
+       }\r
+/*  MR1                                                                                    */\r
+/*  MR1        10-Apr-97  133MR1       Replace __STDC__ with __USE_PROTOS              */\r
+/*  MR1                                                                                                        */\r
+       if ( !GenCC ) _gen("#ifdef __USE_PROTOS\n");                 /* MR1 */\r
+       if ( !GenCC ) gen2("%s%s(", RulePrefix, q->rname)\r
+       else gen3("%s::%s%s(", CurrentClassName, RulePrefix,q->rname);\r
+\r
+       /* If we generate C++ method names, we must hide default arguments */\r
+        /* which can appear in the parameter declaration list.             */\r
+        /* NOTICE: this is done only here, for the method definition, but  */\r
+        /*         not for the method declaration inside the class         */\r
+        /*         definition. This is exactly the behaviour defined in    */\r
+        /*         C++ standard for default paramters.                     */\r
+\r
+       DumpANSIFunctionArgDef(output,q, 0 /* emit initializers ? */);\r
+       _gen("\n");\r
+\r
+       if ( GenCC ) {\r
+      gen("{\n");\r
+      return;\r
+    }\r
+\r
+       /* K & R */\r
+       gen("#else\n");\r
+       gen2("%s%s(", RulePrefix, q->rname);\r
+       needComma=0;                                                                         /* MR1 */\r
+       if ( GenAST )                                                                        /* MR1 */\r
+       {                                                                                            /* MR1 */\r
+               _gen("_root");                                                               /* MR1 */\r
+               needComma=1;                                                                 /* MR1 */\r
+       }                                                                                            /* MR1 */\r
+       if ( FoundException )                                                            /* MR1 */\r
+       {                                                                                            /* MR1 */\r
+               if (needComma) {_gen(",");needComma=0;};                         /* MR1 */\r
+               _gen("_retsignal");                                                          /* MR1 */\r
+               needComma=1;                                                                 /* MR1 */\r
+       }                                                                                            /* MR1 */\r
+/* MR5 Change below by Jan Mikkelsen (janm@zeta.org.au) 26-May-97      MR5 */\r
+       DumpListOfParmNames( q->pdecl, output, needComma );                  /* MR5 */\r
+       gen(")\n");\r
+       if ( GenAST ) gen("AST **_root;\n");\r
+       if ( FoundException ) gen("int *_retsignal;\n");\r
+       DumpOldStyleParms( q->pdecl, output );\r
+       gen("#endif\n");\r
+    gen("{\n");\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInitializer)\r
+#else\r
+DumpANSIFunctionArgDef(f,q,bInitializer)\r
+FILE *f;\r
+Junction *q;\r
+int bInitializer;\r
+#endif\r
+{\r
+       if ( GenAST )\r
+       {\r
+               if ( GenCC ) {fprintf(f,"ASTBase **_root");}\r
+               else fprintf(f,"AST**_root");\r
+               if ( !FoundException && q->pdecl!=NULL ) fprintf(f,",");\r
+       }\r
+       if ( FoundException )\r
+       {\r
+               if ( GenAST ) fprintf(f,",");\r
+               fprintf(f,"int *_retsignal");\r
+               if ( q->pdecl!=NULL ) {\r
+            fprintf(f,",");\r
+        }\r
+       }\r
+       if ( q->pdecl!=NULL ) {\r
+        DumpFormals(f, q->pdecl, bInitializer);     /* MR23 */\r
+    }\r
+       else {\r
+        if ( !GenAST && !FoundException ) {\r
+            fprintf(f,"void");\r
+        }\r
+    }\r
+       fprintf(f,")");\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genJunction( Junction *q )\r
+#else\r
+genJunction( q )\r
+Junction *q;\r
+#endif\r
+{\r
+       require(q->ntype == nJunction,  "genJunction: not junction");\r
+       require(q->jtype == Generic,    "genJunction: not generic junction");\r
+\r
+       if ( q->p1 != NULL ) TRANS(q->p1);\r
+       if ( q->p2 != NULL ) TRANS(q->p2);\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genEndBlk( Junction *q )\r
+#else\r
+genEndBlk( q )\r
+Junction *q;\r
+#endif\r
+{\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genEndRule( Junction *q )\r
+#else\r
+genEndRule( q )\r
+Junction *q;\r
+#endif\r
+{\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genHdr( int file )\r
+#else\r
+genHdr( file )\r
+int file;\r
+#endif\r
+{\r
+    int     i;\r
+\r
+       _gen("/*\n");\r
+       _gen(" * A n t l r  T r a n s l a t i o n  H e a d e r\n");\r
+       _gen(" *\n");\r
+       _gen(" * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");\r
+       _gen(" * Purdue University Electrical Engineering\n");\r
+       _gen(" * With AHPCRC, University of Minnesota\n");\r
+       _gen1(" * ANTLR Version %s\n", Version);\r
+       _gen(" *\n");\r
+/* MR10 */    _gen(" *  ");\r
+/* MR10 */    for (i=0 ; i < Save_argc ; i++) {\r
+/* MR10 */      _gen(" ");\r
+/* MR10 */      _gen(Save_argv[i]);\r
+/* MR10 */    };\r
+       _gen("\n");\r
+       _gen(" *\n");\r
+    _gen(" */\n\n");\r
+       if (FirstAction != NULL ) dumpAction( FirstAction, output, 0, -1, 0, 1);    /* MR11 MR15b */\r
+       _gen1("#define ANTLR_VERSION    %s\n", VersionDef);\r
+       _gen("#include \"pcctscfg.h\"\n");\r
+       _gen("#include \"pccts_stdio.h\"\n");\r
+       if ( strcmp(ParserName, DefaultParserName)!=0 )\r
+               _gen2("#define %s %s\n", DefaultParserName, ParserName);\r
+       if ( strcmp(ParserName, DefaultParserName)!=0 )\r
+               {_gen1("#include \"%s\"\n", RemapFileName);}\r
+    OutLineInfo(output,1,FileStr[file]);\r
+       if ( GenCC ) {\r
+               if ( UserTokenDefsFile != NULL )\r
+                       fprintf(output, "#include %s\n", UserTokenDefsFile);\r
+               else\r
+                       fprintf(output, "#include \"%s\"\n", DefFileName);\r
+       }\r
+\r
+       if ( HdrAction != NULL ) dumpAction( HdrAction, output, 0, -1, 0, 1);\r
+       if ( !GenCC && FoundGuessBlk )\r
+       {\r
+               _gen("#define ZZCAN_GUESS\n");\r
+               _gen("#include \"pccts_setjmp.h\"\n");  /* MR15 K.J. Cummings (cummings@peritus.com) */\r
+       }\r
+       if ( FoundException )\r
+       {\r
+               _gen("#define EXCEPTION_HANDLING\n");\r
+               _gen1("#define NUM_SIGNALS %d\n", NumSignals);\r
+       }\r
+       if ( !GenCC && OutputLL_k > 1 ) _gen1("#define LL_K %d\n", OutputLL_k);\r
+       if ( GenAST&&!GenCC ) _gen("#define GENAST\n\n");\r
+       if ( GenAST ) {\r
+               if ( GenCC ) {_gen1("#include \"%s\"\n\n", ASTBASE_H);}\r
+               else _gen("#include \"ast.h\"\n\n");\r
+       }\r
+       if ( !GenCC && DemandLookahead ) _gen("#define DEMAND_LOOK\n\n");\r
+#ifdef DUM\r
+       if ( !GenCC && LexGen ) {\r
+               _gen1("#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));\r
+       }\r
+#endif\r
+       /* ###WARNING: This will have to change when SetWordSize changes */\r
+       if ( !GenCC ) _gen1("#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));\r
+    if (TraceGen) {\r
+      _gen("#ifndef zzTRACE_RULES\n");  /* MR20 */\r
+      _gen("#define zzTRACE_RULES\n");  /* MR20 */\r
+      _gen("#endif\n");                 /* MR22 */\r
+    };\r
+       if ( !GenCC ) {_gen("#include \"antlr.h\"\n");}\r
+       else {\r
+               _gen1("#include \"%s\"\n", APARSER_H);\r
+               _gen1("#include \"%s.h\"\n", CurrentClassName);\r
+       }\r
+       if ( !GenCC ) {\r
+               if ( UserDefdTokens )\r
+                       {_gen1("#include %s\n", UserTokenDefsFile);}\r
+               /* still need this one as it has the func prototypes */\r
+               _gen1("#include \"%s\"\n", DefFileName);\r
+       }\r
+       /* still need this one as it defines the DLG interface */\r
+       if ( !GenCC ) _gen("#include \"dlgdef.h\"\n");\r
+       if ( LexGen && GenCC ) _gen1("#include \"%s\"\n", DLEXERBASE_H);\r
+       if ( GenCC ) _gen1("#include \"%s\"\n", ATOKPTR_H);\r
+       if ( !GenCC && LexGen ) _gen1("#include \"%s\"\n", ModeFileName);\r
+\r
+/* MR10  Ofer Ben-Ami (gremlin@cs.huji.ac.il)           */\r
+/* MR10    Finally, a definition of the Purify macro    */\r
+\r
+    if (PURIFY == TRUE) {                                                   /* MR23 */\r
+        _gen("\n/* MR23 In order to remove calls to PURIFY use the antlr"); /* MR23 */\r
+        _gen(" -nopurify option */\n\n");                                   /* MR23 */\r
+       _gen("#ifndef PCCTS_PURIFY\n");\r
+        _gen("#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\\0',(s));\n");\r
+        _gen("#endif\n\n");\r
+    }                                                                       /* MR23 */\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genHdr1( int file )\r
+#else\r
+genHdr1( file )\r
+int file;\r
+#endif\r
+{\r
+       ListNode *p;\r
+\r
+       genHdr(file);\r
+       if ( GenAST )\r
+       {\r
+               if ( !GenCC ) {\r
+                       _gen("#include \"ast.c\"\n");\r
+                       _gen("zzASTgvars\n\n");\r
+               }\r
+       }\r
+       if ( !GenCC ) _gen("ANTLR_INFO\n");\r
+       if ( BeforeActions != NULL )\r
+       {\r
+               for (p = BeforeActions->next; p!=NULL; p=p->next)\r
+               {\r
+                       UserAction *ua = (UserAction *)p->elem;\r
+                       dumpAction( ua->action, output, 0, ua->file, ua->line, 1);\r
+               }\r
+       }\r
+\r
+       if ( !FoundException ) return;\r
+\r
+       if ( GenCC )\r
+       {\r
+               _gen1("\nvoid %s::\n", CurrentClassName);\r
+               _gen("zzdflthandlers( int _signal, int *_retsignal )\n");\r
+               _gen("{\n");\r
+       }\r
+       else\r
+       {\r
+               _gen("\nvoid\n");\r
+/*  MR1                                                                                        */\r
+/*  MR1        10-Apr-97  133MR1       Replace __STDC__ with __USE_PROTOS              */\r
+/*  MR1                                                                            */\r
+           _gen("#ifdef __USE_PROTOS\n");                               /* MR1 */\r
+               _gen("zzdflthandlers( int _signal, int *_retsignal )\n");\r
+               _gen("#else\n");\r
+               _gen("zzdflthandlers( _signal, _retsignal )\n");\r
+               _gen("int _signal;\n");\r
+               _gen("int *_retsignal;\n");\r
+               _gen("#endif\n");\r
+               _gen("{\n");\r
+       }\r
+       tabs++;\r
+       if ( DefaultExGroup!=NULL )\r
+       {\r
+               dumpException(DefaultExGroup, 1);\r
+               if ( !hasDefaultException(DefaultExGroup) )\r
+               {\r
+                       gen("default :\n");\r
+                       tabs++;\r
+                       gen("*_retsignal = _signal;\n");\r
+                       tabs--;\r
+                       gen("}\n");\r
+               }\r
+       }\r
+       else {\r
+               gen("*_retsignal = _signal;\n");\r
+       }\r
+\r
+       tabs--;\r
+       _gen("}\n\n");\r
+}\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+genStdPCCTSIncludeFile( FILE *f,char *gate )    /* MR10 */\r
+#else\r
+genStdPCCTSIncludeFile( f , gate)               /* MR10 */\r
+FILE *f;\r
+char * gate;                                    /* MR10 */\r
+#endif\r
+{\r
+/* MR10 Ramanathan Santhanam (ps@kumaran.com)           */\r
+/* MR10 Same preprocessor symbol use to gate stdpccts.h */\r
+/* MR10   even when two grammars are in use.            */\r
+/* MR10 Derive gate symbol from -fh filename            */\r
+\r
+    if (gate == NULL) {\r
+      fprintf(f,"#ifndef STDPCCTS_H\n");          /* MR10 */\r
+      fprintf(f,"#define STDPCCTS_H\n");          /* MR10 */\r
+    } else {\r
+      fprintf(f,"#ifndef STDPCCTS_%s_H\n",gate);  /* MR10 */\r
+      fprintf(f,"#define STDPCCTS_%s_H\n",gate);  /* MR10 */\r
+    };\r
+       fprintf(f,"/*\n");\r
+    if (gate == NULL) {\r
+         fprintf(f," * %s -- P C C T S  I n c l u d e\n", stdpccts);\r
+    } else {\r
+         fprintf(f," * Standard PCCTS include file with -fh %s -- P C C T S  I n c l u d e\n", stdpccts);\r
+    }\r
+       fprintf(f," *\n");\r
+       fprintf(f," * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");\r
+       fprintf(f," * Purdue University Electrical Engineering\n");\r
+       fprintf(f," * With AHPCRC, University of Minnesota\n");\r
+       fprintf(f," * ANTLR Version %s\n", Version);\r
+       fprintf(f," */\n\n");\r
+\r
+    fprintf(f,"#ifndef ANTLR_VERSION\n");\r
+       fprintf(f,"#define ANTLR_VERSION        %s\n", VersionDef);\r
+    fprintf(f,"#endif\n\n");\r
+\r
+    if (FirstAction != NULL ) dumpAction(FirstAction, f, 0, -1, 0, 1);  /* MR11 */\r
+\r
+       fprintf(f,"#include \"pcctscfg.h\"\n");\r
+       fprintf(f,"#include \"pccts_stdio.h\"\n");\r
+       if ( GenCC )\r
+       {\r
+               if ( UserDefdTokens )\r
+                       fprintf(f, "#include %s\n", UserTokenDefsFile);\r
+               else {\r
+                       fprintf(f, "#include \"%s\"\n", DefFileName);\r
+               }\r
+\r
+               fprintf(f, "#include \"%s\"\n", ATOKEN_H);\r
+\r
+               if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);\r
+\r
+               fprintf(f, "#include \"%s\"\n", ATOKENBUFFER_H);\r
+\r
+               if ( OutputLL_k > 1 ) fprintf(f,"static const unsigned LL_K=%d;\n", OutputLL_k);\r
+               if ( GenAST ) {\r
+                       fprintf(f, "#include \"%s\"\n", ASTBASE_H);\r
+               }\r
+\r
+        if (TraceGen) {\r
+          fprintf(f,"#ifndef zzTRACE_RULES\n");  /* MR20 */\r
+          fprintf(f,"#define zzTRACE_RULES\n");  /* MR20 */\r
+          fprintf(f,"#endif\n");                 /* MR22 */\r
+        };\r
+\r
+               fprintf(f,"#include \"%s\"\n", APARSER_H);\r
+               fprintf(f,"#include \"%s.h\"\n", CurrentClassName);\r
+               if ( LexGen ) fprintf(f,"#include \"%s\"\n", DLEXERBASE_H);\r
+               fprintf(f, "#endif\n");\r
+               return;\r
+       }\r
+\r
+       if ( strcmp(ParserName, DefaultParserName)!=0 )\r
+               fprintf(f, "#define %s %s\n", DefaultParserName, ParserName);\r
+       if ( strcmp(ParserName, DefaultParserName)!=0 )\r
+               fprintf(f, "#include \"%s\"\n", RemapFileName);\r
+       if ( UserTokenDefsFile != NULL )\r
+          fprintf(f, "#include %s\n", UserTokenDefsFile);\r
+       if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);\r
+       if ( FoundGuessBlk )\r
+       {\r
+               fprintf(f,"#define ZZCAN_GUESS\n");\r
+               fprintf(f,"#include \"pccts_setjmp.h\"\n");\r
+       }\r
+    if (TraceGen) {\r
+      fprintf(f,"#ifndef zzTRACE_RULES\n");  /* MR20 */\r
+      fprintf(f,"#define zzTRACE_RULES\n");  /* MR20 */\r
+      fprintf(f,"#endif\n");                 /* MR22 */\r
+    };\r
+       if ( OutputLL_k > 1 ) fprintf(f,"#define LL_K %d\n", OutputLL_k);\r
+       if ( GenAST ) fprintf(f,"#define GENAST\n");\r
+       if ( FoundException )\r
+       {\r
+/* MR1  7-Apr-97  1.33MR1                                                                 */\r
+/* MR1            Fix suggested by:                                               */\r
+/* MR1            Francois-Xavier Fontaine (fontaine_f@istvax.ist.lu)         */\r
+\r
+               fprintf(f,"#define EXCEPTION_HANDLING\n");                  /* MR1 */\r
+               fprintf(f,"#define NUM_SIGNALS %d\n", NumSignals);          /* MR1 */\r
+       }\r
+       if ( DemandLookahead ) fprintf(f,"#define DEMAND_LOOK\n");\r
+#ifdef DUM\r
+       if ( LexGen ) fprintf(f, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));\r
+#endif\r
+       /* ###WARNING: This will have to change when SetWordSize changes */\r
+       fprintf(f, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));\r
+    if (TraceGen) {\r
+      fprintf(f,"#ifndef zzTRACE_RULES\n");  /* MR20 */\r
+      fprintf(f,"#define zzTRACE_RULES\n");  /* MR20 */\r
+      fprintf(f,"#endif\n");                 /* MR22 */\r
+    };\r
+       fprintf(f,"#include \"antlr.h\"\n");\r
+       if ( GenAST ) fprintf(f,"#include \"ast.h\"\n");\r
+       if ( UserDefdTokens )\r
+               fprintf(f, "#include %s\n", UserTokenDefsFile);\r
+       /* still need this one as it has the func prototypes */\r
+       fprintf(f, "#include \"%s\"\n", DefFileName);\r
+       /* still need this one as it defines the DLG interface */\r
+       fprintf(f,"#include \"dlgdef.h\"\n");\r
+       /* don't need this one unless DLG is used */\r
+       if ( LexGen ) fprintf(f,"#include \"%s\"\n", ModeFileName);\r
+       fprintf(f,"#endif\n");\r
+}\r
+\r
+/* dump action 's' to file 'output' starting at "local" tab 'tabs'\r
+   Dump line information in front of action if GenLineInfo is set\r
+   If file == -1 then GenLineInfo is ignored.\r
+   The user may redefine the LineInfoFormatStr to his/her liking\r
+   most compilers will like the default, however.\r
+\r
+   June '93; changed so that empty lines are left alone so that\r
+   line information is correct for the compiler/debuggers.\r
+*/\r
+void\r
+#ifdef __USE_PROTOS\r
+dumpAction( char *s, FILE *output, int tabs, int file, int line,\r
+int final_newline )\r
+#else\r
+dumpAction( s, output, tabs, file, line, final_newline )\r
+char *s;\r
+FILE *output;\r
+int tabs;\r
+int file;\r
+int line;\r
+int final_newline;\r
+#endif\r
+{\r
+    int inDQuote, inSQuote;\r
+    require(s!=NULL,           "dumpAction: NULL action");\r
+    require(output!=NULL,      eMsg1("dumpAction: output FILE is NULL for %s",s));\r
+\r
+       if ( GenLineInfo && file != -1 )\r
+       {\r
+        OutLineInfo(output,line,FileStr[file]);\r
+       }\r
+    PastWhiteSpace( s );\r
+       /* don't print a tab if first non-white char is a # (preprocessor command) */\r
+       if ( *s!='#' ) {TAB;}\r
+    inDQuote = inSQuote = FALSE;\r
+    while ( *s != '\0' )\r
+    {\r
+        if ( *s == '\\' )\r
+        {\r
+            fputc( *s++, output ); /* Avoid '"' Case */\r
+            if ( *s == '\0' ) return;\r
+            if ( *s == '\'' ) fputc( *s++, output );\r
+            if ( *s == '\"' ) fputc( *s++, output );\r
+        }\r
+        if ( *s == '\'' )\r
+        {\r
+            if ( !inDQuote ) inSQuote = !inSQuote;\r
+        }\r
+        if ( *s == '"' )\r
+        {\r
+            if ( !inSQuote ) inDQuote = !inDQuote;\r
+        }\r
+        if ( *s == '\n' )\r
+        {\r
+            fputc('\n', output);\r
+                       s++;\r
+            PastWhiteSpace( s );\r
+            if ( *s == '}' )\r
+            {\r
+                --tabs;\r
+                               TAB;\r
+                fputc( *s++, output );\r
+                continue;\r
+            }\r
+            if ( *s == '\0' ) return;\r
+                       if ( *s != '#' )        /* #define, #endif etc.. start at col 1 */\r
+            {\r
+                               TAB;\r
+                       }\r
+        }\r
+        if ( *s == '}' && !(inSQuote || inDQuote) )\r
+        {\r
+            --tabs;            /* Indent one fewer */\r
+        }\r
+        if ( *s == '{' && !(inSQuote || inDQuote) )\r
+        {\r
+            tabs++;            /* Indent one more */\r
+        }\r
+        fputc( *s, output );\r
+        s++;\r
+    }\r
+    if ( final_newline ) fputc('\n', output);\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+dumpAfterActions( FILE *output )\r
+#else\r
+dumpAfterActions( output )\r
+FILE *output;\r
+#endif\r
+{\r
+       ListNode *p;\r
+       require(output!=NULL, "dumpAfterActions: output file was NULL for some reason");\r
+       if ( AfterActions != NULL )\r
+       {\r
+               for (p = AfterActions->next; p!=NULL; p=p->next)\r
+               {\r
+                       UserAction *ua = (UserAction *)p->elem;\r
+                       dumpAction( ua->action, output, 0, ua->file, ua->line, 1);\r
+               }\r
+       }\r
+       fclose( output );\r
+}\r
+\r
+/*\r
+ * Find the next action in the stream of execution.  Do not pass\r
+ * junctions with more than one path leaving them.\r
+ * Only pass generic junctions.\r
+ *\r
+ *     Scan forward while (generic junction with p2==NULL)\r
+ *     If we stop on an action, return ptr to the action\r
+ *     else return NULL;\r
+ */\r
+static ActionNode *\r
+#ifdef __USE_PROTOS\r
+findImmedAction( Node *q )\r
+#else\r
+findImmedAction( q )\r
+Node *q;\r
+#endif\r
+{\r
+       Junction *j;\r
+       require(q!=NULL, "findImmedAction: NULL node");\r
+       require(q->ntype>=1 && q->ntype<=NumNodeTypes, "findImmedAction: invalid node");\r
+       \r
+       while ( q->ntype == nJunction )\r
+       {\r
+               j = (Junction *)q;\r
+               if ( j->jtype != Generic || j->p2 != NULL ) return NULL;\r
+               q = j->p1;\r
+               if ( q == NULL ) return NULL;\r
+       }\r
+       if ( q->ntype == nAction ) return (ActionNode *)q;\r
+       return NULL;\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+dumpRetValAssign( char *retval, char *ret_def, RuleRefNode * ruleRef /* MR30 */)\r
+#else\r
+dumpRetValAssign( retval, ret_def, ruleRef /* MR30 */)\r
+char *retval;\r
+char *ret_def;\r
+RuleRefNode *ruleRefNode;\r
+#endif\r
+{\r
+       char *q = ret_def;\r
+       \r
+       tab();\r
+       while ( *retval != '\0' && *q != '\0')\r
+       {\r
+               while ( isspace((*retval)) ) retval++;\r
+               while ( *retval!=',' && *retval!='\0' ) fputc(*retval++, output);\r
+               fprintf(output, " = _trv.");\r
+               \r
+               DumpNextNameInDef(&q, output);\r
+               while ( isspace(*q) ) q++;\r
+               fputc(';', output); fputc(' ', output);\r
+               if ( *retval == ',' ) retval++;\r
+       }\r
+       if (*retval == '\0' && *q != '\0') {\r
+/* MR30 */    errFL("Fewer output values than output formals for rule reference",\r
+/* MR30 */                 FileStr[ruleRef->file],ruleRef->line);\r
+       }\r
+       if (*retval != '\0' && *q == '\0') {\r
+/* MR30 */    errFL("More output actuals than output formals for rule reference",\r
+/* MR30 */                 FileStr[ruleRef->file],ruleRef->line);\r
+       }\r
+}\r
+\r
+/* This function computes the set of tokens that can possibly be seen k\r
+ * tokens in the future from point j\r
+ */\r
+\r
+static set\r
+#ifdef __USE_PROTOS\r
+ComputeErrorSet( Junction *j, int k, int usePlusBlockBypass)\r
+#else\r
+ComputeErrorSet( j, k, usePlusBlockBypass )\r
+Junction *j;\r
+int k;\r
+int usePlusBlockBypass;\r
+#endif\r
+{\r
+       Junction *alt1;\r
+       set a, rk, f;\r
+       require(j->ntype==nJunction, "ComputeErrorSet: non junction passed");\r
+\r
+       f = rk = empty;\r
+       for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2)\r
+       {\r
+        if (alt1->ignore && ! usePlusBlockBypass) continue;     /* MR21 - Ignore aPlusBlk forward p2 */\r
+               REACH(alt1->p1, k, &rk, a);\r
+               require(set_nil(rk), "ComputeErrorSet: rk != nil");\r
+               set_free(rk);\r
+               set_orin(&f, a);\r
+               set_free(a);\r
+       }\r
+       return f;\r
+}\r
+\r
+static char *\r
+#ifdef __USE_PROTOS\r
+tokenFollowSet(TokNode *p)\r
+#else\r
+tokenFollowSet(p)\r
+TokNode *p;\r
+#endif\r
+{\r
+    static char buf[100];\r
+    set rk, a;\r
+    int n;\r
+    rk = empty;\r
+\r
+    REACH(p->next, 1, &rk, a);\r
+    require(set_nil(rk), "rk != nil");\r
+    set_free(rk);\r
+    n = DefErrSet( &a, 0, NULL );\r
+    set_free(a);\r
+    if ( GenCC )\r
+        sprintf(buf, "err%d", n);\r
+    else\r
+        sprintf(buf, "zzerr%d", n);\r
+    return buf;\r
+}\r
+\r
+static void\r
+#ifdef __USE_PROTOS\r
+makeErrorClause( Junction *q, set f, int max_k, int usePlusBlockBypass )\r
+#else\r
+makeErrorClause( q, f, max_k, usePlusBlockBypass )\r
+Junction *q;\r
+set f;\r
+int max_k;\r
+int usePlusBlockBypass;\r
+#endif\r
+{\r
+    char *  handler_id="";                                           /* MR7 */\r
+    int     nilf=0;                                                  /* MR13 */\r
+    RuleEntry *ruleEntry;                                            /* MR14 */\r
+\r
+       if ( FoundException )\r
+       {\r
+               _gen("else {\n");\r
+               tabs++;\r
+               if ( FoundGuessBlk )\r
+               {\r
+                       if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}\r
+                       else gen("if ( zzguessing ) goto fail;\n");\r
+               }\r
+               gen("if (_sva) _signal=NoViableAlt;\n");\r
+               gen("else _signal=NoSemViableAlt;\n");\r
+        if (q->outerEG != NULL) {\r
+          handler_id=q->outerEG->altID;\r
+#if 0\r
+        } else {\r
+          printf("q->curAltNum=%d q->exception_label=%s\n",q->curAltNum,q->exception_label);\r
+          gen("*** DEBUG *** outerEG==NULL\n");\r
+#endif\r
+        };\r
+               gen1("goto %s_handler;  /* MR7 */\n",handler_id);    /* MR7 */\r
+               tabs--;\r
+               gen("}\n");\r
+               return;\r
+       }\r
+\r
+       if ( max_k == 1 )\r
+       {\r
+/* MR13 */  nilf=set_nil(f);\r
+               if ( GenCC ) {\r
+              _gen1("else {FAIL(1,err%d", DefErrSet1(1,&f,1,NULL));\r
+            } else {\r
+               _gen1("else {zzFAIL(1,zzerr%d", DefErrSet1(1,&f,1,NULL));\r
+            };\r
+               set_free(f);\r
+       }\r
+       else\r
+       {\r
+               int i;\r
+               set_free(f);\r
+               if ( GenCC ) {_gen1("else {FAIL(%d", max_k);}\r
+               else _gen1("else {zzFAIL(%d", max_k);\r
+\r
+    ruleEntry = (RuleEntry *) hash_get(Rname,q->rname);\r
+\r
+               for (i=1; i<=max_k; i++)\r
+               {\r
+/* MR14 */  if (ruleEntry->dontComputeErrorSet) {\r
+/* MR14 */    f=empty;\r
+            } else {\r
+             f = ComputeErrorSet(q, i, usePlusBlockBypass /* use plus block bypass ? */ );\r
+            }\r
+\r
+      if ( GenCC ) {_gen1(",err%d", DefErrSet( &f, 1, NULL ));}\r
+                       else _gen1(",zzerr%d", DefErrSet( &f, 1, NULL ));\r
+                       \r
+                       set_free(f);\r
+               }\r
+       }\r
+       _gen(",&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}\n");\r
+/* MR13 */  if (nilf) {\r
+/* MR13 */    errFL("empty error set for alt - probably because of undefined rule or infinite left recursion",\r
+/* MR13 */                 FileStr[q->file],q->line);\r
+/* MR13 */    gen(" /* MR13 empty error set for this alt - undef rule ? infinite left recursion ? */");\r
+/* MR13 */  };\r
+}\r
+\r
+static                                                               /* MR7 */\r
+#ifdef __USE_PROTOS\r
+char * findOuterHandlerLabel(ExceptionGroup *eg)                     /* MR7 */\r
+#else\r
+char * findOuterHandlerLabel(eg)                                     /* MR7 */\r
+ExceptionGroup *eg;                                                  /* MR7 */\r
+#endif\r
+{\r
+  char              *label=NULL;                                     /* MR7 */\r
+  ExceptionGroup    *outerEG;                                        /* MR7 */\r
+\r
+  if (eg->forRule == 0) {                                            /* MR7 */\r
+    if (eg->labelEntry != NULL) {                                    /* MR7 */\r
+      outerEG=eg->labelEntry->outerEG;                               /* MR7 */\r
+      if (outerEG != NULL) {                                         /* MR7 */\r
+        label=outerEG->altID;                                        /* MR7 */\r
+        outerEG->used=1;                                             /* MR7 */\r
+      };                                                             /* MR7 */\r
+    } else if (eg->outerEG != NULL) {                                /* MR7 */\r
+      outerEG=eg->outerEG;                                           /* MR7 */\r
+      label=outerEG->altID;                                          /* MR7 */\r
+      outerEG->used=1;                                               /* MR7 */\r
+    };                                                               /* MR7 */\r
+  };                                                                 /* MR7 */\r
+  return (label==NULL ? "" : label);                                 /* MR7 */\r
+}                                                                    /* MR7 */\r
+\r
+/*** debug ***/\r
+#if 0\r
+** static                                                               /* MR7 */\r
+** #ifdef __USE_PROTOS\r
+** char * findOuterAltHandlerLabel(Junction *startJ)                    /* MR7 */\r
+** #else\r
+** char * findOuterAltHandlerLabel(startJ)                              /* MR7 */\r
+** Junction *startJ;                                                    /* MR7 */\r
+** #endif\r
+** {                                                                    /* MR7 */\r
+**   char      *label=NULL;                                             /* MR7 */\r
+**   Junction  *alt;                                                    /* MR7 */\r
+**                                                                      /* MR7 */\r
+**   for (alt=startJ; alt != NULL; alt=alt->outerAltstart) {            /* MR7 */\r
+**     label=alt->exception_label;                                      /* MR7 */\r
+**     if (label != NULL) break;                                        /* MR7 */\r
+**   };                                                                 /* MR7 */\r
+**   return (label==NULL ? "" : label);                                 /* MR7 */\r
+** }                                                                    /* MR7 */\r
+#endif\r
+\r
+#ifdef __USE_PROTOS\r
+static void OutLineInfo(FILE *file,int line,char *fileName)\r
+#else\r
+static void OutLineInfo(file,line,fileName)\r
+  FILE *    file;\r
+  int       line;\r
+  char *    fileName;\r
+#endif\r
+{\r
+    static  char * prevFileName=NULL;\r
+    static  char * prevFileNameMS=NULL;\r
+\r
+    char *  p;\r
+    char *  q;\r
+\r
+    if (! GenLineInfo) return;\r
+\r
+    if (!GenLineInfoMS) {\r
+           fprintf(file, LineInfoFormatStr,line,fileName);\r
+    } else {\r
+      if (fileName == prevFileName) {\r
+           fprintf(file, LineInfoFormatStr,line,prevFileNameMS);\r
+      } else {\r
+        if (prevFileNameMS != NULL) free (prevFileNameMS);\r
+        prevFileNameMS=(char *)calloc(1,strlen(fileName)+1);\r
+        require(prevFileNameMS != NULL,"why not do this in calloc wrapper");\r
+        q=prevFileNameMS;\r
+        for (p=fileName; *p != 0; p++) {\r
+            *q=*p;\r
+            if (*q == '\\') *q='/';\r
+            q++;\r
+        }\r
+      }\r
+      prevFileName=fileName;\r
+    };\r
+}\r
+\r
+#if 0\r
+\r
+/* MR21 */\r
+\r
+#ifdef __USE_PROTOS\r
+void OutFirstSetSymbol(Junction *q, char * pSymbol)\r
+#else\r
+void OutFirstSetSymbol(q, pSymbol)\r
+    Junction* q;\r
+       char * pSymbol\r
+#endif\r
+{\r
+\r
+       set f;\r
+    if (pSymbol == NULL) return;\r
+       gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol);\r
+    f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */);\r
+    DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, "");\r
+    set_free(f);\r
+}\r
+#endif\r
+\r
+/* MR21 */\r
+\r
+#ifdef __USE_PROTOS\r
+void BlockPreambleOption(Junction *q, char * pSymbol)\r
+#else\r
+void BlockPreambleOption(q, pSymbol)\r
+    Junction* q;\r
+       char * pSymbol;\r
+#endif\r
+{\r
+       set f = empty;\r
+    if (pSymbol != NULL) {\r
+        f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */);\r
+       gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol);\r
+        DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, "");\r
+    }\r
+    set_free(f);\r
+}\r
+\r
+/* MR21 */\r
+\r
+void\r
+#ifdef __USE_PROTOS\r
+dumpActionPlus(ActionNode *a, char *s, FILE *output, int tabs, int file, int line,\r
+int final_newline )\r
+#else\r
+dumpActionPlus(a, s, output, tabs, file, line, final_newline )\r
+ActionNode *a;\r
+char *s;\r
+FILE *output;\r
+int tabs;\r
+int file;\r
+int line;\r
+int final_newline;\r
+#endif\r
+{\r
+    dumpAction(s,output,tabs,file,line,final_newline);\r
+}\r
+\r
+\r
+#if 0\r
+** #ifdef __USE_PROTOS\r
+** void MR_ErrorSets(Junction *q, int max_k, int usePlusBlockBypass)\r
+** #else\r
+** void MR_ErrorSets(q, max_k, usePlusBlockBypass)\r
+** Junction *q;\r
+** int max_k;\r
+** int usePlusBlockBypass;\r
+** #endif\r
+** {\r
+**     int k;\r
+**     set setResult;\r
+**     Junction* alt1;\r
+**     Junction* p;\r
+**     set rk;\r
+** \r
+**     require (max_k <= CLL_k, "k > CLL_k");\r
+** \r
+** \r
+**     for (k = 1; k <= CLL_k; k++) {set_clr(q->fset[k]); }\r
+** \r
+**     for (k = 1; k <= max_k; k++) {\r
+**         for (alt1=q; alt1 != NULL; alt1 = (Junction *)alt1->p2)\r
+**             {\r
+**             if (alt1->ignore && ! usePlusBlockBypass) continue;\r
+**             p = analysis_point((Junction *)alt1->p1);\r
+**                     REACH(p, k, &rk, setResult);\r
+**                     require(set_nil(rk), "rk != nil");\r
+**             set_orin(&q->fset[k], setResult);\r
+**             }\r
+**     }\r
+** }\r
+#endif\r
+\r
+\r
+#ifdef __USE_PROTOS\r
+void DumpInitializers(FILE* output, RuleEntry *r, char * pReturn)\r
+#else\r
+void DumpInitializers(output, r, pReturn)\r
+FILE* output;\r
+RuleEntry *r;\r
+char * pReturn;\r
+#endif\r
+{\r
+       char *p = pReturn;\r
+       char *pDataType;\r
+       char *pSymbol;\r
+       char *pEqualSign;\r
+       char *pValue;\r
+       char *pSeparator;\r
+       int nest = 0;\r
+    char *q;\r
+\r
+       require(pReturn!=NULL, "DumpInitializer: invalid string"); \r
+\r
+    while (*p != 0) {\r
+       p = endFormal(p,\r
+                             &pDataType,\r
+                                 &pSymbol,\r
+                                 &pEqualSign,\r
+                                 &pValue,\r
+                                 &pSeparator,\r
+                                 &nest);\r
+        if (nest != 0) return;\r
+        if (pValue != NULL) {\r
+                       tab();\r
+            q = strBetween(pSymbol, pEqualSign, pSeparator);\r
+            fprintf(output, "_retv.%s", q);\r
+            q = strBetween(pValue, NULL, pSeparator);\r
+            fprintf(output, " = %s;\n", q);\r
+        }\r
+    }\r
+}\r
+\r
+#ifdef __USE_PROTOS\r
+void DumpFormals(FILE* output, char * pReturn, int bInitializer)\r
+#else\r
+void DumpFormals(output, pReturn, bInitializer)\r
+FILE* output;\r
+char * pReturn;\r
+int bInitializer;\r
+#endif\r
+{\r
+       char *p = pReturn;\r
+       char *pDataType;\r
+       char *pSymbol;\r
+       char *pEqualSign;\r
+       char *pValue;\r
+       char *pSeparator;\r
+       int nest = 0;\r
+    char *q;\r
+    int count = 0;\r
+\r
+       require(pReturn!=NULL, "DumpFormals: invalid string"); \r
+\r
+    while (*p != 0) {\r
+       p = endFormal(p,\r
+                             &pDataType,\r
+                                 &pSymbol,\r
+                                 &pEqualSign,\r
+                                 &pValue,\r
+                                 &pSeparator,\r
+                                 &nest);\r
+        if (nest != 0) return;\r
+        if (count > 0) fprintf(output,",");\r
+        if (pDataType != NULL && pSymbol != NULL) {\r
+            q = strBetween(pDataType, pSymbol, pSeparator);\r
+            fprintf(output, "%s", q);\r
+            q = strBetween(pSymbol, pEqualSign, pSeparator);\r
+            fprintf(output," %s",q);\r
+            if (pValue != NULL) {\r
+                q = strBetween(pValue, NULL, pSeparator);\r
+                if (bInitializer != 0) {\r
+                    fprintf(output, " = %s", q);\r
+                }\r
+            }\r
+        }\r
+        count++;\r
+    }\r
+}\r
+\r
+/* MR23 Check for empty alt in a more intelligent way.\r
+        Previously, an empty alt for genBlk had to point directly\r
+               to the endBlock.  This did not work once I changed {...}\r
+               blocks to look like (...|...| epsilon) since there were\r
+               intervening generics.  This fixes the problem for this\r
+               particular case.  Things like actions or empty blocks of\r
+               various kinds will still cause problems, but I wasnt't\r
+               prepared to handle pathological cases like (A|()*). It\r
+               does handle (A | ()), which is a recommended idiom for\r
+               epsilon.\r
+\r
+        Actually, this isn't quite correct since it doesn't handle\r
+               the case of the ignore bit in the plus block bypass, but\r
+               I'm too tired to figure out the correct fix, and will just\r
+               work around it.\r
+*/\r
+\r
+#ifdef __USE_PROTOS\r
+int isEmptyAlt(Node * alt, Node * endBlock)\r
+#else\r
+int isEmptyAlt(alt, endBlock)\r
+Node * alt;\r
+Node * endBlock;\r
+#endif\r
+{\r
+       Node * n = alt;\r
+       Junction * j;\r
+       while (n != endBlock) {\r
+               switch (n->ntype) {\r
+\r
+                       case nRuleRef:\r
+                               return 0;\r
+\r
+                       case nToken:\r
+                               return 0;\r
+\r
+                       case nAction:\r
+                               return 0;\r
+\r
+                       case nJunction:\r
+                               goto JUNCTION;\r
+\r
+                       default:\r
+                               fatal_internal("Invalid node type");\r
+                               return 0;\r
+               }\r
+JUNCTION:\r
+               j = (Junction *) n;\r
+\r
+               switch (j->jtype) {\r
+                       case Generic:\r
+                               {\r
+                                       n = j->p1;\r
+                                       goto NEXT;\r
+                               }\r
+\r
+                       case aSubBlk:\r
+                               {\r
+                                       n = j->p1;      /* MR26 */\r
+                                       goto NEXT;      /* MR26 */\r
+                               }\r
+\r
+                       case EndBlk:\r
+                                       return 0;\r
+\r
+                       case EndRule:\r
+                                       return 1;\r
+\r
+                       default:\r
+                                       return 0;\r
+               }\r
+NEXT: continue;\r
+       }\r
+       return 1;\r
+}\r