home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pccts1.zip / ANTLR / GEN.C < prev    next >
C/C++ Source or Header  |  1993-09-02  |  37KB  |  1,561 lines

  1. /*
  2.  * gen.c
  3.  *
  4.  * $Id: gen.c,v 1.17 1993/08/24 14:44:32 pccts Exp pccts $
  5.  * $Revision: 1.17 $
  6.  *
  7.  * Generate C code (ANSI, K&R, C++)
  8.  *
  9.  * SOFTWARE RIGHTS
  10.  *
  11.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  12.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  13.  * company may do whatever they wish with source code distributed with
  14.  * PCCTS or the code generated by PCCTS, including the incorporation of
  15.  * PCCTS, or its output, into commerical software.
  16.  * 
  17.  * We encourage users to develop software with PCCTS.  However, we do ask
  18.  * that credit is given to us for developing PCCTS.  By "credit",
  19.  * we mean that if you incorporate our source code into one of your
  20.  * programs (commercial product, research project, or otherwise) that you
  21.  * acknowledge this fact somewhere in the documentation, research report,
  22.  * etc...  If you like PCCTS and have developed a nice tool with the
  23.  * output, please mention that you developed it using PCCTS.  In
  24.  * addition, we ask that this header remain intact in our source code.
  25.  * As long as these guidelines are kept, we expect to continue enhancing
  26.  * this system and expect to make other tools available as they are
  27.  * completed.
  28.  *
  29.  * ANTLR 1.10
  30.  * Terence Parr
  31.  * Purdue University
  32.  * 1989-1993
  33.  */
  34. #include <stdio.h>
  35. #ifdef __cplusplus
  36. #ifndef __STDC__
  37. #define __STDC__
  38. #endif
  39. #endif
  40. #include <ctype.h>
  41. #include "set.h"
  42. #include "syn.h"
  43. #include "hash.h"
  44. #include "generic.h"
  45. #include "dlgdef.h"
  46.  
  47.                     /* T r a n s l a t i o n  T a b l e s */
  48.  
  49. /* C_Trans[node type] == pointer to function that knows how to translate that node. */
  50. #ifdef __cplusplus
  51. void (*C_Trans[NumNodeTypes+1])(...) = {
  52.     NULL,
  53.     NULL,                    /* See next table.  Junctions have many types */
  54.     (void (*)(...)) genRuleRef,
  55.     (void (*)(...)) genToken,
  56.     (void (*)(...)) genAction
  57. };
  58. #else
  59. void (*C_Trans[NumNodeTypes+1])() = {
  60.     NULL,
  61.     NULL,                    /* See next table.  Junctions have many types */
  62.     genRuleRef,
  63.     genToken,
  64.     genAction
  65. };
  66. #endif
  67.  
  68. /* C_JTrans[Junction type] == pointer to function that knows how to translate that
  69.  * kind of junction node.
  70.  */
  71. #ifdef __cplusplus
  72. void (*C_JTrans[NumJuncTypes+1])(...) = {
  73.     NULL,
  74.     (void (*)(...)) genSubBlk,
  75.     (void (*)(...)) genOptBlk,
  76.     (void (*)(...)) genLoopBlk,
  77.     (void (*)(...)) genEndBlk,
  78.     (void (*)(...)) genRule,
  79.     (void (*)(...)) genJunction,
  80.     (void (*)(...)) genEndRule,
  81.     (void (*)(...)) genPlusBlk,
  82.     (void (*)(...)) genLoopBegin
  83. };
  84. #else
  85. void (*C_JTrans[NumJuncTypes+1])() = {
  86.     NULL,
  87.     genSubBlk,
  88.     genOptBlk,
  89.     genLoopBlk,
  90.     genEndBlk,
  91.     genRule,
  92.     genJunction,
  93.     genEndRule,
  94.     genPlusBlk,
  95.     genLoopBegin
  96. };
  97. #endif
  98.  
  99. #define PastWhiteSpace(s)    while (*(s) == ' ' || *(s) == '\t') {s++;}
  100.  
  101. static int tabs = 0;
  102. #define TAB { int i; for (i=0; i<tabs; i++) putc('\t', output); }
  103. static void
  104. #ifdef __STDC__
  105. tab( void )
  106. #else
  107. tab( )
  108. #endif
  109. TAB
  110.  
  111. #ifdef __STDC__
  112. static ActionNode *findImmedAction( Node * );
  113. static void dumpRetValAssign(char *, char *);
  114. static void dumpAfterActions(FILE *output);
  115. static set ComputeErrorSet(Junction *, int);
  116. static void makeErrorClause(Junction *, set, int);
  117. static void DumpFuncHeader( Junction *, RuleEntry * );
  118. static int has_guess_block_as_first_item(Junction *);
  119. static int genExprSets(set *, int);
  120. #else
  121. static ActionNode *findImmedAction();
  122. static void dumpRetValAssign();
  123. static void dumpAfterActions();
  124. static set ComputeErrorSet();
  125. static void makeErrorClause();
  126. static void DumpFuncHeader();
  127. static int has_guess_block_as_first_item();
  128. static int genExprSets();
  129. #endif
  130.  
  131. #define gen(s)            {tab(); fprintf(output, s);}
  132. #define gen1(s,a)        {tab(); fprintf(output, s,a);}
  133. #define gen2(s,a,b)        {tab(); fprintf(output, s,a,b);}
  134. #define gen3(s,a,b,c)    {tab(); fprintf(output, s,a,b,c);}
  135. #define gen4(s,a,b,c,d)    {tab(); fprintf(output, s,a,b,c,d);}
  136. #define gen5(s,a,b,c,d,e)    {tab(); fprintf(output, s,a,b,c,d,e);}
  137. #define gen6(s,a,b,c,d,e,f)    {tab(); fprintf(output, s,a,b,c,d,e,f);}
  138.  
  139. #define _gen(s)            {fprintf(output, s);}
  140. #define _gen1(s,a)        {fprintf(output, s,a);}
  141. #define _gen2(s,a,b)    {fprintf(output, s,a,b);}
  142. #define _gen3(s,a,b,c)    {fprintf(output, s,a,b,c);}
  143. #define _gen4(s,a,b,c,d){fprintf(output, s,a,b,c,d);}
  144. #define _gen5(s,a,b,c,d,e){fprintf(output, s,a,b,c,d,e);}
  145.  
  146. static void
  147. #ifdef __STDC__
  148. warn_about_using_gk_option(void)
  149. #else
  150. warn_about_using_gk_option()
  151. #endif
  152. {
  153.     static int warned_already=0;
  154.  
  155.     if ( !DemandLookahead || warned_already ) return;
  156.     warned_already = 1;
  157.     warnNoFL("-gk option could cause trouble for <<...>>? predicates");
  158. }
  159.  
  160. void
  161. #ifdef __STDC__
  162. freeBlkFsets( Junction *q )
  163. #else
  164. freeBlkFsets( q )
  165. Junction *q;
  166. #endif
  167. {
  168.     int i;
  169.     Junction *alt;
  170.     require(q!=NULL, "freeBlkFsets: invalid node");
  171.  
  172.     for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
  173.     {
  174.         for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]);
  175.     }
  176. }
  177.  
  178. static void
  179. #ifdef __STDC__
  180. BLOCK_Head( void )
  181. #else
  182. BLOCK_Head( )
  183. #endif
  184. {
  185.     gen("{\n");
  186.     tabs++;
  187.     gen1("zzBLOCK(zztasp%d);\n", BlkLevel);
  188. }
  189.  
  190. static void
  191. #ifdef __STDC__
  192. BLOCK_Tail( void )
  193. #else
  194. BLOCK_Tail( )
  195. #endif
  196. {
  197.     gen1("zzEXIT(zztasp%d);\n", BlkLevel);
  198.     gen("}\n");
  199.     tabs--;
  200.     gen("}\n");
  201. }
  202.  
  203. static void
  204. #ifdef __STDC__
  205. BLOCK_Preamble( Junction *q )
  206. #else
  207. BLOCK_Preamble( q )
  208. Junction *q;
  209. #endif
  210. {
  211.     ActionNode *a;
  212.     Junction *begin;
  213.  
  214.     BLOCK_Head();
  215.     if ( q->jtype == aPlusBlk ) gen("int zzcnt=1;\n");
  216.     if ( q->parm != NULL ) gen1("zzaPush(%s);\n", q->parm)
  217.     else gen("zzMake0;\n");
  218.     gen("{\n");
  219.     if ( q->jtype == aLoopBegin ) begin = (Junction *) ((Junction *)q->p1);
  220.     else begin = q;
  221.     if ( has_guess_block_as_first_item(begin) )
  222.     {
  223.         gen("zzGUESS_BLOCK\n");
  224.     }
  225.     if ( q->jtype == aLoopBegin )
  226.         a = findImmedAction( ((Junction *)q->p1)->p1 );    /* look at aLoopBlk */
  227.     else
  228.         a = findImmedAction( q->p1 );
  229.     if ( a!=NULL && !a->is_predicate ) {
  230.         dumpAction(a->action, output, tabs, a->file, a->line, 1);
  231.         a->done = 1;    /* remove action. We have already handled it */
  232.     }
  233. }
  234.  
  235. static void
  236. #ifdef __STDC__
  237. genExprTree( Tree *t, int k )
  238. #else
  239. genExprTree( t, k )
  240. Tree *t;
  241. int k;
  242. #endif
  243. {
  244.     require(t!=NULL, "genExprTree: NULL tree");
  245.     
  246.     if ( t->token == ALT )
  247.     {
  248.         _gen("("); genExprTree(t->down, k); _gen(")");
  249.         if ( t->right!=NULL )
  250.         {
  251.             _gen("||");
  252.             _gen("("); genExprTree(t->right, k); _gen(")");
  253.         }
  254.         return;
  255.     }
  256.     if ( t->down!=NULL ) _gen("(");
  257.     _gen1("LA(%d)==",k);
  258.     if ( TokenStr[t->token] == NULL ) _gen1("%d", t->token)
  259.     else _gen1("%s", TokenStr[t->token]);
  260.     if ( t->down!=NULL )
  261.     {
  262.         _gen("&&");
  263.         _gen("("); genExprTree(t->down, k+1); _gen(")");
  264.     }
  265.     if ( t->down!=NULL ) _gen(")");
  266.     if ( t->right!=NULL )
  267.     {
  268.         _gen("||");
  269.         _gen("("); genExprTree(t->right, k); _gen(")");
  270.     }
  271. }
  272.  
  273. /*
  274.  * Generate LL(k) type expressions of the form:
  275.  *
  276.  *         (LA(1) == T1 || LA(1) == T2 || ... || LA(1) == Tn) &&
  277.  *         (LA(2) == T1 || LA(2) == T2 || ... || LA(2) == Tn) &&
  278.  *            .....
  279.  *         (LA(k) == T1 || LA(k) == T2 || ... || LA(k) == Tn)
  280.  *
  281.  * If GenExprSets generate:
  282.  *
  283.  *        (setwdi[LA(1)]&(1<<j)) && (setwdi[LA(2)]&(1<<j)) ...
  284.  *
  285.  * where n is set_deg(expr) and Ti is some random token and k is the last nonempty
  286.  * set in fset <=CLL_k.
  287.  * k=1..CLL_k where CLL_k >= 1.
  288.  *
  289.  * This routine is visible only to this file and cannot answer a TRANS message.
  290.  *
  291.  * TJP June '93: If predicates are allowed in parsing expressions:
  292.  *
  293.  * (    production 1
  294.  * |    production 2
  295.  * ...
  296.  * |    production n
  297.  * )
  298.  *
  299.  * where production 1 yields visible predicates: <<pred>>? <<pred2>>?
  300.  *
  301.  * generates:
  302.  *
  303.  * if ( (context_of_pred && pred) &&
  304.  *        (context_of_pred2 && pred2) &&
  305.  *        (production 1 prediction) ) {
  306.  *         ...
  307.  * }
  308.  * else if ( production 2 prediction ) {
  309.  *         ...
  310.  * }
  311.  * ...
  312.  *
  313.  * If no context, then just test expression.
  314.  */
  315. static int
  316. #ifdef __STDC__
  317. genExpr( Junction *j )
  318. #else
  319. genExpr( j )
  320. Junction *j;
  321. #endif
  322. {
  323.     int max_k, context_was_present=0;
  324.  
  325.     if ( ParseWithPredicates && j->predicate!=NULL )
  326.     {
  327.         Predicate *p = j->predicate;
  328.         warn_about_using_gk_option();
  329.         _gen("(");
  330.         while ( p!=NULL )
  331.         {
  332.             if ( HoistPredicateContext )
  333.             {
  334.                 context_was_present = 0;
  335.                 if ( LL_k>1 && p->tcontext!=NULL )
  336.                 {
  337.                     context_was_present = 1;
  338.                     _gen("((");
  339.                     genExprTree(p->tcontext, 1);
  340.                     _gen(") && (");
  341.                 }
  342.                 else if ( LL_k==1 && set_deg(p->scontext[1])>0 )
  343.                 {
  344.                     context_was_present = 1;
  345.                     _gen("((");
  346.                     genExprSets(&(p->scontext[0]), CLL_k);
  347.                     _gen(") && (");
  348.                 }
  349.             }
  350.  
  351.             dumpAction(p->expr, output, 0, j->file, j->line, 0);
  352.  
  353.             if ( HoistPredicateContext && context_was_present )
  354.             {
  355.                 _gen("))");
  356.             }
  357.             p = p->next;
  358.             if ( p!=NULL ) _gen(" && ");
  359.         }
  360.         _gen(") && (");
  361.     }
  362.  
  363.     /* if full LL(k) is sufficient, then don't use approximate (-ck) lookahead
  364.      * from CLL_k..LL_k
  365.      */
  366.     {
  367.         int limit;
  368.         if ( j->ftree!=NULL ) limit = LL_k;
  369.         else limit = CLL_k;
  370.         max_k = genExprSets(j->fset, limit);
  371.     }
  372.  
  373.     /* Do tests for real tuples from other productions that conflict with
  374.      * artificial tuples generated by compression (using sets of tokens
  375.      * rather than k-trees).
  376.      */
  377.     if ( j->ftree != NULL )
  378.     {
  379.         _gen(" && !("); genExprTree(j->ftree, 1); _gen(")");
  380.     }
  381.     if ( ParseWithPredicates && j->predicate!=NULL ) _gen(")");
  382.     return max_k;
  383. }
  384.  
  385. static int
  386. #ifdef __STDC__
  387. genExprSets( set *fset, int limit )
  388. #else
  389. genExprSets( fset, limit )
  390. set *fset;
  391. int limit;
  392. #endif
  393. {
  394.     int k = 1;
  395.     int max_k = 0;
  396.     unsigned *e, *g, firstTime=1;
  397.  
  398.     if ( GenExprSets )
  399.     {
  400.         while ( !set_nil(fset[k]) && k<=limit )
  401.         {
  402.             if ( set_deg(fset[k])==1 )    /* too simple for a set? */
  403.             {
  404.                 int e;
  405.                 _gen1("(LA(%d)==",k);
  406.                 e = set_int(fset[k]);
  407.                 if ( TokenStr[e] == NULL ) _gen1("%d)", e)
  408.                 else _gen1("%s)", TokenStr[e]);
  409.             }
  410.             else
  411.             {
  412.                 NewSet();
  413.                 FillSet( fset[k] );
  414.                 _gen3("(setwd%d[LA(%d)]&0x%x)", wordnum, k, 1<<setnum);
  415.             }
  416.             if ( k>max_k ) max_k = k;
  417.             if ( k == CLL_k ) break;
  418.             k++;
  419.             if ( !set_nil(fset[k]) && k<=limit ) _gen(" && ");
  420.         }
  421.         return max_k;
  422.     }
  423.  
  424.     while ( !set_nil(fset[k]) && k<=limit )
  425.     {
  426.         if ( (e=g=set_pdq(fset[k])) == NULL ) fatal("genExpr: cannot allocate IF expr pdq set");
  427.         for (; *e!=nil; e++)
  428.         {
  429.             if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; }
  430.             _gen1("LA(%d)==",k);
  431.             if ( TokenStr[*e] == NULL ) _gen1("%d", *e)
  432.             else _gen1("%s", TokenStr[*e]);
  433.         }
  434.         free( g );
  435.         _gen(")");
  436.         if ( k>max_k ) max_k = k;
  437.         if ( k == CLL_k ) break;
  438.         k++;
  439.         if ( !set_nil(fset[k]) && k<=limit ) { firstTime=1; _gen(" && "); }
  440.     }
  441.     return max_k;
  442. }
  443.  
  444. /*
  445.  * Generate code for any type of block.  If the last alternative in the block is
  446.  * empty (not even an action) don't bother doing it.  This permits us to handle
  447.  * optional and loop blocks as well.
  448.  *
  449.  * Only do this block, return after completing the block.
  450.  * This routine is visible only to this file and cannot answer a TRANS message.
  451.  */
  452. static set
  453. #ifdef __STDC__
  454. genBlk( Junction *q, int jtype, int *max_k, int *need_right_curly )
  455. #else
  456. genBlk( q, jtype, max_k, need_right_curly )
  457. Junction *q;
  458. int jtype;
  459. int *max_k;
  460. int *need_right_curly;
  461. #endif
  462. {
  463.     set f;
  464.     Junction *alt;
  465.     int a_guess_in_block = 0;
  466.     require(q!=NULL,                "genBlk: invalid node");
  467.     require(q->ntype == nJunction,    "genBlk: not junction");
  468.  
  469.     *need_right_curly=0;
  470.     if ( q->p2 == NULL )    /* only one alternative?  Then don't need if */
  471.     {    
  472.         if ( first_item_is_guess_block((Junction *)q->p1)!=NULL )
  473.         {
  474.             warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line);
  475.             gen("zzGUESS\n");    /* guess anyway to make output code consistent */
  476.             gen("if ( !zzrv )\n");
  477.         }
  478.         TRANS(q->p1);
  479.         return empty;        /* no decision to be made-->no error set */
  480.     }
  481.  
  482.     f = First(q, 1, jtype, max_k);
  483.     for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
  484.     {
  485.         if ( alt->p2 == NULL )                    /* chk for empty alt */
  486.         {    
  487.             Node *p = alt->p1;
  488.             if ( p->ntype == nJunction )
  489.             {
  490.                 /* we have empty alt */
  491.                 if ( ((Junction *)p)->p1 == (Node *)q->end )
  492.                 {
  493.                     break;                        /* don't do this one, quit */
  494.                 }
  495.             }
  496.         }
  497.         if ( alt != q ) gen("else ")
  498.         else
  499.         {
  500.             if ( DemandLookahead ) gen1("LOOK(%d);\n", *max_k);
  501.         }
  502.         if ( alt!=q )
  503.         {
  504.             _gen("{\n");
  505.             tabs++;
  506.             (*need_right_curly)++;
  507.             /* code to restore state if a prev alt didn't follow guess */
  508.             if ( a_guess_in_block ) gen("if ( zzguessing ) zzGUESS_DONE;\n");
  509.         }
  510.         if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL )
  511.         {
  512.             a_guess_in_block = 1;
  513.             gen("zzGUESS\n");
  514.         }
  515.         gen("if ( ");
  516.         if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && ");
  517.         genExpr(alt);
  518.         _gen(" ) ");
  519.         _gen("{\n");
  520.         tabs++;
  521.         TRANS(alt->p1);
  522.         --tabs;
  523.         gen("}\n");
  524.     }
  525.     return f;
  526. }
  527.  
  528. static int
  529. #ifdef __STDC__
  530. has_guess_block_as_first_item( Junction *q )
  531. #else
  532. has_guess_block_as_first_item( q )
  533. Junction *q;
  534. #endif
  535. {
  536.     Junction *alt;
  537.  
  538.     for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
  539.     {
  540.         if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1;
  541.     }
  542.     return 0;
  543. }
  544.  
  545. /* return NULL if 1st item of alt is (...)? block; else return ptr to aSubBlk node
  546.  * of (...)?;  This function ignores actions and predicates.
  547.  */
  548. Junction *
  549. #ifdef __STDC__
  550. first_item_is_guess_block( Junction *q )
  551. #else
  552. first_item_is_guess_block( q )
  553. Junction *q;
  554. #endif
  555. {
  556.     while ( q!=NULL && ((q->ntype==nJunction && q->jtype==Generic) || q->ntype==nAction) )
  557.     {
  558.         if ( q->ntype==nJunction ) q = (Junction *)q->p1;
  559.         else q = (Junction *) ((ActionNode *)q)->next;
  560.     }
  561.  
  562.     if ( q==NULL ) return NULL;
  563.     if ( q->ntype!=nJunction ) return NULL;
  564.     if ( q->jtype!=aSubBlk ) return NULL;
  565.     if ( !q->guess ) return NULL;
  566.     return q;
  567. }
  568.  
  569. /* Generate an action.  Don't if action is NULL which means that it was already
  570.  * handled as an init action.
  571.  */
  572. void
  573. #ifdef __STDC__
  574. genAction( ActionNode *p )
  575. #else
  576. genAction( p )
  577. ActionNode *p;
  578. #endif
  579. {
  580.     require(p!=NULL,            "genAction: invalid node and/or rule");
  581.     require(p->ntype==nAction,    "genAction: not action");
  582.     
  583.     if ( !p->done )
  584.     {
  585.         if ( p->is_predicate )
  586.         {
  587.             gen("if (!(");
  588.             dumpAction(p->action, output, 0, p->file, p->line, 0);
  589.             if ( p->pred_fail != NULL ) {_gen1(")) {{%s};}\n", p->pred_fail);}
  590.             else _gen1(")) {zzfailed_pred(\"%s\");}\n",p->action);
  591.         }
  592.         else
  593.         {
  594.             gen("zzNON_GUESS_MODE {\n");
  595.             dumpAction(p->action, output, tabs, p->file, p->line, 1);
  596.             gen("}\n");
  597.         }
  598. /*        p->done = 1; */
  599.     }
  600.     TRANS(p->next)
  601. }
  602.  
  603. /*
  604.  *        if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in
  605.  *        else pass addr of temp root ptr (&_ast) (don't zzlink it in).
  606.  *
  607.  *        if ! modifies rule-ref, then never link it in and never pass zzSTR.
  608.  *        Always pass address of temp root ptr.
  609.  */
  610. void
  611. #ifdef __STDC__
  612. genRuleRef( RuleRefNode *p )
  613. #else
  614. genRuleRef( p )
  615. RuleRefNode *p;
  616. #endif
  617. {
  618.     Junction *q;
  619.     RuleEntry *r, *r2;
  620.     char *parm = "";
  621.     require(p!=NULL,            "genRuleRef: invalid node and/or rule");
  622.     require(p->ntype==nRuleRef, "genRuleRef: not rule reference");
  623.     
  624.     r = (RuleEntry *) hash_get(Rname, p->text);
  625.     if ( r == NULL ) {warnNoFL( eMsg1("rule %s not defined", p->text) ); return;}
  626.     r2 = (RuleEntry *) hash_get(Rname, p->rname);
  627.     if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
  628.  
  629.     tab();
  630.     if ( GenAST )
  631.     {
  632.         if ( r2->noAST || p->astnode==ASTexclude )
  633.         {
  634.             _gen("_ast = NULL; ");
  635.             parm = "&_ast";
  636.         }
  637.         else parm = "zzSTR";
  638.         if ( p->assign!=NULL )
  639.         {
  640.             if ( !HasComma(p->assign) ) {_gen1("%s = ",p->assign);}
  641.             else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
  642.         }
  643.         _gen5("%s%s(%s%s%s);", RulePrefix,
  644.                                p->text,
  645.                                parm,
  646.                                (p->parms!=NULL)?",":"",
  647.                                (p->parms!=NULL)?p->parms:"");
  648.         if ( !r2->noAST && p->astnode == ASTinclude )
  649.         {
  650.             _gen(" zzlink(_root, &_sibling, &_tail);");
  651.         }
  652.     }
  653.     else
  654.     {
  655.         if ( p->assign!=NULL )
  656.         {
  657.             if ( !HasComma(p->assign) ) {_gen1("%s = ",p->assign);}
  658.             else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
  659.         }
  660.         _gen3("%s%s(%s);", RulePrefix, p->text, (p->parms!=NULL)?p->parms:"");
  661.     }
  662.     q = RulePtr[r->rulenum];    /* find definition of ref'd rule */
  663.     if ( p->assign!=NULL )
  664.         if ( HasComma(p->assign) )
  665.         {
  666.             dumpRetValAssign(p->assign, q->ret);
  667.             _gen("}");
  668.         }
  669.     _gen("\n");
  670.     TRANS(p->next)
  671. }
  672.  
  673. /*
  674.  * Generate code to match a token.
  675.  *
  676.  * Getting the next token is tricky.  We want to ensure that any action
  677.  * following a token is executed before the next GetToken();
  678.  */ 
  679. void
  680. #ifdef __STDC__
  681. genToken( TokNode *p )
  682. #else
  683. genToken( p )
  684. TokNode *p;
  685. #endif
  686. {
  687.     RuleEntry *r;
  688.     ActionNode *a;
  689.     require(p!=NULL,            "genToken: invalid node and/or rule");
  690.     require(p->ntype==nToken,    "genToken: not token");
  691.     
  692.     r = (RuleEntry *) hash_get(Rname, p->rname);
  693.     if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
  694.     if ( TokenStr[p->token]!=NULL ) gen1("zzmatch(%s);", TokenStr[p->token])
  695.     else gen1("zzmatch(%d);", p->token);
  696.     a = findImmedAction( p->next );
  697.     if ( GenAST )
  698.     {
  699.         if ( !r->noAST )
  700.         {
  701.             if ( p->astnode==ASTchild )
  702.                 {_gen(" zzsubchild(_root, &_sibling, &_tail);");}
  703.             else if ( p->astnode==ASTroot )
  704.                 {_gen(" zzsubroot(_root, &_sibling, &_tail);");}
  705.             else
  706.                 {_gen(" zzastDPush;");}
  707.         }
  708.         else _gen(" zzastDPush;");
  709.     }
  710.     if ( a != NULL )
  711.     {
  712.         /* delay next token fetch until after action */
  713.         _gen("\n");
  714.         if ( a->is_predicate )
  715.         {
  716.             gen("if (!(");
  717.             dumpAction(a->action, output, 0, a->file, a->line, 0);
  718.             _gen1(")) {zzfailed_pred(\"%s\");}\n",a->action);
  719.         }
  720.         else
  721.         {
  722.             dumpAction(a->action, output, tabs, a->file, a->line, 1);
  723.         }
  724.         a->done = 1;
  725.         if ( !DemandLookahead ) {gen(" zzCONSUME;\n");}
  726.         else gen("\n");
  727.         TRANS( a->next );
  728.     }
  729.     else
  730.     {
  731.         if ( !DemandLookahead ) {_gen(" zzCONSUME;\n");}
  732.         else gen("\n");
  733.         TRANS(p->next);
  734.     }
  735. }
  736.  
  737. void
  738. #ifdef __STDC__
  739. genOptBlk( Junction *q )
  740. #else
  741. genOptBlk( q )
  742. Junction *q;
  743. #endif
  744. {
  745.     int max_k;
  746.     set f;
  747.     int need_right_curly;
  748.     require(q!=NULL,                "genOptBlk: invalid node and/or rule");
  749.     require(q->ntype == nJunction,    "genOptBlk: not junction");
  750.     require(q->jtype == aOptBlk,    "genOptBlk: not optional block");
  751.  
  752.     BLOCK_Preamble(q);
  753.     BlkLevel++;
  754.     f = genBlk(q, aOptBlk, &max_k, &need_right_curly);
  755.     set_free(f);
  756.     freeBlkFsets(q);
  757.     BlkLevel--;
  758.     { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
  759.     BLOCK_Tail();
  760.     if (q->end->p1 != NULL) TRANS(q->end->p1);
  761. }
  762.  
  763. /*
  764.  * Generate code for a loop blk of form:
  765.  *
  766.  *                 |---|
  767.  *                 v   |
  768.  *               --o-G-o-->o--
  769.  */
  770. void
  771. #ifdef __STDC__
  772. genLoopBlk( Junction *q, Junction *begin, int max_k )
  773. #else
  774. genLoopBlk( q, begin, max_k )
  775. Junction *q;
  776. Junction *begin;
  777. int max_k;
  778. #endif
  779. {
  780.     int dum_k;
  781.     set f;
  782.     int need_right_curly;
  783.     require(q->ntype == nJunction,    "genLoopBlk: not junction");
  784.     require(q->jtype == aLoopBlk,    "genLoopBlk: not loop block");
  785.  
  786.     if ( q->visited ) return;
  787.     q->visited = TRUE;
  788.     if ( q->p2 == NULL )    /* only one alternative? */
  789.     {
  790.         f = First(q, 1, aLoopBlk, &dum_k);
  791.         if ( DemandLookahead ) gen1("LOOK(%d);\n", max_k);
  792.         gen("while ( ");
  793.         if ( begin!=NULL )
  794.         {
  795.             genExpr(begin);
  796.         }
  797.         else genExpr(q);
  798.         _gen(" ) {\n");
  799.         tabs++;
  800.         TRANS(q->p1);
  801.         gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);
  802.         if ( DemandLookahead ) gen1("LOOK(%d);\n", max_k);
  803.         --tabs;
  804.         gen("}\n");
  805.         freeBlkFsets(q);
  806.         set_free(f);
  807.         q->visited = FALSE;
  808.         return;
  809.     }
  810.     gen("while ( 1 ) {\n");
  811.     tabs++;
  812.     if ( begin!=NULL )
  813.     {
  814.         if ( DemandLookahead ) gen1("LOOK(%d);\n",max_k);
  815.         gen("if ( ");
  816.         genExpr((Junction *)begin->p2);
  817.         _gen(" ) break;\n");
  818.     }
  819.     f = genBlk(q, aLoopBlk, &max_k, &need_right_curly);
  820.     set_free(f);
  821.     freeBlkFsets(q);
  822.     if ( begin==NULL ) gen("else break;\n");        /* code for exiting loop */
  823.     { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
  824.     gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);
  825.     --tabs;
  826.     gen("}\n");
  827.     q->visited = FALSE;
  828. }
  829.  
  830. /*
  831.  * Generate code for a loop blk of form:
  832.  *
  833.  *                          |---|
  834.  *                         v   |
  835.  *               --o-->o-->o-G-o-->o--
  836.  *                   |           ^
  837.  *                   v           |
  838.  *                     o-----------o
  839.  *
  840.  * q->end points to the last node (far right) in the blk.  Note that q->end->jtype
  841.  * must be 'EndBlk'.
  842.  *
  843.  * Generate code roughly of the following form:
  844.  *
  845.  *    do {
  846.  *        ... code for alternatives ...
  847.  *  } while ( First Set of aLoopBlk );
  848.  *
  849.  *    OR if > 1 alternative
  850.  *
  851.  *    do {
  852.  *        ... code for alternatives ...
  853.  *        else break;
  854.  *  } while ( 1 );
  855.  */
  856. void
  857. #ifdef __STDC__
  858. genLoopBegin( Junction *q )
  859. #else
  860. genLoopBegin( q )
  861. Junction *q;
  862. #endif
  863. {
  864.     set f;
  865.     int i;
  866.     int max_k;
  867.     require(q!=NULL,                "genLoopBegin: invalid node and/or rule");
  868.     require(q->ntype == nJunction,    "genLoopBegin: not junction");
  869.     require(q->jtype == aLoopBegin,    "genLoopBegin: not loop block");
  870.     require(q->p2!=NULL,            "genLoopBegin: invalid Loop Graph");
  871.  
  872.     BLOCK_Preamble(q);
  873.     BlkLevel++;
  874.     f = First(q, 1, aLoopBegin, &max_k);
  875.     if ( LL_k>1 && !set_nil(q->fset[2]) )
  876.         genLoopBlk( (Junction *)q->p1, q, max_k );
  877.     else genLoopBlk( (Junction *)q->p1, NULL, max_k );
  878.     for (i=1; i<=CLL_k; i++) set_free(q->fset[i]);
  879.     for (i=1; i<=CLL_k; i++) set_free(((Junction *)q->p2)->fset[i]);
  880.     --BlkLevel;
  881.     BLOCK_Tail();
  882.     set_free(f);
  883.     if (q->end->p1 != NULL) TRANS(q->end->p1);
  884. }
  885.  
  886. /*
  887.  * Generate code for a loop blk of form:
  888.  *
  889.  *                      |---|
  890.  *                     v   |
  891.  *                   --o-G-o-->o--
  892.  *
  893.  * q->end points to the last node (far right) in the blk.  Note that q->end->jtype
  894.  * must be 'EndBlk'.
  895.  *
  896.  * Generate code roughly of the following form:
  897.  *
  898.  *    do {
  899.  *        ... code for alternatives ...
  900.  *  } while ( First Set of aPlusBlk );
  901.  *
  902.  *    OR if > 1 alternative
  903.  *
  904.  *    do {
  905.  *        ... code for alternatives ...
  906.  *        else if not 1st time through, break;
  907.  *  } while ( 1 );
  908.  */
  909. void
  910. #ifdef __STDC__
  911. genPlusBlk( Junction *q )
  912. #else
  913. genPlusBlk( q )
  914. Junction *q;
  915. #endif
  916. {
  917.     int max_k;
  918.     set f;
  919.     int need_right_curly;
  920.     require(q!=NULL,                "genPlusBlk: invalid node and/or rule");
  921.     require(q->ntype == nJunction,    "genPlusBlk: not junction");
  922.     require(q->jtype == aPlusBlk,    "genPlusBlk: not Plus block");
  923.  
  924.     if ( q->visited ) return;
  925.     q->visited = TRUE;
  926.     BLOCK_Preamble(q);
  927.     BlkLevel++;
  928.     if ( q->p2 == NULL )    /* only one alternative? */
  929.     {
  930.         gen("do {\n");
  931.         tabs++;
  932.         TRANS(q->p1);
  933.         gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);
  934.         f = First(q, 1, aPlusBlk, &max_k);
  935.         if ( DemandLookahead ) gen1("LOOK(%d);\n", max_k);
  936.         --tabs;
  937.         gen("} while ( ");
  938.         genExpr(q);
  939.         _gen(" );\n");
  940.         --BlkLevel;
  941.         BLOCK_Tail();
  942.         q->visited = FALSE;
  943.         freeBlkFsets(q);
  944.         set_free(f);
  945.         if (q->end->p1 != NULL) TRANS(q->end->p1);
  946.         return;
  947.     }
  948.     gen("do {\n");
  949.     tabs++;
  950.     f = genBlk(q, aPlusBlk, &max_k, &need_right_curly);
  951.     gen("else if ( zzcnt>1 ) break; ");/* code for exiting loop */
  952.     makeErrorClause(q,f,max_k);
  953.     { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
  954.     freeBlkFsets(q);
  955.     gen1("zzcnt++; zzLOOP(zztasp%d);\n", BlkLevel-1);
  956.     if ( DemandLookahead ) gen1("LOOK(%d);\n", max_k);
  957.     --tabs;
  958.     gen("} while ( 1 );\n");
  959.     --BlkLevel;
  960.     BLOCK_Tail();
  961.     q->visited = FALSE;
  962.     if (q->end->p1 != NULL) TRANS(q->end->p1);
  963. }
  964.  
  965. /*
  966.  * Generate code for a sub blk of alternatives of form:
  967.  *
  968.  *                   --o-G1--o--
  969.  *                     |     ^
  970.  *                     v    /|
  971.  *                     o-G2-o|
  972.  *                     |     ^
  973.  *                     v     |
  974.  *                   ..........
  975.  *                     |     ^
  976.  *                     v    /
  977.  *                     o-Gn-o
  978.  *
  979.  * q points to the 1st junction of blk (upper-left).
  980.  * q->end points to the last node (far right) in the blk.  Note that q->end->jtype
  981.  * must be 'EndBlk'.
  982.  * The last node in every alt points to q->end.
  983.  *
  984.  * Generate code of the following form:
  985.  *    if ( First(G1) ) {
  986.  *        ...code for G1...
  987.  *    }
  988.  *    else if ( First(G2) ) {
  989.  *        ...code for G2...
  990.  *    }
  991.  *    ...
  992.  *    else {
  993.  *        ...code for Gn...
  994.  *    }
  995.  */
  996. void
  997. #ifdef __STDC__
  998. genSubBlk( Junction *q )
  999. #else
  1000. genSubBlk( q )
  1001. Junction *q;
  1002. #endif
  1003. {
  1004.     int max_k;
  1005.     set f;
  1006.     int need_right_curly;
  1007.     require(q->ntype == nJunction,    "genSubBlk: not junction");
  1008.     require(q->jtype == aSubBlk,    "genSubBlk: not subblock");
  1009.  
  1010.     BLOCK_Preamble(q);
  1011.     BlkLevel++;
  1012.     f = genBlk(q, aSubBlk, &max_k, &need_right_curly);
  1013.     if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k);}
  1014.     { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
  1015.     freeBlkFsets(q);
  1016.     --BlkLevel;
  1017.     BLOCK_Tail();
  1018.  
  1019.     if ( q->guess )
  1020.     {
  1021.         gen("zzGUESS_DONE\n");
  1022.     }
  1023.  
  1024.     /* must duplicate if (alpha)?; one guesses (validates), the second pass matches */
  1025.     if ( q->guess && analysis_point(q)==q )
  1026.     {
  1027.         BLOCK_Preamble(q);
  1028.         BlkLevel++;
  1029.         f = genBlk(q, aSubBlk, &max_k, &need_right_curly);
  1030.         if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k);}
  1031.         { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
  1032.         freeBlkFsets(q);
  1033.         --BlkLevel;
  1034.         BLOCK_Tail();
  1035.     }
  1036.  
  1037.     if (q->end->p1 != NULL) TRANS(q->end->p1);
  1038. }
  1039.  
  1040. /*
  1041.  * Generate code for a rule.
  1042.  *
  1043.  *        rule--> o-->o-Alternatives-o-->o
  1044.  * Or,
  1045.  *        rule--> o-->o-Alternative-o-->o
  1046.  *
  1047.  * The 1st junction is a RuleBlk.  The second can be a SubBlk or just a junction
  1048.  * (one alternative--no block), the last is EndRule.
  1049.  * The second to last is EndBlk if more than one alternative exists in the rule.
  1050.  *
  1051.  * To get to the init-action for a rule, we must bypass the RuleBlk,
  1052.  * and possible SubBlk.
  1053.  * Mark any init-action as generated so genBlk() does not regenerate it.
  1054.  */
  1055. void
  1056. #ifdef __STDC__
  1057. genRule( Junction *q )
  1058. #else
  1059. genRule( q )
  1060. Junction *q;
  1061. #endif
  1062. {
  1063.     int max_k;
  1064.     set follow, rk, f;
  1065.     ActionNode *a;
  1066.     RuleEntry *r;
  1067.     static int file = -1;
  1068.     int need_right_curly;
  1069.     require(q->ntype == nJunction,    "genRule: not junction");
  1070.     require(q->jtype == RuleBlk,    "genRule: not rule");
  1071.  
  1072.     r = (RuleEntry *) hash_get(Rname, q->rname);
  1073.     if ( r == NULL ) warnNoFL("Rule hash table is screwed up beyond belief");
  1074.     if ( q->file != file )        /* open new output file if need to */
  1075.     {
  1076.         if ( output != NULL ) fclose( output );
  1077.         output = fopen(outname(FileStr[q->file]), "w");
  1078.         require(output != NULL, "genRule: can't open output file");
  1079.         if ( file == -1 ) genHdr1(q->file);
  1080.         else genHdr(q->file);
  1081.         file = q->file;
  1082.     }
  1083.     DumpFuncHeader(q,r);
  1084.     tabs++;
  1085.     if ( q->ret!=NULL )
  1086.     {
  1087.         if ( HasComma(q->ret) ) {gen1("struct _rv%d _retv;\n",r->rulenum);}
  1088.         else
  1089.         {
  1090.             tab();
  1091.             DumpType(q->ret, output);
  1092.             gen(" _retv;\n");
  1093.         }
  1094.     }
  1095.     gen("zzRULE;\n");
  1096.     gen1("zzBLOCK(zztasp%d);\n", BlkLevel);
  1097.     gen("zzMake0;\n");
  1098.     gen("{\n");
  1099.  
  1100.     if ( has_guess_block_as_first_item((Junction *)q->p1) )
  1101.     {
  1102.         gen("zzGUESS_BLOCK\n");
  1103.     }
  1104.  
  1105.     /* L o o k  F o r  I n i t  A c t i o n */
  1106.     if ( ((Junction *)q->p1)->jtype == aSubBlk )
  1107.         a = findImmedAction( ((Junction *)q->p1)->p1 );
  1108.     else
  1109.         a = findImmedAction( q->p1 );    /* only one alternative in rule */
  1110.     if ( a!=NULL && !a->is_predicate )
  1111.     {
  1112.         dumpAction(a->action, output, tabs, a->file, a->line, 1);
  1113.         a->done = 1;    /* ignore action. We have already handled it */
  1114.     }
  1115.     if ( TraceGen ) gen1("zzTRACEIN(\"%s\");\n", q->rname);
  1116.  
  1117.     BlkLevel++;
  1118.     q->visited = TRUE;                /* mark RULE as visited for FIRST/FOLLOW */
  1119.     f = genBlk((Junction *)q->p1, RuleBlk, &max_k, &need_right_curly);
  1120.     if ( q->p1 != NULL )
  1121.         if ( ((Junction *)q->p1)->p2 != NULL )
  1122.             {tab(); makeErrorClause((Junction *)q->p1,f,max_k);}
  1123.     { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
  1124.     freeBlkFsets((Junction *)q->p1);
  1125.     q->visited = FALSE;
  1126.     --BlkLevel;
  1127.     gen1("zzEXIT(zztasp%d);\n", BlkLevel);
  1128.  
  1129.     if ( TraceGen ) gen1("zzTRACEOUT(\"%s\");\n", q->rname);
  1130.  
  1131.     if ( q->ret!=NULL ) gen("return _retv;\n") else gen("return;\n");
  1132.     /* E r r o r  R e c o v e r y */
  1133.     NewSet();
  1134.     rk = empty;
  1135.     REACH(q->end, 1, &rk, follow);
  1136.     FillSet( follow );
  1137.     set_free( follow );
  1138.     _gen("fail:\n");
  1139.     gen("zzEXIT(zztasp1);\n");
  1140.     if ( FoundGuessBlk ) gen("if ( zzguessing ) {zzGUESS_FAIL;}\n");
  1141.     if ( q->erraction!=NULL )
  1142.         dumpAction(q->erraction, output, tabs, q->file, q->line, 1);
  1143.     gen1("zzsyn(zzMissText, zzBadTok, %s, zzMissSet, zzMissTok, zzErrk, zzBadText);\n", r->egroup==NULL?"\"\"":r->egroup);
  1144.     gen2("zzresynch(setwd%d, 0x%x);\n", wordnum, 1<<setnum);
  1145.  
  1146.     if ( TraceGen ) gen1("zzTRACEOUT(\"%s\");\n", q->rname);
  1147.  
  1148.     if ( q->ret!=NULL ) gen("return _retv;\n");
  1149.     gen("}\n");
  1150.     tabs--;
  1151.     gen("}\n");
  1152.     if ( q->p2 != NULL ) {TRANS(q->p2);} /* generate code for next rule too */
  1153.     else dumpAfterActions( output );
  1154. }
  1155.  
  1156. static void
  1157. #ifdef __STDC__
  1158. DumpFuncHeader( Junction *q, RuleEntry *r )
  1159. #else
  1160. DumpFuncHeader( q, r )
  1161. Junction *q;
  1162. RuleEntry *r;
  1163. #endif
  1164. {
  1165.     /* A N S I */
  1166.     _gen("\n#ifdef __STDC__\n");
  1167.     if ( q->ret!=NULL )
  1168.     {
  1169.         if ( HasComma(q->ret) ) {gen1("struct _rv%d\n",r->rulenum);}
  1170.         else
  1171.         {
  1172.             DumpType(q->ret, output);
  1173.             gen("\n");
  1174.         }
  1175.     }
  1176.     else
  1177.     {
  1178.         _gen("void\n");
  1179.     }
  1180.     gen2("%s%s(", RulePrefix, q->rname);
  1181.     if ( GenAST )
  1182.     {
  1183.         _gen("AST **_root");
  1184.         if ( q->pdecl!=NULL ) _gen(",");
  1185.     }
  1186.     _gen1("%s)\n", (q->pdecl!=NULL)?q->pdecl:"");
  1187.  
  1188.     /* K & R */
  1189.     gen("#else\n");
  1190.     if ( q->ret!=NULL )
  1191.     {
  1192.         if ( HasComma(q->ret) ) {gen1("struct _rv%d\n",r->rulenum);}
  1193.         else
  1194.         {
  1195.             DumpType(q->ret, output);
  1196.             gen("\n");
  1197.         }
  1198.     }
  1199.     gen2("%s%s(", RulePrefix, q->rname);
  1200.     if ( GenAST )
  1201.     {
  1202.         _gen("_root");
  1203.         if ( q->pdecl!=NULL ) _gen(",");
  1204.     }
  1205.  
  1206.     DumpListOfParmNames( q->pdecl, output );
  1207.     gen(")\n");
  1208.     if ( GenAST ) gen("AST **_root;\n");
  1209.     DumpOldStyleParms( q->pdecl, output );
  1210.     gen("#endif\n");
  1211.     gen("{\n");
  1212. }
  1213.  
  1214. void
  1215. #ifdef __STDC__
  1216. genJunction( Junction *q )
  1217. #else
  1218. genJunction( q )
  1219. Junction *q;
  1220. #endif
  1221. {
  1222.     require(q->ntype == nJunction,    "genJunction: not junction");
  1223.     require(q->jtype == Generic,    "genJunction: not generic junction");
  1224.  
  1225.     if ( q->p1 != NULL ) TRANS(q->p1);
  1226.     if ( q->p2 != NULL ) TRANS(q->p2);
  1227. }
  1228.  
  1229. void
  1230. #ifdef __STDC__
  1231. genEndBlk( Junction *q )
  1232. #else
  1233. genEndBlk( q )
  1234. Junction *q;
  1235. #endif
  1236. {
  1237. }
  1238.  
  1239. void
  1240. #ifdef __STDC__
  1241. genEndRule( Junction *q )
  1242. #else
  1243. genEndRule( q )
  1244. Junction *q;
  1245. #endif
  1246. {
  1247. }
  1248.  
  1249. void
  1250. #ifdef __STDC__
  1251. genHdr( int file )
  1252. #else
  1253. genHdr( file )
  1254. int file;
  1255. #endif
  1256. {
  1257.     _gen("/*\n");
  1258.     _gen(" * A n t l r  T r a n s l a t i o n  H e a d e r\n");
  1259.     _gen(" *\n");
  1260.     _gen(" * Terence Parr, Hank Dietz and Will Cohen: 1989-1993\n");
  1261.     _gen(" * Purdue University Electrical Engineering\n");
  1262.     _gen1(" * ANTLR Version %s\n", Version);
  1263.     _gen(" */\n");
  1264.     _gen("#include <stdio.h>\n");
  1265.     _gen1("#define ANTLR_VERSION    %s\n", VersionDef);
  1266.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  1267.         _gen2("#define %s %s\n", DefaultParserName, ParserName);
  1268.        if ( strcmp(ParserName, DefaultParserName)!=0 )
  1269.         {_gen1("#include \"%s\"\n", RemapFileName);}
  1270.     if ( GenLineInfo ) _gen2(LineInfoFormatStr, 1, FileStr[file]);
  1271.     if ( HdrAction != NULL ) dumpAction( HdrAction, output, 0, -1, 0, 1);
  1272.     if ( FoundGuessBlk )
  1273.     {
  1274.         _gen("#define ZZCAN_GUESS\n");
  1275.         _gen("#include <setjmp.h>\n");
  1276.     }
  1277.     if ( OutputLL_k > 1 ) _gen1("#define LL_K %d\n", OutputLL_k);
  1278.     if ( GenAST ) _gen("#define GENAST\n\n");
  1279.     if ( DemandLookahead ) _gen("#define DEMAND_LOOK\n\n");
  1280.     _gen1("#define zzEOF_TOKEN %d\n", EofToken);
  1281.     _gen1("#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));
  1282.     _gen("#include \"antlr.h\"\n");
  1283.     if ( GenAST ) _gen("#include \"ast.h\"\n\n");
  1284.     _gen1("#include \"%s\"\n", DefFileName);
  1285.     _gen("#include \"dlgdef.h\"\n");
  1286.     _gen1("#include \"%s\"\n", ModeFileName);
  1287. }
  1288.  
  1289. void
  1290. #ifdef __STDC__
  1291. genHdr1( int file )
  1292. #else
  1293. genHdr1( file )
  1294. int file;
  1295. #endif
  1296. {
  1297.     ListNode *p;
  1298.  
  1299.     genHdr(file);
  1300.     if ( GenAST )
  1301.     {
  1302.         _gen("#include \"ast.c\"\n");
  1303.         _gen("zzASTgvars\n\n");
  1304.     }
  1305.     _gen("ANTLR_INFO\n");
  1306.     if ( BeforeActions != NULL )
  1307.     {
  1308.         for (p = BeforeActions->next; p!=NULL; p=p->next)
  1309.             dumpAction( (char *)p->elem, output, 0, -1, 0, 1);
  1310.     }
  1311. }
  1312.  
  1313. void
  1314. #ifdef __STDC__
  1315. genStdPCCTSIncludeFile( FILE *f )
  1316. #else
  1317. genStdPCCTSIncludeFile( f )
  1318. FILE *f;
  1319. #endif
  1320. {
  1321.     fprintf(f,"/*\n");
  1322.     fprintf(f," * %s -- P C C T S  I n c l u d e\n", stdpccts);
  1323.     fprintf(f," *\n");
  1324.     fprintf(f," * Terence Parr, Hank Dietz and Will Cohen: 1989-1993\n");
  1325.     fprintf(f," * Purdue University Electrical Engineering\n");
  1326.     fprintf(f," * ANTLR Version %s\n", Version);
  1327.     fprintf(f," */\n");
  1328.     fprintf(f,"#include <stdio.h>\n");
  1329.     fprintf(f, "#define ANTLR_VERSION    %s\n", VersionDef);
  1330.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  1331.         fprintf(f, "#define %s %s\n", DefaultParserName, ParserName);
  1332.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  1333.         fprintf(f, "#include \"%s\"\n", RemapFileName);
  1334.     if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);
  1335.     if ( OutputLL_k > 1 ) fprintf(f,"#define LL_K %d\n", OutputLL_k);
  1336.     if ( GenAST ) fprintf(f,"#define GENAST\n");
  1337.     if ( DemandLookahead ) fprintf(f,"#define DEMAND_LOOK\n");
  1338.     fprintf(f, "#define zzEOF_TOKEN %d\n", EofToken);
  1339.     fprintf(f, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));
  1340.     fprintf(f,"#include \"antlr.h\"\n");
  1341.     if ( GenAST ) fprintf(f,"#include \"ast.h\"\n");
  1342.     fprintf(f,"#include \"%s\"\n", DefFileName);
  1343.     fprintf(f,"#include \"dlgdef.h\"\n");
  1344.     fprintf(f,"#include \"%s\"\n", ModeFileName);
  1345. }
  1346.  
  1347. /* dump action 's' to file 'output' starting at "local" tab 'tabs'
  1348.    Dump line information in front of action if GenLineInfo is set
  1349.    If file == -1 then GenLineInfo is ignored.
  1350.    The user may redefine the LineInfoFormatStr to his/her liking
  1351.    most compilers will like the default, however.
  1352.  
  1353.    June '93; changed so that empty lines are left alone so that
  1354.    line information is correct for the compiler/debuggers.
  1355. */
  1356. void
  1357. #ifdef __STDC__
  1358. dumpAction( char *s, FILE *output, int tabs, int file, int line, int final_newline )
  1359. #else
  1360. dumpAction( s, output, tabs, file, line, final_newline )
  1361. char *s;
  1362. FILE *output;
  1363. int tabs;
  1364. int file;
  1365. int line;
  1366. int final_newline;
  1367. #endif
  1368. {
  1369.     int inDQuote, inSQuote;
  1370.     require(s!=NULL,         "dumpAction: NULL action");
  1371.     require(output!=NULL,    eMsg1("dumpAction: output FILE is NULL for %s",s));
  1372.  
  1373.     if ( GenLineInfo && file != -1 )
  1374.     {
  1375.         fprintf(output, LineInfoFormatStr, line, FileStr[file]);
  1376.     }
  1377.     PastWhiteSpace( s );
  1378.     /* don't print a tab if first non-white char is a # (preprocessor command) */
  1379.     if ( *s!='#' ) {TAB;}
  1380.     inDQuote = inSQuote = FALSE;
  1381.     while ( *s != '\0' )
  1382.     {
  1383.         if ( *s == '\\' )
  1384.         {
  1385.             putc( *s++, output ); /* Avoid '"' Case */
  1386.             if ( *s == '\0' ) return;
  1387.             if ( *s == '\'' ) putc( *s++, output );
  1388.             if ( *s == '\"' ) putc( *s++, output );
  1389.         }
  1390.         if ( *s == '\'' )
  1391.         {
  1392.             if ( !inDQuote ) inSQuote = !inSQuote;
  1393.         }
  1394.         if ( *s == '"' )
  1395.         {
  1396.             if ( !inSQuote ) inDQuote = !inDQuote;
  1397.         }
  1398.         if ( *s == '\n' )
  1399.         {
  1400.             putc('\n', output);
  1401.             s++;
  1402.             PastWhiteSpace( s );
  1403.             if ( *s == '}' )
  1404.             {
  1405.                 --tabs;
  1406.                 TAB;
  1407.                 putc( *s++, output );
  1408.                 continue;
  1409.             }
  1410.             if ( *s == '\0' ) return;
  1411.             if ( *s != '#' )    /* #define, #endif etc.. start at col 1 */
  1412.             {
  1413.                 TAB;
  1414.             }
  1415.         }
  1416.         if ( *s == '}' && !(inSQuote || inDQuote) )
  1417.         {
  1418.             --tabs;            /* Indent one fewer */
  1419.         }
  1420.         if ( *s == '{' && !(inSQuote || inDQuote) )
  1421.         {
  1422.             tabs++;            /* Indent one more */
  1423.         }
  1424.         putc( *s, output );
  1425.         s++;
  1426.     }
  1427.     if ( final_newline ) putc('\n', output);
  1428. }
  1429.  
  1430. static void
  1431. #ifdef __STDC__
  1432. dumpAfterActions( FILE *output )
  1433. #else
  1434. dumpAfterActions( output )
  1435. FILE *output;
  1436. #endif
  1437. {
  1438.     ListNode *p;
  1439.     require(output!=NULL, "dumpAfterActions: output file was NULL for some reason");
  1440.     if ( AfterActions != NULL )
  1441.     {
  1442.         for (p = AfterActions->next; p!=NULL; p=p->next)
  1443.             dumpAction( (char *)p->elem, output, 0, -1, 0, 1 );
  1444.     }
  1445.     fclose( output );
  1446. }
  1447.  
  1448. /*
  1449.  * Find the next action in the stream of execution.  Do not pass
  1450.  * junctions with more than one path leaving them.
  1451.  * Only pass generic junctions.
  1452.  *
  1453.  *    Scan forward while (generic junction with p2==NULL)
  1454.  *    If we stop on an action, return ptr to the action
  1455.  *    else return NULL;
  1456.  */
  1457. static ActionNode *
  1458. #ifdef __STDC__
  1459. findImmedAction( Node *q )
  1460. #else
  1461. findImmedAction( q )
  1462. Node *q;
  1463. #endif
  1464. {
  1465.     Junction *j;
  1466.     require(q!=NULL, "findImmedAction: NULL node");
  1467.     require(q->ntype>=1 && q->ntype<=NumNodeTypes, "findImmedAction: invalid node");
  1468.     
  1469.     while ( q->ntype == nJunction )
  1470.     {
  1471.         j = (Junction *)q;
  1472.         if ( j->jtype != Generic || j->p2 != NULL ) return NULL;
  1473.         q = j->p1;
  1474.         if ( q == NULL ) return NULL;
  1475.     }
  1476.     if ( q->ntype == nAction ) return (ActionNode *)q;
  1477.     return NULL;
  1478. }
  1479.  
  1480. static void
  1481. #ifdef __STDC__
  1482. dumpRetValAssign( char *retval, char *ret_def )
  1483. #else
  1484. dumpRetValAssign( retval, ret_def )
  1485. char *retval;
  1486. char *ret_def;
  1487. #endif
  1488. {
  1489.     char *q = ret_def;
  1490.     
  1491.     tab();
  1492.     while ( *retval != '\0' )
  1493.     {
  1494.         while ( isspace((*retval)) ) retval++;
  1495.         while ( *retval!=',' && *retval!='\0' ) putc(*retval++, output);
  1496.         fprintf(output, " = _trv.");
  1497.         
  1498.         DumpNextNameInDef(&q, output);
  1499.         putc(';', output); putc(' ', output);
  1500.         if ( *retval == ',' ) retval++;
  1501.     }
  1502. }
  1503.  
  1504. /* This function computes the set of tokens that can possibly be seen k
  1505.  * tokens in the future from point j
  1506.  */
  1507. static set
  1508. #ifdef __STDC__
  1509. ComputeErrorSet( Junction *j, int k )
  1510. #else
  1511. ComputeErrorSet( j, k )
  1512. Junction *j;
  1513. int k;
  1514. #endif
  1515. {
  1516.     Junction *alt1;
  1517.     set a, rk, f;
  1518.     require(j->ntype==nJunction, "ComputeErrorSet: non junction passed");
  1519.  
  1520.     f = rk = empty;
  1521.     for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2)
  1522.     {
  1523.         REACH(alt1->p1, k, &rk, a);
  1524.         require(set_nil(rk), "ComputeErrorSet: rk != nil");
  1525.         set_free(rk);
  1526.         set_orin(&f, a);
  1527.         set_free(a);
  1528.     }
  1529.     return f;
  1530. }
  1531.  
  1532. static void
  1533. #ifdef __STDC__
  1534. makeErrorClause( Junction *q, set f, int max_k )
  1535. #else
  1536. makeErrorClause( q, f, max_k )
  1537. Junction *q;
  1538. set f;
  1539. int max_k;
  1540. #endif
  1541. {
  1542.     if ( max_k == 1 )
  1543.     {
  1544.         _gen1("else {zzFAIL(1,zzerr%d", DefErrSet(&f))
  1545.         set_free(f);
  1546.     }
  1547.     else
  1548.     {
  1549.         int i;
  1550.         set_free(f);
  1551.         _gen1("else {zzFAIL(%d", max_k);
  1552.         for (i=1; i<=max_k; i++)
  1553.         {
  1554.             f = ComputeErrorSet(q, i);
  1555.             _gen1(",zzerr%d", DefErrSet( &f ));
  1556.             set_free(f);
  1557.         }
  1558.     }
  1559.     _gen(",&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}\n");
  1560. }
  1561.