gen.c
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:109k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * gen.c
  3.  *
  4.  * Generate C code (ANSI, K&R, C++)
  5.  *
  6.  * SOFTWARE RIGHTS
  7.  *
  8.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  9.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  10.  * company may do whatever they wish with source code distributed with
  11.  * PCCTS or the code generated by PCCTS, including the incorporation of
  12.  * PCCTS, or its output, into commerical software.
  13.  *
  14.  * We encourage users to develop software with PCCTS.  However, we do ask
  15.  * that credit is given to us for developing PCCTS.  By "credit",
  16.  * we mean that if you incorporate our source code into one of your
  17.  * programs (commercial product, research project, or otherwise) that you
  18.  * acknowledge this fact somewhere in the documentation, research report,
  19.  * etc...  If you like PCCTS and have developed a nice tool with the
  20.  * output, please mention that you developed it using PCCTS.  In
  21.  * addition, we ask that this header remain intact in our source code.
  22.  * As long as these guidelines are kept, we expect to continue enhancing
  23.  * this system and expect to make other tools available as they are
  24.  * completed.
  25.  *
  26.  * ANTLR 1.33
  27.  * Terence Parr
  28.  * Parr Research Corporation
  29.  * with Purdue University and AHPCRC, University of Minnesota
  30.  * 1989-1998
  31.  */
  32. #include <stdio.h>
  33. #include <ctype.h>
  34. #include "set.h"
  35. #include "syn.h"
  36. #include "hash.h"
  37. #include "generic.h"
  38. #include "dlgdef.h"
  39. #define NumExprPerLine 4
  40. static int on1line=0;
  41. static set tokensRefdInBlock;
  42. extern char *PRED_AND_LIST;
  43. extern char *PRED_OR_LIST;
  44. /* T r a n s l a t i o n  T a b l e s */
  45. /* C_Trans[node type] == pointer to function that knows how to translate that node. */
  46. #ifdef __cplusplus
  47. void (*C_Trans[NumNodeTypes+1])(...) = {
  48. NULL,
  49. NULL, /* See next table.
  50. Junctions have many types */
  51. (void (*)(...)) genRuleRef,
  52. (void (*)(...)) genToken,
  53. (void (*)(...)) genAction
  54.  };
  55. #else
  56. void (*C_Trans[NumNodeTypes+1])() = {
  57. NULL,
  58. NULL, /* See next table.
  59. Junctions have many types */
  60. genRuleRef,
  61. genToken,
  62. genAction
  63.  };
  64. #endif
  65. /* C_JTrans[Junction type] == pointer to function that knows how to translate that
  66.  * kind of junction node.
  67.  */
  68. #ifdef __cplusplus
  69. void (*C_JTrans[NumJuncTypes+1])(...) = {
  70. NULL,
  71. (void (*)(...)) genSubBlk,
  72. (void (*)(...)) genOptBlk,
  73. (void (*)(...)) genLoopBlk,
  74. (void (*)(...)) genEndBlk,
  75. (void (*)(...)) genRule,
  76. (void (*)(...)) genJunction,
  77. (void (*)(...)) genEndRule,
  78. (void (*)(...)) genPlusBlk,
  79. (void (*)(...)) genLoopBegin
  80.  };
  81. #else
  82. void (*C_JTrans[NumJuncTypes+1])() = {
  83. NULL,
  84. genSubBlk,
  85. genOptBlk,
  86. genLoopBlk,
  87. genEndBlk,
  88. genRule,
  89. genJunction,
  90. genEndRule,
  91. genPlusBlk,
  92. genLoopBegin
  93.  };
  94. #endif
  95. #define PastWhiteSpace(s) while (*(s) == ' ' || *(s) == 't') {s++;}
  96. static int tabs = 0;
  97. /* MR6 Got tired of text running off page when using standard tab stops */
  98. #define TAB { int i;                  
  99.       if (TabWidth==0) {                  
  100.          for (i=0; i<tabs; i++) fputc('t', output);
  101.       } else {           
  102.  for (i=0; i<tabs*TabWidth; i++) fputc(' ',output);     
  103.       };                 
  104.     }
  105. static void
  106. #ifdef __USE_PROTOS
  107. tab( void )
  108. #else
  109. tab( )
  110. #endif
  111. TAB
  112. #ifdef __USE_PROTOS
  113. static char *tokenFollowSet(TokNode *);
  114. static ActionNode *findImmedAction( Node * );
  115. static void dumpRetValAssign(char *, char *);
  116. static void dumpAfterActions(FILE *output);
  117. static set ComputeErrorSet(Junction *, int);
  118. static void makeErrorClause(Junction *, set, int);
  119. static void DumpFuncHeader( Junction *, RuleEntry * );
  120. static int has_guess_block_as_first_item(Junction *);
  121. static int genExprSets(set *, int);
  122. static void genExprTree( Tree *t, int k );
  123. static void genExprTreeOriginal( Tree *t, int k );                  /* MR10 */
  124. static char * findOuterHandlerLabel(ExceptionGroup *eg);            /* MR7 */
  125. static void OutLineInfo(FILE *file,int line,char *fileName);        /* MR14 */
  126. #else
  127. static char *tokenFollowSet();
  128. static ActionNode *findImmedAction();
  129. static void dumpRetValAssign();
  130. static void dumpAfterActions();
  131. static set ComputeErrorSet();
  132. static void makeErrorClause();
  133. static void DumpFuncHeader();
  134. static int has_guess_block_as_first_item();
  135. static int genExprSets();
  136. static void genExprTree();
  137. static void genExprTreeOriginal();                                  /* MR10 */
  138. static char * findOuterHandlerLabel();                              /* MR7 */
  139. static void OutLineInfo();                                          /* MR14 */
  140. #endif
  141. #define gen(s) {tab(); fprintf(output, s);}
  142. #define gen1(s,a) {tab(); fprintf(output, s,a);}
  143. #define gen2(s,a,b) {tab(); fprintf(output, s,a,b);}
  144. #define gen3(s,a,b,c) {tab(); fprintf(output, s,a,b,c);}
  145. #define gen4(s,a,b,c,d) {tab(); fprintf(output, s,a,b,c,d);}
  146. #define gen5(s,a,b,c,d,e) {tab(); fprintf(output, s,a,b,c,d,e);}
  147. #define gen6(s,a,b,c,d,e,f) {tab(); fprintf(output, s,a,b,c,d,e,f);}
  148. #define gen7(s,a,b,c,d,e,f,g) {tab(); fprintf(output, s,a,b,c,d,e,f,g);}
  149. #define _gen(s) {fprintf(output, s);}
  150. #define _gen1(s,a) {fprintf(output, s,a);}
  151. #define _gen2(s,a,b) {fprintf(output, s,a,b);}
  152. #define _gen3(s,a,b,c) {fprintf(output, s,a,b,c);}
  153. #define _gen4(s,a,b,c,d){fprintf(output, s,a,b,c,d);}
  154. #define _gen5(s,a,b,c,d,e){fprintf(output, s,a,b,c,d,e);}
  155. #define _gen6(s,a,b,c,d,e,f){fprintf(output, s,a,b,c,d,e,f);}
  156. #define _gen7(s,a,b,c,d,e,f,g){fprintf(output, s,a,b,c,d,e,f,g);}
  157. /* MR11 a convenient place to set a break point */
  158. void MR_break() {
  159.   return;
  160. }
  161. /* MR10 genTraceOut(Junction *)      */
  162. #ifdef __STDC__
  163. static void genTraceOut(Junction *q)
  164. #else
  165. static void genTraceOut(q)
  166.   Junction  *q;
  167. #endif
  168. {
  169.   if ( TraceGen )
  170. if ( GenCC ) {gen1("zzTRACEOUT("%s");n", q->rname);}
  171.      else gen1("zzTRACEOUT((ANTLRChar *)"%s");n", q->rname);
  172. }
  173. static void
  174. #ifdef __USE_PROTOS
  175. warn_about_using_gk_option(void)
  176. #else
  177. warn_about_using_gk_option()
  178. #endif
  179. {
  180. static int warned_already=0;
  181. if ( !DemandLookahead || warned_already ) return;
  182. warned_already = 1;
  183. warnNoFL("-gk option could cause trouble for <<...>>? predicates");
  184. }
  185. void
  186. #ifdef __USE_PROTOS
  187. freeBlkFsets( Junction *q )
  188. #else
  189. freeBlkFsets( q )
  190. Junction *q;
  191. #endif
  192. {
  193. int i;
  194. Junction *alt;
  195. require(q!=NULL, "freeBlkFsets: invalid node");
  196. for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
  197. {
  198. for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]);
  199. }
  200. }
  201. /*
  202.  * Generate a local variable allocation for each token references
  203.  * in this block.
  204.  */
  205. static void
  206. #ifdef __USE_PROTOS
  207. genTokenPointers( Junction *q )
  208. #else
  209. genTokenPointers( q )
  210. Junction *q;
  211. #endif
  212. {
  213. /* Rule refs are counted and can be referenced, but their
  214.  * value is not set to anything useful ever.
  215.  *
  216.      * The ptrs are to be named _tij where i is the current level
  217.  * and j is the element number within an alternative.
  218.  */
  219. int first=1, t=0;
  220. set a;
  221. tokensRefdInBlock = q->tokrefs;
  222. if ( set_deg(q->tokrefs) == 0 ) return;
  223. a = set_dup(q->tokrefs);
  224. gen("ANTLRTokenPtr ");
  225. for (; !set_nil(a); set_rm(t, a))
  226. {
  227. t = set_int(a);
  228. if ( first ) first = 0;
  229. else _gen(",");
  230. if ( !DontCopyTokens ) _gen2("_tv%d%d,", BlkLevel, t);
  231. _gen2("_t%d%d", BlkLevel, t);
  232. if ( !DontCopyTokens ) {_gen2("= &_tv%d%d", BlkLevel, t);}
  233. else _gen("=NULL");
  234. }
  235. _gen(";n");
  236. set_free(a);
  237. }
  238. static int
  239. #ifdef __USE_PROTOS
  240. hasDefaultException(ExceptionGroup *eg)
  241. #else
  242. hasDefaultException(eg)
  243. ExceptionGroup *eg;
  244. #endif
  245. {
  246.     ListNode *q;
  247.     for (q = eg->handlers->next; q!=NULL; q=q->next)
  248.     {
  249.         ExceptionHandler *eh = (ExceptionHandler *)q->elem;
  250.         if ( strcmp("default", eh->signalname)==0 ) {
  251.             return 1;
  252.         }
  253.     }
  254.     return 0;
  255. }
  256. static void
  257. #ifdef __USE_PROTOS
  258. dumpException(ExceptionGroup *eg, int no_default_case)
  259. #else
  260. dumpException(eg, no_default_case)
  261. ExceptionGroup *eg;
  262. int no_default_case;
  263. #endif
  264. {
  265.     char    *outerLabel;                                             /* MR7 */
  266.     int     nullOuterLabel=0;                                        /* MR7 */
  267.     int     altHandler=0;                                            /* MR7 */
  268.     int     ruleHandler=0;                                           /* MR7 */
  269.     int     namedHandler=0;                                          /* MR7 */
  270.     outerLabel=findOuterHandlerLabel(eg);                            /* MR7 */
  271.     if (*outerLabel=='') nullOuterLabel=1;                         /* MR7 */
  272.     if (eg->label != NULL) {                                         /* MR7 */
  273.       namedHandler=1;                                                /* MR7 */
  274.     } else if (eg->forRule) {                                        /* MR7 */
  275.       ruleHandler=1;                                                 /* MR7 */
  276.     } else {                                                         /* MR7 */
  277.       altHandler=1;                                                  /* MR7 */
  278.     };                                                               /* MR7 */
  279. #if 0
  280. **     if (! eg->used) {                                             /* MR7 */
  281. **      warnFL("exception group never used",                         /* MR7 */
  282. **             FileStr[eg->altstart->file],eg->altstart->line);      /* MR7 */
  283. **     };                                                            /* MR7 */
  284. #endif
  285.     if (namedHandler) {                                              /* MR7 */
  286.   gen1("switch ( _signal ) {  /* [%s] */n",eg->label);          /* MR7 */
  287.     } else {                                                         /* MR7 */
  288.   gen("switch ( _signal ) {n");                                 /* MR7 */
  289.       gen("case NoSignal: break;  /* MR7 */n");                     /* MR7 */
  290.     };                                                               /* MR7 */
  291. {
  292. ListNode *q;
  293. for (q = eg->handlers->next; q!=NULL; q=q->next)
  294. {
  295. ExceptionHandler *eh = (ExceptionHandler *)q->elem;
  296. if ( strcmp("default", eh->signalname)==0 ) {
  297. gen("default :n");
  298. tabs++;
  299. dumpAction(eh->action, output, tabs, -1, 1, 1);
  300.                 gen("_signal=NoSignal;  /* MR7 */n");               /* MR7 */
  301.                 gen("break;  /* MR7 */n");                          /* MR7 */
  302. tabs--;
  303. gen("}n");
  304.                 /* copied from later code in dumpException              MR7 */
  305.                 if (namedHandler) {                                  /* MR7 */
  306.                   gen("if (_signal != NoSignal)");                   /* MR7 */
  307.                   _gen1(" goto %s_handler;  /* MR7 */n",outerLabel);/* MR7 */
  308.                 } else if (altHandler) {                             /* MR7 */
  309.                   gen1("goto %s_handler;  /* MR7 */n",outerLabel);  /* MR7 */
  310.                 };
  311. return;
  312. }
  313. gen1("case %s :n", eh->signalname);
  314. tabs++;
  315. if ( eh->action != NULL )
  316. {
  317. dumpAction(eh->action, output, tabs, -1, 1, 1);
  318.                 gen("break;  /* MR7 */n");                          /* MR7 */
  319. }
  320. tabs--;
  321. }
  322. }
  323. if ( no_default_case ) return;
  324. gen("default :n");
  325.     tabs++;                                                         /* MR7 */
  326.     gen("break;  /* MR7 */n");                                     /* MR7 */
  327.     tabs--;                                                         /* MR7 */
  328. tabs++;
  329. /***** gen("*_retsignal = _signal;n"); *****/
  330. tabs--;
  331. gen("}n");
  332.     if (namedHandler) {                                             /* MR7 */
  333.       gen("if (_signal != NoSignal)");                              /* MR7 */
  334.       _gen1(" goto %s_handler;  /* MR7 */n",outerLabel);           /* MR7 */
  335.     } else if (altHandler) {                                        /* MR7 */
  336.       gen1("goto %s_handler;  /* MR7 */n",outerLabel);             /* MR7 */
  337.     };
  338. }
  339. static void
  340. #ifdef __USE_PROTOS
  341. dumpExceptions(ListNode *list)
  342. #else
  343. dumpExceptions(list)
  344. ListNode *list;
  345. #endif
  346. {
  347. ListNode *p;
  348. for (p = list->next; p!=NULL; p=p->next)
  349. {
  350. ExceptionGroup *eg = (ExceptionGroup *) p->elem;
  351. _gen2("%s%s_handler:n",
  352.   eg->label==NULL?"":eg->label,
  353.   eg->altID==NULL?"":eg->altID);
  354. if ( eg->altID!=NULL ) dumpException(eg, 0);
  355. else {
  356. /* This must be the rule exception handler */
  357. dumpException(eg, 1);
  358. if ( !hasDefaultException(eg) )
  359.             {
  360.                 gen("default :n");
  361.                 tabs++;
  362.                 gen("zzdflthandlers(_signal,_retsignal);n");
  363.                 tabs--;
  364.                 gen("}n");
  365.             }
  366. }
  367. }
  368. }
  369. /* For each element label that is found in a rule, generate a unique
  370.  * Attribute (and AST pointer if GenAST) variable.
  371.  */
  372. void
  373. #ifdef __USE_PROTOS
  374. genElementLabels(ListNode *list)
  375. #else
  376. genElementLabels(list)
  377. ListNode *list;
  378. #endif
  379. {
  380. int first=1;
  381. ListNode *p;
  382. if ( GenCC ) {gen("ANTLRTokenPtr");}
  383. else {gen("Attrib");}
  384. for (p = list->next; p!=NULL; p=p->next)
  385. {
  386. char *ep = (char *)p->elem;
  387. if ( first ) first = 0;
  388. else _gen(",");
  389. if ( GenCC ) {_gen1(" %s=NULL",ep);}
  390. else {_gen1(" %s",ep);}
  391. }
  392. _gen(";n");
  393. if ( !GenAST ) return;
  394. first = 1;
  395. gen("AST");
  396. for (p = list->next; p!=NULL; p=p->next)
  397. {
  398. char *ep = (char *)p->elem;
  399. if ( first ) first = 0;
  400. else _gen(",");
  401. _gen1(" *%s_ast=NULL",ep);
  402. }
  403. _gen(";n");
  404. }
  405. /*
  406.  * Generate a local variable allocation for each token or rule reference
  407.  * in this block.
  408.  */
  409. static void
  410. #ifdef __USE_PROTOS
  411. genASTPointers( Junction *q )
  412. #else
  413. genASTPointers( q )
  414. Junction *q;
  415. #endif
  416. {
  417. int first=1, t;
  418. set a;
  419. a = set_or(q->tokrefs, q->rulerefs);
  420. if ( set_deg(a) > 0 )
  421. {
  422. gen("AST ");
  423. for (; !set_nil(a); set_rm(t, a))
  424. {
  425. t = set_int(a);
  426. if ( first ) first = 0;
  427. else _gen(",");
  428. _gen2("*_ast%d%d=NULL", BlkLevel, t);
  429. }
  430. set_free(a);
  431. }
  432. _gen(";n");
  433. }
  434. static void
  435. #ifdef __USE_PROTOS
  436. BLOCK_Head( void )
  437. #else
  438. BLOCK_Head( )
  439. #endif
  440. {
  441. gen("{n");
  442. tabs++;
  443. if ( !GenCC ) gen1("zzBLOCK(zztasp%d);n", BlkLevel);
  444. }
  445. static void
  446. #ifdef __USE_PROTOS
  447. BLOCK_Tail( void )
  448. #else
  449. BLOCK_Tail( )
  450. #endif
  451. {
  452. if ( !GenCC ) gen1("zzEXIT(zztasp%d);n", BlkLevel);
  453. if ( !GenCC ) gen("}n");
  454. tabs--;
  455. gen("}n");
  456. }
  457. static void
  458. #ifdef __USE_PROTOS
  459. BLOCK_Preamble( Junction *q )
  460. #else
  461. BLOCK_Preamble( q )
  462. Junction *q;
  463. #endif
  464. {
  465. ActionNode *a;
  466. Junction *begin;
  467. BLOCK_Head();
  468. if ( GenCC ) genTokenPointers(q);
  469. if ( GenCC&&GenAST ) genASTPointers(q);
  470. if ( q->jtype == aPlusBlk ) gen("int zzcnt=1;n");
  471. if ( q->parm != NULL && !q->predparm ) gen1("zzaPush(%s);n", q->parm)
  472. else if ( !GenCC ) gen("zzMake0;n");
  473. if ( !GenCC ) gen("{n");
  474. if ( q->jtype == aLoopBegin ) begin = (Junction *) ((Junction *)q->p1);
  475. else begin = q;
  476. if ( has_guess_block_as_first_item(begin) )
  477. {
  478. gen("zzGUESS_BLOCKn");
  479. }
  480. if ( q->jtype == aLoopBegin )
  481. a = findImmedAction( ((Junction *)q->p1)->p1 ); /* look at aLoopBlk */
  482. else
  483. a = findImmedAction( q->p1 );
  484. if ( a!=NULL && !a->is_predicate) {
  485. if (!a->noHoist) dumpAction(a->action, output, tabs, a->file, a->line, 1);
  486. a->done = 1; /* remove action. We have already handled it */
  487. }
  488. }
  489. void
  490. #ifdef __USE_PROTOS
  491. genCombinedPredTreeContextOrig( Predicate *p )
  492. #else
  493. genCombinedPredTreeContextOrig( p )
  494. Predicate *p;
  495. #endif
  496. {
  497. static set *ctx=NULL; /* genExprSets() is destructive, make copy*/
  498. require(p!=NULL, "can't make context tree for NULL pred tree");
  499. #ifdef DBG_PRED
  500. fprintf(stderr, "enter genCombinedPredTreeContextOrig(%s,0x%x) with sets:n", p->expr, p);
  501. s_fprT(stderr, p->scontext[1]);
  502. fprintf(stderr, "n");
  503. #endif
  504. if ( p->down == NULL )
  505. {
  506. /*** if ( p->k>1 && p->tcontext!=NULL ) ***/
  507. if ( p->tcontext!=NULL )
  508. {
  509. _gen("(");
  510. genExprTree(p->tcontext, 1);
  511. _gen(")");
  512. }
  513. /*** else if ( p->k==1 && set_deg(p->scontext[1])>0 ) ***/
  514. else if ( set_deg(p->scontext[1])>0 )
  515. {
  516. if ( ctx==NULL ) ctx = (set *)calloc(CLL_k+1, sizeof(set));
  517. require(ctx!=NULL, "ctx cannot allocate");
  518. ctx[0]=empty;
  519. ctx[1]=set_dup(p->scontext[1]);
  520. _gen("(");
  521. genExprSets(&(ctx[0]), p->k);
  522. _gen(")");
  523. set_free(ctx[1]);
  524. }
  525. else if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) {
  526. fatal_internal("pred tree is orphan OR or AND list");
  527. }
  528. else {
  529.             if (! HoistPredicateContext) {
  530.               _gen(" 1 /* no context: prc is off */ ");
  531.             } else {
  532.               fatal_internal("pred tree context is empty");
  533.             };
  534. }
  535. return;
  536. }
  537. /* MR10 - make AND just like OR */
  538. if ( p->expr == PRED_AND_LIST )
  539. {
  540.         Predicate *list = p->down;
  541.         for (; list!=NULL; list=list->right)
  542.         {
  543.            genCombinedPredTreeContextOrig(list);
  544.          if ( list->right!=NULL ) _gen("|| /* MR10 was wrong */ ");
  545.         };
  546. return;
  547. }
  548. if ( p->expr == PRED_OR_LIST )
  549. {
  550.         Predicate *list = p->down;
  551.         for (; list!=NULL; list=list->right)
  552.         {
  553.            genCombinedPredTreeContextOrig(list);
  554.            if ( list->right!=NULL ) _gen("||");
  555.         };
  556.         return;
  557.      };
  558. fatal("pred tree is really wacked");
  559. }
  560. /* [genCombinedPredTreeContext] */
  561. void
  562. #ifdef __USE_PROTOS
  563. genCombinedPredTreeContext( Predicate *p )
  564. #else
  565. genCombinedPredTreeContext( p )
  566. Predicate *p;
  567. #endif
  568. {
  569.   Tree  *t;
  570.   int   predDepth=0;
  571.   if (0 && ! MR_usingPredNames && ! MRhoisting) {
  572.     genCombinedPredTreeContextOrig(p);
  573.   } else {
  574. /* MR13 */    MR_pred_depth(p,&predDepth);
  575. /* MR13 */    if (predDepth == 1) {
  576. /* MR13 */
  577. /* MR13 */      set   scontext[2];
  578. /* MR13 */      scontext[0]=empty;
  579. /* MR13 */      scontext[1]=MR_compute_pred_set(p);
  580. /* MR13 */      if (set_nil(scontext[1])) {
  581. /* MR13 */        _gen(" 1 /* MR12 no context (-prc off) */ ");
  582. /* MR13 */      } else {
  583. /* MR13 */        _gen("(");
  584. /* MR13 */        genExprSets(&scontext[0], 1);
  585. /* MR13 */        set_free(scontext[1]);
  586. /* MR13 */        _gen(")");
  587. /* MR13 */      };
  588.     } else {
  589.       t=MR_compute_pred_tree_context(p);
  590.       if (t == NULL) {
  591.         _gen(" 1 /* MR12 no context (-prc off) */ ");
  592.       } else {
  593.         _gen("(");
  594.         genExprTree(t, 1);
  595.         Tfree(t);   /* MR10 */
  596.         _gen(")");
  597.       };
  598.     };
  599.   };
  600. }
  601. /* [genPredTreeGate] */
  602. void
  603. #ifdef __USE_PROTOS
  604. genPredTreeGate( Predicate *p, int in_and_expr )
  605. #else
  606. genPredTreeGate( p, in_and_expr )
  607. Predicate *p;
  608. int in_and_expr;
  609. #endif
  610. {
  611. if ( in_and_expr )
  612. {
  613. _gen("!(");
  614. genCombinedPredTreeContext(p);
  615. _gen(")||");
  616. if ( p->down!=NULL ) _gen("n");
  617. }
  618. else
  619. {
  620. _gen("(");
  621. genCombinedPredTreeContext(p);
  622. _gen(")&&");
  623. if ( p->down!=NULL ) _gen("n");
  624. }
  625. }
  626. #ifdef __USE_PROTOS
  627. void genPredEntry(Predicate *p,int outer)
  628. #else
  629. void genPredEntry(p,outer)
  630.   Predicate     *p;
  631.   int           outer;
  632. #endif
  633. {
  634.     int         inverted=0;
  635.     Predicate   *q;
  636.     int         localOuter=outer;
  637.     int         needRP=0;
  638.     if (p == NULL) return;
  639.     if (p->predEntry != NULL && p->predEntry->predLiteral != NULL) {
  640.       if (p->inverted != p->predEntry->pred->inverted) {
  641.         _gen("! /* inverted pred */ (");
  642.         needRP=1;
  643.       } else {
  644.         if (!localOuter) _gen("(");
  645.         needRP=1;
  646.       };
  647.       dumpAction(p->predEntry->predLiteral,output,0,p->source->file,p->source->line,0);
  648.       if (needRP) _gen(")");
  649.       return;
  650.     };
  651.     inverted=p->inverted;
  652.     if (inverted) {
  653.       _gen(" ! /* inverted pred */ (");
  654.       localOuter=1;
  655.     };
  656.     if (p->expr == PRED_OR_LIST) {
  657.       if (!localOuter) _gen("(");
  658.       for (q=p->down; q != NULL ; q=q->right) {
  659.         genPredEntry(q,0);
  660.         if (q->right != NULL) _gen(" || ");
  661.       };
  662.       if (!localOuter) _gen(")");
  663.     } else if (p->expr == PRED_AND_LIST) {
  664.       if (!localOuter) _gen("(");
  665.       for (q=p->down; q != NULL ; q=q->right) {
  666.         genPredEntry(q,0);
  667.         if (q->right != NULL) _gen(" && ");
  668.       };
  669.       if (!localOuter) _gen(")");
  670.     } else {
  671.       if (!localOuter) _gen("(");
  672.       require (p->source != NULL,"predEntry->source == NULL");
  673.       require (p->source->inverted == 0,"dumpPredEntry p->source->inverted != 0");
  674.       dumpAction(p->source->action,output,0,p->source->file,p->source->line,0);
  675.       if (!localOuter) _gen(")");
  676.     };
  677.     if (inverted) {
  678.         _gen(")");
  679.     }
  680. }
  681. void
  682. #ifdef __USE_PROTOS
  683. dumpPredAction(ActionNode *anode,
  684.                     char *s,FILE *output,int tabs,int file,int line,int final_newline)
  685. #else
  686. dumpPredAction(anode,
  687.                     s,output,tabs,file,line,final_newline)
  688.     ActionNode  *anode;
  689.     char        *s;
  690.     FILE        *output;
  691.     int         tabs;
  692.     int         file;
  693.     int         line;
  694.     int         final_newline;
  695. #endif
  696. {
  697.     PredEntry   *predEntry=anode->predEntry;
  698.     int         inverted=anode->inverted;
  699.     Predicate   *workPred;
  700.     if (predEntry == NULL) {
  701.       /* inline predicate literal */
  702.       require(inverted == 0,"dumpPredAction action->inverted");
  703.      dumpAction(s,output,tabs,file,line,final_newline);
  704.     } else {
  705.       /* a reference to a predicate - possibly with an inverted source */
  706.       if (predEntry->predLiteral != NULL) {
  707.         if (inverted) _gen("! /* inverted pred */ (");
  708.         dumpAction(predEntry->predLiteral,output,0,anode->file,anode->line,0);
  709.         if (inverted) _gen(")");
  710.       } else {
  711.         workPred=predicate_dup(predEntry->pred);
  712.         if (inverted) workPred->inverted=!workPred->inverted;
  713.         genPredEntry(workPred,1);
  714.         predicate_free(workPred);
  715.       };
  716.     };
  717. }
  718. /* [genPred] */
  719. void
  720. #ifdef __USE_PROTOS
  721. genPred(Predicate *p, Node *j,int suppress_sva)
  722. #else
  723. genPred(p,j,suppress_sva)
  724.     Predicate   *p;
  725.     Node        *j;
  726.     int         suppress_sva;
  727. #endif
  728. {
  729. if ( FoundException && !suppress_sva) {_gen("(_sva=(");}    /* MR11 suppress_sva */
  730. else {_gen("(");}
  731. if ( GenLineInfo && j->file != -1 ) _gen("n");
  732.     if (p->source != NULL && p->source->ampersandPred != NULL) {
  733.       if (p->source->ampersandPred->k == 1) {
  734.             set     ctx[2];
  735. ctx[0]=empty;
  736. ctx[1]=set_dup(p->source->ampersandPred->scontext[1]);
  737. _gen("(");
  738. genExprSets(&(ctx[0]), p->k);
  739. _gen(") && ");
  740. set_free(ctx[1]);
  741.       } else {
  742.         _gen("( ");
  743.         genExprTree(p->source->ampersandPred->tcontext,1);
  744. _gen(" ) && ");
  745.       };
  746.     };
  747.     dumpPredAction((ActionNode *)p->source,
  748.                 p->expr, output, 0, -1 /*indicates no line info*/, j->line, 0);
  749. if ( FoundException && !suppress_sva)   /* MR11 suppress_sva */
  750.          {_gen("),_sva)");}    /* MR10 - get red of "meant ==" messages */
  751. else {_gen(")");}
  752. }
  753. void
  754. #ifdef __USE_PROTOS
  755. MR_distinctORcontextOpt(Predicate *p,Node *j,int in_and_expr)
  756. #else
  757. MR_distinctORcontextOpt(p,j,in_and_expr)
  758.     Predicate   *p;
  759.     Node        *j;
  760.     int         in_and_expr;
  761. #endif
  762. {
  763.     Predicate   *q;
  764.     _gen(" /* MR10 Distinct OR context optimization */ n");
  765.     if (in_and_expr) {
  766.       gen("zzpf=0,n");
  767.       for (q=p->down; q != NULL; q=q->right) {
  768.         gen("(  ");
  769.         genCombinedPredTreeContext(q);
  770.         _gen(" && (zzpf=1, ");
  771.         genPred(q,j,0);
  772.         _gen("  )) ||n");
  773.       };
  774.       gen("!zzpf)");
  775.     } else {
  776.       require (0,
  777.             "MR_distinctORcontextOpt: can't get here when using MR_predSimplify");
  778. #if 0
  779. **      for (q=p->down; q != NULL; q=q->right) {
  780. **        gen("(  ");
  781. **        genCombinedPredTreeContext(q);
  782. **        _gen(" && ");
  783. **        genPred(q,j);
  784. **        if (q->right != NULL) {
  785. **          _gen("  ) ||n");
  786. **        };
  787. **      };
  788. **      gen(")");
  789. #endif
  790.    };
  791. }
  792. void
  793. #ifdef __USE_PROTOS
  794. genPredTreeOrig( Predicate *p, Node *j, int in_and_expr )
  795. #else
  796. genPredTreeOrig( p, j, in_and_expr )
  797. Predicate *p;
  798. Node *j;
  799. int in_and_expr;
  800. #endif
  801. {
  802. /* MR10 */  int     allHaveContext=1;
  803. /* MR10 */  int     noneHaveContext=1;
  804. /* MR10 */  MR_predContextPresent(p,&allHaveContext,&noneHaveContext);
  805. if ( ! noneHaveContext )                  /* MR10 context guards ignored when -prc off */
  806. {
  807. _gen("(");
  808. genPredTreeGate(p, in_and_expr);
  809. }
  810. /* if leaf node, just gen predicate */
  811. if ( p->down==NULL )
  812. {
  813. genPred(p,j,0);
  814. if ( ! noneHaveContext ) _gen(")");   /* MR10 context guards ignored when -prc off */
  815. return;
  816. }
  817. /* if AND list, do both preds (only two possible) */
  818. if ( p->expr == PRED_AND_LIST )
  819. {
  820. #if 0
  821. ** _gen("(");
  822. ** genPredTreeOrig(p->down, j, 1);
  823. ** _gen("&&");
  824. ** genPredTreeOrig(p->down->right, j, 1);
  825. ** _gen(")");
  826. ** if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */
  827. ** return;
  828. #endif
  829.         /* MR11 - make it work with AND with more than two children - like OR */
  830. Predicate *list;
  831. _gen("(");
  832. list = p->down;
  833. for (; list!=NULL; list=list->right)
  834. {
  835. genPredTreeOrig(list, j, 1);
  836. if ( list->right!=NULL ) _gen("&&");
  837. }
  838. _gen(")");
  839. if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */
  840. return;
  841.     };
  842. if ( p->expr == PRED_OR_LIST )
  843. {
  844. Predicate *list;
  845. _gen("(");
  846. list = p->down;
  847. for (; list!=NULL; list=list->right)
  848. {
  849. genPredTreeOrig(list, j, 0);
  850. if ( list->right!=NULL ) _gen("||");
  851. }
  852. _gen(")");
  853. if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */
  854. return;
  855. }
  856. fatal_internal("genPredTreeOrig: predicate tree is wacked");
  857. }
  858. #if 0
  859. **   Predicate member dummyPredDepth is no longer used in MR10
  860. **     but we might need it again in the future
  861. **
  862. **   if (MRhoisting) {
  863. **     if ( !noneHaveContext &&
  864. **          ! in_and_expr &&
  865. **          p->source != NULL &&
  866. **          p->source->dummyPredicateDepth > 0 &&
  867. **          p->down == NULL) {
  868. **  _gen("(");
  869. **  genCombinedPredTreeContext(p);
  870. **  _gen("  )n");
  871. **  return;
  872. **     };
  873. **   };
  874. #endif
  875. /* [genPredTree] */
  876. /* in_and_expr
  877.    what to do if the context is wrong
  878.    what to do if the context is correct but the predicate is false
  879.    remember: if the context is wrong it's the same as if the
  880.              predicate is true as far as enabling an alternative
  881.         Consider (AND p q r)
  882.         if in an ... && ... expression then you don't want
  883.         the entire predicate chain to fail just because the
  884.         context for one component is wrong: so return true
  885.         Consider (OR p q r)
  886.         if in an ... || ... expression then you don't want
  887.         the entire predicate chain to succeed just because
  888.         the context for one component is correct when the
  889.         corresponding test is false: so return false when
  890.         the context is correct but the test is false.
  891. */
  892. void
  893. #ifdef __USE_PROTOS
  894. genPredTree( Predicate *p, Node *j, int in_and_expr, int suppress_sva )
  895. #else
  896. genPredTree( p, j, in_and_expr, suppress_sva)
  897.   Predicate     *p;
  898.   Node          *j;
  899.   int           in_and_expr;
  900.   int           suppress_sva;
  901. #endif
  902. {
  903.     int         allHaveContext=1;
  904.     int         noneHaveContext=1;
  905.     Tree        *groupTree;
  906.     Tree        *oneTree;
  907.     Predicate   *q;
  908.     int         identicalORcontextOptimization=0;
  909.     int         identicalANDcontextOptimization=0;
  910.     if (0 && !MR_usingPredNames && !MRhoisting) {
  911.       genPredTreeOrig(p,j,in_and_expr);
  912.       return;
  913.     };
  914.     MR_predContextPresent(p,&allHaveContext,&noneHaveContext);
  915. if ( ! noneHaveContext ) {                 /* MR10 context guards ignored when -prc off */
  916.       _gen("(");
  917.             /* MR10 optimize OR predicates which are all leaves */
  918.       if (p->expr == PRED_OR_LIST && MR_allPredLeaves(p->down)) {
  919.         groupTree=MR_compute_pred_tree_context(p);
  920.         for (q=p->down ; q != NULL ; q=q->right) {
  921.           oneTree=MR_compute_pred_tree_context(q);
  922.           if (! MR_tree_equ(groupTree,oneTree)) {
  923.             Tfree(oneTree);
  924.             break;
  925.           };
  926.           Tfree(oneTree);
  927.         };
  928.         Tfree(groupTree);
  929.         if (q == NULL) {
  930.           _gen("/* MR10 individual OR gates suppressed when all predicates are leaves");
  931.           _gen(" with identical context */n");
  932.           genPredTreeGate(p,in_and_expr);   /* use the parent's in_and_expr for this gate */
  933.           identicalORcontextOptimization=1;
  934.         } else {
  935.           MR_distinctORcontextOpt(p,j,in_and_expr);
  936.           return;
  937.         };
  938.       } else if (p->expr == PRED_AND_LIST && MR_allPredLeaves(p->down)) {
  939.             /* MR12 optimize AND predicates which are all leaves */
  940.         groupTree=MR_compute_pred_tree_context(p);
  941.         for (q=p->down ; q != NULL ; q=q->right) {
  942.           oneTree=MR_compute_pred_tree_context(q);
  943.           if (! MR_tree_equ(groupTree,oneTree)) {
  944.             Tfree(oneTree);
  945.             break;
  946.           };
  947.           Tfree(oneTree);
  948.         };
  949.         Tfree(groupTree);
  950.         if (q == NULL) {
  951.           _gen("/* MR12 individual AND gates suppressed when all predicates are leaves");
  952.           _gen(" with identical context */n");
  953.           genPredTreeGate(p,in_and_expr);   /* use the parent's in_and_expr for this gate */
  954.           identicalANDcontextOptimization=1;
  955.         } else {
  956.           genPredTreeGate(p, in_and_expr);
  957.         };
  958.       } else {
  959.        genPredTreeGate(p, in_and_expr);
  960.       };
  961. }
  962. /* if leaf node, just gen predicate */
  963. if ( p->down==NULL )
  964. {
  965. genPred(p,j,suppress_sva);
  966. if ( ! noneHaveContext ) _gen(")");   /* MR10 context guards ignored when -prc off */
  967. return;
  968. }
  969. /* if AND list, do both preds (only two possible) */
  970.     /* MR10    not any more ! */
  971. if ( p->expr == PRED_AND_LIST )
  972. {
  973. Predicate *list;
  974. _gen("(");
  975. list = p->down;
  976.         for (; list != NULL; list=list->right) {
  977.           if (identicalANDcontextOptimization) {
  978.             genPred(list, j,suppress_sva);
  979.           } else {
  980.         genPredTree(list, j, 1, suppress_sva);  /* in and context */
  981.           };
  982.           if ( list->right!=NULL ) _gen("&&");
  983.         };
  984. _gen(")");
  985. if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */
  986. return;
  987. }
  988. if ( p->expr == PRED_OR_LIST )
  989. {
  990. Predicate *list;
  991. _gen("(");
  992. list = p->down;
  993. for (; list!=NULL; list=list->right)
  994. {
  995.             if (identicalORcontextOptimization) {
  996.           genPred(list, j,suppress_sva);
  997.             } else {
  998.           genPredTree(list, j, 0, suppress_sva);
  999.             };
  1000. if ( list->right!=NULL ) _gen("||");
  1001. }
  1002. _gen(")");
  1003. if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */
  1004. return;
  1005. }
  1006. fatal_internal("predicate tree is wacked");
  1007. }
  1008. /* [genPredTreeMainXX] */
  1009. Predicate *     /* MR10 */
  1010. #ifdef __USE_PROTOS
  1011. genPredTreeMainXX( Predicate *p, Node *j ,int in_and_expr)
  1012. #else
  1013. genPredTreeMainXX( p, j ,in_and_expr)
  1014.     Predicate   *p;
  1015.     Node        *j;
  1016.     int         in_and_expr;
  1017. #endif
  1018. {
  1019.     int     allHaveContext=1;
  1020.     int     noneHaveContext=1;
  1021. #if 0
  1022.     fprintf(stderr,"Pred beforen");
  1023.     dumppred(p);
  1024.     fprintf(stderr,"n");
  1025.     fprintf(stderr,"Pred aftern");
  1026.     dumppred(p);
  1027.     fprintf(stderr,"n");
  1028. #endif
  1029.     p=MR_predSimplifyALL(p);    /* MR10 */
  1030.     require (MR_predicate_context_completed(p),"predicate context is not complete");
  1031.     MR_cleanup_pred_trees(p);   /* MR10 */
  1032.     MR_predContextPresent(p,&allHaveContext,&noneHaveContext);
  1033.     if (!noneHaveContext & !allHaveContext) {
  1034.       warnFL("predicate contains elements both with and without context",
  1035.                 FileStr[j->file],j->line);
  1036.     };
  1037.     if (InfoP) {
  1038.        _gen("n#if 0nn");
  1039.        MR_dumpPred(p,1);
  1040.        _gen("#endifn");
  1041.     };
  1042. genPredTree(p,j,in_and_expr,0);
  1043.     return p;
  1044. }
  1045. Predicate *     /* MR10 */
  1046. #ifdef __USE_PROTOS
  1047. genPredTreeMain( Predicate *p, Node *j)
  1048. #else
  1049. genPredTreeMain( p, j)
  1050.     Predicate   *p;
  1051.     Node        *j;
  1052. #endif
  1053. {
  1054.   return genPredTreeMainXX(p,j,1);
  1055. }
  1056. static void
  1057. #ifdef __USE_PROTOS
  1058. genExprTreeOriginal( Tree *t, int k )
  1059. #else
  1060. genExprTreeOriginal( t, k )
  1061. Tree *t;
  1062. int k;
  1063. #endif
  1064. {
  1065. require(t!=NULL, "genExprTreeOriginal: NULL tree");
  1066. if ( t->token == ALT )
  1067. {
  1068. _gen("("); genExprTreeOriginal(t->down, k); _gen(")");
  1069. if ( t->right!=NULL )
  1070. {
  1071. _gen("||");
  1072. on1line++;
  1073. if ( on1line > NumExprPerLine ) { on1line=0; _gen("n"); }
  1074. _gen("("); genExprTreeOriginal(t->right, k); _gen(")");
  1075. }
  1076. return;
  1077. }
  1078. if ( t->down!=NULL ) _gen("(");
  1079. _gen1("LA(%d)==",k);
  1080. if ( TokenString(t->token) == NULL ) _gen1("%d", t->token)
  1081. else _gen1("%s", TokenString(t->token));
  1082. if ( t->down!=NULL )
  1083. {
  1084. _gen("&&");
  1085. on1line++;
  1086. if ( on1line > NumExprPerLine ) { on1line=0; _gen("n"); }
  1087. _gen("("); genExprTreeOriginal(t->down, k+1); _gen(")");
  1088. }
  1089. if ( t->down!=NULL ) _gen(")");
  1090. if ( t->right!=NULL )
  1091. {
  1092. _gen("||");
  1093. on1line++;
  1094. if ( on1line > NumExprPerLine ) { on1line=0; _gen("n"); }
  1095. _gen("("); genExprTreeOriginal(t->right, k); _gen(")");
  1096. }
  1097. }
  1098. #ifdef __STDC__
  1099. static void MR_LAtokenString(int k,int token)
  1100. #else
  1101. static void MR_LAtokenString(k,token)
  1102.   int   k;
  1103.   int   token;
  1104. #endif
  1105. {
  1106.     char    *ts;
  1107.     ts=TokenString(token);
  1108.     if (ts == NULL) {
  1109.       _gen2(" LA(%d)==%d",k,token);
  1110.     } else {
  1111.       _gen2(" LA(%d)==%s",k,ts);
  1112.     };
  1113. }
  1114. #ifdef __STDC__
  1115. static int MR_countLeaves(Tree *t)
  1116. #else
  1117. static int MR_countLeaves(t)
  1118.   Tree  *t;
  1119. #endif
  1120. {
  1121.   if (t == NULL) return 0;
  1122.   if (t->token == ALT) {
  1123.     return MR_countLeaves(t->down)+MR_countLeaves(t->right);
  1124.   } else {
  1125.     return 1+MR_countLeaves(t->down)+MR_countLeaves(t->right);
  1126.   };
  1127. }
  1128. #ifdef __STDC__
  1129. static void MR_genOneLine(Tree *tree,int k)
  1130. #else
  1131. static void MR_genOneLine(tree,k)
  1132.   Tree      *tree;
  1133.   int       k;
  1134. #endif
  1135. {
  1136.     if (tree == NULL) return;
  1137.     if (tree->token == ALT) {
  1138.        MR_genOneLine(tree->down,k);
  1139.     } else {
  1140.        MR_LAtokenString(k,tree->token);
  1141.        if (tree->down != NULL &&
  1142.            tree->down->right == NULL) {
  1143.           _gen(" &&");
  1144.           MR_genOneLine(tree->down,k+1);
  1145.        } else if (tree->down != NULL) {
  1146.          _gen(" && (");
  1147.          MR_genOneLine(tree->down,k+1);
  1148.          _gen(")");
  1149.        };
  1150.     };
  1151.     if (tree->right != NULL) {
  1152.       _gen(" ||");
  1153.       MR_genOneLine(tree->right,k);
  1154.     };
  1155. }
  1156. /* @@@ */
  1157. static int across;
  1158. static int depth;
  1159. static int lastkonline;
  1160. #ifdef __STDC__
  1161. static void MR_genMultiLine(Tree *tree,int k)
  1162. #else
  1163. static void MR_genMultiLine(tree,k)
  1164.   Tree  *tree;
  1165.   int   k;
  1166. #endif
  1167. {
  1168.     int     i;
  1169.     if (tree == NULL) return;
  1170.     if (tree->token == ALT) {
  1171.       MR_genMultiLine(tree,k);
  1172.     } else {
  1173.       MR_LAtokenString(k,tree->token);
  1174.       lastkonline=k;
  1175.       across++;
  1176.       if (tree->down != NULL && tree->down->right == NULL) {
  1177.         if (across > 3) {
  1178.           _gen("n");
  1179.           across=0;
  1180.           lastkonline=0;
  1181.           for (i=0 ; i < depth+k ; i++) _gen("   ");
  1182.           _gen("&&");
  1183.         } else {
  1184.           _gen(" &&");
  1185.         };
  1186.         MR_genMultiLine(tree->down,k+1);
  1187.       } else if (tree->down != NULL) {
  1188.         _gen("n");
  1189.         lastkonline=0;
  1190.         across=0;
  1191.         for (i=0 ; i < depth+k ; i++) _gen("   ");
  1192.         _gen("&& (");
  1193.         MR_genMultiLine(tree->down,k+1);
  1194.         _gen(")");
  1195.       };
  1196.     };
  1197.     if (tree->right != NULL) {
  1198.       if (k < lastkonline) {
  1199.         _gen("n");
  1200.         across=0;
  1201.         lastkonline=0;
  1202.         for (i=0; i < depth+k-1 ; i++) _gen("   ");
  1203.         _gen("||");
  1204.       } else if (across > 3 ) {
  1205.         _gen("n");
  1206.         across=0;
  1207.         lastkonline=0;
  1208.         for (i=0; i < depth+k ; i++) _gen("   ");
  1209.         _gen("||");
  1210.       } else {
  1211.         _gen(" ||");
  1212.       };
  1213.       MR_genMultiLine(tree->right,k);
  1214.     };
  1215. }
  1216. #ifdef __STDC__
  1217. static void genExprTree(Tree *tree,int k)
  1218. #else
  1219. static void genExprTree(tree,k)
  1220.   Tree  *tree;
  1221.   int   k;
  1222. #endif
  1223. {
  1224.     int     count;
  1225.     int     across;
  1226.     require (tree != NULL,"genExprTree: tree is NULL");
  1227.     require (k > 0,"genExprTree: k <= 0");
  1228.     if (0 && !MRhoisting) {   /* MR11 make new version standard */
  1229.       genExprTreeOriginal(tree,k);
  1230.     } else {
  1231.       count=MR_countLeaves(tree);
  1232.       if (count < 5) {
  1233.         MR_genOneLine(tree,k);
  1234.       } else {
  1235.         _gen("n");
  1236.         across=0;
  1237.         depth=0;
  1238.         lastkonline=0;
  1239.         MR_genMultiLine(tree,k);
  1240.         _gen("n");
  1241.       };
  1242.     };
  1243. }
  1244. /*
  1245.  * Generate LL(k) type expressions of the form:
  1246.  *
  1247.  *  (LA(1) == T1 || LA(1) == T2 || ... || LA(1) == Tn) &&
  1248.  *  (LA(2) == T1 || LA(2) == T2 || ... || LA(2) == Tn) &&
  1249.  * .....
  1250.  *  (LA(k) == T1 || LA(k) == T2 || ... || LA(k) == Tn)
  1251.  *
  1252.  * If GenExprSetsOpt generate:
  1253.  *
  1254.  * (setwdi[LA(1)]&(1<<j)) && (setwdi[LA(2)]&(1<<j)) ...
  1255.  *
  1256.  * where n is set_deg(expr) and Ti is some random token and k is the last nonempty
  1257.  * set in fset <=CLL_k.
  1258.  * k=1..CLL_k where CLL_k >= 1.
  1259.  *
  1260.  * This routine is visible only to this file and cannot answer a TRANS message.
  1261.  *
  1262.  */
  1263. /*  [genExpr] */
  1264. static int
  1265. #ifdef __USE_PROTOS
  1266. genExpr( Junction *j )
  1267. #else
  1268. genExpr( j )
  1269. Junction *j;
  1270. #endif
  1271. {
  1272. int max_k;
  1273. /* if full LL(k) is sufficient, then don't use approximate (-ck) lookahead
  1274.  * from CLL_k..LL_k
  1275.  */
  1276. {
  1277. int limit;
  1278. if ( j->ftree!=NULL ) limit = LL_k;
  1279. else limit = CLL_k;
  1280. max_k = genExprSets(j->fset, limit);
  1281. }
  1282. /* Do tests for real tuples from other productions that conflict with
  1283.  * artificial tuples generated by compression (using sets of tokens
  1284.  * rather than k-trees).
  1285.  */
  1286. if ( j->ftree != NULL )
  1287. {
  1288. _gen(" && !("); genExprTree(j->ftree, 1); _gen(")");
  1289. }
  1290. if ( ParseWithPredicates && j->predicate!=NULL )
  1291. {
  1292. Predicate *p = j->predicate;
  1293. warn_about_using_gk_option();
  1294. _gen("&&");
  1295. j->predicate=genPredTreeMain(p, (Node *)j);     /* MR10 */
  1296. }
  1297. return max_k;
  1298. }
  1299. static int
  1300. #ifdef __USE_PROTOS
  1301. genExprSets( set *fset, int limit )
  1302. #else
  1303. genExprSets( fset, limit )
  1304. set *fset;
  1305. int limit;
  1306. #endif
  1307. {
  1308. int k = 1;
  1309. int max_k = 0;
  1310. unsigned *e, *g, firstTime=1;
  1311.     if (set_nil(fset[1])) {
  1312.       _gen(" 0 /* MR13 empty set expression  - undefined rule ? infinite left recursion ? */ ");
  1313.       MR_BadExprSets++;
  1314.     };
  1315. if ( GenExprSetsOpt )
  1316. {
  1317. while ( k <= limit && !set_nil(fset[k]) )   /* MR11 */
  1318. {
  1319. if ( set_deg(fset[k])==1 ) /* too simple for a set? */
  1320. {
  1321. int e;
  1322. _gen1("(LA(%d)==",k);
  1323. e = set_int(fset[k]);
  1324. if ( TokenString(e) == NULL ) _gen1("%d)", e)
  1325. else _gen1("%s)", TokenString(e));
  1326. }
  1327. else
  1328. {
  1329. NewSet();
  1330. FillSet( fset[k] );
  1331. _gen3("(setwd%d[LA(%d)]&0x%x)", wordnum, k, 1<<setnum);
  1332. }
  1333. if ( k>max_k ) max_k = k;
  1334. if ( k == CLL_k ) break;
  1335. k++;
  1336. if ( k<=limit && !set_nil(fset[k]) ) _gen(" && ");  /* MR11 */
  1337. on1line++;
  1338. if ( on1line > NumExprPerLine ) { on1line=0; _gen("n"); }
  1339. }
  1340. return max_k;
  1341. }
  1342. while ( k<= limit &&  !set_nil(fset[k]) )       /* MR11 */
  1343. {
  1344. if ( (e=g=set_pdq(fset[k])) == NULL ) fatal_internal("genExpr: cannot allocate IF expr pdq set");
  1345. for (; *e!=nil; e++)
  1346. {
  1347. if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; }
  1348. on1line++;
  1349. if ( on1line > NumExprPerLine ) { on1line=0; _gen("n"); }
  1350. _gen1("LA(%d)==",k);
  1351. if ( TokenString(*e) == NULL ) _gen1("%d", *e)
  1352. else _gen1("%s", TokenString(*e));
  1353. }
  1354. free( (char *)g );
  1355. _gen(")");
  1356. if ( k>max_k ) max_k = k;
  1357. if ( k == CLL_k ) break;
  1358. k++;
  1359. if ( k <= limit && !set_nil(fset[k]) ) { firstTime=1; _gen(" && "); }   /* MR11 */
  1360. on1line++;
  1361. if ( on1line > NumExprPerLine ) { on1line=0; _gen("n"); }
  1362. }
  1363. return max_k;
  1364. }
  1365. /*
  1366.  * Generate code for any type of block.  If the last alternative in the block is
  1367.  * empty (not even an action) don't bother doing it.  This permits us to handle
  1368.  * optional and loop blocks as well.
  1369.  *
  1370.  * Only do this block, return after completing the block.
  1371.  * This routine is visible only to this file and cannot answer a TRANS message.
  1372.  */
  1373. static set
  1374. #ifdef __USE_PROTOS
  1375. genBlk( Junction *q, int jtype, int *max_k, int *need_right_curly )
  1376. #else
  1377. genBlk( q, jtype, max_k, need_right_curly )
  1378. Junction *q;
  1379. int jtype;
  1380. int *max_k;
  1381. int *need_right_curly;
  1382. #endif
  1383. {
  1384. set f;
  1385. Junction *alt;
  1386. int a_guess_in_block = 0;
  1387. require(q!=NULL, "genBlk: invalid node");
  1388. require(q->ntype == nJunction, "genBlk: not junction");
  1389. *need_right_curly=0;
  1390. if ( q->p2 == NULL ) /* only one alternative?  Then don't need if */
  1391. {
  1392. if (first_item_is_guess_block((Junction *)q->p1)!=NULL )
  1393. {
  1394.             if (jtype != aLoopBlk && jtype != aOptBlk && jtype != aPlusBlk) {
  1395.      warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line);
  1396.             };
  1397.             gen("zzGUESSn"); /* guess anyway to make output code consistent */
  1398. /* MR10 disable */  /**** gen("if ( !zzrv )n"); ****/
  1399. /* MR10 */          gen("if ( !zzrv ) {n"); tabs++; (*need_right_curly)++;
  1400.         };
  1401. TRANS(q->p1);
  1402. return empty; /* no decision to be made-->no error set */
  1403. }
  1404. f = First(q, 1, jtype, max_k);
  1405. for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
  1406. {
  1407. if ( alt->p2 == NULL ) /* chk for empty alt */
  1408. {
  1409. Node *p = alt->p1;
  1410. if ( p->ntype == nJunction )
  1411. {
  1412. /* we have empty alt */
  1413. if ( ((Junction *)p)->p1 == (Node *)q->end )
  1414. {
  1415. break; /* don't do this one, quit */
  1416. }
  1417. }
  1418. }
  1419. /* MR10 */        if (alt->p2 == NULL &&
  1420. /* MR10 */               ( q->jtype == aSubBlk || q->jtype == RuleBlk) ) {
  1421. /* MR10 */          if (first_item_is_guess_block(alt)) {
  1422. /* MR10 */               warnFL("(...)? as last alternative of block is unnecessary",
  1423. /* MR10 */                                FileStr[alt->file],alt->line);
  1424. /* MR10 */          };
  1425. /* MR10 */        };
  1426. if ( alt != q ) gen("else ")
  1427. else
  1428. {
  1429. if ( DemandLookahead )
  1430. if ( !GenCC ) {gen1("LOOK(%d);n", *max_k);}
  1431. else gen1("look(%d);n", *max_k);
  1432. }
  1433. if ( alt!=q )
  1434. {
  1435. _gen("{n");
  1436. tabs++;
  1437. (*need_right_curly)++;
  1438. /* code to restore state if a prev alt didn't follow guess */
  1439. if ( a_guess_in_block )
  1440. gen("if ( !zzrv ) zzGUESS_DONE;n");
  1441. }
  1442. if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL )
  1443. {
  1444. a_guess_in_block = 1;
  1445. gen("zzGUESSn");
  1446. }
  1447. gen("if ( ");
  1448. if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && ");
  1449. genExpr(alt);
  1450. _gen(" ) ");
  1451. _gen("{n");
  1452. tabs++;
  1453. TRANS(alt->p1);
  1454. --tabs;
  1455. gen("}n");
  1456. /* MR10 */        if (alt->p2 == NULL) {
  1457. /* MR10 */          if (first_item_is_guess_block(alt)) {
  1458. /* MR10 */            gen("/* MR10 */ else {n");
  1459. /* MR10 */            tabs++;
  1460. /* MR10 */     (*need_right_curly)++;
  1461. /* MR10 */     /* code to restore state if a prev alt didn't follow guess */
  1462. /* MR10 */            gen("/* MR10 */ if ( !zzrv ) zzGUESS_DONE;n");
  1463. /* MR10 */            gen("/* MR10 */ if (0) {}     /* last alternative of block is guess block */n");
  1464. /* MR10 */          };
  1465. /* MR10 */        };
  1466. }
  1467. return f;
  1468. }
  1469. static int
  1470. #ifdef __USE_PROTOS
  1471. has_guess_block_as_first_item( Junction *q )
  1472. #else
  1473. has_guess_block_as_first_item( q )
  1474. Junction *q;
  1475. #endif
  1476. {
  1477. Junction *alt;
  1478. for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
  1479. {
  1480. if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1;
  1481. }
  1482. return 0;
  1483. }
  1484. static int
  1485. #ifdef __USE_PROTOS
  1486. has_guess_block_as_last_item( Junction *q )
  1487. #else
  1488. has_guess_block_as_last_item( q )
  1489. Junction *q;
  1490. #endif
  1491. {
  1492. Junction *alt;
  1493.     if (q == NULL) return 0;
  1494. for (alt=q; alt->p2 != NULL && !( (Junction *) alt->p2)->ignore; alt= (Junction *) alt->p2 ) {};
  1495.     return first_item_is_guess_block( (Junction *) alt->p1) != NULL;
  1496. }
  1497. /* return NULL if 1st item of alt is NOT (...)? block; else return ptr to aSubBlk node
  1498.  * of (...)?;  This function ignores actions and predicates.
  1499.  */
  1500. Junction *
  1501. #ifdef __USE_PROTOS
  1502. first_item_is_guess_block( Junction *q )
  1503. #else
  1504. first_item_is_guess_block( q )
  1505. Junction *q;
  1506. #endif
  1507. {
  1508.     /* MR14  Couldnt' find aSubBlock which was a guess block when it lay
  1509.              behind aLoopBlk.  The aLoopBlk only appear in conjunction with
  1510.              aLoopBegin, but the routine didn't know that.  I think.
  1511.     */
  1512. while ( q!=NULL &&
  1513.           ( q->ntype==nAction ) ||
  1514.           ( q->ntype==nJunction && (q->jtype==Generic || q->jtype == aLoopBlk )) )
  1515. {
  1516. if ( q->ntype==nJunction ) q = (Junction *)q->p1;
  1517. else q = (Junction *) ((ActionNode *)q)->next;
  1518. }
  1519. if ( q==NULL ) return NULL;
  1520. if ( q->ntype!=nJunction ) return NULL;
  1521. if ( q->jtype!=aSubBlk ) return NULL;
  1522. if ( !q->guess ) return NULL;
  1523. return q;
  1524. }
  1525. /* MR1                       */
  1526. /* MR1  10-Apr-97 MR1 Routine to stringize failed semantic predicates msgs  */
  1527. /* MR1                                                         */
  1528. #define STRINGIZEBUFSIZE 1024
  1529. static char stringizeBuf[STRINGIZEBUFSIZE];
  1530. char *
  1531. #ifdef __USE_PROTOS
  1532. stringize(char * s)
  1533. #else
  1534. stringize(s)
  1535. char *s;
  1536. #endif
  1537. {
  1538.   char *p;
  1539.   char *stop;
  1540.   p=stringizeBuf;
  1541.   stop=&stringizeBuf[1015];
  1542.   if (s != 0) {
  1543.     while (*s != 0) {
  1544.       if (p >= stop) {
  1545. goto stringizeStop;
  1546.       } else if (*s == 'n') {
  1547.         *p++='\';
  1548.         *p++='n';
  1549.         *p++='\';
  1550. *p++=*s++;
  1551.       } else if (*s == '\') {
  1552. *p++=*s;
  1553. *p++=*s++;
  1554.       } else if (*s == '"') {
  1555.         *p++='\';
  1556. *p++=*s++;
  1557.         while (*s != 0) {
  1558.           if (p >= stop) {
  1559.      goto stringizeStop;
  1560.   } else if (*s == 'n') {
  1561.     *p++='\';
  1562.     *p++=*s++;
  1563.   } else if (*s == '\') {
  1564.     *p++=*s++;
  1565.     *p++=*s++;
  1566.   } else if (*s == '"') {
  1567.     *p++='\';
  1568.     *p++=*s++;
  1569.     break;
  1570.   } else {
  1571.     *p++=*s++;
  1572.           };
  1573.         };
  1574.       } else if (*s == ''') {
  1575. *p++=*s++;
  1576.         while (*s != 0) {
  1577.           if (p >= stop) {
  1578.      goto stringizeStop;
  1579.   } else if (*s == ''') {
  1580.     *p++=*s++;
  1581.     break;
  1582.   } else if (*s == '\') {
  1583.     *p++=*s++;
  1584.     *p++=*s++;
  1585.   } else if (*s == '"') {
  1586.     *p++='\';
  1587.     *p++=*s++;
  1588.     break;
  1589.   } else {
  1590.     *p++=*s++;
  1591.           };
  1592.         };
  1593.       } else {
  1594.         *p++=*s++;
  1595.       };
  1596.     };
  1597.   };
  1598.   goto stringizeExit;
  1599. stringizeStop:
  1600.   *p++='.';        
  1601.   *p++='.';        
  1602.   *p++='.';        
  1603. stringizeExit:
  1604.   *p=0;
  1605.   return stringizeBuf;
  1606. }
  1607. #ifdef __STDC__
  1608. int isNullAction(char *s)
  1609. #else
  1610. int isNullAction(s)
  1611.   char  *s;
  1612. #endif
  1613. {
  1614.   char  *p;
  1615.   for (p=s; *p != '' ; p++) {
  1616.     if (*p != ';' && *p !=' ') return 0;
  1617.   };
  1618.   return 1;
  1619. }
  1620. /* MR1                                     */
  1621. /* MR1 End of Routine to stringize code for failed predicates msgs         */
  1622. /* MR1                                                         */
  1623. /* Generate an action.  Don't if action is NULL which means that it was already
  1624.  * handled as an init action.
  1625.  */
  1626. void
  1627. #ifdef __USE_PROTOS
  1628. genAction( ActionNode *p )
  1629. #else
  1630. genAction( p )
  1631. ActionNode *p;
  1632. #endif
  1633. {
  1634. require(p!=NULL, "genAction: invalid node and/or rule");
  1635. require(p->ntype==nAction, "genAction: not action");
  1636. if ( !p->done )  /* MR10 */ /* MR11 */
  1637. {
  1638. if ( p->is_predicate)
  1639. {
  1640. if ( p->guardpred != NULL )
  1641. {
  1642.                 Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */
  1643.                 gen("if (!");
  1644.         guardDup=genPredTreeMain(guardDup, (Node *)p);
  1645.                 predicate_free(guardDup);
  1646. }
  1647. /* MR10 */  else if (p->ampersandPred != NULL) {
  1648. /* MR10 */      gen("if (!");
  1649. /* MR10 */      p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p);
  1650. /* MR10 */  }
  1651. else
  1652. {
  1653. gen("if (!(");
  1654. /* make sure that '#line n' is on front of line */
  1655. if ( GenLineInfo && p->file != -1 ) _gen("n");
  1656. dumpPredAction(p,p->action, output, 0, p->file, p->line, 0);
  1657. _gen(")");
  1658. }
  1659. if ( p->pred_fail != NULL )
  1660. {
  1661. _gen(")n");
  1662. tabs++;
  1663. /* MR1                                                         */
  1664. /* MR1  10-Apr-97 MR1  Put {...} envelope around failed semantic predicates */
  1665. /* MR1                                                         */
  1666. gen1("{%s};n", p->pred_fail);                      /* MR1 */
  1667. tabs--;
  1668. }
  1669. /* MR1                                                 */
  1670. /* MR1  10-Apr-97 MR1 Properly stringize failed semantic predicates      */
  1671. /* MR1                                                         */
  1672. else _gen1(") {zzfailed_pred("%s");}n",               /* MR1 */
  1673. stringize(p->action));                      /* MR1 */
  1674. }
  1675. else    /* not a predicate */
  1676. {
  1677.             if (! isNullAction(p->action) && !p->noHoist) {
  1678.         if ( FoundGuessBlk ) {
  1679. if ( GenCC ) {
  1680.                   gen("if ( !guessing ) {n");
  1681.                 } else {
  1682.   gen("zzNON_GUESS_MODE {n");
  1683.                 };
  1684.               };
  1685.   dumpAction(p->action, output, tabs, p->file, p->line, 1);
  1686.   if ( FoundGuessBlk ) gen("}n");
  1687.             };
  1688. }
  1689. }
  1690. TRANS(p->next)
  1691. }
  1692. /*
  1693.  * if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in
  1694.  * else pass addr of temp root ptr (&_ast) (don't zzlink it in).
  1695.  *
  1696.  * if ! modifies rule-ref, then never link it in and never pass zzSTR.
  1697.  * Always pass address of temp root ptr.
  1698.  */
  1699. void
  1700. #ifdef __USE_PROTOS
  1701. genRuleRef( RuleRefNode *p )
  1702. #else
  1703. genRuleRef( p )
  1704. RuleRefNode *p;
  1705. #endif
  1706. {
  1707. Junction *q;
  1708. char *handler_id = "";
  1709. RuleEntry *r, *r2;
  1710. char *parm = "", *exsig = "";
  1711.     int     genRuleRef_emittedGuessGuard=0;     /* MR10 */
  1712. require(p!=NULL, "genRuleRef: invalid node and/or rule");
  1713. require(p->ntype==nRuleRef, "genRuleRef: not rule reference");
  1714. if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )
  1715. handler_id = p->altstart->exception_label;
  1716. r = (RuleEntry *) hash_get(Rname, p->text);
  1717. if ( r == NULL )
  1718. {
  1719. warnFL( eMsg1("rule %s not defined",
  1720.   p->text), FileStr[p->file], p->line );
  1721. return;
  1722. }
  1723. /* MR8 5-Aug-97     Reported by S.Bochnak@microtool.com.pl                  */
  1724. /*                  Don't do assign when no return values declared          */
  1725. /*                  Move definition of q up and use it to guard p->assign   */
  1726. q = RulePtr[r->rulenum]; /* find definition of ref'd rule */  /* MR8 */
  1727. r2 = (RuleEntry *) hash_get(Rname, p->rname);
  1728. if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
  1729.     OutLineInfo(output,p->line,FileStr[p->file]);
  1730. if ( GenCC && GenAST ) {
  1731. gen("_ast = NULL;n");
  1732. }
  1733. if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) {      /* MR8 */
  1734. if ( GenCC ) {
  1735.           gen("if ( !guessing ) {n");
  1736.         } else {
  1737.           gen("zzNON_GUESS_MODE {n");
  1738.         };
  1739.         tabs++;                                                      /* MR11 */
  1740.         genRuleRef_emittedGuessGuard=1;                              /* MR11 */
  1741.     };
  1742. if ( FoundException ) exsig = "&_signal";
  1743. tab();
  1744. if ( GenAST )
  1745. {
  1746. if ( GenCC ) {
  1747. /**** if ( r2->noAST || p->astnode==ASTexclude )
  1748. ****/
  1749. {
  1750. /**** _gen("_ast = NULL;n");
  1751. ****/
  1752. parm = "&_ast";
  1753. }
  1754. /*** we always want to set just a pointer now, then set correct
  1755. pointer after
  1756. else {
  1757. _gen("_astp =
  1758. (_tail==NULL)?(&_sibling):(&(_tail->_right));n");
  1759. parm = "_astp";
  1760. }
  1761. ****/
  1762. }
  1763. else {
  1764. if ( r2->noAST || p->astnode==ASTexclude )
  1765. {
  1766. _gen("_ast = NULL; ");
  1767. parm = "&_ast";
  1768. }
  1769. else parm = "zzSTR";
  1770. }
  1771. if ( p->assign!=NULL && q->ret!=NULL )                       /* MR8 */
  1772. {
  1773. if ( !HasComma(p->assign) ) {_gen1("%s = ",p->assign);}
  1774. else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
  1775. }
  1776. if ( FoundException ) {
  1777. _gen5("%s%s(%s,&_signal%s%s); ",
  1778.   RulePrefix,
  1779.   p->text,
  1780.   parm,
  1781.   (p->parms!=NULL)?",":"",
  1782.   (p->parms!=NULL)?p->parms:"");
  1783. if ( p->ex_group!=NULL ) {
  1784. _gen("n");
  1785. gen("if (_signal) {n");
  1786. tabs++;
  1787. dumpException(p->ex_group, 0);
  1788. tabs--;
  1789. gen("}");
  1790. }
  1791. else {
  1792. _gen1("if (_signal) goto %s_handler;", handler_id);
  1793. }
  1794. }
  1795. else {
  1796. _gen5("%s%s(%s%s%s);",
  1797.   RulePrefix,
  1798.   p->text,
  1799.   parm,
  1800.   (p->parms!=NULL)?",":"",
  1801.   (p->parms!=NULL)?p->parms:"");
  1802. }
  1803. if ( GenCC && (r2->noAST || p->astnode==ASTexclude) )
  1804. {
  1805. /* rule has a ! or element does */
  1806. /* still need to assign to #i so we can play with it */
  1807. _gen("n");
  1808. gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum);
  1809. }
  1810. else if ( !r2->noAST && p->astnode == ASTinclude )
  1811. {
  1812. /* rule doesn't have a ! and neither does element */
  1813. /* MR10 */  if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {
  1814. /* MR10 */    _gen("n");
  1815. /* MR10 */    if (GenCC) gen ("if (!guessing) {    /* MR10 */")
  1816. /* MR10 */          else gen ("if (!zzguessing) {    /* MR10 */n");
  1817. /* MR10 */    tabs++;
  1818. /* MR10 */  };
  1819. if ( GenCC ) {
  1820. _gen("n");
  1821. gen("if ( _tail==NULL ) _sibling = _ast; else _tail->setRight(_ast);n");
  1822. gen2("_ast%d%d = (AST *)_ast;n", BlkLevel-1, p->elnum);
  1823. tab();
  1824. }
  1825. else _gen(" ");
  1826.             if ( GenCC ) {
  1827.                 _gen("ASTBase::"); }
  1828.                 else _gen("zz");
  1829. _gen("link(_root, &_sibling, &_tail);");
  1830. /* MR10 */  if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {     /* MR10 */
  1831. /* MR10 */    _gen("n");
  1832. /* MR10 */    tabs--;
  1833. /* MR10 */    if (GenCC) gen ("};    /* MR10 */")
  1834. /* MR10 */          else gen ("};    /* MR10 */");
  1835. /* MR10 */  };
  1836. }
  1837. }
  1838. else
  1839. {
  1840. if ( p->assign!=NULL && q->ret!=NULL )                       /* MR8 */
  1841. {
  1842. if ( !HasComma(p->assign) ) {_gen1("%s = ",p->assign);}
  1843. else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
  1844. }
  1845. if ( FoundException ) {
  1846. _gen4("%s%s(&_signal%s%s); ",
  1847.   RulePrefix,
  1848.   p->text,
  1849.   (p->parms!=NULL)?",":"",
  1850.   (p->parms!=NULL)?p->parms:"");
  1851. if ( p->ex_group!=NULL ) {
  1852. _gen("n");
  1853. gen("if (_signal) {n");
  1854. tabs++;
  1855. dumpException(p->ex_group, 0);
  1856. tabs--;
  1857. gen("}");
  1858. }
  1859. else {
  1860. _gen1("if (_signal) goto %s_handler;", handler_id);
  1861. }
  1862. }
  1863. else {
  1864. _gen3("%s%s(%s);",
  1865.   RulePrefix,
  1866.   p->text,
  1867.   (p->parms!=NULL)?p->parms:"");
  1868. }
  1869. if ( p->assign!=NULL && q->ret!=NULL ) _gen("n");           /* MR8 */
  1870. }
  1871. if ( p->assign!=NULL && q->ret!=NULL) {                          /* MR8 */
  1872. if ( HasComma(p->assign) )
  1873. {
  1874. _gen("n");
  1875. dumpRetValAssign(p->assign, q->ret);
  1876. _gen("}");
  1877. }
  1878. }
  1879. _gen("n");
  1880. /* Handle element labels now */
  1881. if ( p->el_label!=NULL )
  1882. {
  1883. if ( GenAST )
  1884. {
  1885. if ( GenCC ) {
  1886. gen3("%s_ast = _ast%d%d;n", p->el_label, BlkLevel-1, p->elnum);
  1887. }
  1888. else {gen1("%s_ast = zzastCur;n", p->el_label);}
  1889. }
  1890.         else if (!GenCC ) {
  1891. gen1("%s = zzaCur;n", p->el_label);
  1892.         }
  1893. }
  1894. if ( FoundGuessBlk && p->assign!=NULL && q->ret!=NULL ) {       /* MR8 */
  1895. /* in guessing mode, don't branch to handler upon error */
  1896.         tabs--;                                                     /* MR11 */
  1897. gen("} else {n");
  1898.         tabs++;                                                     /* MR11 */
  1899. if ( FoundException ) {
  1900. gen6("%s%s(%s%s&_signal%s%s);n",
  1901.  RulePrefix,
  1902.  p->text,
  1903.  parm,
  1904.                  (*parm!='')?",":"",
  1905.                  (p->parms!=NULL)?",":"",
  1906.  (p->parms!=NULL)?p->parms:"");
  1907. }
  1908. else {
  1909. gen5("%s%s(%s%s%s);n",
  1910.  RulePrefix,
  1911.  p->text,
  1912.  parm,
  1913.  (p->parms!=NULL && *parm!='')?",":"",
  1914.  (p->parms!=NULL)?p->parms:"");
  1915. }
  1916.         tabs--;                                                     /* MR11 */
  1917. gen("}n");
  1918. }
  1919. TRANS(p->next)
  1920. }
  1921. /*
  1922.  * Generate code to match a token.
  1923.  *
  1924.  * Getting the next token is tricky.  We want to ensure that any action
  1925.  * following a token is executed before the next GetToken();
  1926.  */
  1927. void
  1928. #ifdef __USE_PROTOS
  1929. genToken( TokNode *p )
  1930. #else
  1931. genToken( p )
  1932. TokNode *p;
  1933. #endif
  1934. {
  1935. RuleEntry *r;
  1936. char *handler_id = "";
  1937. ActionNode *a;
  1938. char *set_name;
  1939. require(p!=NULL, "genToken: invalid node and/or rule");
  1940. require(p->ntype==nToken, "genToken: not token");
  1941. if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )
  1942. handler_id = p->altstart->exception_label;
  1943. r = (RuleEntry *) hash_get(Rname, p->rname);
  1944. if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
  1945.     OutLineInfo(output,p->line,FileStr[p->file]);
  1946. if ( !set_nil(p->tset) ) /* implies '.', ~Tok, or tokenclass */
  1947. {
  1948. unsigned e;
  1949. set b;
  1950. b = set_dup(p->tset);
  1951. if ( p->tclass!=NULL ) /* token class? */
  1952. {
  1953. static char buf[MaxRuleName+1];
  1954. if ( p->tclass->dumped )
  1955. e = p->tclass->setnum;
  1956. else {
  1957. e = DefErrSet(&b, 0, TokenString(p->token));
  1958. p->tclass->dumped = 1; /* indicate set has been created */
  1959. p->tclass->setnum = e;
  1960. }
  1961. sprintf(buf, "%s_set", TokenString(p->token));
  1962. set_name = buf;
  1963. }
  1964. else { /* wild card to ~ operator */
  1965. static char buf[sizeof("zzerr")+10];
  1966. int n = DefErrSet( &b, 0, NULL );
  1967. if ( GenCC ) sprintf(buf, "err%d", n);
  1968. else sprintf(buf, "zzerr%d", n);
  1969. set_name = buf;
  1970. }
  1971. if ( !FoundException )
  1972. {gen1("zzsetmatch(%s);", set_name);}
  1973. else if ( p->ex_group==NULL ) {
  1974.             if ( p->use_def_MT_handler )
  1975.                 gen3("zzsetmatch_wdfltsig(%s,(ANTLRTokenType)%d,%s);",
  1976.                      set_name,
  1977.                      p->token,
  1978.                      tokenFollowSet(p))
  1979.             else
  1980.                 gen2("zzsetmatch_wsig(%s, %s_handler);",
  1981.                      set_name,
  1982.                      handler_id);
  1983. }
  1984. else
  1985. {
  1986. gen1("if ( !_setmatch_wsig(%s) ) {n", set_name);
  1987. tabs++;
  1988. /* MR6 */ if (FoundGuessBlk) {
  1989. /* MR6 */   if ( GenCC ) {gen("if ( guessing ) goto fail;n");}
  1990. /* MR6 */   else gen("if ( zzguessing ) goto fail;n");
  1991. /* MR6 */ };
  1992. gen("_signal=MismatchedToken;n");
  1993. dumpException(p->ex_group, 0);
  1994. tabs--;
  1995. gen("}n");
  1996. }
  1997. set_free(b);
  1998. }
  1999. else if ( TokenString(p->token)!=NULL )
  2000. {
  2001. if ( FoundException ) {
  2002. if ( p->use_def_MT_handler )
  2003. gen2("zzmatch_wdfltsig(%s,%s);",TokenString(p->token),tokenFollowSet(p))
  2004. else if ( p->ex_group==NULL )
  2005. {
  2006. gen2("zzmatch_wsig(%s, %s_handler);",
  2007.  TokenString(p->token),
  2008.  handler_id);
  2009. }
  2010. else
  2011. {
  2012. /* MR6 */ if (GenCC) {
  2013. /* MR6 */   gen1("if ( !_match_wsig(%s) ) {n", TokenString(p->token));
  2014. /* MR6 */ } else {
  2015. /* MR6 */   gen1("if ( !_zzmatch_wsig(%s) ) {n", TokenString(p->token));
  2016. /* MR6 */ };
  2017. tabs++;
  2018. /* MR6 */ if (FoundGuessBlk) {
  2019. /* MR6 */      if ( GenCC ) {gen("if ( guessing ) goto fail;n");}
  2020. /* MR6 */   else gen("if ( zzguessing ) goto fail;n");
  2021. /* MR6 */ };
  2022. gen("_signal=MismatchedToken;n");
  2023. dumpException(p->ex_group, 0);
  2024. tabs--;
  2025. gen("}n");
  2026. }
  2027. }
  2028. else gen1("zzmatch(%s);", TokenString(p->token));
  2029. }
  2030. else {
  2031.         if ( FoundException ) {
  2032.             if ( p->use_def_MT_handler )
  2033. gen2("zzmatch_wdfltsig((ANTLRTokenType)%d,%s);",
  2034.  p->token,tokenFollowSet(p))
  2035.             else
  2036.                 gen2("zzmatch_wsig(%d,%s_handler);",p->token,handler_id);
  2037.         }
  2038. else {gen1("zzmatch(%d);", p->token);}
  2039. }
  2040. a = findImmedAction( p->next );
  2041. /* generate the token labels */
  2042. if ( GenCC && p->elnum>0 )
  2043. {
  2044. /* If building trees in C++, always gen the LT() assigns */
  2045. if ( set_el(p->elnum, tokensRefdInBlock) || GenAST )
  2046. {
  2047. /* MR10 */ if ( FoundGuessBlk ) {
  2048. /* MR10 */    gen("n");
  2049. /* MR10 */    if (p->label_used_in_semantic_pred) {
  2050. /* MR10 */ gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);  /* MR10 */n", BlkLevel-1, p->elnum);
  2051. /* MR10 */    } else {
  2052. /* MR10 */ gen("if ( !guessing ) {n"); tab();
  2053. /* MR10 */ _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);n", BlkLevel-1, p->elnum);
  2054. /* MR10 */      _gen("}n");
  2055. /* MR10 */    };
  2056. /* MR10 */  } else {
  2057. /* MR10 */   _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);", BlkLevel-1, p->elnum);
  2058. /* MR10 */  };
  2059. /* MR10 */
  2060. }
  2061. if ( LL_k>1 )
  2062. if ( !DemandLookahead ) _gen(" labase++;");
  2063. _gen("n");
  2064. tab();
  2065. }
  2066. if ( GenAST )
  2067. {
  2068. if ( FoundGuessBlk && !(p->astnode == ASTexclude || r->noAST) )
  2069. {
  2070. if ( GenCC ) {_gen("if ( !guessing ) {n"); tab();}
  2071. else {_gen("zzNON_GUESS_MODE {n"); tab();}
  2072. }
  2073. if ( !r->noAST )
  2074. {
  2075. if ( GenCC && !(p->astnode == ASTexclude || r->noAST) ) {
  2076. _gen("n");
  2077. /* MR13 */      if (NewAST) {
  2078. /* MR13 */         gen4("_ast%d%d = newAST(_t%d%d);n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);
  2079. /* MR13 */      } else {
  2080. /* MR13 */         gen4("_ast%d%d = new AST(_t%d%d);n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);
  2081. /* MR13 */      }
  2082. tab();
  2083. }
  2084. if ( GenCC && !(p->astnode == ASTexclude || r->noAST) )
  2085. {_gen2("_ast%d%d->", BlkLevel-1, p->elnum);}
  2086. else _gen(" ");
  2087. if ( p->astnode==ASTchild ) {
  2088. if ( !GenCC ) _gen("zz");
  2089. _gen("subchild(_root, &_sibling, &_tail);");
  2090. }
  2091. else if ( p->astnode==ASTroot ) {
  2092. if ( !GenCC ) _gen("zz");
  2093. _gen("subroot(_root, &_sibling, &_tail);");
  2094. }
  2095. if ( GenCC && !(p->astnode == ASTexclude || r->noAST) ) {
  2096. _gen("n");
  2097. tab();
  2098. }
  2099. }
  2100. else if ( !GenCC ) _gen(" zzastDPush;");
  2101. if ( FoundGuessBlk && !(p->astnode == ASTexclude || r->noAST) )
  2102. {_gen("}n"); tab();}
  2103. }
  2104. /* Handle element labels now */
  2105. if ( p->el_label!=NULL )
  2106. {
  2107.         int     done_NON_GUESSMODE=0;
  2108. _gen("n");
  2109. /* MR10 */    /* do Attrib / Token ptr for token label used in semantic pred */
  2110. /* MR10 */    /* for these cases do assign even in guess mode                */
  2111. /* MR10 */
  2112. /* MR10 */    if (p->label_used_in_semantic_pred) {
  2113. /* MR10 */      if ( GenCC ) {
  2114. /* MR10 */        if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {
  2115. /* MR10 */          gen3("%s = _t%d%d;", p->el_label, BlkLevel-1, p->elnum);
  2116. /* MR10 */        } else {
  2117. /* MR10 */          gen1("%s = (ANTLRTokenPtr)LT(1);n", p->el_label);
  2118. /* MR10 */        };
  2119. /* MR10 */      } else {
  2120. /* MR10 */   gen1("%s = zzaCur;", p->el_label);
  2121. /* MR10 */      };
  2122. /* MR10 */      if (FoundGuessBlk) _gen("  /* MR10 */");
  2123. /* MR10 */      _gen("n");
  2124. /* MR10 */    };
  2125. /* Do Attrib / Token ptr */
  2126. /* MR10 */  if (! p->label_used_in_semantic_pred) {
  2127. /* MR10 */
  2128. /* MR10 */      if ( FoundGuessBlk ) {
  2129. /* MR10 */        if (! done_NON_GUESSMODE) {
  2130. /* MR10 */          done_NON_GUESSMODE=1;
  2131. /* MR10 */          if ( GenCC ) {gen("if ( !guessing ) {n"); tab();}
  2132. /* MR10 */          else {gen("zzNON_GUESS_MODE {n"); tab();}
  2133. /* MR10 */        };
  2134. /* MR10 */      };
  2135. /* MR10 */
  2136. /* MR10 */      if ( GenCC ) {
  2137. /* MR10 */        if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {
  2138. /* MR10 */          gen3("%s = _t%d%d;n", p->el_label, BlkLevel-1, p->elnum);
  2139. /* MR10 */        } else {
  2140. /* MR10 */          gen1("%s = (ANTLRTokenPtr)LT(1);n", p->el_label);
  2141. /* MR10 */        };
  2142. /* MR10 */      } else {
  2143. /* MR10 */        gen1("%s = zzaCur;n", p->el_label);
  2144. /* MR10 */      };
  2145. /* MR10 */  };
  2146. /* Do AST ptr */
  2147. if ( GenAST && !(p->astnode == ASTexclude || r->noAST) )
  2148. {
  2149. /* MR10 */      if ( FoundGuessBlk ) {
  2150. /* MR10 */        if (! done_NON_GUESSMODE) {
  2151. /* MR10 */          done_NON_GUESSMODE=1;
  2152. /* MR10 */          if ( GenCC ) {gen("if ( !guessing ) {n"); tab();}
  2153. /* MR10 */          else {gen("zzNON_GUESS_MODE {n"); tab();}
  2154. /* MR10 */        };
  2155. /* MR10 */      };
  2156. if ( GenCC ) {
  2157. gen3("%s_ast = _ast%d%d;n", p->el_label, BlkLevel-1, p->elnum);
  2158. }
  2159. else {gen1("%s_ast = zzastCur;n", p->el_label);}
  2160. }
  2161. /* MR10 */  if (done_NON_GUESSMODE) {
  2162. /* MR10 */    gen("}n"); tab();
  2163. /* MR10 */  };
  2164. }
  2165. /* Handle any actions immediately following action */
  2166. if ( a != NULL )  /* MR10 */ /* MR11 */
  2167.     {
  2168.      /* delay next token fetch until after action */
  2169. _gen("n");
  2170. if ( a->is_predicate)
  2171. {
  2172. gen("if (!(");
  2173. /* make sure that '#line n' is on front of line */  /* MR14 */
  2174. if ( GenLineInfo && p->file != -1 ) _gen("n");     /* MR14 */
  2175. dumpPredAction(a,a->action, output, 0, a->file, a->line, 0);
  2176. if ( a->pred_fail != NULL )
  2177. {
  2178. _gen(")) {n");
  2179. /************** if ( FoundGuessBlk ) gen("zzNON_GUESS_MODE {n"); *****/
  2180. tabs++;
  2181. /* MR1                                                         */
  2182. /* MR1  10-Apr-97 MR1  Put {...} envelope around failed semantic predicates */
  2183. /* MR1                                                         */
  2184. gen1("{%s};n", a->pred_fail);
  2185. tabs--;
  2186. gen("}n");
  2187. /************** if ( FoundGuessBlk ) gen("}n"); *****/
  2188. }
  2189. /* MR1                                      */
  2190. /* MR1  10-Apr-97 MR1 Properly stringize failed semantic predicates      */
  2191. /* MR1                                                 */
  2192. else
  2193.             {
  2194.                  _gen1(")) {zzfailed_pred("%s");}n",              /* MR1 */
  2195. stringize(a->action));                      /* MR1 */
  2196.             }
  2197. }
  2198. else    /* MR9 a regular action - not a predicate action */
  2199. {
  2200. if ( FoundGuessBlk )
  2201. if ( GenCC ) {gen("if ( !guessing ) {n");}
  2202. else gen("zzNON_GUESS_MODE {n");
  2203. dumpAction(a->action, output, tabs, a->file, a->line, 1);
  2204. if ( FoundGuessBlk ) gen("}n");
  2205. }
  2206. a->done = 1;
  2207. if ( !DemandLookahead ) {
  2208. if ( GenCC ) {
  2209. if ( FoundException && p->use_def_MT_handler ) gen("if (!_signal)");
  2210. _gen(" consume();")
  2211.                 if ( FoundException && p->use_def_MT_handler )
  2212.                     _gen(" _signal=NoSignal;");
  2213.                 _gen("n");
  2214. }
  2215.             else
  2216.             {
  2217.                 if ( FoundException && p->use_def_MT_handler ) _gen("if (!_signal)");
  2218. _gen(" zzCONSUME;n");
  2219.                 if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");
  2220.                 _gen("n");
  2221.             }
  2222. }
  2223. else gen("n");
  2224. TRANS( a->next );
  2225. }
  2226. else
  2227. {
  2228.         if ( !DemandLookahead ) {
  2229. if ( GenCC ) {
  2230. if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");
  2231. _gen(" consume();")
  2232. if (FoundException&&p->use_def_MT_handler) _gen(" _signal=NoSignal;");
  2233. _gen("n");
  2234. }
  2235. else {
  2236. if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");
  2237. _gen(" zzCONSUME;");
  2238. if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");
  2239. _gen("n");
  2240. }
  2241. }
  2242. else _gen("n");
  2243. TRANS(p->next);
  2244. }
  2245. }
  2246. void
  2247. #ifdef __USE_PROTOS
  2248. genOptBlk( Junction *q )
  2249. #else
  2250. genOptBlk( q )
  2251. Junction *q;
  2252. #endif
  2253. {
  2254. int max_k;
  2255. set f;
  2256. int need_right_curly;
  2257. set savetkref;
  2258. savetkref = tokensRefdInBlock;
  2259. require(q!=NULL, "genOptBlk: invalid node and/or rule");
  2260. require(q->ntype == nJunction, "genOptBlk: not junction");
  2261. require(q->jtype == aOptBlk, "genOptBlk: not optional block");
  2262.     OutLineInfo(output,q->line,FileStr[q->file]);
  2263. BLOCK_Preamble(q);
  2264. BlkLevel++;
  2265. f = genBlk(q, aOptBlk, &max_k, &need_right_curly);
  2266. set_free(f);
  2267. freeBlkFsets(q);
  2268. BlkLevel--;
  2269.     if ( first_item_is_guess_block((Junction *)q->p1)!=NULL )
  2270. {
  2271. gen("else if ( !zzrv ) zzGUESS_DONE;n");
  2272. }
  2273. { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}n");} }
  2274. BLOCK_Tail();
  2275. tokensRefdInBlock = savetkref;
  2276. if (q->end->p1 != NULL) TRANS(q->end->p1);
  2277. }
  2278. /*
  2279.  * Generate code for a loop blk of form:
  2280.  *
  2281.  *  |---|
  2282.  *  v   |
  2283.  *    --o-G-o-->o--
  2284.  */
  2285. void
  2286. #ifdef __USE_PROTOS
  2287. genLoopBlk( Junction *begin, Junction *q, Junction *start, int max_k )
  2288. #else
  2289. genLoopBlk( begin, q, start, max_k )
  2290. Junction *begin;
  2291. Junction *q;
  2292. Junction *start; /* where to start generating code from */
  2293. int max_k;
  2294. #endif
  2295. {
  2296. set         f;
  2297. int         need_right_curly;
  2298. set         savetkref;
  2299.     Junction    *guessBlock;    /* MR10 */
  2300.     int         singleAlt;      /* MR10 */
  2301. savetkref = tokensRefdInBlock;
  2302. require(q->ntype == nJunction, "genLoopBlk: not junction");
  2303. require(q->jtype == aLoopBlk, "genLoopBlk: not loop block");
  2304. if ( q->visited ) return;
  2305. q->visited = TRUE;
  2306.     /* first_item_is_guess_block doesn't care what kind of node it is */
  2307.     guessBlock=first_item_is_guess_block( (Junction *) q->p1);  /* MR10 */
  2308.     singleAlt=q->p2==NULL;                                      /* MR10 */
  2309. if (singleAlt && !guessBlock)     /* MR10 */ /* only one alternative? */
  2310. {
  2311. if ( DemandLookahead )
  2312. if ( !GenCC ) {gen1("LOOK(%d);n", max_k);}
  2313. else gen1("look(%d);n", max_k);
  2314. gen("while ( ");
  2315. if ( begin!=NULL ) genExpr(begin);
  2316. else genExpr(q);
  2317. /* if no predicates have been hoisted for this single alt (..)*
  2318.  * do so now
  2319.  */
  2320.         require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
  2321. if ( ParseWithPredicates && begin->predicate==NULL )
  2322. {
  2323. Predicate *a = MR_find_predicates_and_supp((Node *)q->p1);
  2324.             require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
  2325. if ( a!=NULL )
  2326. {
  2327. _gen("&&");
  2328. a=genPredTreeMain(a, (Node *)q);    /* MR10 */
  2329. }
  2330. /* MR10 */  if (MRhoisting) {
  2331. /* MR10 */    predicate_free(a);
  2332. /* MR10 */  };
  2333. }
  2334. _gen(" ) {n");
  2335. tabs++;
  2336. TRANS(q->p1);
  2337. if ( !GenCC ) gen1("zzLOOP(zztasp%d);n", BlkLevel-1);
  2338. if ( DemandLookahead )
  2339. if ( !GenCC ) {gen1("LOOK(%d);n", max_k);}
  2340. else gen1("look(%d);n", max_k);
  2341. --tabs;
  2342. gen("}n");
  2343. freeBlkFsets(q);
  2344. q->visited = FALSE;
  2345. tokensRefdInBlock = savetkref;
  2346. return;
  2347. }
  2348. gen("while ( 1 ) {n");
  2349. tabs++;
  2350. /* MR6                  */
  2351. /* MR6     "begin" can never be null when called from genLoopBegin */
  2352. /* MR6     because q==(Junction *)begin->p1 and we know q is valid */
  2353. /* MR6                              */
  2354. /* MR6    from genLoopBegin:                 */
  2355. /* MR6                              */
  2356. /* MR6  if ( LL_k>1 && !set_nil(q->fset[2]) )         */
  2357. /* MR6      genLoopBlk( q, (Junction *)q->p1, q, max_k );     */
  2358. /* MR6 else genLoopBlk( q, (Junction *)q->p1, NULL, max_k ); */
  2359. /* MR6                               */
  2360. if ( begin!=NULL )
  2361. {
  2362. if ( DemandLookahead )
  2363. {
  2364. if ( !GenCC ) {gen1("LOOK(%d);n", max_k);}
  2365. else gen1("look(%d);n", max_k);
  2366. }
  2367. /* The bypass arc of the (...)* predicts what to do when you fail, but
  2368.  * ONLY after having tested the loop start expression.  To avoid this,
  2369.  * we simply break out of the (...)* loop when we find something that
  2370.  * is not in the prediction of the loop (all alts thereof).
  2371.  */
  2372. gen("if ( !(");
  2373. /*** TJP says: It used to use the prediction expression for the bypass arc
  2374.       of the (...)*.  HOWEVER, if a non LL^1(k) decision was found, this
  2375.      thing would miss the ftree stored in the aLoopBegin node and generate
  2376.      an LL^1(k) decision anyway.
  2377.  *** genExpr((Junction *)begin->p2);
  2378.  ***/
  2379.             genExpr((Junction *)begin);
  2380.             _gen(")) break;n");
  2381. }
  2382. /* generate code for terminating loop (this is optional branch) */
  2383. f = genBlk(q, aLoopBlk, &max_k, &need_right_curly);
  2384. set_free(f);
  2385. freeBlkFsets(q);
  2386. /* generate code for terminating loop (this is optional branch) */
  2387. /* MR6                                   */
  2388. /* MR6  30-May-97 Bug reported by Manuel Ornato             */
  2389. /* MR6            A definite bug involving the exit from a loop block   */
  2390. /* MR6    In 1.23 and later versions (including 1.33) Instead       */
  2391. /* MR6              exiting the block and reporting a syntax error the  */
  2392. /* MR6     code loops forever.                      */
  2393. /* MR6           Looking at 1.20 which generates proper code it is not */
  2394. /* MR6     clear which of two changes should be undone.            */
  2395. /* MR6   This is my best guess.                                    */
  2396. /* MR6   From earlier MR6 note we know that begin can never be     */
  2397. /* MR6     null when genLoopBlk called from genLoopBegin           */
  2398. /* MR6 */
  2399. /* MR6 */ if ( begin==NULL) {
  2400. /* MR6 */   /* code for exiting loop "for sure" */
  2401. /* MR6 */   gen("/* Suppressed by MR6 */ /*** else break; ***/n");
  2402. /* MR6 */ };
  2403. /* MR10 */if (singleAlt && guessBlock) {
  2404. /* MR10 */  tabs--;
  2405. /* MR6 */   gen("} else break; /* MR6 code for exiting loop "for sure" */n");
  2406. /* MR10 */  need_right_curly--;
  2407. /* MR10 */ } else {
  2408. /* MR6 */   gen("else break; /* MR6 code for exiting loop "for sure" */n");
  2409. /* MR10 */ };
  2410. { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}n");} }
  2411. if ( !GenCC ) gen1("zzLOOP(zztasp%d);n", BlkLevel-1);
  2412. --tabs;
  2413. gen("}n");
  2414. q->visited = FALSE;
  2415. tokensRefdInBlock = savetkref;
  2416. }
  2417. /*
  2418.  * Generate code for a loop blk of form:
  2419.  *
  2420.  *           |---|
  2421.  *      v   |
  2422.  *    --o-->o-->o-G-o-->o--
  2423.  *                   |           ^
  2424.  *                   v           |
  2425.  *  o-----------o
  2426.  *
  2427.  * q->end points to the last node (far right) in the blk.
  2428.  *
  2429.  * Note that q->end->jtype must be 'EndBlk'.
  2430.  *
  2431.  * Generate code roughly of the following form:
  2432.  *
  2433.  * do {
  2434.  * ... code for alternatives ...
  2435.  *  } while ( First Set of aLoopBlk );
  2436.  *
  2437.  * OR if > 1 alternative
  2438.  *
  2439.  * do {
  2440.  * ... code for alternatives ...
  2441.  * else break;
  2442.  *  } while ( 1 );
  2443.  */
  2444. void
  2445. #ifdef __USE_PROTOS
  2446. genLoopBegin( Junction *q )
  2447. #else
  2448. genLoopBegin( q )
  2449. Junction *q;
  2450. #endif
  2451. {
  2452. set f;
  2453. int i;
  2454. int max_k;
  2455. set savetkref;
  2456. savetkref = tokensRefdInBlock;
  2457. require(q!=NULL, "genLoopBegin: invalid node and/or rule");
  2458. require(q->ntype == nJunction, "genLoopBegin: not junction");
  2459. require(q->jtype == aLoopBegin, "genLoopBegin: not loop block");
  2460. require(q->p2!=NULL, "genLoopBegin: invalid Loop Graph");
  2461.     OutLineInfo(output,q->line,FileStr[q->file]);
  2462. BLOCK_Preamble(q);
  2463. BlkLevel++;
  2464. f = First(q, 1, aLoopBegin, &max_k);
  2465. /* If not simple LL(1), must specify to start at LoopBegin, not LoopBlk */
  2466. if ( LL_k>1 && !set_nil(q->fset[2]) )
  2467. genLoopBlk( q, (Junction *)q->p1, q, max_k );
  2468. else genLoopBlk( q, (Junction *)q->p1, NULL, max_k );
  2469. for (i=1; i<=CLL_k; i++) set_free(q->fset[i]);
  2470. for (i=1; i<=CLL_k; i++) set_free(((Junction *)q->p2)->fset[i]);
  2471. --BlkLevel;
  2472. BLOCK_Tail();
  2473. set_free(f);
  2474. tokensRefdInBlock = savetkref;
  2475. if (q->end->p1 != NULL) TRANS(q->end->p1);
  2476. }
  2477. /*
  2478.  * Generate code for a loop blk of form:
  2479.  *
  2480.  *   |---|
  2481.  *  v   |
  2482.  *        --o-G-o-->o--
  2483.  *
  2484.  * q->end points to the last node (far right) in the blk.
  2485.  * Note that q->end->jtype must be 'EndBlk'.
  2486.  *
  2487.  * Generate code roughly of the following form:
  2488.  *
  2489.  * do {
  2490.  * ... code for alternatives ...
  2491.  *  } while ( First Set of aPlusBlk );
  2492.  *
  2493.  * OR if > 1 alternative
  2494.  *
  2495.  * do {
  2496.  * ... code for alternatives ...
  2497.  * else if not 1st time through, break;
  2498.  *  } while ( 1 );
  2499.  */
  2500. void
  2501. #ifdef __USE_PROTOS
  2502. genPlusBlk( Junction *q )
  2503. #else
  2504. genPlusBlk( q )
  2505. Junction *q;
  2506. #endif
  2507. {
  2508. int         max_k;
  2509. set         f;
  2510. int         need_right_curly;
  2511. set         savetkref;
  2512.     Junction    *guessBlock;    /* MR10 */
  2513.     int         singleAlt;      /* MR10 */
  2514. savetkref = tokensRefdInBlock;
  2515. require(q!=NULL, "genPlusBlk: invalid node and/or rule");
  2516. require(q->ntype == nJunction, "genPlusBlk: not junction");
  2517. require(q->jtype == aPlusBlk, "genPlusBlk: not Plus block");
  2518. require(q->p2 != NULL, "genPlusBlk: not a valid Plus block");
  2519. if ( q->visited ) return;
  2520. q->visited = TRUE;
  2521.     OutLineInfo(output,q->line,FileStr[q->file]);
  2522. BLOCK_Preamble(q);
  2523. BlkLevel++;
  2524.     /* first_item_is_guess_block  doesn't care what kind of node it is */
  2525.     guessBlock=first_item_is_guess_block( (Junction *)q->p1);   /* MR10 */
  2526. /* if the ignore flag is set on the 2nd alt and that alt is empty,
  2527.  * then it is the implied optional alternative that we added for (...)+
  2528.  * and, hence, only 1 alt.
  2529.  */
  2530. /* MR10  Reported by Pulkkinen Esa (esap@cs.tut.fi)
  2531.  *       Outer code for guess blocks ignored when there is only one alt
  2532.  *         for a (...)+ block.
  2533.  *       Force use of regular code rather than "optimized" code for that case
  2534.  */
  2535.     singleAlt=( ( (Junction *) q->p2)->p2 == NULL) &&
  2536.            ( ( (Junction *) q->p2)->ignore ); /* only one alternative? */
  2537.     if (singleAlt && !guessBlock)   /* MR10 */
  2538. {
  2539. Predicate *a=NULL;
  2540. /* if the only alt has a semantic predicate, hoist it; must test before
  2541.  * entering loop.
  2542.  */
  2543. if ( ParseWithPredicates )
  2544. {
  2545.             require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
  2546. a = MR_find_predicates_and_supp((Node *)q);
  2547.             require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
  2548. if ( a!=NULL ) {
  2549. gen("if (");
  2550. a=genPredTreeMain(a, (Node *)q);    /* MR10 */
  2551. _gen(") {n");
  2552. }
  2553. }
  2554. gen("do {n");
  2555. tabs++;
  2556. TRANS(q->p1);
  2557. if ( !GenCC ) gen1("zzLOOP(zztasp%d);n", BlkLevel-1);
  2558. f = First(q, 1, aPlusBlk, &max_k);
  2559. if ( DemandLookahead )
  2560. if ( !GenCC ) {gen1("LOOK(%d);n", max_k);}
  2561. else gen1("look(%d);n", max_k);
  2562. --tabs;
  2563. gen("} while ( ");
  2564. if ( q->parm!=NULL && q->predparm ) _gen1("(%s) && ", q->parm);
  2565. genExpr(q);
  2566. if ( ParseWithPredicates && a!=NULL )
  2567. {
  2568.             if (! MR_comparePredicates(q->predicate,a)) {
  2569.      _gen("&&");
  2570.      a=genPredTreeMain(a, (Node *)q);    /* MR10 */
  2571.             };
  2572. }
  2573. _gen(" );n");
  2574. if ( ParseWithPredicates && a!=NULL ) gen("}n");
  2575. --BlkLevel;
  2576. BLOCK_Tail();
  2577. q->visited = FALSE;
  2578. freeBlkFsets(q);
  2579. set_free(f);
  2580. tokensRefdInBlock = savetkref;
  2581. if (q->end->p1 != NULL) TRANS(q->end->p1);
  2582. /* MR10 */  if (MRhoisting) {
  2583. /* MR10 */    predicate_free(a);
  2584. /* MR10 */  };
  2585. return;
  2586. }
  2587. gen("do {n");
  2588. tabs++;
  2589. f = genBlk(q, aPlusBlk, &max_k, &need_right_curly);
  2590. /* MR6                       */
  2591. /* MR6 Sinan Karasu (sinan@tardis.ds.boeing.com) */
  2592. /* MR6    Failed to turn off guess mode when leaving block */
  2593. /* MR6                             */
  2594. /* MR6  */ if ( has_guess_block_as_last_item(q) ) {
  2595. /* MR10 */   gen("/* MR10 ()+ */ else {n");
  2596. /* MR10 */   tabs++;
  2597. /* MR10 */   need_right_curly++;
  2598. /* MR10 */   gen("/* MR10 ()+ */ if ( !zzrv ) zzGUESS_DONE;n");
  2599. /* MR6  */   gen("/* MR10 ()+ */ if ( zzcnt > 1 ) break;n");
  2600. /* MR10 */ } else {
  2601. /* MR10 */   gen("/* MR10 ()+ */ else {n");
  2602. /* MR10 */   tabs++;
  2603. /* MR10 */   need_right_curly++;
  2604. /* MR10 */   gen("if ( zzcnt > 1 ) break;n");
  2605. /* MR10 */ };
  2606. tab();
  2607. makeErrorClause(q,f,max_k);
  2608. { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}n");} }
  2609. freeBlkFsets(q);
  2610. gen("zzcnt++;");
  2611. if ( !GenCC ) _gen1(" zzLOOP(zztasp%d);", BlkLevel-1);
  2612. _gen("n");
  2613. if ( DemandLookahead )
  2614. if ( !GenCC ) {gen1("LOOK(%d);n", max_k);}
  2615. else gen1("look(%d);n", max_k);
  2616. --tabs;
  2617. if ( q->parm!=NULL && q->predparm ) {gen1("} while (%s);n", q->parm);}
  2618. else gen("} while ( 1 );n");
  2619. --BlkLevel;
  2620. BLOCK_Tail();
  2621. q->visited = FALSE;
  2622. tokensRefdInBlock = savetkref;
  2623. if (q->end->p1 != NULL) TRANS(q->end->p1);
  2624. }
  2625. /*
  2626.  * Generate code for a sub blk of alternatives of form:
  2627.  *
  2628.  *        --o-G1--o--
  2629.  *  |     ^
  2630.  *  v    /|
  2631.  *          o-G2-o|
  2632.  *  |     ^
  2633.  *  v     |
  2634.  *    ..........
  2635.  *  |     ^
  2636.  *  v    /
  2637.  *          o-Gn-o
  2638.  *
  2639.  * q points to the 1st junction of blk (upper-left).
  2640.  * q->end points to the last node (far right) in the blk.
  2641.  * Note that q->end->jtype must be 'EndBlk'.
  2642.  * The last node in every alt points to q->end.
  2643.  *
  2644.  * Generate code of the following form:
  2645.  * if ( First(G1) ) {
  2646.  * ...code for G1...
  2647.  * }
  2648.  * else if ( First(G2) ) {
  2649.  * ...code for G2...
  2650.  * }
  2651.  * ...
  2652.  * else {
  2653.  * ...code for Gn...
  2654.  * }
  2655.  */
  2656. void
  2657. #ifdef __USE_PROTOS
  2658. genSubBlk( Junction *q )
  2659. #else
  2660. genSubBlk( q )
  2661. Junction *q;
  2662. #endif
  2663. {
  2664. int max_k;
  2665. set f;
  2666. int need_right_curly;
  2667. set savetkref;
  2668. savetkref = tokensRefdInBlock;
  2669. require(q->ntype == nJunction, "genSubBlk: not junction");
  2670. require(q->jtype == aSubBlk, "genSubBlk: not subblock");
  2671.     OutLineInfo(output,q->line,FileStr[q->file]);
  2672. BLOCK_Preamble(q);
  2673. BlkLevel++;
  2674. f = genBlk(q, aSubBlk, &max_k, &need_right_curly);
  2675. if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k);}
  2676. { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}n");} }
  2677. freeBlkFsets(q);
  2678. --BlkLevel;
  2679. BLOCK_Tail();
  2680. if ( q->guess )
  2681. {
  2682. gen("zzGUESS_DONEn");
  2683. }
  2684. /* must duplicate if (alpha)?; one guesses (validates), the
  2685.  * second pass matches */
  2686. if ( q->guess && analysis_point(q)==q )
  2687. {
  2688.         OutLineInfo(output,q->line,FileStr[q->file]);
  2689. BLOCK_Preamble(q);
  2690. BlkLevel++;
  2691. f = genBlk(q, aSubBlk, &max_k, &need_right_curly);
  2692. if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k);}
  2693. { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}n");} }
  2694. freeBlkFsets(q);
  2695. --BlkLevel;
  2696. BLOCK_Tail();
  2697. }
  2698. tokensRefdInBlock = savetkref;
  2699. if (q->end->p1 != NULL) TRANS(q->end->p1);
  2700. }
  2701. static int TnodesAllocatedPrevRule=0;
  2702. /*
  2703.  * Generate code for a rule.
  2704.  *
  2705.  * rule--> o-->o-Alternatives-o-->o
  2706.  * Or,
  2707.  * rule--> o-->o-Alternative-o-->o
  2708.  *
  2709.  * The 1st junction is a RuleBlk.  The second can be a SubBlk or just a junction
  2710.  * (one alternative--no block), the last is EndRule.
  2711.  * The second to last is EndBlk if more than one alternative exists in the rule.
  2712.  *
  2713.  * To get to the init-action for a rule, we must bypass the RuleBlk,
  2714.  * and possible SubBlk.
  2715.  * Mark any init-action as generated so genBlk() does not regenerate it.
  2716.  */
  2717. void
  2718. #ifdef __USE_PROTOS
  2719. genRule( Junction *q )
  2720. #else
  2721. genRule( q )
  2722. Junction *q;
  2723. #endif
  2724. {
  2725. do {    /* MR10     Change recursion into iteration         */
  2726. int max_k;
  2727. set follow, rk, f;
  2728. ActionNode *a;
  2729. RuleEntry *r;
  2730. static int file = -1;
  2731. int need_right_curly;
  2732. require(q->ntype == nJunction, "genRule: not junction");
  2733. require(q->jtype == RuleBlk, "genRule: not rule");
  2734. /* MR14 */    require (MR_BackTraceStack.count == 0,"-alpha MR_BackTraceStack.count != 0");
  2735. /* MR14 */    MR_pointerStackReset(&MR_BackTraceStack);
  2736. /* MR14 */    if (AlphaBetaTrace) MR_MaintainBackTrace=1;
  2737.     CurRule=q->rname;                               /* MR11 */
  2738. r = (RuleEntry *) hash_get(Rname, q->rname);
  2739. if ( r == NULL ) warnNoFL("Rule hash table is screwed up beyond belief");
  2740. if ( q->file != file ) /* open new output file if need to */
  2741. {
  2742. /* MR6               */
  2743. /* MR6  Simpler to debug when output goes to stdout rather than a file  */
  2744. /* MR6                  */
  2745. /* MR6 */ if (UseStdout) {
  2746. /* MR6 */   output = stdout;
  2747. /* MR6 */ } else {
  2748. /* MR6 */     if ( output != NULL) fclose( output );
  2749. /* MR6 */   output = fopen(OutMetaName(outname(FileStr[q->file])), "w");
  2750. /* MR6 */ };
  2751. require(output != NULL, "genRule: can't open output file");
  2752. #ifdef SPECIAL_FOPEN
  2753.        special_fopen_actions(OutMetaName(outname(FileStr[q->file]))); /* MR1 */
  2754. #endif
  2755. if ( file == -1 ) genHdr1(q->file);
  2756. else genHdr(q->file);
  2757. file = q->file;
  2758. }
  2759.     if (InfoM) {
  2760.       fprintf(stderr,"    rule %sn",q->rname);
  2761.       fflush(output);
  2762.     };
  2763. #if 0
  2764.     if (strcmp(q->rname,"***debug***") == 0) {
  2765.       fprintf(stderr,"***debug*** %s reachedn",q->rname);
  2766.       MR_break();
  2767.     };
  2768. #endif
  2769. DumpFuncHeader(q,r);
  2770. tabs++;
  2771. if ( q->ret!=NULL )
  2772. {
  2773. /* Declare the return value - and PURIFY it -ATG 6/5/95 */
  2774. /* MR7      Moved PURIFY() to after all local variables have been declared */
  2775. /* MR7      so that the generated code is valid C as well as C++           */
  2776. /* MR7        Jan Mikkelsen 10-June-1997                                   */
  2777. if ( HasComma(q->ret) )
  2778. {
  2779. gen1("struct _rv%d _retv;n",r->rulenum);
  2780. }
  2781. else
  2782. {
  2783. tab();
  2784. DumpType(q->ret, output);
  2785. /* MR3  17-May-97  Undo change since _retv is of unpredictable type        */
  2786. /* MR3    If an object it may not be possible to assign 0 or NULL     */
  2787. /* MR3    Reported by Cortland Starrett (cort@shay.ecn.purdue.edu     */
  2788. /* MR1  10-Apr-97  Get rid of annoying Possibly ref'd before use msgs      */
  2789. gen(" _retv;n");            /* MR1 MR3         */
  2790. }
  2791. }
  2792.     OutLineInfo(output,q->line,FileStr[q->file]);
  2793.     if (InfoM) {
  2794.       fflush(output);
  2795.     };
  2796. gen("zzRULE;n");
  2797. if ( FoundException )
  2798. {
  2799. gen("int _sva=1;n");
  2800. }
  2801. if ( GenCC && GenAST )
  2802. gen("ASTBase *_ast = NULL, *_sibling = NULL, *_tail = NULL;n");
  2803. if ( GenCC ) genTokenPointers(q);
  2804. if ( GenCC&&GenAST ) genASTPointers(q);
  2805. if ( q->el_labels!=NULL ) genElementLabels(q->el_labels);
  2806. if ( FoundException ) gen("int _signal=NoSignal;n");
  2807. if ( !GenCC ) gen1("zzBLOCK(zztasp%d);n", BlkLevel);
  2808. /* MR10 */  /* move zzTRACEIN to before init action */
  2809. /* MR10 */ if ( TraceGen )
  2810. /* MR10 */ if ( GenCC ) {gen1("zzTRACEIN("%s");n", q->rname);}
  2811. /* MR10 */ else gen1("zzTRACEIN((ANTLRChar *)"%s");n", q->rname);
  2812. /* MR7      Moved PURIFY() to after all local variables have been declared */
  2813. /* MR7      so that the generated code is valid C as well as C++           */
  2814. /* MR7        Jan Mikkelsen 10-June-1997                                   */
  2815. if ( q->ret != NULL )                                            /* MR7 */
  2816. {                                                                /* MR7 */
  2817. if ( HasComma(q->ret) )                                      /* MR7 */
  2818. {                                                            /* MR7 */
  2819. gen1("PURIFY(_retv,sizeof(struct _rv%d))n",r->rulenum); /* MR7 */
  2820. }                                                            /* MR7 */
  2821. else                                                         /* MR7 */
  2822. {                                                            /* MR7 */
  2823. gen("PURIFY(_retv,sizeof(");                             /* MR7 */
  2824. DumpType(q->ret, output);                                /* MR7 */
  2825. gen("))n");                                             /* MR7 */
  2826. }                                                            /* MR7 */
  2827. }                                                                /* MR7 */
  2828. if ( !GenCC ) gen("zzMake0;n");
  2829. if ( FoundException ) gen("*_retsignal = NoSignal;n");
  2830. if ( !GenCC ) gen("{n");
  2831. if ( has_guess_block_as_first_item((Junction *)q->p1) )
  2832. {
  2833. gen("zzGUESS_BLOCKn");
  2834. }
  2835. /* L o o k  F o r  I n i t  A c t i o n */
  2836. if ( ((Junction *)q->p1)->jtype == aSubBlk )
  2837. a = findImmedAction( ((Junction *)q->p1)->p1 );
  2838. else
  2839. a = findImmedAction( q->p1 ); /* only one alternative in rule */
  2840. if ( a!=NULL && !a->is_predicate)
  2841. {
  2842. if (!a->noHoist) dumpAction(a->action, output, tabs, a->file, a->line, 1);
  2843. a->done = 1; /* ignore action. We have already handled it */
  2844. }
  2845. BlkLevel++;
  2846. q->visited = TRUE; /* mark RULE as visited for FIRST/FOLLOW */
  2847. f = genBlk((Junction *)q->p1, RuleBlk, &max_k, &need_right_curly);
  2848. if ( q->p1 != NULL )
  2849. if ( ((Junction *)q->p1)->p2 != NULL )
  2850. {tab(); makeErrorClause((Junction *)q->p1,f,max_k);}
  2851. { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}n");} }
  2852. freeBlkFsets((Junction *)q->p1);
  2853. q->visited = FALSE;
  2854. --BlkLevel;
  2855. if ( !GenCC ) gen1("zzEXIT(zztasp%d);n", BlkLevel);
  2856.     genTraceOut(q);
  2857. if ( q->ret!=NULL ) gen("return _retv;n") else gen("return;n");
  2858. /* E r r o r  R e c o v e r y */
  2859. NewSet();
  2860. rk = empty;
  2861. /* MR14 */    if (r->dontComputeErrorSet) {
  2862. /* MR14 */      follow=empty;
  2863.               } else {
  2864.                 MR_pointerStackReset(&MR_BackTraceStack);   /* MR14 */
  2865.                 MR_ErrorSetComputationActive=1;
  2866.                 REACH(q->end, 1, &rk, follow);
  2867.                 MR_ErrorSetComputationActive=0;
  2868.                 require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0");
  2869.               }
  2870. FillSet( follow );
  2871. set_free( follow );
  2872. _gen("fail:n");
  2873. if ( !GenCC ) gen("zzEXIT(zztasp1);n");
  2874. if ( FoundGuessBlk )
  2875.     if ( !GenCC ) {gen("if ( zzguessing ) zzGUESS_FAIL;n");}
  2876. else gen("if ( guessing ) zzGUESS_FAIL;n");
  2877. if ( q->erraction!=NULL )
  2878. dumpAction(q->erraction, output, tabs, q->file, q->line, 1);
  2879. if ( GenCC )
  2880. {
  2881. gen1("syn(zzBadTok, %s, zzMissSet, zzMissTok, zzErrk);n",
  2882.  r->egroup==NULL?"(ANTLRChar *)""":r->egroup);
  2883. }
  2884. else
  2885. {
  2886. gen1("zzsyn(zzMissText, zzBadTok, %s, zzMissSet, zzMissTok, zzErrk, zzBadText);n",
  2887.  r->egroup==NULL?"(ANTLRChar *)""":r->egroup);
  2888. }
  2889. gen3("%sresynch(setwd%d, 0x%x);n", GenCC?"":"zz", wordnum, 1<<setnum);
  2890. if ( q->ret!=NULL ) {
  2891.       genTraceOut(q);
  2892.       gen("return _retv;n");
  2893.     } else if ( q->exceptions!=NULL ) {
  2894.       genTraceOut(q);
  2895.       gen("return;n");
  2896.     } else if (!FoundException) {       /* MR10 */
  2897.       genTraceOut(q);                   /* MR10 */
  2898.     };
  2899. if ( !GenCC ) gen("}n");
  2900. /* Gen code for exception handlers */
  2901.     /* make sure each path out contains genTraceOut() */
  2902. if ( q->exceptions!=NULL )
  2903. {
  2904. gen("/* exception handlers */n");
  2905. dumpExceptions(q->exceptions);
  2906.         if ( !r->has_rule_exception )
  2907.         {
  2908.             _gen("_handler:n");
  2909.             gen("zzdflthandlers(_signal,_retsignal);n");
  2910.         }
  2911. _gen("_adios:n");
  2912. if ( q->ret!=NULL ) {
  2913.             genTraceOut(q);
  2914.             gen("return _retv;n");
  2915.         }
  2916. else {
  2917.             genTraceOut(q);
  2918.             gen("return;n");
  2919.         }
  2920. }
  2921. else if ( FoundException )
  2922. {
  2923.       _gen("_handler:n");
  2924.       gen("zzdflthandlers(_signal,_retsignal);n");
  2925. /* MR1                                                                      */
  2926. /* MR1  7-Apr-97 Fix suggested by: John Bair (jbair@iftime.com)            */
  2927. /* MR1                                             */
  2928.       if ( q->ret != NULL) {                              /* MR1 */
  2929.             genTraceOut(q);                                          /* MR10 */
  2930.             gen("return _retv;n");                          /* MR1 */
  2931.       } else {                                      /* MR1 */
  2932.             genTraceOut(q);                                          /* MR10 */
  2933.             gen("return;n")    ;                      /* MR1 */
  2934.       };                                      /* MR1 */
  2935. }
  2936. tabs--;
  2937. gen("}n");
  2938. /* MR10     Tired of looking at stacks that are as deep as the number of    */
  2939. /* MR10       rules.  Changes recursion to iteration.                       */
  2940.     MR_releaseResourcesUsedInRule( (Node *) q );      /* MR10 */
  2941.     if (InfoT) {
  2942.       fprintf(output,"n/* tnodes created for rule %s:  %d */n",
  2943.                 q->rname, (TnodesAllocated-TnodesAllocatedPrevRule) );
  2944.     };
  2945.     TnodesAllocatedPrevRule=TnodesAllocated;
  2946.     if (q->p2 == NULL) dumpAfterActions( output );
  2947.     q=(Junction *)q->p2;
  2948.     require(q==NULL || q->jtype==RuleBlk,"RuleBlk p2 does not point to another RuleBlk");
  2949. } while (q != NULL);
  2950. /**** The old code                           ****/
  2951. /**** if ( q->p2 != NULL ) {TRANS(q->p2);} ****/ /* generate code for next rule too */
  2952. /**** else dumpAfterActions( output );     ****/
  2953. }
  2954. static void
  2955. #ifdef __USE_PROTOS
  2956. DumpFuncHeader( Junction *q, RuleEntry *r )
  2957. #else
  2958. DumpFuncHeader( q, r )
  2959. Junction *q;
  2960. RuleEntry *r;
  2961. #endif
  2962. {
  2963. /*                                             */
  2964. /*  MR1 10-Apr-97  MR1  Simplify insertion of commas in function header     */
  2965. /*                                             */
  2966. int needComma;                                  /* MR1 */
  2967. /* A N S I */
  2968. _gen("n");
  2969. if ( q->ret!=NULL )
  2970. {
  2971. if ( HasComma(q->ret) )
  2972. {
  2973. if (GenCC) gen2("%s::_rv%dn", CurrentClassName, r->rulenum)
  2974. else gen1("struct _rv%dn",r->rulenum);
  2975. }
  2976. else
  2977. {
  2978. DumpType(q->ret, output);
  2979. gen("n");
  2980. }
  2981. }
  2982. else
  2983. {
  2984. _gen("voidn");
  2985. }
  2986. /*  MR1                                                             */
  2987. /*  MR1 10-Apr-97  133MR1 Replace __STDC__ with __USE_PROTOS              */
  2988. /*  MR1                                         */
  2989. if ( !GenCC ) _gen("#ifdef __USE_PROTOSn");      /* MR1 */
  2990. if ( !GenCC ) gen2("%s%s(", RulePrefix, q->rname)
  2991. else gen3("%s::%s%s(", CurrentClassName, RulePrefix,q->rname);
  2992. DumpANSIFunctionArgDef(output,q);
  2993. _gen("n");
  2994. if ( GenCC ) {
  2995.       gen("{n");
  2996.       return;
  2997.     }
  2998. /* K & R */
  2999. gen("#elsen");
  3000. gen2("%s%s(", RulePrefix, q->rname);
  3001. needComma=0;                              /* MR1 */
  3002. if ( GenAST )                              /* MR1 */
  3003. {                                      /* MR1 */
  3004. _gen("_root");                              /* MR1 */
  3005. needComma=1;                              /* MR1 */
  3006. }                                      /* MR1 */
  3007. if ( FoundException )                          /* MR1 */
  3008. {                                      /* MR1 */
  3009. if (needComma) {_gen(",");needComma=0;};                  /* MR1 */
  3010. _gen("_retsignal");                              /* MR1 */
  3011. needComma=1;                              /* MR1 */
  3012. }                                      /* MR1 */
  3013. /* MR5 Change below by Jan Mikkelsen (janm@zeta.org.au) 26-May-97      MR5 */
  3014. DumpListOfParmNames( q->pdecl, output, needComma );              /* MR5 */
  3015. gen(")n");
  3016. if ( GenAST ) gen("AST **_root;n");
  3017. if ( FoundException ) gen("int *_retsignal;n");
  3018. DumpOldStyleParms( q->pdecl, output );
  3019. gen("#endifn");
  3020.     gen("{n");
  3021. }
  3022. void
  3023. #ifdef __USE_PROTOS
  3024. DumpANSIFunctionArgDef(FILE *f, Junction *q)
  3025. #else
  3026. DumpANSIFunctionArgDef(f,q)
  3027. FILE *f;
  3028. Junction *q;
  3029. #endif
  3030. {
  3031. if ( GenAST )
  3032. {
  3033. if ( GenCC ) {fprintf(f,"ASTBase **_root");}
  3034. else fprintf(f,"AST**_root");
  3035. if ( !FoundException && q->pdecl!=NULL ) fprintf(f,",");
  3036. }
  3037. if ( FoundException )
  3038. {
  3039. if ( GenAST ) fprintf(f,",");
  3040. fprintf(f,"int *_retsignal");
  3041. if ( q->pdecl!=NULL ) fprintf(f,",");
  3042. }
  3043. if ( q->pdecl!=NULL ) {fprintf(f,"%s", q->pdecl);}
  3044. else if ( !GenAST && !FoundException ) fprintf(f,"void");
  3045. fprintf(f,")");
  3046. }
  3047. void
  3048. #ifdef __USE_PROTOS
  3049. genJunction( Junction *q )
  3050. #else
  3051. genJunction( q )
  3052. Junction *q;
  3053. #endif
  3054. {
  3055. require(q->ntype == nJunction, "genJunction: not junction");
  3056. require(q->jtype == Generic, "genJunction: not generic junction");
  3057. if ( q->p1 != NULL ) TRANS(q->p1);
  3058. if ( q->p2 != NULL ) TRANS(q->p2);
  3059. }
  3060. void
  3061. #ifdef __USE_PROTOS
  3062. genEndBlk( Junction *q )
  3063. #else
  3064. genEndBlk( q )
  3065. Junction *q;
  3066. #endif
  3067. {
  3068. }
  3069. void
  3070. #ifdef __USE_PROTOS
  3071. genEndRule( Junction *q )
  3072. #else
  3073. genEndRule( q )
  3074. Junction *q;
  3075. #endif
  3076. {
  3077. }
  3078. void
  3079. #ifdef __USE_PROTOS
  3080. genHdr( int file )
  3081. #else
  3082. genHdr( file )
  3083. int file;
  3084. #endif
  3085. {
  3086.     int     i;
  3087. _gen("/*n");
  3088. _gen(" * A n t l r  T r a n s l a t i o n  H e a d e rn");
  3089. _gen(" *n");
  3090. _gen(" * Terence Parr, Will Cohen, and Hank Dietz: 1989-1998n");
  3091. _gen(" * Purdue University Electrical Engineeringn");
  3092. _gen(" * With AHPCRC, University of Minnesotan");
  3093. _gen1(" * ANTLR Version %sn", Version);
  3094. _gen(" *n");
  3095. /* MR10 */    _gen(" *  ");
  3096. /* MR10 */    for (i=0 ; i < Save_argc ; i++) {
  3097. /* MR10 */      _gen(" ");
  3098. /* MR10 */      _gen(Save_argv[i]);
  3099. /* MR10 */    };
  3100. _gen("n");
  3101. _gen(" *n");
  3102.     _gen(" */nn");
  3103. _gen1("#define ANTLR_VERSION %sn", VersionDef);
  3104. if (FirstAction != NULL ) dumpAction( FirstAction, output, 0, -1, 0, 1);    /* MR11 */
  3105. _gen("#include "pcctscfg.h"n");
  3106. _gen("#include PCCTS_STDIO_Hn");
  3107. if ( strcmp(ParserName, DefaultParserName)!=0 )
  3108. _gen2("#define %s %sn", DefaultParserName, ParserName);
  3109.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  3110. {_gen1("#include "%s"n", RemapFileName);}
  3111.     OutLineInfo(output,1,FileStr[file]);
  3112. if ( GenCC ) {
  3113. if ( UserTokenDefsFile != NULL )
  3114. fprintf(output, "#include %sn", UserTokenDefsFile);
  3115. else
  3116. fprintf(output, "#include "%s"n", DefFileName);
  3117. }
  3118. if ( HdrAction != NULL ) dumpAction( HdrAction, output, 0, -1, 0, 1);
  3119. if ( !GenCC && FoundGuessBlk )
  3120. {
  3121. _gen("#define ZZCAN_GUESSn");
  3122. _gen("#include PCCTS_SETJMPn");
  3123. }
  3124. if ( FoundException )
  3125. {
  3126. _gen("#define EXCEPTION_HANDLINGn");
  3127. _gen1("#define NUM_SIGNALS %dn", NumSignals);
  3128. }
  3129. if ( !GenCC && OutputLL_k > 1 ) _gen1("#define LL_K %dn", OutputLL_k);
  3130. if ( GenAST&&!GenCC ) _gen("#define GENASTnn");
  3131. if ( GenAST ) {
  3132. if ( GenCC ) {_gen1("#include "%s"nn", ASTBASE_H);}
  3133. else _gen("#include "ast.h"nn");
  3134. }
  3135. if ( !GenCC && DemandLookahead ) _gen("#define DEMAND_LOOKnn");
  3136. #ifdef DUM
  3137. if ( !GenCC && LexGen ) {
  3138. _gen1("#define zzEOF_TOKEN %dn", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));
  3139. }
  3140. #endif
  3141. /* ###WARNING: This will have to change when SetWordSize changes */
  3142. if ( !GenCC ) _gen1("#define zzSET_SIZE %dn", NumWords(TokenNum-1)*sizeof(unsigned));
  3143.     if (TraceGen) {
  3144.       _gen("#define zzTRACE_RULESn");  /* MR10 */
  3145.     };
  3146. if ( !GenCC ) {_gen("#include "antlr.h"n");}
  3147. else {
  3148. _gen1("#include "%s"n", APARSER_H);
  3149. _gen1("#include "%s.h"n", CurrentClassName);
  3150. }
  3151. if ( !GenCC ) {
  3152. if ( UserDefdTokens )
  3153. {_gen1("#include %sn", UserTokenDefsFile);}
  3154. /* still need this one as it has the func prototypes */
  3155. _gen1("#include "%s"n", DefFileName);
  3156. }
  3157. /* still need this one as it defines the DLG interface */
  3158. if ( !GenCC ) _gen("#include "dlgdef.h"n");
  3159. if ( LexGen && GenCC ) _gen1("#include "%s"n", DLEXERBASE_H);
  3160. if ( GenCC ) _gen1("#include "%s"n", ATOKPTR_H);
  3161. if ( !GenCC && LexGen ) _gen1("#include "%s"n", ModeFileName);
  3162. /* MR10  Ofer Ben-Ami (gremlin@cs.huji.ac.il)           */
  3163. /* MR10    Finally, a definition of the Purify macro    */
  3164. _gen("#ifndef PURIFYn");
  3165.     _gen("#define PURIFY(r,s) memset((char *) &(r),'\0',(s));n");
  3166.     _gen("#endifn");
  3167. }
  3168. void
  3169. #ifdef __USE_PROTOS
  3170. genHdr1( int file )
  3171. #else
  3172. genHdr1( file )
  3173. int file;
  3174. #endif
  3175. {
  3176. ListNode *p;
  3177. genHdr(file);
  3178. if ( GenAST )
  3179. {
  3180. if ( !GenCC ) {
  3181. _gen("#include "ast.c"n");
  3182. _gen("zzASTgvarsnn");
  3183. }
  3184. }
  3185. if ( !GenCC ) _gen("ANTLR_INFOn");
  3186. if ( BeforeActions != NULL )
  3187. {
  3188. for (p = BeforeActions->next; p!=NULL; p=p->next)
  3189. {
  3190. UserAction *ua = (UserAction *)p->elem;
  3191. dumpAction( ua->action, output, 0, ua->file, ua->line, 1);
  3192. }
  3193. }
  3194. if ( !FoundException ) return;
  3195. if ( GenCC )
  3196. {
  3197. _gen1("nvoid %s::n", CurrentClassName);
  3198. _gen("zzdflthandlers( int _signal, int *_retsignal )n");
  3199. _gen("{n");
  3200. }
  3201. else
  3202. {
  3203. _gen("nvoidn");
  3204. /*  MR1                                                         */
  3205. /*  MR1 10-Apr-97  133MR1 Replace __STDC__ with __USE_PROTOS              */
  3206. /*  MR1                                                                     */
  3207.     _gen("#ifdef __USE_PROTOSn");                               /* MR1 */
  3208. _gen("zzdflthandlers( int _signal, int *_retsignal )n");
  3209. _gen("#elsen");
  3210. _gen("zzdflthandlers( _signal, _retsignal )n");
  3211. _gen("int _signal;n");
  3212. _gen("int *_retsignal;n");
  3213. _gen("#endifn");
  3214. _gen("{n");
  3215. }
  3216. tabs++;
  3217. if ( DefaultExGroup!=NULL )
  3218. {
  3219. dumpException(DefaultExGroup, 1);
  3220. if ( !hasDefaultException(DefaultExGroup) )
  3221. {
  3222. gen("default :n");
  3223. tabs++;
  3224. gen("*_retsignal = _signal;n");
  3225. tabs--;
  3226. gen("}n");
  3227. }
  3228. }
  3229. else {
  3230. gen("*_retsignal = _signal;n");
  3231. }
  3232. tabs--;
  3233. _gen("}nn");
  3234. }
  3235. void
  3236. #ifdef __USE_PROTOS
  3237. genStdPCCTSIncludeFile( FILE *f,char *gate )    /* MR10 */
  3238. #else
  3239. genStdPCCTSIncludeFile( f , gate)               /* MR10 */
  3240. FILE *f;
  3241. char * gate;                                    /* MR10 */
  3242. #endif
  3243. {
  3244. /* MR10 Ramanathan Santhanam (ps@kumaran.com)           */
  3245. /* MR10 Same preprocessor symbol use to gate stdpccts.h */
  3246. /* MR10   even when two grammars are in use.            */
  3247. /* MR10 Derive gate symbol from -fh filename            */
  3248.     if (gate == NULL) {
  3249.       fprintf(f,"#ifndef STDPCCTS_Hn");          /* MR10 */
  3250.       fprintf(f,"#define STDPCCTS_Hn");          /* MR10 */
  3251.     } else {
  3252.       fprintf(f,"#ifndef STDPCCTS_%s_Hn",gate);  /* MR10 */
  3253.       fprintf(f,"#define STDPCCTS_%s_Hn",gate);  /* MR10 */
  3254.     };
  3255. fprintf(f,"/*n");
  3256.     if (gate == NULL) {
  3257.   fprintf(f," * %s -- P C C T S  I n c l u d en", stdpccts);
  3258.     } else {
  3259.   fprintf(f," * Standard PCCTS include file with -fh %s -- P C C T S  I n c l u d en", stdpccts);
  3260.     }
  3261. fprintf(f," *n");
  3262. fprintf(f," * Terence Parr, Will Cohen, and Hank Dietz: 1989-1998n");
  3263. fprintf(f," * Purdue University Electrical Engineeringn");
  3264. fprintf(f," * With AHPCRC, University of Minnesotan");
  3265. fprintf(f," * ANTLR Version %sn", Version);
  3266. fprintf(f," */nn");
  3267.     fprintf(f,"#ifndef ANTLR_VERSIONn");
  3268. fprintf(f,"#define ANTLR_VERSION %sn", VersionDef);
  3269.     fprintf(f,"#endifnn");
  3270.     if (FirstAction != NULL ) dumpAction(FirstAction, f, 0, -1, 0, 1);  /* MR11 */
  3271. fprintf(f,"#include "pcctscfg.h"n");
  3272. fprintf(f,"#include PCCTS_STDIO_Hn");
  3273. if ( GenCC )
  3274. {
  3275. if ( UserDefdTokens )
  3276. fprintf(f, "#include %sn", UserTokenDefsFile);
  3277. else {
  3278. fprintf(f, "#include "%s"n", DefFileName);
  3279. }
  3280. fprintf(f, "#include "%s"n", ATOKEN_H);
  3281. if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);
  3282. fprintf(f, "#include "%s"n", ATOKENBUFFER_H);
  3283. if ( OutputLL_k > 1 ) fprintf(f,"static const unsigned LL_K=%d;n", OutputLL_k);
  3284. if ( GenAST ) {
  3285. fprintf(f, "#include "%s"n", ASTBASE_H);
  3286. }
  3287. fprintf(f,"#include "%s"n", APARSER_H);
  3288. fprintf(f,"#include "%s.h"n", CurrentClassName);
  3289. if ( LexGen ) fprintf(f,"#include "%s"n", DLEXERBASE_H);
  3290. fprintf(f, "#endifn");
  3291. return;
  3292. }
  3293. if ( strcmp(ParserName, DefaultParserName)!=0 )
  3294. fprintf(f, "#define %s %sn", DefaultParserName, ParserName);
  3295. if ( strcmp(ParserName, DefaultParserName)!=0 )
  3296. fprintf(f, "#include "%s"n", RemapFileName);
  3297. if ( UserTokenDefsFile != NULL )
  3298.    fprintf(f, "#include %sn", UserTokenDefsFile);
  3299. if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);
  3300. if ( FoundGuessBlk )
  3301. {
  3302. fprintf(f,"#define ZZCAN_GUESSn");
  3303. fprintf(f,"#include <setjmp.h>n");
  3304. }
  3305.     if (TraceGen) {
  3306.       fprintf(f,"#define zzTRACE_RULESn");  /* MR10 */
  3307.     };
  3308. if ( OutputLL_k > 1 ) fprintf(f,"#define LL_K %dn", OutputLL_k);
  3309. if ( GenAST ) fprintf(f,"#define GENASTn");
  3310. if ( FoundException )
  3311. {
  3312. /* MR1  7-Apr-97  1.33MR1                            */
  3313. /* MR1      Fix suggested by:                    */
  3314. /* MR1    Francois-Xavier Fontaine (fontaine_f@istvax.ist.lu)         */
  3315. fprintf(f,"#define EXCEPTION_HANDLINGn");             /* MR1 */
  3316. fprintf(f,"#define NUM_SIGNALS %dn", NumSignals);          /* MR1 */
  3317. }
  3318. if ( DemandLookahead ) fprintf(f,"#define DEMAND_LOOKn");
  3319. #ifdef DUM
  3320. if ( LexGen ) fprintf(f, "#define zzEOF_TOKEN %dn", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));
  3321. #endif
  3322. /* ###WARNING: This will have to change when SetWordSize changes */
  3323. fprintf(f, "#define zzSET_SIZE %dn", NumWords(TokenNum-1)*sizeof(unsigned));
  3324. fprintf(f,"#include "antlr.h"n");
  3325. if ( GenAST ) fprintf(f,"#include "ast.h"n");
  3326. if ( UserDefdTokens )
  3327. fprintf(f, "#include %sn", UserTokenDefsFile);
  3328. /* still need this one as it has the func prototypes */
  3329. fprintf(f, "#include "%s"n", DefFileName);
  3330. /* still need this one as it defines the DLG interface */
  3331. fprintf(f,"#include "dlgdef.h"n");
  3332. /* don't need this one unless DLG is used */
  3333. if ( LexGen ) fprintf(f,"#include "%s"n", ModeFileName);
  3334. fprintf(f,"#endifn");
  3335. }
  3336. /* dump action 's' to file 'output' starting at "local" tab 'tabs'
  3337.    Dump line information in front of action if GenLineInfo is set
  3338.    If file == -1 then GenLineInfo is ignored.
  3339.    The user may redefine the LineInfoFormatStr to his/her liking
  3340.    most compilers will like the default, however.
  3341.    June '93; changed so that empty lines are left alone so that
  3342.    line information is correct for the compiler/debuggers.
  3343. */
  3344. void
  3345. #ifdef __USE_PROTOS
  3346. dumpAction( char *s, FILE *output, int tabs, int file, int line,
  3347. int final_newline )
  3348. #else
  3349. dumpAction( s, output, tabs, file, line, final_newline )
  3350. char *s;
  3351. FILE *output;
  3352. int tabs;
  3353. int file;
  3354. int line;
  3355. int final_newline;
  3356. #endif
  3357. {
  3358.     int inDQuote, inSQuote;
  3359.     require(s!=NULL,  "dumpAction: NULL action");
  3360.     require(output!=NULL, eMsg1("dumpAction: output FILE is NULL for %s",s));
  3361. if ( GenLineInfo && file != -1 )
  3362. {
  3363.         OutLineInfo(output,line,FileStr[file]);
  3364. }
  3365.     PastWhiteSpace( s );
  3366. /* don't print a tab if first non-white char is a # (preprocessor command) */
  3367. if ( *s!='#' ) {TAB;}
  3368.     inDQuote = inSQuote = FALSE;
  3369.     while ( *s != '' )
  3370.     {
  3371.         if ( *s == '\' )
  3372.         {
  3373.             fputc( *s++, output ); /* Avoid '"' Case */
  3374.             if ( *s == '' ) return;
  3375.             if ( *s == ''' ) fputc( *s++, output );
  3376.             if ( *s == '"' ) fputc( *s++, output );
  3377.         }
  3378.         if ( *s == ''' )
  3379.         {
  3380.             if ( !inDQuote ) inSQuote = !inSQuote;
  3381.         }
  3382.         if ( *s == '"' )
  3383.         {
  3384.             if ( !inSQuote ) inDQuote = !inDQuote;
  3385.         }
  3386.         if ( *s == 'n' )
  3387.         {
  3388.             fputc('n', output);
  3389. s++;
  3390.             PastWhiteSpace( s );
  3391.             if ( *s == '}' )
  3392.             {
  3393.                 --tabs;
  3394. TAB;
  3395.                 fputc( *s++, output );
  3396.                 continue;
  3397.             }
  3398.             if ( *s == '' ) return;
  3399. if ( *s != '#' ) /* #define, #endif etc.. start at col 1 */
  3400.             {
  3401. TAB;
  3402. }
  3403.         }
  3404.         if ( *s == '}' && !(inSQuote || inDQuote) )
  3405.         {
  3406.             --tabs;            /* Indent one fewer */
  3407.         }
  3408.         if ( *s == '{' && !(inSQuote || inDQuote) )
  3409.         {
  3410.             tabs++;            /* Indent one more */
  3411.         }
  3412.         fputc( *s, output );
  3413.         s++;
  3414.     }
  3415.     if ( final_newline ) fputc('n', output);
  3416. }
  3417. static void
  3418. #ifdef __USE_PROTOS
  3419. dumpAfterActions( FILE *output )
  3420. #else
  3421. dumpAfterActions( output )
  3422. FILE *output;
  3423. #endif
  3424. {
  3425. ListNode *p;
  3426. require(output!=NULL, "dumpAfterActions: output file was NULL for some reason");
  3427. if ( AfterActions != NULL )
  3428. {
  3429. for (p = AfterActions->next; p!=NULL; p=p->next)
  3430. {
  3431. UserAction *ua = (UserAction *)p->elem;
  3432. dumpAction( ua->action, output, 0, ua->file, ua->line, 1);
  3433. }
  3434. }
  3435. fclose( output );
  3436. }
  3437. /*
  3438.  * Find the next action in the stream of execution.  Do not pass
  3439.  * junctions with more than one path leaving them.
  3440.  * Only pass generic junctions.
  3441.  *
  3442.  * Scan forward while (generic junction with p2==NULL)
  3443.  * If we stop on an action, return ptr to the action
  3444.  * else return NULL;
  3445.  */
  3446. static ActionNode *
  3447. #ifdef __USE_PROTOS
  3448. findImmedAction( Node *q )
  3449. #else
  3450. findImmedAction( q )
  3451. Node *q;
  3452. #endif
  3453. {
  3454. Junction *j;
  3455. require(q!=NULL, "findImmedAction: NULL node");
  3456. require(q->ntype>=1 && q->ntype<=NumNodeTypes, "findImmedAction: invalid node");
  3457. while ( q->ntype == nJunction )
  3458. {
  3459. j = (Junction *)q;
  3460. if ( j->jtype != Generic || j->p2 != NULL ) return NULL;
  3461. q = j->p1;
  3462. if ( q == NULL ) return NULL;
  3463. }
  3464. if ( q->ntype == nAction ) return (ActionNode *)q;
  3465. return NULL;
  3466. }
  3467. static void
  3468. #ifdef __USE_PROTOS
  3469. dumpRetValAssign( char *retval, char *ret_def )
  3470. #else
  3471. dumpRetValAssign( retval, ret_def )
  3472. char *retval;
  3473. char *ret_def;
  3474. #endif
  3475. {
  3476. char *q = ret_def;
  3477. tab();
  3478. while ( *retval != '' )
  3479. {
  3480. while ( isspace((*retval)) ) retval++;
  3481. while ( *retval!=',' && *retval!='' ) fputc(*retval++, output);
  3482. fprintf(output, " = _trv.");
  3483. DumpNextNameInDef(&q, output);
  3484. fputc(';', output); fputc(' ', output);
  3485. if ( *retval == ',' ) retval++;
  3486. }
  3487. }
  3488. /* This function computes the set of tokens that can possibly be seen k
  3489.  * tokens in the future from point j
  3490.  */
  3491. static set
  3492. #ifdef __USE_PROTOS
  3493. ComputeErrorSet( Junction *j, int k )
  3494. #else
  3495. ComputeErrorSet( j, k )
  3496. Junction *j;
  3497. int k;
  3498. #endif
  3499. {
  3500. Junction *alt1;
  3501. set a, rk, f;
  3502. require(j->ntype==nJunction, "ComputeErrorSet: non junction passed");
  3503. f = rk = empty;
  3504. for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2)
  3505. {
  3506. REACH(alt1->p1, k, &rk, a);
  3507. require(set_nil(rk), "ComputeErrorSet: rk != nil");
  3508. set_free(rk);
  3509. set_orin(&f, a);
  3510. set_free(a);
  3511. }
  3512. return f;
  3513. }
  3514. static char *
  3515. #ifdef __USE_PROTOS
  3516. tokenFollowSet(TokNode *p)
  3517. #else
  3518. tokenFollowSet(p)
  3519. TokNode *p;
  3520. #endif
  3521. {
  3522.     static char buf[100];
  3523.     set rk, a;
  3524.     int n;
  3525.     rk = empty;
  3526.     REACH(p->next, 1, &rk, a);
  3527.     require(set_nil(rk), "rk != nil");
  3528.     set_free(rk);
  3529.     n = DefErrSet( &a, 0, NULL );
  3530.     set_free(a);
  3531.     if ( GenCC )
  3532.         sprintf(buf, "err%d", n);
  3533.     else
  3534.         sprintf(buf, "zzerr%d", n);
  3535.     return buf;
  3536. }
  3537. static void
  3538. #ifdef __USE_PROTOS
  3539. makeErrorClause( Junction *q, set f, int max_k )
  3540. #else
  3541. makeErrorClause( q, f, max_k )
  3542. Junction *q;
  3543. set f;
  3544. int max_k;
  3545. #endif
  3546. {
  3547.     char *  handler_id="";                                           /* MR7 */
  3548.     int     nilf=0;                                                  /* MR13 */
  3549.     RuleEntry *ruleEntry;                                            /* MR14 */
  3550. if ( FoundException )
  3551. {
  3552. _gen("else {n");
  3553. tabs++;
  3554. if ( FoundGuessBlk )
  3555. {
  3556. if ( GenCC ) {gen("if ( guessing ) goto fail;n");}
  3557. else gen("if ( zzguessing ) goto fail;n");
  3558. }
  3559. gen("if (_sva) _signal=NoViableAlt;n");
  3560. gen("else _signal=NoSemViableAlt;n");
  3561.         if (q->outerEG != NULL) {
  3562.           handler_id=q->outerEG->altID;
  3563. #if 0
  3564.         } else {
  3565.           printf("q->curAltNum=%d q->exception_label=%sn",q->curAltNum,q->exception_label);
  3566.           gen("*** DEBUG *** outerEG==NULLn");
  3567. #endif
  3568.         };
  3569. gen1("goto %s_handler;  /* MR7 */n",handler_id);    /* MR7 */
  3570. tabs--;
  3571. gen("}n");
  3572. return;
  3573. }
  3574. if ( max_k == 1 )
  3575. {
  3576. /* MR13 */  nilf=set_nil(f);
  3577.         if ( GenCC ) {
  3578.               _gen1("else {FAIL(1,err%d", DefErrSet1(1,&f,1,NULL));
  3579.             } else {
  3580.                _gen1("else {zzFAIL(1,zzerr%d", DefErrSet1(1,&f,1,NULL));
  3581.             };
  3582.      set_free(f);
  3583. }
  3584. else
  3585. {
  3586. int i;
  3587. set_free(f);
  3588. if ( GenCC ) {_gen1("else {FAIL(%d", max_k);}
  3589. else _gen1("else {zzFAIL(%d", max_k);
  3590.         ruleEntry = (RuleEntry *) hash_get(Rname,q->rname);
  3591. for (i=1; i<=max_k; i++)
  3592. {
  3593. /* MR14 */  if (ruleEntry->dontComputeErrorSet) {
  3594. /* MR14 */    f=empty;
  3595.             } else {
  3596.            f = ComputeErrorSet(q, i);
  3597.             }
  3598. if ( GenCC ) {_gen1(",err%d", DefErrSet( &f, 1, NULL ));}
  3599. else _gen1(",zzerr%d", DefErrSet( &f, 1, NULL ));
  3600. set_free(f);
  3601. }
  3602. }
  3603. _gen(",&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}n");
  3604. /* MR13 */  if (nilf) {
  3605. /* MR13 */    errFL("empty error set for alt - probably because of undefined rule or infinite left recursion",
  3606. /* MR13 */                 FileStr[q->file],q->line);
  3607. /* MR13 */    gen(" /* MR13 empty error set for this alt - undef rule ? infinite left recursion ? */");
  3608. /* MR13 */  };
  3609. }
  3610. static                                                               /* MR7 */
  3611. #ifdef __USE_PROTOS
  3612. char * findOuterHandlerLabel(ExceptionGroup *eg)                     /* MR7 */
  3613. #else
  3614. char * findOuterHandlerLabel(eg)                                     /* MR7 */
  3615. ExceptionGroup *eg;                                                  /* MR7 */
  3616. #endif
  3617. {
  3618.   char              *label=NULL;                                     /* MR7 */
  3619.   ExceptionGroup    *outerEG;                                        /* MR7 */
  3620.   if (eg->forRule == 0) {                                            /* MR7 */
  3621.     if (eg->labelEntry != NULL) {                                    /* MR7 */
  3622.       outerEG=eg->labelEntry->outerEG;                               /* MR7 */
  3623.       if (outerEG != NULL) {                                         /* MR7 */
  3624.         label=outerEG->altID;                                        /* MR7 */
  3625.         outerEG->used=1;                                             /* MR7 */
  3626.       };                                                             /* MR7 */
  3627.     } else if (eg->outerEG != NULL) {                                /* MR7 */
  3628.       outerEG=eg->outerEG;                                           /* MR7 */
  3629.       label=outerEG->altID;                                          /* MR7 */
  3630.       outerEG->used=1;                                               /* MR7 */
  3631.     };                                                               /* MR7 */
  3632.   };                                                                 /* MR7 */
  3633.   return (label==NULL ? "" : label);                                 /* MR7 */
  3634. }                                                                    /* MR7 */
  3635. /*** debug ***/
  3636. #if 0
  3637. ** static                                                               /* MR7 */
  3638. ** #ifdef __USE_PROTOS
  3639. ** char * findOuterAltHandlerLabel(Junction *startJ)                    /* MR7 */
  3640. ** #else
  3641. ** char * findOuterAltHandlerLabel(startJ)                              /* MR7 */
  3642. ** Junction *startJ;                                                    /* MR7 */
  3643. ** #endif
  3644. ** {                                                                    /* MR7 */
  3645. **   char      *label=NULL;                                             /* MR7 */
  3646. **   Junction  *alt;                                                    /* MR7 */
  3647. **                                                                      /* MR7 */
  3648. **   for (alt=startJ; alt != NULL; alt=alt->outerAltstart) {            /* MR7 */
  3649. **     label=alt->exception_label;                                      /* MR7 */
  3650. **     if (label != NULL) break;                                        /* MR7 */
  3651. **   };                                                                 /* MR7 */
  3652. **   return (label==NULL ? "" : label);                                 /* MR7 */
  3653. ** }                                                                    /* MR7 */
  3654. #endif
  3655. #ifdef __USE_PROTOS
  3656. static void OutLineInfo(FILE *file,int line,char *fileName)
  3657. #else
  3658. static void OutLineInfo(file,line,fileName)
  3659.   FILE *    file;
  3660.   int       line;
  3661.   char *    fileName;
  3662. #endif
  3663. {
  3664.     static  char * prevFileName=NULL;
  3665.     static  char * prevFileNameMS=NULL;
  3666.     char *  p;
  3667.     char *  q;
  3668.     if (! GenLineInfo) return;
  3669.     if (! GenLineInfoMS) {
  3670.     fprintf(file, LineInfoFormatStr,line,fileName);
  3671.     } else {
  3672.       if (fileName == prevFileName) {
  3673.     fprintf(file, LineInfoFormatStr,line,prevFileNameMS);
  3674.       } else {
  3675.         if (prevFileNameMS != NULL) free (prevFileNameMS);
  3676.         prevFileNameMS=(char *)calloc(1,strlen(fileName)+1);
  3677.         require(prevFileNameMS != NULL,"why not do this in calloc wrapper");
  3678.         q=prevFileNameMS;
  3679.         for (p=fileName; *p != 0; p++) {
  3680.             *q=*p;
  3681.             if (*q == '\') *q='/';
  3682.             q++;
  3683.         }
  3684.       }
  3685.       prevFileName=fileName;
  3686.     };
  3687. }