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

编译器/解释器

开发平台:

Others

  1. /*
  2.  * mrhoist.c
  3.  *
  4.  * SOFTWARE RIGHTS
  5.  *
  6.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  7.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  8.  * company may do whatever they wish with source code distributed with
  9.  * PCCTS or the code generated by PCCTS, including the incorporation of
  10.  * PCCTS, or its output, into commerical software.
  11.  *
  12.  * We encourage users to develop software with PCCTS.  However, we do ask
  13.  * that credit is given to us for developing PCCTS.  By "credit",
  14.  * we mean that if you incorporate our source code into one of your
  15.  * programs (commercial product, research project, or otherwise) that you
  16.  * acknowledge this fact somewhere in the documentation, research report,
  17.  * etc...  If you like PCCTS and have developed a nice tool with the
  18.  * output, please mention that you developed it using PCCTS.  In
  19.  * addition, we ask that this header remain intact in our source code.
  20.  * As long as these guidelines are kept, we expect to continue enhancing
  21.  * this system and expect to make other tools available as they are
  22.  * completed.
  23.  *
  24.  * ANTLR 1.33MR10
  25.  *
  26.  */
  27. #include <stdio.h>
  28. #ifdef __cplusplus
  29. #ifndef __STDC__
  30. #define __STDC__
  31. #endif
  32. #endif
  33. #include "set.h"
  34. #include "syn.h"
  35. #include "hash.h"
  36. #include "generic.h"
  37. #include "dlgdef.h"
  38. #include <ctype.h>
  39. #ifdef __STDC__
  40. void dumppred(Predicate *);
  41. #else
  42. void dumppred();
  43. #endif
  44. /*
  45.   Try to determine whether predicate "first" is true for
  46.     all cases where "second" is true.  Comparison takes place
  47.     without regard to context.
  48.   Assumes that predicate symbols have been expanded.
  49.   Assumes that there are no NAND or NOR nodes
  50. */
  51. #ifdef __STDC__
  52. int MR_secondPredicateUnreachable(Predicate *first,Predicate *second)
  53. #else
  54. int MR_secondPredicateUnreachable(first,second)
  55.   Predicate     *first;
  56.   Predicate     *second;
  57. #endif
  58. {
  59.   Predicate     *f;
  60.   Predicate     *s;
  61.   if (first == NULL) {
  62.     return 1;
  63.   } else if (second == NULL) {
  64.     return 0;
  65.   } else if (first->down == NULL && second->down == NULL) {
  66.     if (first->source == second->source &&
  67.         first->inverted == second->inverted) {
  68.       return 1; /* look identical - will never reach alt2 */
  69.     } else {
  70.       return 0; /* look different */
  71.     };
  72.   } else if (first->down == NULL && second->down != NULL) {
  73.     if (second->expr == PRED_AND_LIST) {
  74.       /* unreachable if first covers any child of second */
  75.       for (s=second->down; s != NULL; s=s->right) {
  76.         if (MR_secondPredicateUnreachable(first,s)) {
  77.           return 1;
  78.         };
  79.       };
  80.       return 0;
  81.     } else if (second->expr == PRED_OR_LIST) {
  82.       /* unreachable if first covers every child of second */
  83.       for (s=second->down; s != NULL; s=s->right) {
  84.         if (!MR_secondPredicateUnreachable(first,s)) {
  85.           return 0;
  86.         };
  87.       };
  88.       return 1;
  89.     } else {
  90.       require (0,"Illegal pred->expr");
  91.     };
  92.   } else if (first->down != NULL && second->down == NULL) {
  93.     if (first->expr == PRED_AND_LIST) {
  94.       /* unreachable if every child of first covers second */
  95.       for (f=first->down; f != NULL; f=f->right) {
  96.         if (!MR_secondPredicateUnreachable(f,second)) {
  97.           return 0;
  98.         };
  99.       };
  100.       return 1;
  101.     } else if (first->expr == PRED_OR_LIST) {
  102.       /* unreachable if any child of first covers second */
  103.       for (f=first->down; f != NULL; f=f->right) {
  104.         if (MR_secondPredicateUnreachable(f,second)) {
  105.           return 1;
  106.         };
  107.       };
  108.       return 0;
  109.     } else {
  110.       require (0,"Illegal predicate->expr");
  111.     };
  112.   } else {
  113.     if (first->expr == PRED_AND_LIST && second->expr == PRED_AND_LIST) {
  114.       /* unreachable if each child of first covers at least one child of second */
  115.       for (f=first->down; f != NULL ; f=f->right) {
  116.         for (s=second->down; s != NULL ; s=s->right) {
  117.           if (MR_secondPredicateUnreachable(f,s)) goto A_next_f;
  118.         };
  119.         return 0;
  120. A_next_f:
  121.         continue;
  122.       };
  123.       return 1;
  124.     } else if (first->expr == PRED_AND_LIST && second->expr == PRED_OR_LIST) {
  125.       /* unreachable if each child of first covers ALL of second's children */
  126.       for (f=first->down; f != NULL ; f=f->right) {
  127.         for (s=second->down; s != NULL ; s=s->right) {
  128.           if (!MR_secondPredicateUnreachable(f,s)) return 0;
  129.         };
  130.       };
  131.       return 1;
  132.     } else if (first->expr == PRED_OR_LIST && second->expr == PRED_AND_LIST) {
  133.       /* unreachable if any child of second is covered by any child of first */
  134.       for (f=first->down; f != NULL ; f=f->right) {
  135.         for (s=second->down; s != NULL ; s=s->right) {
  136.           if (MR_secondPredicateUnreachable(f,s)) return 1;
  137.         };
  138.       };
  139.       return 0;
  140.     } else if (first->expr == PRED_OR_LIST && second->expr == PRED_OR_LIST) {
  141.       /* unreachable if every child of second is covered by some child of first */
  142.       for (f=first->down; f != NULL ; f=f->right) {
  143.         for (s=second->down; s != NULL ; s=s->right) {
  144.           if (MR_secondPredicateUnreachable(f,s)) goto B_next_f;
  145.         };
  146.         return 0;
  147. B_next_f:
  148.        continue;
  149.       };
  150.       return 1;
  151.     } else {
  152.       require (0,"Illegal predicate->expr");
  153.     };
  154.   };
  155. }
  156. #ifdef __STDC__
  157. void MR_xxxIndent(FILE *f,int depth)
  158. #else
  159. void MR_xxxIndent(f,depth)
  160.   FILE  *f;
  161.   int   depth;
  162. #endif
  163. {
  164.   int   i;
  165.   for (i=0; i<depth ; i++) {
  166.     fprintf(f,"  ");
  167.   };
  168. }
  169. #ifdef __STDC__
  170. void MR_stderrIndent(int depth)
  171. #else
  172. void MR_stderrIndent(depth)
  173.   int   depth;
  174. #endif
  175. {
  176.   MR_xxxIndent(stderr,depth);
  177. }
  178. #ifdef __STDC__
  179. void MR_outputIndent(int depth)
  180. #else
  181. void MR_outputIndent(depth)
  182.   int   depth;
  183. #endif
  184. {
  185.   MR_xxxIndent(output,depth);
  186. }
  187. #ifdef __STDC__
  188. void MR_set_reuse(set *s)
  189. #else
  190. void MR_set_reuse(s)
  191.   set   *s;
  192. #endif
  193. {
  194.   set_free(*s);
  195.   *s=empty;
  196. }
  197. #ifdef __STDC__
  198. void MR_dumpPredRuleRefStack(FILE *iounit,int indent)
  199. #else
  200. void MR_dumpPredRuleRefStack(iounit,indent)
  201.   FILE  *iounit;
  202.   int   indent;
  203. #endif
  204. {
  205.     int             i;
  206.     int             j;
  207.     int             count=MR_PredRuleRefStack.count;
  208.     RuleRefNode     *rrn=NULL;
  209.     Junction        *lastOne;
  210.     if (count == 0) {
  211.       fprintf(iounit,"emptyn");
  212.       return;
  213.     };
  214.     for (i=0; i < count; i++) {
  215.       rrn=(RuleRefNode *) MR_PredRuleRefStack.data[i];
  216.       for (j=0; j<indent; j++) fprintf(iounit," ");
  217.       fprintf(iounit,"#%-2d in rule %s (line %d %s) to rule %sn",
  218.             i,rrn->rname,rrn->line,FileStr[rrn->file],rrn->text);
  219.     };
  220.     lastOne=MR_ruleReferenced(rrn);
  221.     if (lastOne != NULL) {
  222.       for (j=0; j<indent; j++) fprintf(iounit," ");
  223.       fprintf(iounit,"#%-2d in rule %s (line %d %s)n",
  224.         count,lastOne->rname,lastOne->line,FileStr[lastOne->file]);
  225.     };
  226. }
  227. #ifdef __STDC__
  228. void MR_dumpTreeF(FILE *f,int depth,Tree *tree,int across)
  229. #else
  230. void MR_dumpTreeF(f,depth,tree,across)
  231.   FILE  *f;
  232.   Tree  *tree;
  233.   int   depth;
  234.   int   across;
  235. #endif
  236. {
  237.     int     newAcross=across;
  238. if (tree == NULL ) return;
  239. if (tree->down != NULL ) {
  240.       fprintf(output,"n");
  241.       MR_outputIndent(depth);
  242.       fprintf(output, "(root =");
  243.     };
  244. if (tree->token == ALT ) {
  245.       fprintf(output," %-16s","Alt");
  246. } else if (tree->token==EpToken ) {
  247.       fprintf(output,"(%d)%13s",tree->v.rk," ");
  248. } else {
  249.       fprintf(output," %-16s",TerminalString(tree->token));
  250.     };
  251.     if (tree->down != NULL) {
  252.       fprintf(output,"n");
  253.       MR_outputIndent(depth+1);
  254.       MR_dumpTreeF(f,depth+1,tree->down,1);
  255.       newAcross=0;
  256.       fprintf(output,"n");
  257.       MR_outputIndent(depth);
  258.       fprintf(output,")");
  259.     };
  260.     if (newAcross > 3) {
  261.       fprintf(output,"n");
  262.       MR_outputIndent(depth);
  263.       newAcross=0;
  264.     };
  265.     MR_dumpTreeF(f,depth,tree->right,newAcross+1);
  266. }
  267. #ifdef __STDC__
  268. void MR_dumpTreeX(int depth,Tree *tree,int across)
  269. #else
  270. void MR_dumpTreeX(depth,tree,across)
  271.   Tree  *tree;
  272.   int   depth;
  273.   int   across;
  274. #endif
  275. {
  276.   MR_dumpTreeF(output,depth,tree,across);
  277. }
  278. #ifdef __STDC__
  279. void MR_dumpTokenSet(FILE *f,int depth,set s)
  280. #else
  281. void MR_dumpTokenSet(f,depth,s)
  282.   FILE  *f;
  283.   int   depth;
  284.   set   s;
  285. #endif
  286. {
  287.     int     i;
  288.     int     j;
  289.     unsigned  *pdq;
  290.     if (set_nil(s)) {
  291.       fprintf(f,"n");
  292.       MR_xxxIndent(f,depth+1);
  293.       fprintf(f,"niln");
  294.       return;
  295.     };
  296.     pdq=set_pdq(s);
  297.     require(pdq != NULL,"set_pdq failed");
  298.     i=0;
  299.     for (i=0 ; ; i=i+4) {
  300.       fprintf(f,"n");
  301.       MR_xxxIndent(f,depth+1);
  302.       for (j=0; j < 4 ; j++) {
  303.         if (pdq[i+j] == nil) break;
  304.         fprintf(f," %-16s",TerminalString(pdq[i+j]));
  305.       };
  306.       if (pdq[i+j] == nil) break;
  307.     };
  308.     fprintf(f,"n");
  309.     free( (char *) pdq);
  310. }
  311. #ifdef __STDC__
  312. void MR_dumpPred1(int depth,Predicate *p,int withContext)
  313. #else
  314. void MR_dumpPred1(depth,p,withContext)
  315.   int           depth;
  316.   Predicate     *p;
  317.   int           withContext;
  318. #endif
  319. {
  320.   unsigned      k;
  321.   if (p == NULL) {
  322.     MR_outputIndent(depth);
  323.     fprintf(output,"The predicate is empty (or always true)nn");
  324.     return;
  325.   };
  326.   if (p->down != NULL) {
  327.     MR_outputIndent(depth);
  328.     if (p->inverted) {
  329.       if (p->expr == PRED_AND_LIST) fprintf(output,"%s NAND (not AND) exprnn");
  330.       if (p->expr == PRED_OR_LIST) fprintf(output,"%s NOR (not OR) exprnn");
  331.     } else {
  332.       fprintf(output,"%s exprnn",p->expr);
  333.     };
  334.   } else {
  335.     MR_outputIndent(depth);
  336.     fprintf(output,"pred %s <<%s>>?n",
  337.             (p->inverted ? " *not*" : ""),
  338.             (p->expr == NULL ? "null expr" : p->expr));
  339.     MR_outputIndent(depth+1);
  340.     fprintf(output,"              ");
  341.     fprintf(output,"  depth=k=%d",p->k);
  342.     if (p->source != NULL && p->source->guardpred) {
  343.       fprintf(output,"  ("=>" guard)");
  344.     }
  345.     if (p->source != NULL && p->source->ampersandPred != NULL) {
  346.       fprintf(output,"  ("&&" guard)");
  347.     };
  348.     k=set_int(p->completionSet);
  349.     if (k != nil) {
  350.       fprintf(output," Incomplete Set at k=%d !",k);
  351.     };
  352.     k=set_int(p->completionTree);
  353.     if (k != nil) {
  354.       fprintf(output," Incomplete Tree at k=%d !",k);
  355.     };
  356.     if (p->source != NULL) {
  357.       fprintf(output,"  rule %s  line %d  %s",
  358.                     p->source->rname,p->source->line,FileStr[p->source->file]);
  359.     };
  360.     fprintf(output,"n");
  361.     if (withContext &&
  362.             (HoistPredicateContext ||
  363.              ! set_nil(p->scontext[1]) ||
  364.              p->tcontext != NULL)) {
  365.       if (p->k == 1) {
  366.         MR_outputIndent(depth+1);
  367.         fprintf(output,"set context: ");
  368.         MR_dumpTokenSet(output,depth+1,p->scontext[1]);
  369.       }
  370.       if (p->k != 1) {
  371.         MR_outputIndent(depth+1);
  372.         fprintf(output,"tree context:");
  373.         if (p->tcontext == NULL) {
  374.           fprintf(output," null");
  375.         } else {
  376.           MR_dumpTreeX(depth+2,p->tcontext,0);
  377.         };
  378.         fprintf(output,"n");
  379.       };
  380.     };
  381.     fprintf(output,"n");
  382.   };
  383.   if (p->down != NULL) {
  384.     MR_dumpPred1(depth+1,p->down,withContext);
  385.   };
  386.   if (p->right != NULL) {
  387.     MR_dumpPred1(depth,p->right,withContext);
  388.   };
  389. }
  390. #ifdef __STDC__
  391. void MR_dumpPred(Predicate *p,int withContext)
  392. #else
  393. void MR_dumpPred(p,withContext)
  394.   Predicate     *p;
  395.   int           withContext;
  396. #endif
  397. {
  398.   MR_dumpPred1(0,p,withContext);
  399. }
  400. #ifdef __STDC__
  401. Tree * MR_make_tree_from_set(set s)
  402. #else
  403. Tree * MR_make_tree_from_set(s)
  404.   set   s;
  405. #endif
  406. {
  407.   Tree  *t=NULL;
  408.   Tree  *node;
  409.   Tree  **tp=&t;
  410.   int   i;
  411.   unsigned *pdq=set_pdq(s);
  412.   if (pdq != NULL) {
  413.     for (i=0 ; pdq[i] != nil ; i++) {
  414.       node=tnode( (int) pdq[i]);
  415.       *tp=node;
  416.       tp=&(node->right);
  417.     };
  418.     *tp=NULL;
  419.     free ( (char *) pdq);
  420.   };
  421.   return t;
  422. }
  423. #ifdef __STDC__
  424. void MR_check_pred_too_long(Predicate *p,set completion)
  425. #else
  426. void MR_check_pred_too_long(p,completion)
  427.   Predicate     *p;
  428.   set           completion;
  429. #endif
  430. {
  431.   if (p != NULL &&
  432.       p->source != NULL &&
  433.       ! p->source->predTooLong) {
  434.     if ( !set_nil(completion)) {
  435.       p->source->predTooLong=1;
  436. warnFL("It is unusual (but ok) for a semantic predicate to test context past the end of its own rule",
  437.                                 FileStr[p->source->file],p->source->line);
  438.     };
  439.   };
  440. }
  441. #ifdef __STDC__
  442. int MR_predicate_context_completed(Predicate *p)
  443. #else
  444. int MR_predicate_context_completed(p)
  445.   Predicate     *p;
  446. #endif
  447. {
  448.   if (p == NULL) return 1;
  449.   if (p->expr != PRED_AND_LIST &&
  450.       p->expr != PRED_OR_LIST) {
  451.     if ( ! set_nil(p->completionSet)) return 0;
  452.     if ( ! set_nil(p->completionTree)) return 0;
  453.   };
  454.   return MR_predicate_context_completed(p->down) &
  455.          MR_predicate_context_completed(p->right);
  456. }
  457. #ifdef __STDC__
  458. Node * MR_advance(Node *n)
  459. #else
  460. Node * MR_advance(n)
  461.   Node  *n;
  462. #endif
  463. {
  464.     if (n == NULL) return NULL;
  465.     switch (n->ntype) {
  466.       case nJunction:   return ((Junction *)n)->p1;
  467.       case nToken:      return ((TokNode *)n)->next;
  468.       case nRuleRef:    return ((RuleRefNode *)n)->next;
  469.       case nAction:     return ((ActionNode *)n)->next;
  470.     };
  471. }
  472. #ifdef __STDC__
  473. Junction * MR_find_endRule(Node *n)
  474. #else
  475. Junction * MR_find_endRule(n)
  476.   Node  *n;
  477. #endif
  478. {
  479.     Node    *next;
  480.     if (n == NULL) return NULL;
  481.     for (next=n; next != NULL; next=MR_advance(next)) {
  482.       if (next->ntype == nJunction &&
  483.             ( (Junction *) next)->jtype == EndRule) {
  484.         break;
  485.       };
  486.     };
  487.     return (Junction *)next;
  488. }
  489. /*
  490.    Intersection:  a branch which is shorter is chosen
  491.    over one which is longer: (A B C) intersect (A B) yields (A B).
  492.    AND: a branch which is longer is chosen over the one
  493.    which is shorter: (A B C) AND (A B) yields (A B C)
  494. */
  495. #ifdef __STDC__
  496. Tree *MR_computeTreeIntersection(Tree *l,Tree *r)
  497. #else
  498. Tree *MR_computeTreeIntersection(l,r)
  499.     Tree    *l;
  500.     Tree    *r;
  501. #endif
  502. {
  503.     Tree    *result=NULL;
  504.     Tree    **tail;
  505.     Tree    *p;
  506.     Tree    *q;
  507.     Tree    *match;
  508.     if (l == NULL || r == NULL) return NULL;
  509.     for (p=l; p != NULL; p=p->right) {
  510.       require(p->token != EpToken,"MR_computeTreeIntersection: p->EpToken unexpectedn");
  511.       require (p->token != ALT,"MR_computeTreeIntersection: p->ALT unexpectedn");
  512.     };
  513.     for (q=r; q != NULL; q=q->right) {
  514.       require(q->token != EpToken,"MR_computeTreeIntersection: q->EpToken unexpectedn");
  515.       require(q->token != ALT,"MR_computeTreeIntersection: q->ALT unexpectedn");
  516.     };
  517.     result=tnode(ALT);
  518.     tail=&(result->down);
  519.     for (p=l; p != NULL ; p=p->right) {
  520.       for (q=r; q != NULL ; q=q->right) {
  521.         if (p->token == q->token) {
  522.           match=tnode(p->token);
  523.           match->down=MR_computeTreeIntersection(p->down,q->down);
  524.           *tail=match;
  525.           tail=&(match->right);
  526.         };
  527.       };
  528.     };
  529.     *tail=NULL;
  530.     result=tshrink(result);
  531.     result=tflatten( result );
  532.     result=tleft_factor( result );
  533.     return result;
  534. }
  535. /* the predicates which are ANDed together have a common
  536.    context:  they must all have common roots.  Thus the
  537.    AND operation is more like an OR operation because
  538.    branches which are longer are grafted onto shorter
  539.    branches of the AND tree.  For instance combining
  540.    (A B C) with (A B C D) gives (A B C D).  There
  541.    should never be a case of (A B C) and (A B D) because
  542.    they have the same context.
  543.    Actually, this may not be true once one throws in
  544.    guard predicates which are defined by the user, not
  545.    the context.
  546. */
  547. /* requires input trees to be in "canonical" format */
  548. #ifdef __STDC__
  549. Tree *MR_computeTreeAND(Tree *l,Tree *r)
  550. #else
  551. Tree *MR_computeTreeAND(l,r)
  552.     Tree    *l;
  553.     Tree    *r;
  554. #endif
  555. {
  556.     Tree    *result=NULL;
  557.     Tree    **tail;
  558.     Tree    *p;
  559.     Tree    *q;
  560.     Tree    *match;
  561.     if (l == NULL) return tdup(r);
  562.     if (r == NULL) return tdup(l);
  563.     for (p=l; p != NULL; p=p->right) {
  564. /**** require(p->token != EpToken,"MR_computeTreeAND: p->EpToken unexpectedn"); ****/
  565.       require (p->token != ALT,"MR_computeTreeAND: p->ALT unexpectedn");
  566.     };
  567.     for (q=r; q != NULL; q=q->right) {
  568. /**** require(q->token != EpToken,"MR_computeTreeAND: q->EpToken unexpectedn"); ****/
  569.       require(q->token != ALT,"MR_computeTreeAND: q->ALT unexpectedn");
  570.     };
  571.     result=tnode(ALT);
  572.     tail=&(result->down);
  573.     for (p=l; p != NULL ; p=p->right) {
  574.       for (q=r; q != NULL ; q=q->right) {
  575.         if (p->token == q->token) {
  576.           match=tnode(p->token);
  577.           match->down=MR_computeTreeAND(p->down,q->down);
  578.           *tail=match;
  579.           tail=&(match->right);
  580.         };
  581.       };
  582.     };
  583.     *tail=NULL;
  584.     result=tshrink(result);
  585.     result=tflatten( result );
  586.     result=tleft_factor( result );
  587.     return result;
  588. }
  589. #ifdef __STDC__
  590. void MR_union_plain_sets1(Predicate *p,set *theUnion)
  591. #else
  592. void MR_union_plain_sets1(p,theUnion)
  593.   Predicate     *p;
  594.   set           *theUnion;
  595. #endif
  596. {
  597.   if (p == NULL) return;
  598.   MR_union_plain_sets1(p->down,theUnion);
  599.   MR_union_plain_sets1(p->right,theUnion);
  600.   set_orin(theUnion,p->plainSet);
  601.   return;
  602. }
  603. #ifdef __STDC__
  604. set MR_union_plain_sets(Predicate *p)
  605. #else
  606. set MR_union_plain_sets(p)
  607.   Predicate     *p;
  608. #endif
  609. {
  610.   set   theUnion;
  611.   theUnion=empty;
  612.   MR_union_plain_sets1(p,&theUnion);
  613.   return theUnion;
  614. }
  615. /* does NOT left factor: do not want to merge
  616.      (A B) with (A) to get (A B)
  617.    in fact the opposite: (A B) with (A) gives (A)
  618. */
  619. #ifdef __STDC__
  620. Tree *MR_compute_pred_tree_ctxXX(Predicate *p)
  621. #else
  622. Tree *MR_compute_pred_tree_ctxXX(p)
  623.   Predicate     *p;
  624. #endif
  625. {
  626.     Tree        *result=NULL;
  627.     Predicate   *q;
  628.     Tree        *t;
  629.     if (p == NULL) return NULL;
  630. /* this appears strange: why do we OR the context
  631.    of and AND predicate ?  It is because of the way
  632.    that predicates are evaluated: if the context is
  633.    wrong then it's the same as if the predicate was
  634.    true.  That means that even when one leg of an
  635.    AND has unmatched context, if the other leg has
  636.    matched context and is true then the predicate
  637.    succeeds.  It's only when all the legs have unmatched
  638.    context that this one can skip evaluation of the
  639.    predicates.
  640. */
  641.     if (p->expr == PRED_OR_LIST ||
  642.         p->expr == PRED_AND_LIST) {
  643.       for (q=p->down; q != NULL ; q=q->right) {
  644.         t=MR_compute_pred_tree_ctxXX(q);
  645.         result=tappend(result,t);
  646.         t=NULL;
  647.       };
  648.       result=tshrink(result);
  649.       result=tflatten( result );
  650. /* does NOT left factor: do not want to merge
  651.      (A B) with (A) to get (A B)
  652.    in fact the opposite: (A B) with (A) gives (A)
  653. */
  654. /**** result=tleft_factor( result ); ****/
  655.       return result;
  656.     };
  657. #if 0
  658. **    if (p->expr == PRED_AND_LIST) {
  659. **
  660. **      Predicate     *l;
  661. **      Predicate     *r;
  662. **      Tree          *l1;
  663. **      Tree          *r1;
  664. **      Tree          *prevl1;
  665. **
  666. **      l=p->down;
  667. **      require (l->right != NULL,"MR_compute_pred_tree - AND has only one child");
  668. **
  669. **/* l1 and r1 should already be in "canonical" format */
  670. **
  671. **      l1=MR_compute_pred_tree(l);
  672. **      for (r=l->right; r != NULL; r=r->right) {
  673. **        r1=MR_compute_pred_tree(r);
  674. **        prevl1=l1;
  675. **        l1=MR_computeTreeAND(l1,r1);
  676. **        Tfree(r1);
  677. **        Tfree(prevl1);
  678. **      };
  679. **
  680. **/* result from computeTreeAND should be in "canonical" format */
  681. **
  682. **      result=l1;
  683. **
  684. **/* result of MR_computeTreeAND should be in "canonical" format */
  685. **
  686. **      return result;
  687. **    };
  688. #endif
  689.     if (p->k == 1) {
  690.       result=MR_make_tree_from_set(p->scontext[1]);
  691.     } else {
  692.       result=tdup(p->tcontext);
  693.       result=MR_remove_epsilon_from_tree(result);
  694.       result=tshrink(result);
  695.       result=tflatten(result);
  696.       result=tleft_factor(result);
  697.     };
  698.     return result;
  699. }
  700. #ifdef __STDC__
  701. void MR_pred_depth(Predicate *p,int *maxDepth)
  702. #else
  703. void MR_pred_depth(p,maxDepth)
  704.   Predicate     *p;
  705.   int           *maxDepth;
  706. #endif
  707. {
  708.   if (p == NULL) return;
  709.   if (p->expr != PRED_OR_LIST &&
  710.       p->expr != PRED_AND_LIST) {
  711.     if (p->k > *maxDepth) *maxDepth=p->k;
  712.   };
  713.   MR_pred_depth(p->down,maxDepth);
  714.   MR_pred_depth(p->right,maxDepth);
  715. }
  716. /* this computes the OR of all the contexts */
  717. #ifdef __STDC__
  718. set MR_compute_pred_set(Predicate *p)
  719. #else
  720. set MR_compute_pred_set(p)
  721.   Predicate     *p;
  722. #endif
  723. {
  724.     set         result;
  725.     Predicate   *q;
  726.     result=empty;
  727.     if (p == NULL) return empty;
  728.     if (p->expr == PRED_OR_LIST ||
  729.         p->expr == PRED_AND_LIST) {         /* yes, I do mean PRED_AND_LIST !   */
  730.                                             /* remember: r1: (A)? => <<p>>? r2; */
  731.                                             /*           r2: (B)? => <<q>>? r3; */
  732.       set   t;
  733.       t=empty;
  734.       result=empty;
  735.       for (q=p->down; q != NULL; q=q->right) {
  736.         t=MR_compute_pred_set(q);
  737.         set_orin(&result,t);
  738.         set_free(t);
  739.       };
  740.       return result;
  741.     } else if (p->k > 1) {
  742.       return empty;
  743.     } else {
  744.       return set_dup(p->scontext[1]);
  745.     };
  746. }
  747. #ifdef __STDC__
  748. set MR_First(int ck,Junction *j,set *incomplete)
  749. #else
  750. set MR_First(ck,j,incomplete)
  751.   int       ck;
  752.   Junction  *j;
  753.   set       *incomplete;
  754. #endif
  755. {
  756.     Junction    *p;
  757.     set         tokensUsed;
  758.     tokensUsed=empty;
  759. require(j->ntype==nJunction, "MR_First: non junction passed");
  760. p = analysis_point((Junction *)j->p1);
  761. REACH(p,ck,incomplete,tokensUsed);
  762.     return tokensUsed;
  763. }
  764. #ifdef __STDC__
  765. void MR_cleanup_pred_trees(Predicate *p)
  766. #else
  767. void MR_cleanup_pred_trees(p)
  768.   Predicate     *p;
  769. #endif
  770. {
  771.   Tree      *t;
  772.   if (p == NULL) return;
  773.   if (p->expr != PRED_OR_LIST &&
  774.       p->expr != PRED_AND_LIST) {
  775.     t=p->tcontext;
  776.     t=tshrink(t);
  777.     t=tflatten(t);
  778.     t=tleft_factor(t);
  779.     p->tcontext=t;
  780.   };
  781.   MR_cleanup_pred_trees(p->down);
  782.   MR_cleanup_pred_trees(p->right);
  783. }
  784. /* does NOT return canonical tree */
  785. #ifdef __STDC__
  786. Tree * MR_remove_epsilon_from_tree(Tree *t)
  787. #else
  788. Tree * MR_remove_epsilon_from_tree(t)
  789.   Tree  *t;
  790. #endif
  791. {
  792.   if (t == NULL) return NULL;
  793.   /* I think ALT can be ignored as a special case */
  794.   if (t->token != EpToken) {
  795.     t->down=MR_remove_epsilon_from_tree(t->down);
  796.     t->right=MR_remove_epsilon_from_tree(t->right);
  797.     return t;
  798.   } else {
  799.     Tree    *u;
  800.     u=MR_remove_epsilon_from_tree(t->right);
  801.     t->right=NULL;
  802.     Tfree(t);
  803.     return u;
  804.   };
  805. }
  806. #ifdef __STDC__
  807. void MR_complete_set(int predDepth,set *tokensUsed,set *incomplete)
  808. #else
  809. void MR_complete_set(predDepth,tokensUsed,incomplete)
  810.   int       predDepth;
  811.   set       *tokensUsed;
  812.   set       *incomplete;
  813. #endif
  814. {
  815.     int             i;
  816.     RuleRefNode     *ruleRef;
  817. set             rk2;
  818.     set             b;
  819. int             k2;
  820.     Junction        *save_MR_RuleBlkWithHalt;
  821.     if (set_int(*incomplete) > (unsigned) predDepth) {
  822.       return;
  823.     };
  824.     require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,
  825.                 "RuleRefStack and RuleBlkWithHaltStack not same size");
  826.     require(MR_RuleBlkWithHalt == NULL ||
  827.          (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
  828.                      "RuleBlkWithHalt has no halt set");
  829.     save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
  830.     if (MR_RuleBlkWithHalt != NULL) {
  831.       MR_RuleBlkWithHalt->end->halt=FALSE;
  832.     };
  833.     for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {
  834.       ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];
  835.       if (ruleRef == NULL) continue;
  836.       MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];
  837.       if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;
  838.       rk2=empty;
  839.       b=empty;
  840.       while ( !set_nil(*incomplete) ) {
  841. k2=set_int(*incomplete);
  842.         if (k2 > predDepth) break;                    /* <=== another exit from loop */
  843. set_rm(k2,*incomplete);
  844.         REACH(ruleRef->next,k2,&rk2,b);
  845. set_orin(tokensUsed,b);
  846. set_free(b);
  847.       };
  848.       if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;
  849.   set_orin(incomplete,rk2);                       /* remember what we couldn't do */
  850.       set_free(rk2);
  851.   if (set_int(*incomplete) > (unsigned) predDepth) break;    /* <=== another exit from loop */
  852.     };
  853.     MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;
  854.     if (MR_RuleBlkWithHalt != NULL) {
  855.       MR_RuleBlkWithHalt->end->halt=TRUE;
  856.     };
  857. }
  858. #ifdef __STDC__
  859. void MR_complete_tree(int predDepth,Tree **t,set *incomplete)
  860. #else
  861. void MR_complete_tree(predDepth,t,incomplete)
  862.   int       predDepth;
  863.   Tree      **t;
  864.   set       *incomplete;
  865. #endif
  866. {
  867.     int             i;
  868.     RuleRefNode     *ruleRef;
  869. set             rk2;
  870.     Tree            *u;
  871. unsigned        k2;
  872.     Junction        *save_MR_RuleBlkWithHalt;
  873.     int             saveConstrainSearch;
  874.     if (set_int(*incomplete) > (unsigned) predDepth) {
  875.       return;
  876.     };
  877.     require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,
  878.                 "RuleRefStack and RuleBlkWithHaltStack not same size");
  879.     require(MR_RuleBlkWithHalt == NULL ||
  880.          (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
  881.                      "RuleBlkWithHalt has no halt set");
  882.     save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
  883.     saveConstrainSearch=ConstrainSearch;
  884.     ConstrainSearch=0;
  885.     if (MR_RuleBlkWithHalt != NULL) {
  886.       MR_RuleBlkWithHalt->end->halt=FALSE;
  887.     };
  888.     for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {
  889.       ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];
  890.       if (ruleRef == NULL) continue;
  891.       MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];
  892.       if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;
  893.       rk2=empty;
  894.       while ( !set_nil(*incomplete) ) {
  895. k2 = set_int(*incomplete);
  896.         if (k2 > (unsigned) predDepth) break;       /* <=== another exit from loop */
  897. set_rm(k2,*incomplete);
  898. u = NULL;
  899.         TRAV(ruleRef->next,k2,&rk2,u);
  900. /* any subtrees missing k2 tokens, add u onto end */
  901. *t=tlink(*t,u,k2);
  902.         Tfree(u);
  903.       }
  904.   set_orin(incomplete,rk2);         /* remember what we couldn't do */
  905.       set_free(rk2);
  906.       if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;
  907.   if (set_int(*incomplete) > (unsigned) predDepth) break;    /* <=== another exit from loop */
  908.     };
  909.     MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;
  910.     if (MR_RuleBlkWithHalt != NULL) {
  911.       MR_RuleBlkWithHalt->end->halt=TRUE;
  912.     };
  913.     ConstrainSearch=saveConstrainSearch;
  914. }
  915. #ifdef __STDC__
  916. void MR_complete_predicates(int predDepth,Predicate *pred)
  917. #else
  918. void MR_complete_predicates(predDepth,pred)
  919.   int           predDepth;
  920.   Predicate     *pred;
  921. #endif
  922. {
  923.   if (pred == NULL) return;
  924.   if (pred->expr != PRED_AND_LIST &&
  925.       pred->expr != PRED_OR_LIST) {
  926.     MR_complete_set(predDepth,&(pred->scontext[1]),&(pred->completionSet));
  927.     MR_complete_tree(predDepth,&(pred->tcontext),&(pred->completionTree));
  928.   };
  929.   MR_complete_predicates(predDepth,pred->down);
  930.   MR_complete_predicates(predDepth,pred->right);
  931. }
  932. #ifdef __STDC__
  933. Junction * MR_junctionWithoutP2(Junction *j)
  934. #else
  935. Junction * MR_junctionWithoutP2(j)
  936.   Junction  *j;
  937. #endif
  938. {
  939.   Junction  *thisAlt;
  940. /* don't want to follow p2 to the next alternative of this rule */
  941. /* insert a generic node with null p2 if necessary              */
  942. /* however FIRST requires a junction                            */
  943.   thisAlt=j;
  944.   if (thisAlt->p2 != NULL) {
  945.     if (thisAlt->p1->ntype == nJunction) {
  946.       thisAlt=(Junction *) thisAlt->p1;
  947.     } else {
  948.       thisAlt=newJunction();
  949.       thisAlt->p1=j->p1;
  950.       thisAlt->rname=j->rname;
  951.       thisAlt->file=j->file;
  952.       thisAlt->line=j->line;
  953.       j->p1=(Node *)thisAlt;
  954.     };
  955.   };
  956.   return thisAlt;
  957. }
  958. #ifdef __STDC__
  959. int MR_tree_equ(Tree *big, Tree *small) {
  960. #else
  961. int MR_tree_equ(big,small)
  962.   Tree  *big;
  963.   Tree  *small;
  964. {
  965. #endif
  966.   Tree      *b;
  967.   Tree      *s;
  968.   int       bcount=0;
  969.   int       scount=0;
  970.   if (small == NULL && big == NULL) return 1;
  971.   if (small == NULL) return 0;
  972.   if (big == NULL) return 0;
  973.   if (small->token == ALT) {
  974.     require(small->right == NULL,
  975.                 "MR_tree_equ: small: ALT node has siblings");
  976.     return MR_tree_equ(big,small->down);
  977.   };
  978.   if (big->token == ALT) {
  979.     require(big->right == NULL,
  980.                 "MR_tree_equ: big: ALT node has siblings");
  981.     return MR_tree_equ(big->down,small);
  982.   };
  983.   for (s=small; s != NULL; s=s->right) {
  984.     scount++;
  985.     require(s->token != EpToken,"MR_tree_equ: s->EpToken unexpectedn");
  986.   };
  987.   for (b=big; b != NULL; b=b->right) {
  988.     bcount++;
  989.     require(b->token != EpToken,"MR_tree_equ: b->EpToken unexpectedn");
  990.   };
  991.   if (bcount != scount) return 0;
  992.   for (s=small; s != NULL; s=s->right) {
  993.     for (b=big; b!= NULL; b=b->right) {
  994.       if (s->token == b->token) {
  995.         if (MR_tree_equ(b->down,s->down)) goto next_s;
  996.       };
  997.     };
  998.     return 0;
  999. next_s:
  1000.     continue;
  1001.   };
  1002.   return 1;
  1003. }
  1004. /* this does not compare sources - only contexts ! */
  1005. #ifdef __STDC__
  1006. int MR_identicalContext(Predicate *p,Predicate *q)
  1007. #else
  1008. int MR_identicalContext(p,q)
  1009.   Predicate     *p;
  1010.   Predicate     *q;
  1011. #endif
  1012. {
  1013.   if (p->k != q->k) return 0;
  1014.   require ( (p->tcontext == NULL) == (q->tcontext == NULL),
  1015.         "tcontext inconsistent");
  1016.   if (p->k == 1) {
  1017.     return set_equ(p->scontext[1],q->scontext[1]);
  1018.   } else {
  1019.     return MR_tree_equ(p->tcontext,q->tcontext);
  1020.   };
  1021. }
  1022. #ifdef __STDC__
  1023. void MR_reportSetSuppression(int predDepth,
  1024.             set predSet,set plainSet,Junction *jPred,Junction *jPlain,Predicate *p)
  1025. #else
  1026. void MR_reportSetSuppression(predDepth,predSet,plainSet,jPred,jPlain,p)
  1027.   int       predDepth;
  1028.   set       predSet;
  1029.   set       plainSet;
  1030.   Junction  *jPred;
  1031.   Junction  *jPlain;
  1032.   Predicate *p;
  1033. #endif
  1034. {
  1035.   if (InfoP) {
  1036.     fprintf(output,"n#if 0nn");
  1037.     fprintf(output,"Hoisting of predicate suppressed by alternative without predicate.n");
  1038.     fprintf(output,"The alt without the predicate includes all cases where the predicate is false.nn");
  1039.     fprintf(output,"   WITH predicate: line %d  %sn",jPred->line,FileStr[jPred->file]);
  1040.     if (jPlain != NULL) {
  1041.       fprintf(output,"   WITHOUT predicate: line %d  %sn",jPlain->line,FileStr[jPlain->file]);
  1042.     } else {
  1043.       fprintf(output,"   WITHOUT predicate: all alternatives without predicates (combined)n");
  1044.     };
  1045.     if (predDepth == 1) {
  1046.       fprintf(output,"nThe context set for the predicate:n");
  1047.       MR_dumpTokenSet(output,1,predSet);
  1048.     };
  1049.     fprintf(output,"nThe lookahead set for the alt WITHOUT the semantic predicate:n");
  1050.     MR_dumpTokenSet(output,1,plainSet);
  1051.     fprintf(output,"nThe predicate:nn");
  1052.     MR_dumpPred1(1,p,1);
  1053.     fprintf(output,"Chain of referenced rules:nn");
  1054.     MR_dumpPredRuleRefStack(output,4);
  1055.     fprintf(output,"n#endifn");
  1056.   };
  1057. }
  1058. #ifdef __STDC__
  1059. void MR_reportSetRestriction(int predDepth,set predSet,set plainSet,
  1060.             Junction *jPred,Junction *jPlain,Predicate *origPred,Predicate *newPred)
  1061. #else
  1062. void MR_reportSetRestriction(predDepth,predSet,plainSet,jPred,jPlain,origPred,newPred)
  1063.   int       predDepth;
  1064.   set       predSet;
  1065.   set       plainSet;
  1066.   Junction  *jPred;
  1067.   Junction  *jPlain;
  1068.   Predicate *origPred;
  1069.   Predicate *newPred;
  1070. #endif
  1071. {
  1072.   set       intersect;
  1073.   intersect=empty;
  1074.   if (! InfoP) return;
  1075.   fprintf(output,"n#if 0nn");
  1076.   fprintf(output,"Restricting the context of a predicate because of overlap in the lookahead setn");
  1077.   fprintf(output,"  between the alternative with the semantic predicate and one withoutn");
  1078.   fprintf(output,"Without this restriction the alternative without the predicate could notn");
  1079.   fprintf(output,"  be reached when input matched the context of the predicate and the predicaten");
  1080.   fprintf(output,"  was false.nn");
  1081.   fprintf(output,"   WITH predicate: line %d  %sn",jPred->line,FileStr[jPred->file]);
  1082.   if (jPlain != NULL) {
  1083.     fprintf(output,"   WITHOUT predicate: line %d  %sn",jPlain->line,FileStr[jPlain->file]);
  1084.   } else {
  1085.     fprintf(output,"   WITHOUT predicate: all alternatives without predicates (combined)n");
  1086.   };
  1087.   if (predDepth == 1) {
  1088.     fprintf(output,"nThe original context set for the predicate:n");
  1089.     MR_dumpTokenSet(output,1,predSet);
  1090.   };
  1091.   fprintf(output,"nThe lookahead set for the alt WITHOUT the semantic predicate:n");
  1092.   MR_dumpTokenSet(output,1,plainSet);
  1093.   if (predDepth == 1) {
  1094.     fprintf(output,"nThe intersection of the two setsn");
  1095.     intersect=set_and(predSet,plainSet);
  1096.     MR_dumpTokenSet(output,1,intersect);
  1097.     set_free(intersect);
  1098.   };
  1099.   fprintf(output,"nThe original predicate:nn");
  1100.   MR_dumpPred1(1,origPred,1);
  1101.   fprintf(output,"The new (modified) form of the predicate:nn");
  1102.   MR_dumpPred1(1,newPred,1);
  1103.   fprintf(output,"#endifn");
  1104. }
  1105. /* don't use Pass3 by itself unless you know that inverted is not important */
  1106. #ifdef __STDC__
  1107. Predicate * MR_removeRedundantPredPass3(Predicate *p)
  1108. #else
  1109. Predicate * MR_removeRedundantPredPass3(p)
  1110.   Predicate *p;
  1111. #endif
  1112. {
  1113.   Predicate     *q;
  1114.   if (p == NULL) return NULL;
  1115.   p->right=MR_removeRedundantPredPass3(p->right);
  1116.   p->down=MR_removeRedundantPredPass3(p->down);
  1117.   if (p->redundant) {
  1118.     q=p->right;
  1119.     p->right=NULL;
  1120.     predicate_free(p);
  1121.     return q;
  1122.   };
  1123.   if (p->expr == PRED_AND_LIST ||
  1124.       p->expr == PRED_OR_LIST) {
  1125.     if (p->down == NULL) {
  1126.       q=p->right;
  1127.       p->right=NULL;
  1128.       predicate_free(p);
  1129.       return q;
  1130.     };
  1131.     if (p->down != NULL && p->down->right == NULL) {
  1132.       q=p->down;
  1133.       q->right=p->right;
  1134.       p->right=NULL;
  1135.       p->down=NULL;
  1136.       return q;
  1137.     };
  1138.   };
  1139.   return p;
  1140. }
  1141. #ifdef __STDC__
  1142. void MR_removeRedundantPredPass2(Predicate *p)
  1143. #else
  1144. void MR_removeRedundantPredPass2(p)
  1145.   Predicate *p;
  1146. #endif
  1147. {
  1148.   Predicate     *q;
  1149.   if (p == NULL) return;
  1150.   if (p->expr == PRED_AND_LIST) {
  1151.     for (q=p->down ; q != NULL ; q=q->right) {
  1152.       MR_removeRedundantPredPass2(q);
  1153.       if (q->isConst) {
  1154.         if (q->constValue == 0) {
  1155.           p->isConst=1;
  1156.           p->constValue=0;
  1157.           return;
  1158.         } else {
  1159.           q->redundant=1;
  1160.         };
  1161.       };
  1162.     };
  1163.   };
  1164.   if (p->expr == PRED_OR_LIST) {
  1165.     for (q=p->down ; q != NULL ; q=q->right) {
  1166.       MR_removeRedundantPredPass2(q);
  1167.       if (q->isConst) {
  1168.         if (q->constValue == 0) {
  1169.           q->redundant=1;
  1170.         } else {
  1171.           p->isConst=1;
  1172.           p->constValue=1;
  1173.           return;
  1174.         };
  1175.       };
  1176.     };
  1177.   };
  1178.   return;
  1179. }
  1180. #if 0
  1181.    this totally ignores the implications of guarded predicates
  1182.      in which the part after the guard could possibly cover a predicate.
  1183.    that would be much harder:
  1184.         rule : (A)? => <<p>>? sub1;     /* 1 */
  1185.              | (B)? => <<r>>? sub2      /* 2 */
  1186.         sub1 : (A)? => <<q>>? A B       /* 3 */
  1187.              | B                        /* 4 - suppresses line 2 */
  1188.              ;
  1189. #endif
  1190. #ifdef __STDC__
  1191. void MR_apply_restriction1(Predicate *pred,set *plainSet,int *changed)
  1192. #else
  1193. void MR_apply_restriction1(pred,plainSet,changed)
  1194.   Predicate     *pred;
  1195.   set           *plainSet;
  1196.   int           *changed;
  1197. #endif
  1198. {
  1199.   if (pred == NULL) return;
  1200.   MR_apply_restriction1(pred->right,plainSet,changed);
  1201.   if (pred->down != NULL) {
  1202.     MR_apply_restriction1(pred->down,plainSet,changed);
  1203.   } else {
  1204.     set     t;
  1205.     if (pred->k == 1) {
  1206.       t=set_dif(pred->scontext[1],*plainSet);
  1207.       if (*changed == 0 &&
  1208.           !set_equ(t,pred->scontext[1])) {
  1209.         *changed=1;
  1210.       };
  1211.       if (set_nil(t)) {
  1212.         pred->redundant=1;
  1213.       };
  1214.       set_free(pred->scontext[1]);
  1215.       pred->scontext[1]=t;
  1216.     };
  1217.   };
  1218. }
  1219. #ifdef __STDC__
  1220. void MR_orin_plainSet(Predicate *p,set plainSet)
  1221. #else
  1222. void MR_orin_plainSet(p,plainSet)
  1223.   Predicate     *p;
  1224.   set           plainSet;
  1225. #endif
  1226. {
  1227.   if (p == NULL) return;
  1228.   MR_orin_plainSet(p->down,plainSet);
  1229.   MR_orin_plainSet(p->right,plainSet);
  1230.   set_orin(&p->plainSet,plainSet);
  1231. }
  1232. Predicate   *PRED_SUPPRESS;
  1233. #ifdef __STDC__
  1234. Predicate * MR_find_in_aSubBlk(Junction *alt)
  1235. #else
  1236. Predicate * MR_find_in_aSubBlk(alt)
  1237.   Junction  *alt;
  1238. #endif
  1239. {
  1240.     Predicate       *root=NULL;
  1241.     Predicate       **tail=NULL;
  1242. Junction        *p;
  1243.     int             nAlts=0;
  1244.     Junction        **jList;
  1245.     Predicate       **predList;
  1246.     int             *matchList;
  1247.     set             predSet;
  1248.     int             i;
  1249.     int             j;
  1250.     int             m;
  1251.     int             predDepth;
  1252.     set             incomplete;
  1253.     set             union_plainSet;
  1254.     set             setChange;
  1255.     int             changed;
  1256.     Predicate       *newPred;
  1257.     set             setDif;
  1258.     Predicate       *origPred;
  1259.     int             depth1=1;             /* const int */
  1260.     set             *plainContext;
  1261.     set             plainSet;
  1262.     predSet=empty;
  1263.     incomplete=empty;
  1264.     union_plainSet=empty;
  1265.     setChange=empty;
  1266.     setDif=empty;
  1267.     plainSet=empty;
  1268.     if (PRED_SUPPRESS == NULL) {
  1269.       PRED_SUPPRESS=new_pred();
  1270.       PRED_SUPPRESS->expr="Predicate Suppressed";
  1271.     };
  1272.     /* this section just counts the number of "interesting" alternatives  */
  1273.     /*   in order to allocate arrays                                      */
  1274. for (p=alt; p!=NULL; p=(Junction *)p->p2) {
  1275.   /* ignore empty alts */
  1276.   if ( p->p1->ntype != nJunction ||
  1277.         ((Junction *)p->p1)->jtype != EndBlk ) {
  1278.         nAlts++;
  1279.       };
  1280.     };
  1281.     /* if this is a (...)+ block then don't count the last alt because
  1282.        it can't be taken until at least one time through the block.
  1283.        In other words it isn't a real choice until the (...)+ is entered
  1284.          at which point the hoisting issue is moot.
  1285.        Maybe look at "ignore" instead ?
  1286.     */
  1287.     if (alt->jtype == aPlusBlk) {
  1288.       nAlts--;
  1289.     };
  1290.     jList=(Junction **)calloc(nAlts,sizeof(Junction *));
  1291.     require(jList!=NULL,"cannot allocate MR_find_in_aSubBlk jList");
  1292.     plainContext=(set *)calloc(nAlts,sizeof(set));
  1293.     require(plainContext!=NULL,"cannot allocate MR_find_in_aSubBlk plainContext");
  1294.     for (m=0; m < nAlts; m++) plainContext[m]=empty;
  1295.     predList=(Predicate **)calloc(nAlts,sizeof(Predicate *));
  1296.     require(predList!=NULL,"cannot allocate MR_find_in_aSubBlk predList");
  1297.     matchList=(int *)calloc(nAlts,sizeof(int));
  1298.     require(matchList!=NULL,"cannot allocate MR_find_in_aSubBlk matchList");
  1299.     /* this section just fills in the arrays previously allocated       */
  1300.     /* the most interesting one is matchList[]                          */
  1301.     /*                                                                  */
  1302.     /*   bit 0 => this alt has a semantic pred which is "covered"       */
  1303.     /*              by an alt without a semantic pred.  Don't hoist.    */
  1304. for (i=0,p=alt;
  1305.          p!=NULL && i<nAlts;
  1306.          i++,p=(Junction *)p->p2) {
  1307.   /* ignore empty alts */
  1308.   if ( p->p1->ntype != nJunction ||
  1309.         ((Junction *)p->p1)->jtype != EndBlk ) {
  1310.         jList[i]=MR_junctionWithoutP2(p);
  1311.         predList[i]=find_predicates(p->p1);      /* should be jList ????? */
  1312.         if (predList[i] != NULL) {
  1313.           MR_cleanup_pred_trees(predList[i]);    /* flatten & left factor */
  1314.           plainContext[i]=MR_union_plain_sets(predList[i]);
  1315.         } else {
  1316.           MR_set_reuse(&plainSet);
  1317.           MR_set_reuse(&incomplete);
  1318.           plainSet=MR_First(depth1,jList[i],&incomplete);
  1319.           MR_complete_set(depth1,&plainSet,&incomplete);
  1320.           require(set_nil(incomplete),"couldn't complete k=1");
  1321.           plainContext[i]=plainSet;
  1322.           plainSet=empty;
  1323.         };
  1324.         set_orin(&union_plainSet,plainContext[i]);
  1325.       };
  1326.     };
  1327.     if (nAlts == 1) {
  1328.       goto EXIT_SIMPLE;
  1329.     };
  1330. /*
  1331.  *  Looking for cases where alt i has a semantic pred and alt j does not.
  1332.  *  Don't care about cases where lookahead for semantic predicates overlap
  1333.  *    because normal predicate hoisting does the correct thing automatically.
  1334.  *  Don't care about cases where lookahead for alts without semantic predicates
  1335.  *    overlap because normal prediction does the correct thing automatically.
  1336.  *
  1337.  *  When we find such a case check for one of three subcases:
  1338.  *
  1339.  *      1.  if lookahead for alt i is contained in the lookahead for any
  1340.  *          alt j then ignore semantic predicate of alt i
  1341.  *      2.  if lookahead for alt i is not contained in the lookahead for
  1342.  *          any alt j then add add predicate i to the OR list to be hoisted
  1343.  *      3.  if lookahead for alt i overlaps the lookahead for some alt j then
  1344.  *          add a dummy semantic predicate for alt j
  1345.  *
  1346.  *  There is an implicit assumption that the context of all alternatives following
  1347.  *  the rule being processed here are identical (but may vary from hoist to
  1348.  *  hoist depending on the place where the rule was invoked that led to hoisting
  1349.  *  these predicates.  In othere words in the fragment:
  1350.  *
  1351.  *            ( <<a>>? a1 a2 a3 | <<b>>? b1 b2 b3 )
  1352.  *
  1353.  *  both a3 and b3 have the same follow sets  because they are both at the end of
  1354.  *  alternatives in the same block.
  1355.  */
  1356.     for (i=0; i < nAlts; i++) {
  1357.       if (jList[i] == NULL) continue;
  1358.       if (predList[i] == NULL) continue;
  1359.         /* if the predicate depth turns out to be one token only */
  1360.         /*   then it is can be easily represented as a set and   */
  1361.         /*   compared to the junction set create by MR_First()   */
  1362.       predDepth=0;
  1363.       MR_pred_depth(predList[i],&predDepth);
  1364.       require (predDepth >= 1,"MR_find_in_aSubBlk: pred depth < 1");
  1365.       require (predDepth <= CLL_k,"MR_find_in_aSubBlk: predDepth > CLL_k");
  1366.         /* complete predicates to predDepth
  1367.            If completed to depth=1 then the context would be incomplete.
  1368.            The context would be truncated and the predicate simplify routine
  1369.              would have incomplete information.  It would lead to
  1370.              either false matches of failure to find true matches.
  1371.         */
  1372.       MR_complete_predicates(predDepth,predList[i]);
  1373.       if (predList[i] != NULL) {
  1374.         MR_cleanup_pred_trees(predList[i]);    /* flatten & left factor */
  1375.       };
  1376.       /* If the predicate depth is 1 then it is possible to suppress
  1377.            a predicate completely using a single plain alt.  Check for suppression
  1378.            by a single plain alt first because it gives better messages.  If that
  1379.            fails try the union of all the plain alts.
  1380.       */
  1381.       if (predDepth == 1) {
  1382.         MR_set_reuse(&predSet);
  1383.         predSet=MR_compute_pred_set(predList[i]);   /* ignores k>1 predicates */
  1384.         for (j=0; j < nAlts; j++) {
  1385.           if (jList[j] == NULL) continue;
  1386.           if (j == i) continue;
  1387.           MR_set_reuse(&setDif);
  1388.           setDif=set_dif(predSet,plainContext[j]);
  1389.           if (set_nil(setDif)) {
  1390.             matchList[i] |= 1;
  1391.             MR_reportSetSuppression(predDepth,predSet,plainContext[j],jList[i],jList[j],predList[i]);
  1392.             predicate_free(predList[i]);
  1393.             predList[i]=PRED_SUPPRESS;
  1394.             goto next_i;
  1395.           };
  1396.         }; /* end loop on j */
  1397.         changed=0;
  1398.         /* predicate_dup is only to give good error messages */
  1399.         /* remember to do a predicate_free()                 */
  1400.         origPred=predicate_dup(predList[i]);
  1401.         MR_apply_restriction1(predList[i],&union_plainSet,&changed);
  1402.         if (changed) {
  1403.           /* don't use Pass3 by itself unless you know that inverted is not important */
  1404.           newPred=MR_removeRedundantPredPass3(predList[i]);
  1405.           newPred=MR_predSimplifyALL(newPred);
  1406.           if (newPred == NULL) {
  1407.             matchList[i] |= 1;
  1408.             MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],
  1409.                                                             NULL,origPred);
  1410.             predList[i]=PRED_SUPPRESS;
  1411.           } else {
  1412.             MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],
  1413.                                                     NULL,origPred,newPred);
  1414.             predList[i]=newPred;
  1415.           };
  1416.         };
  1417.         predicate_free(origPred);
  1418.         origPred=NULL;
  1419.       };
  1420.       /*
  1421.          If the predicate depth is > 1 then it can't be suppressed completely
  1422.            because the code doesn't support inspection of such things.  They're
  1423.            much messier than k=1 sets.
  1424.       */
  1425.       if (predDepth > 1 ) {
  1426.         changed=0;
  1427.         /* predicate_dup is only to give good error messages */
  1428.         /* remember to do a predicate_free()                 */
  1429.         origPred=predicate_dup(predList[i]);
  1430.         MR_apply_restriction1(predList[i],&union_plainSet,&changed);
  1431.         if (changed) {
  1432.           newPred=MR_removeRedundantPredPass3(predList[i]);
  1433.           newPred=MR_predSimplifyALL(newPred);
  1434.           if (newPred == NULL) {
  1435.             matchList[i] |= 1;
  1436.             MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],
  1437.                                                             NULL,origPred);
  1438.             predList[i]=PRED_SUPPRESS;
  1439.           } else {
  1440.             MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],
  1441.                                                     NULL,origPred,newPred);
  1442.             predList[i]=newPred;
  1443.           };
  1444.         };
  1445.         predicate_free(origPred);
  1446.         origPred=NULL;
  1447.       };
  1448. next_i:
  1449.       continue;
  1450.     };
  1451. EXIT_SIMPLE:
  1452.     root = new_pred();
  1453.     root->expr=PRED_OR_LIST;
  1454.     tail = &(root->down);
  1455.     for (i=0 ; i< nAlts ; i++) {
  1456.       if (jList[i] == NULL) continue;
  1457.       if (predList[i] == NULL) {
  1458.         continue;
  1459.       } else if ( (matchList[i] & 1) != 0) {
  1460.         if (predList[i] != PRED_SUPPRESS) {
  1461.           predicate_free(predList[i]);
  1462.         };
  1463.         continue;
  1464.       };
  1465.       /* make an OR list of predicates */
  1466.       *tail=predList[i];
  1467.       tail=&(predList[i]->right);
  1468.     };
  1469. /* if just one pred, remove OR root */
  1470. if (root->down == NULL) {
  1471.       predicate_free(root);
  1472.       root=NULL;
  1473.     } else if (root->down->right == NULL) {
  1474.       Predicate     *p=root->down;
  1475.       root->down=NULL;
  1476.       predicate_free(root);
  1477.       root=p;
  1478. }
  1479.     root=MR_predSimplifyALL(root);
  1480.     MR_orin_plainSet(root,union_plainSet);
  1481.     set_free(predSet);
  1482.     set_free(union_plainSet);
  1483.     set_free(incomplete);
  1484.     set_free(setChange);
  1485.     set_free(setDif);
  1486.     for (m=0; m < nAlts; m++) set_free(plainContext[m]);
  1487.     free ( (char *) jList);
  1488.     free ( (char *) predList);
  1489.     free ( (char *) matchList);
  1490.     free ( (char *) plainContext);
  1491. return root;
  1492. }
  1493. #ifdef __STDC__
  1494. void MR_predContextPresent(Predicate *p,int *allHaveContext,int *noneHaveContext)
  1495. #else
  1496. void MR_predContextPresent(p,allHaveContext,noneHaveContext)
  1497.   Predicate     *p;
  1498.   int           *allHaveContext;
  1499.   int           *noneHaveContext;
  1500. #endif
  1501. {
  1502.   if (p == NULL) return;
  1503.   MR_predContextPresent(p->right,allHaveContext,noneHaveContext);
  1504.   if (p->expr != PRED_AND_LIST &&
  1505.       p->expr != PRED_OR_LIST) {
  1506.     if (set_nil(p->scontext[1]) == 0 ||
  1507.             (p->tcontext != NULL)) {
  1508.       *noneHaveContext=0;
  1509.     } else {
  1510.       *allHaveContext=0;
  1511.     };
  1512.   };
  1513.   MR_predContextPresent(p->down,allHaveContext,noneHaveContext);
  1514. }
  1515. #ifdef __STDC__
  1516. int MR_pointerStackPush(PointerStack *ps,void *dataPointer)
  1517. #else
  1518. int MR_pointerStackPush(ps,dataPointer)
  1519.   PointerStack  *ps;
  1520.   void          *dataPointer;
  1521. #endif
  1522. {
  1523.   void             **newStack;
  1524.   int              newSize;
  1525.   int              i;
  1526.   if (ps->count == ps->size) {
  1527.     newSize=20+ps->size*2;
  1528.     newStack=(void **)calloc(newSize,sizeof(void *));
  1529.     require (newStack != NULL,"cannot allocate PointerStack");
  1530.     for (i=0; i < ps->size; i++) {
  1531.       newStack[i]=ps->data[i];
  1532.     };
  1533.     if (ps->data != NULL) free( (char *) ps->data);
  1534.     ps->data=newStack;
  1535.     ps->size=newSize;
  1536.   };
  1537.   ps->data[ps->count]=dataPointer;
  1538.   ps->count++;
  1539.   return ps->count-1;
  1540. }
  1541. #ifdef __STDC__
  1542. void * MR_pointerStackPop(PointerStack *ps)
  1543. #else
  1544. void * MR_pointerStackPop(ps)
  1545.   PointerStack  *ps;
  1546. #endif
  1547. {
  1548.   void  *dataPointer;
  1549.   require(ps->count > 0,"MR_pointerStackPop underflow");
  1550.   dataPointer=ps->data[ps->count-1];
  1551.   ps->data[ps->count-1]=NULL;
  1552.   (ps->count)--;
  1553.   return dataPointer;
  1554. }
  1555. #ifdef __STDC__
  1556. void * MR_pointerStackTop(PointerStack *ps)
  1557. #else
  1558. void * MR_pointerStackTop(ps)
  1559.   PointerStack  *ps;
  1560. #endif
  1561. {
  1562.   require(ps->count > 0,"MR_pointerStackTop underflow");
  1563.   return ps->data[ps->count-1];
  1564. }
  1565. #ifdef __STDC__
  1566. void MR_pointerStackReset(PointerStack *ps)
  1567. #else
  1568. void MR_pointerStackReset(ps)
  1569.   PointerStack  *ps;
  1570. #endif
  1571. {
  1572.   int i;
  1573.   if (ps->data != NULL) {
  1574.     for (i=0; i < ps->count ; i++) {
  1575.        ps->data[i]=NULL;
  1576.     };
  1577.   };
  1578.   ps->count=0;
  1579. }
  1580. #ifdef __STDC__
  1581. Junction *MR_nameToRuleBlk(char *name)
  1582. #else
  1583. Junction *MR_nameToRuleBlk(name)
  1584.   char  *name;
  1585. #endif
  1586. {
  1587.     RuleEntry *q;
  1588.     require (RulePtr != NULL,"MR_nameToRule: RulePtr not initialized");
  1589.     if (name == NULL) return NULL;
  1590.     q = (RuleEntry *) hash_get(Rname,name);
  1591. if ( q == NULL ) {
  1592.       return NULL;
  1593.     } else {
  1594.       return RulePtr[q->rulenum];
  1595.     };
  1596. }
  1597. #ifdef __STDC__
  1598. Junction * MR_ruleReferenced(RuleRefNode *rrn)
  1599. #else
  1600. Junction * MR_ruleReferenced(rrn)
  1601.   RuleRefNode   *rrn;
  1602. #endif
  1603. {
  1604.     return MR_nameToRuleBlk(rrn->text);
  1605. }
  1606. #ifdef __STDC__
  1607. void MR_comparePredLeaves(Predicate *me,Predicate *myParent,Predicate *him,Predicate *hisParent)
  1608. #else
  1609. void MR_comparePredLeaves(me,myParent,him,hisParent)
  1610.     Predicate *me;
  1611.     Predicate *myParent;
  1612.     Predicate *him;
  1613.     Predicate *hisParent;
  1614. #endif
  1615. {
  1616.     if (me == NULL) return;
  1617.     if (me == him) {
  1618.       MR_comparePredLeaves(me->right,myParent,him,hisParent);
  1619.       return;
  1620.     } else if (me->expr == PRED_AND_LIST ||
  1621.                me->expr == PRED_OR_LIST) {
  1622.       MR_comparePredLeaves(me->down,me,him,hisParent);
  1623.       MR_comparePredLeaves(me->right,myParent,him,hisParent);
  1624.       return;
  1625.     } else {
  1626.       if (me->source != NULL) {
  1627.         /* predicate->invert can be set only in the predEntry predicates        */
  1628.         /* thus they are only visible after the predEntry predicates have been "unfolded" */
  1629.         int     sameSource=(me->source == him->source);
  1630.         int     sameInvert=1 &
  1631.                  (1 + me->inverted + him->inverted + me->source->inverted + him->source->inverted);
  1632.         int     samePredEntry=(me->source->predEntry != NULL
  1633.                                  && him->source->predEntry != NULL
  1634.                                     && me->source->predEntry == him->source->predEntry);
  1635.         if (sameInvert && (sameSource || samePredEntry)) {
  1636.           if (MR_identicalContext(me,him)) {
  1637.             /* identical predicates */
  1638.             if (hisParent->expr == PRED_OR_LIST &&
  1639.                 myParent->expr == PRED_OR_LIST) {
  1640.               me->redundant=1;
  1641.             } else if (hisParent->expr == PRED_AND_LIST &&
  1642.                        myParent->expr == PRED_AND_LIST) {
  1643.               me->redundant=1;
  1644.             } else if (  (hisParent->expr == PRED_OR_LIST &&
  1645.                           myParent->expr == PRED_AND_LIST)
  1646.                        ||
  1647.                          (hisParent->expr == PRED_AND_LIST &&
  1648.                           myParent->expr == PRED_OR_LIST)
  1649.                       ) {
  1650.               myParent->redundant=1;
  1651.             } else {
  1652.               require (0,"MR_comparePredLeaves: not both PRED_LIST");
  1653.             };
  1654.           };
  1655.         };  /* end same source or same predEntrr with same invert sense */
  1656.         /* same predEntry but opposite invert sense */
  1657.         if (!sameInvert && (sameSource || samePredEntry)) {
  1658.           if (MR_identicalContext(me,him)) {
  1659.             if (hisParent->expr == PRED_OR_LIST &&
  1660.                 myParent->expr == PRED_OR_LIST) {
  1661.               myParent->isConst=1;
  1662.               myParent->constValue=1;
  1663.             } else if (hisParent->expr == PRED_AND_LIST &&
  1664.                        myParent->expr == PRED_AND_LIST) {
  1665.               myParent->isConst=1;
  1666.               myParent->constValue=0;
  1667.             } else if (  (hisParent->expr == PRED_OR_LIST &&
  1668.                           myParent->expr == PRED_AND_LIST)
  1669.                        ||
  1670.                          (hisParent->expr == PRED_AND_LIST &&
  1671.                           myParent->expr == PRED_OR_LIST)
  1672.                       ) {
  1673.               me->redundant=1;
  1674.             } else {
  1675.               require (0,"MR_comparePredLeaves: not both PRED_LIST");
  1676.             };
  1677.           };
  1678.         };  /* end same predEntry with opposite invert sense */
  1679.       };
  1680.       MR_comparePredLeaves(me->right,myParent,him,hisParent);
  1681.       return;
  1682.     };
  1683. }
  1684. #ifdef __STDC__
  1685. void MR_removeRedundantPredPass1(Predicate *me,Predicate *myParent)
  1686. #else
  1687. void MR_removeRedundantPredPass1(me,myParent)
  1688.   Predicate     *me;
  1689.   Predicate     *myParent;
  1690. #endif
  1691. {
  1692.     if (me == NULL) return;
  1693.     if (me->redundant) {
  1694.       MR_removeRedundantPredPass1(me->right,myParent);
  1695.       return;
  1696.     };
  1697.     if (me->expr == PRED_AND_LIST ||
  1698.         me->expr == PRED_OR_LIST) {
  1699.       MR_removeRedundantPredPass1(me->down,me);
  1700.       MR_removeRedundantPredPass1(me->right,myParent);
  1701.     } else {
  1702.       require (me->source != NULL,"me->source == NULL");
  1703.       if (myParent != NULL) {
  1704.         MR_comparePredLeaves(myParent->down,myParent,me,myParent);
  1705.       };
  1706.       MR_removeRedundantPredPass1(me->right,myParent);
  1707.     };
  1708. }
  1709. /* pretty much ignores things with the inverted bit set */
  1710. #ifdef __STDC__
  1711. Predicate *MR_predFlatten(Predicate *p)
  1712. #else
  1713. Predicate *MR_predFlatten(p)
  1714.   Predicate     *p;
  1715. #endif
  1716. {
  1717.     if (p == NULL) return NULL;
  1718.     if (p->expr == PRED_OR_LIST
  1719.         || p->expr == PRED_AND_LIST) {
  1720.       Predicate     *child;
  1721.       Predicate     *gchild;
  1722.       Predicate     **tail;
  1723.       Predicate     *next;
  1724.       char          *PRED_XXX_LIST=p->expr;
  1725.       require (p->down != NULL,"MR_predFlatten AND/OR no child");
  1726.       p->down=MR_predFlatten(p->down);
  1727.       p->right=MR_predFlatten(p->right);
  1728.       child=p->down;
  1729.       if (child->right == NULL) {
  1730.         child->right=p->right;
  1731.         p->right=NULL;
  1732.         p->down=NULL;
  1733.         if (p->inverted) child->inverted=!child->inverted;
  1734.         predicate_free(p);
  1735.         return child;
  1736.       };
  1737.       /* make a single list of all children and grandchildren */
  1738.       tail=&(p->down);
  1739.       for (child=p->down; child != NULL; child=next) {
  1740.         if (child->expr != PRED_XXX_LIST
  1741.               || child->inverted
  1742.                 || child->predEntry != NULL) {
  1743.           *tail=child;
  1744.           tail=&(child->right);
  1745.           next=child->right;
  1746.         } else {
  1747.           for (gchild=child->down;
  1748.                gchild != NULL;
  1749.                gchild=gchild->right) {
  1750.             *tail=gchild;
  1751.             tail=&(gchild->right);
  1752.           };
  1753.           next=child->right;
  1754.           child->right=NULL;
  1755.           child->down=NULL;
  1756.           predicate_free(child);
  1757.         };
  1758.       };
  1759.       *tail=NULL;
  1760.       return p;
  1761.     } else {
  1762.       p->right=MR_predFlatten(p->right);
  1763.       return p;
  1764.     };
  1765. }
  1766. static char *alwaysFalseWarning=NULL;
  1767. #ifdef __STDC__
  1768. Predicate *checkPredicateConflict(Predicate *p)
  1769. #else
  1770. Predicate *checkPredicateConflict(p)
  1771.   Predicate     *p;
  1772. #endif
  1773. {
  1774.   if (p->isConst) {
  1775.     if (p->constValue == 1) {
  1776.       predicate_free(p);
  1777.       return NULL;
  1778.     } else {
  1779.       if (InfoP && !p->conflictReported) {
  1780.         p->conflictReported=1;
  1781.         fprintf(output,"n#if 0nn");
  1782.         fprintf(output,"The following predicate expression will always be false:nn");
  1783.         MR_dumpPred1(1,p,1);
  1784.         fprintf(output,"n#endifn");
  1785.       };
  1786.       if (alwaysFalseWarning != CurRule) {
  1787.         alwaysFalseWarning=CurRule;
  1788.         if (InfoP) {
  1789.           warnNoFL(eMsg1("one (or more) predicate expression hoisted into rule "%s" are always false 
  1790. - see output file for more information",CurRule));
  1791.         } else {
  1792.           warnNoFL(eMsg1("one (or more) predicate expressions hoisted into rule "%s" are always false 
  1793. - use "-info p" for more information",CurRule));
  1794.         };
  1795.       };
  1796.     };
  1797.   };
  1798.   return p;
  1799. }
  1800. #ifdef __STDC__
  1801. int MR_countPredNodes(Predicate *p)
  1802. #else
  1803. int MR_countPredNodes(p)
  1804.   Predicate     *p;
  1805. #endif
  1806. {
  1807.   if (p == NULL) return 0;
  1808.   return 1 + MR_countPredNodes(p->down) + MR_countPredNodes(p->right);
  1809. }
  1810. #ifdef __STDC__
  1811. Predicate *MR_predSimplifyALLX(Predicate *p,int skipPass3)
  1812. #else
  1813. Predicate *MR_predSimplifyALLX(p,skipPass3)
  1814.   Predicate     *p;
  1815.   int           skipPass3;
  1816. #endif
  1817. {
  1818.   int       countBefore;
  1819.   int       countAfter;
  1820.   countAfter=MR_countPredNodes(p);
  1821.   do {
  1822.       if (p == NULL) return NULL;
  1823.       if (p->right == NULL && p->down == NULL) return p;
  1824.       countBefore=countAfter;
  1825.       MR_simplifyInverted(p,0);
  1826.       p=MR_predFlatten(p);
  1827.       MR_removeRedundantPredPass1(p,NULL);
  1828.       MR_removeRedundantPredPass2(p);
  1829.       if (! skipPass3) {
  1830.         p=checkPredicateConflict(p);
  1831.         p=MR_removeRedundantPredPass3(p);
  1832.       };
  1833.       countAfter=MR_countPredNodes(p);
  1834.   } while (countBefore != countAfter);
  1835.   return p;
  1836. }
  1837. #ifdef __STDC__
  1838. Predicate *MR_predSimplifyALL(Predicate *p)
  1839. #else
  1840. Predicate *MR_predSimplifyALL(p)
  1841.   Predicate     *p;
  1842. #endif
  1843. {
  1844.   return MR_predSimplifyALLX(p,0);
  1845. }
  1846. #ifdef __STDC__
  1847. void MR_releaseResourcesUsedInRule(Node *n)
  1848. #else
  1849. void MR_releaseResourcesUsedInRule(n)
  1850.   Node  *n;
  1851. #endif
  1852. {
  1853.    Node         *next;
  1854.    Junction     *j;
  1855.    int          i;
  1856.    if (n == NULL) return;
  1857.    if (n->ntype == nJunction) {
  1858.      j=(Junction *) n;
  1859.      if (j->predicate != NULL) {
  1860.        predicate_free(j->predicate);
  1861.        j->predicate=NULL;
  1862.      };
  1863.      for (i=0; i< CLL_k; i++) {
  1864.        set_free(j->fset[i]);
  1865.        j->fset[i]=empty;
  1866.      };
  1867.      if (j->ftree != NULL) {
  1868.        Tfree(j->ftree);
  1869.        j->ftree=NULL;
  1870.      };
  1871.      if (j->jtype == EndRule) return;
  1872.      if (j->jtype != RuleBlk && j->jtype != EndBlk) {
  1873.        if (j->p2 != NULL && !j->ignore) {   /* MR11 */
  1874.           MR_releaseResourcesUsedInRule(j->p2);
  1875.        };
  1876.      };
  1877.    };
  1878.    next=MR_advance(n);
  1879.    MR_releaseResourcesUsedInRule(next);
  1880. }
  1881. #ifdef __STDC__
  1882. int MR_allPredLeaves(Predicate *p)
  1883. #else
  1884. int MR_allPredLeaves(p)
  1885.   Predicate *p;
  1886. #endif
  1887. {
  1888.   Predicate     *q;
  1889.   if (p == NULL) return 1;
  1890.   for (q=p; q != NULL; q=q->right) {
  1891.    if (q->down != NULL) return 0;
  1892.   };
  1893.   return 1;
  1894. }
  1895. /* make sure it works for the last rule in a file */
  1896. #ifdef __STDC__
  1897. int MR_offsetFromRule(Node *n)
  1898. #else
  1899. int MR_offsetFromRule(n)
  1900.   Node      *n;
  1901. #endif
  1902. {
  1903.   Junction  *j;
  1904.   int       offset=(-1);
  1905.   for (j=SynDiag; j != NULL; j=(Junction *)j->p2) {
  1906.     require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block");
  1907.     if (n->file < j->file) {
  1908.       return offset;
  1909.     };
  1910.     if (n->file == j->file) {
  1911.       if (n->line < j->line) {
  1912.         return (offset < 0) ? 0 : offset;
  1913.       } else {
  1914.         offset=n->line - j->line;
  1915.         if (offset == 0) return 0;
  1916.       };
  1917.     };
  1918.   };
  1919.   return offset;
  1920. }
  1921. #define ruleNameMax 50
  1922. static char ruleNameStatic1[ruleNameMax];
  1923. static char ruleNameStatic2[ruleNameMax+10];
  1924. #ifdef __STDC__
  1925. char * MR_ruleNamePlusOffset(Node *n)
  1926. #else
  1927. char * MR_ruleNamePlusOffset(n)
  1928.   Node      *n;
  1929. #endif
  1930. {
  1931.     int     offset=MR_offsetFromRule(n);
  1932.     strncpy(ruleNameStatic1,n->rname,ruleNameMax);
  1933.     if (offset < 0) {
  1934.       sprintf(ruleNameStatic2,"%s/?",ruleNameStatic1);
  1935.     } else {
  1936.       sprintf(ruleNameStatic2,"%s/%d",ruleNameStatic1,offset+1);
  1937.     };
  1938.     return ruleNameStatic2;
  1939. }
  1940. #ifdef __STDC__
  1941. int MR_max_height_of_tree(Tree *t)
  1942. #else
  1943. int MR_max_height_of_tree(t)
  1944.   Tree  *t;
  1945. #endif
  1946. {
  1947.   int       h;
  1948.   int       height=0;
  1949.   Tree      *u;
  1950.   if (t == NULL) return 0;
  1951.   require (t->token != ALT && t->token != EpToken,"MR_max_height_of_tree ALT or EpToken");
  1952.   for (u=t; u != NULL; u=u->right) {
  1953.     h=MR_max_height_of_tree(u->down)+1;
  1954.     if (h > height) height=h;
  1955.   };
  1956.   return height;
  1957. }
  1958. #ifdef __STDC__
  1959. int MR_all_leaves_same_height(Tree *t,int depth)
  1960. #else
  1961. int MR_all_leaves_same_height(t,depth)
  1962.   Tree  *t;
  1963.   int   depth;
  1964. #endif
  1965. {
  1966.   if (t == NULL) {
  1967.     return (depth==0);
  1968.   };
  1969.   require (t->token != ALT && t->token != EpToken,"MR_all_leaves_same_height ALT or EpToken");
  1970.   if (depth == 0) {
  1971.     return 0;
  1972.   } else {
  1973.     if ( ! MR_all_leaves_same_height(t->down,depth-1)) {
  1974.       return 0;
  1975.     };
  1976.     if (t->right == NULL) {
  1977.       return 1;
  1978.     } else {
  1979.       return MR_all_leaves_same_height(t->right,depth);
  1980.     };
  1981.   };
  1982. }
  1983. #ifdef __STDC__
  1984. void MR_projectTreeOntoSet(Tree *tree,int ck,set *ckset)
  1985. #else
  1986. void MR_projectTreeOntoSet(tree,ck,ckset)
  1987.   Tree  *tree;
  1988.   int   ck;
  1989.   set   *ckset;
  1990. #endif
  1991. {
  1992.     if (tree == NULL) return;
  1993.     require(tree->token != EpToken,"MR_projectTreeOntoSet: EpToken unexpectedn");
  1994.     MR_projectTreeOntoSet(tree->right,ck,ckset);
  1995.     if (tree->token == ALT) {
  1996.       MR_projectTreeOntoSet(tree->down,ck,ckset);
  1997.     } else {
  1998.       if (ck > 1) {
  1999.         MR_projectTreeOntoSet(tree->down,ck-1,ckset);
  2000.       } else {
  2001.         set_orel(tree->token,ckset);
  2002.       };
  2003.     };
  2004. }
  2005. #ifdef __STDC__
  2006. int MR_comparePredicates(Predicate *a,Predicate *b)
  2007. #else
  2008. int MR_comparePredicates(a,b)
  2009.   Predicate     *a;
  2010.   Predicate     *b;
  2011. #endif
  2012. {
  2013.   Predicate     *p;
  2014.   Predicate     *q;
  2015.   if (a == b) return 1;
  2016.   if (a == NULL || b == NULL ) return 0;
  2017.   if (a->down == NULL && b->down == NULL) {
  2018.     /* predicate->invert can be set only in the predEntry predicates                  */
  2019.     /* thus they are only visible after the predEntry predicates have been "unfolded" */
  2020.     int     sameSource=(a->source == b->source);
  2021.     int     sameInvert= 1 & (1 +a->inverted + b->inverted +
  2022.                                 a->source->inverted + b->source->inverted);
  2023.     int     samePredEntry=(a->source->predEntry != NULL
  2024.                                  && b->source->predEntry != NULL
  2025.                                     && a->source->predEntry == b->source->predEntry);
  2026.     if (sameInvert && (sameSource || samePredEntry)) {
  2027.       if (MR_identicalContext(a,b)) {
  2028.          return 1;
  2029.       };
  2030.     };
  2031.     return 0;
  2032.   };
  2033.   if (a->down == NULL || b->down == NULL) return 0;
  2034.   if (a->expr != b->expr) return 0;
  2035.   for (p=a->down; p != NULL; p=p->right) {
  2036.     for (q=b->down; q != NULL; q=q->right) {
  2037.       if (MR_comparePredicates(p,q)) goto NEXT_P;
  2038.     };
  2039.     return 0;
  2040. NEXT_P:
  2041.     continue;
  2042.   };
  2043.   return 1;
  2044. }
  2045. /*
  2046.  *  action->inverted can be set only when a predicate symbol appears in
  2047.  *      a rule:  "rule : <<!XXX>>? X".  It cannot be set under any
  2048.  *      other circumstances.  In particular it cannot be set by
  2049.  *      "#pred NotA !A" or by "#pred Nota <<!A>>?".  The first case
  2050.  *      creates a predEntry and the predicate expression of that predEntry
  2051.  *      has inverted set.  In the second case, the code for handling "!"
  2052.  *      is only present in buildAction, which is not called by the #pred
  2053.  *      semantic routines, only when a <<...>>? is recognized as part of
  2054.  *      a rule definition.
  2055.  *
  2056.  *  predicate->inverted can only be set by a predicate created by a #pred
  2057.  *      expression, such as "#pred NotA !A" or "#pred NotXY ! (X && Y) or
  2058.  *      "#pred XbarY !(X && Y)".  In particular, it cannot be set by any
  2059.  *      predicate expression occurring under any other circumstances.
  2060.  *      The #pred predicate expresssions are stored with in predEntry->pred
  2061.  *      and do not normally appear anywhere else until the predicates are
  2062.  *      "unfolded" in order to recognize redundancies, conflicts, and
  2063.  *      tautologies.
  2064.  *
  2065.  *  The unfold routine expands all references to #pred expressions.
  2066.  *
  2067.  *  The simplifyInvert goes through and propagates the invert bit so that
  2068.  *      all OR and AND nodes are un-inverted.
  2069.  *
  2070.  *  Note that !(A and B) => (!A or !B)
  2071.  *            !(A or B)  => (!A and !B)
  2072.  *
  2073.  *  MR_unfold() is called to expand predicate symbols by replacing predicates
  2074.  *    that reference predicate entries with the copies of the predicate entries.
  2075.  *    Each reference receives a duplicate of the original.  This is necessary
  2076.  *    because the next phase involves simplification and removal of redundant
  2077.  *    predicate nodes.  Anyway, the point I'm making is that predicate->invert
  2078.  *    should not be set in any predicate until it has been expanded.
  2079.  *
  2080.  *    This is a recursive structure, but there is no need for "recursive expansion"
  2081.  *    by which I mean a predicate symbol refers to other predicate symbols which
  2082.  *    must also be expanded.
  2083.  *
  2084.  *    Recursive expansion is *not* performed by this routine because it is not
  2085.  *    necessary.  Expansion of references is performed by predPrimary when
  2086.  *    a new predicate symbol is created by referring to others in the pred expr.
  2087.  */
  2088. #ifdef __STDC__
  2089. Predicate *MR_unfold(Predicate *pred)
  2090. #else
  2091. Predicate *MR_unfold(pred)
  2092.   Predicate     *pred;
  2093. #endif
  2094. {
  2095.   Predicate     *result;
  2096.   if (pred == NULL) return NULL;
  2097.   pred->right=MR_unfold(pred->right);
  2098.   if (pred->down == NULL) {
  2099.     if (pred->source->predEntry != NULL) {
  2100.       if (pred->source->predEntry->pred == NULL) {
  2101.         ; /* do nothing */ /* a reference to a literal #pred (perhaps with "!" */
  2102.       } else {
  2103.         result=predicate_dup_without_context(pred->source->predEntry->pred);
  2104.         if (pred->inverted) {
  2105.           result->inverted=!result->inverted;
  2106.         };
  2107.         if (pred->source->inverted) {
  2108.           result->inverted=!result->inverted;
  2109.         };
  2110.         result->right=pred->right;
  2111.         pred->right=NULL;
  2112.         predicate_free(pred);
  2113. /***    result=MR_unfold(result); *** not necessary */    /* recursive expansion */
  2114.         return result;
  2115.       };
  2116.     } else {
  2117.       ; /* do nothing */ /* an inline literal predicate */
  2118.     };
  2119.   } else {
  2120.     pred->down=MR_unfold(pred->down);
  2121.   };
  2122.   return pred;
  2123. }
  2124. /* this should be called immediately after MR_unfold() and
  2125.    at no other times
  2126. */
  2127. #ifdef __STDC__
  2128. void MR_simplifyInverted(Predicate *pred,int inverted)
  2129. #else
  2130. void MR_simplifyInverted(pred,inverted)
  2131.   Predicate     *pred;
  2132.   int           inverted;
  2133. #endif
  2134. {
  2135.   int       newInverted;
  2136.   if (pred == NULL) return;
  2137.   MR_simplifyInverted(pred->right,inverted);
  2138.   newInverted= 1 & (inverted + pred->inverted);
  2139.   if (pred->down == NULL) {
  2140.     pred->inverted=newInverted;
  2141.   } else {
  2142.     if (newInverted != 0) {
  2143.       if (pred->expr == PRED_AND_LIST) {
  2144.         pred->expr=PRED_OR_LIST;
  2145.       } else {
  2146.         pred->expr=PRED_AND_LIST;
  2147.       };
  2148.     };
  2149.     pred->inverted=0;
  2150.     MR_simplifyInverted(pred->down,newInverted);
  2151.   };
  2152. }
  2153. /* only remove it from AND and OR nodes, not leaves */
  2154. #ifdef __STDC__
  2155. void MR_clearPredEntry(Predicate *p)
  2156. #else
  2157. void MR_clearPredEntry(p)
  2158.   Predicate     *p;
  2159. #endif
  2160. {
  2161.    if (p == NULL) return;
  2162.    MR_clearPredEntry(p->down);
  2163.    MR_clearPredEntry(p->right);
  2164.    if (p->down != NULL) p->predEntry=NULL;
  2165. }
  2166. #ifdef __STDC__
  2167. void MR_orphanRules(FILE *f)
  2168. #else
  2169. void MR_orphanRules(f)
  2170.   FILE      *f;
  2171. #endif
  2172. {
  2173. set         a;
  2174.     Junction    *p;
  2175.     unsigned    e;
  2176.     RuleEntry   *re;
  2177. a=empty;
  2178.     if (! InfoO) return;
  2179. for (p=SynDiag; p!=NULL; p = (Junction *)p->p2) {
  2180.       if ( (Junction *) (p->end)->p1 == NULL) {
  2181.         re=(RuleEntry *) hash_get(Rname,p->rname);
  2182.         require (re != NULL,"RuleEntry == NULL");
  2183. set_orel(re->rulenum, &a);
  2184.       }
  2185.    }
  2186.     if (set_deg(a) > 1) {
  2187.       fprintf(f,"note: Start rules: {");
  2188.       for (; !set_nil(a); set_rm(e,a)) {
  2189.         e=set_int(a);
  2190.         fprintf(f," %s",RulePtr[e]->rname);
  2191.       };
  2192.       fprintf(f," }n");
  2193.     };
  2194. set_free( a );
  2195. }
  2196. /*  merge (X Y) and (X) to create (X)  */
  2197. static int      *mergeChain;
  2198. static Tree     *mergeTree;
  2199. #ifdef __STDC__
  2200. Tree *MR_merge_tree_contexts_client(Tree *t,int chain[])
  2201. #else
  2202. Tree *MR_merge_tree_contexts_client(t,chain)
  2203.   Tree  *t;
  2204.   int   chain[];
  2205. #endif
  2206. {
  2207.   if (t == NULL)  return NULL;
  2208.   if (chain[0] == 0) {
  2209.     Tree    *u=t->right;
  2210.     t->right=NULL;
  2211.     Tfree(t);
  2212.     return MR_merge_tree_contexts_client(u,&chain[0]);
  2213.   }
  2214.   if (chain[0] == t->token) {
  2215.     t->down=MR_merge_tree_contexts_client(t->down,&chain[1]);
  2216.   };
  2217.   t->right=MR_merge_tree_contexts_client(t->right,&chain[0]);
  2218.   return t;
  2219. }
  2220. #ifdef __STDC__
  2221. void MR_iterateOverTreeContexts(Tree *t,int chain[])
  2222. #else
  2223. void MR_iterateOverTreeContexts(t,chain)
  2224.   Tree          *t;
  2225.   int           chain[];
  2226. #endif
  2227. {
  2228.   if (t == NULL) return;
  2229.   chain[0]=t->token;
  2230.   if (t->down != NULL) {
  2231.     MR_iterateOverTreeContexts(t->down,&chain[1]);
  2232.   } else {
  2233.     MR_merge_tree_contexts_client(mergeTree,mergeChain);
  2234.   };
  2235.   MR_iterateOverTreeContexts(t->right,&chain[0]);
  2236.   chain[0]=0;
  2237. }
  2238. #ifdef __STDC__
  2239. Tree *MR_merge_tree_contexts(Tree *t)
  2240. #else
  2241. Tree *MR_merge_tree_contexts(t)
  2242.   Tree  *t;
  2243. #endif
  2244. {
  2245.     int     h=MR_max_height_of_tree(t);
  2246.     mergeTree=t;
  2247.     mergeChain=(int *) calloc(h+1,sizeof(int));
  2248.     require (mergeChain != NULL,"MR_merge_tree_contexts: can't alloc chain");
  2249.     MR_iterateOverTreeContexts(t,mergeChain);
  2250.     t=tshrink(t);
  2251.     t=tflatten(t);
  2252.     t=tleft_factor(t);
  2253.     free ( (char *) mergeChain);
  2254.     mergeChain=NULL;
  2255.     return t;
  2256. }
  2257. #ifdef __STDC__
  2258. Tree *MR_compute_pred_tree_context(Predicate *p)
  2259. #else
  2260. Tree *MR_compute_pred_tree_context(p)
  2261.   Predicate *p;
  2262. #endif
  2263. {
  2264.   Tree  *t;
  2265.   t=MR_compute_pred_tree_ctxXX(p);
  2266.   MR_merge_tree_contexts(t);
  2267.   return t;
  2268. }
  2269. #ifdef __STDC__
  2270. void MR_guardPred_plainSet(ActionNode *anode,Predicate *pred)
  2271. #else
  2272. void MR_guardPred_plainSet(anode,pred)
  2273.   ActionNode    *anode;
  2274.   Predicate     *pred;
  2275. #endif
  2276. {
  2277.   Junction      *j;
  2278.   Predicate     *workPred;
  2279.   set           maskSet;
  2280.   maskSet=empty;
  2281.   if (!MRhoisting) return;
  2282.   /* it doesn't really matter whether the predicate has
  2283.      depth k=1 or k>1 because we're not really looking
  2284.      at the predicate itself, just the stuff "behind"
  2285.      the predicate.
  2286.   */
  2287.   /* shouldn't have to worry about REACHing off the end
  2288.      of the rule containing the predicate because the
  2289.      Rule->end->halt should have been set already by the
  2290.      the code which handles RuleRef nodes.
  2291.      We don't want to REACH off the end of the rule because
  2292.      this would give the "global" follow context rather than
  2293.      the "local" context.
  2294.          r1a : (A)? => <<p>>? r2 (A|B)
  2295.          r1b : (A)? => <<p>>? r2 (A|C)
  2296.          r2  : ();
  2297.      For r1a we want follow of predicate = {A B}
  2298.              we want plainSet = {B}
  2299.      For r1b we want follow of predicate = {A C}
  2300.              we want plainSet = {C}
  2301.   */
  2302.   require (anode->next->ntype == nJunction,"MR_guardpred_plainSet not Junction");
  2303.   j=(Junction *)(anode->next);
  2304.   workPred=predicate_dup_without_context(pred);
  2305.   workPred->k=1;
  2306.   workPred->scontext[1]=MR_First(1,j, &(workPred->completionSet) );
  2307.   MR_complete_predicates(1,workPred);
  2308.   if (pred->k == 1) {
  2309.     maskSet=pred->scontext[1];
  2310.   } else {
  2311.     MR_projectTreeOntoSet(pred->tcontext,1,&maskSet);
  2312.   }
  2313.   pred->plainSet=set_dif(workPred->scontext[1],maskSet);
  2314.   predicate_free(workPred);
  2315. }
  2316. /*******************************************************************************/
  2317. static Tree *       suppressTree;
  2318. static int *        suppressChain;  /* element 0 not used */
  2319. static set *        suppressSets;
  2320. static Node *       suppressNode;
  2321. static int          suppressChainLength;
  2322. int                 MR_SuppressSearch=0;
  2323. static int          suppressSucceeded;
  2324. static Predicate *  suppressPredicate;
  2325. #ifdef __STDC__
  2326. int MR_isChain(Tree *t)
  2327. #else
  2328. int MR_isChain(t)
  2329.   Tree  *t;
  2330. #endif
  2331. {
  2332.   Tree  *u;
  2333.   for (u=t; u != NULL; u=u->down) {
  2334.     if (u->right != NULL) return 0;
  2335.   }
  2336.   return 1;
  2337. }
  2338. #ifdef __STDC__
  2339. int MR_suppressK_client(Tree *tree,int tokensInChain[])
  2340. #else
  2341. int MR_suppressK_client(tree,tokensInChain)
  2342.   Tree      *tree;
  2343.   int       tokensInChain[];
  2344. #endif
  2345. {
  2346.   int       i;
  2347.   set       *save_fset;
  2348.   int       save_ConstrainSearch;
  2349.   set       incomplete;
  2350.   Tree      *t;
  2351.   suppressSucceeded=0;  /* volatile */
  2352.   if (suppressSets == NULL) {
  2353.     suppressSets=(set *) calloc (CLL_k+1,sizeof(set));
  2354.     require (suppressSets != NULL,"MR_suppressK_client: suppressSets alloc");
  2355.   };
  2356.   for (suppressChainLength=1;
  2357.        tokensInChain[suppressChainLength+1] != 0;
  2358.        suppressChainLength++) {};
  2359.   require (suppressChainLength != 0,"MR_suppressK_client: chain empty");
  2360.   for (i=1 ; i <= suppressChainLength ; i++) {
  2361.     set_clr(suppressSets[i]);
  2362.     set_orel( (unsigned) tokensInChain[i],
  2363.                               &suppressSets[i]);
  2364.   };
  2365.   save_fset=fset;
  2366.   save_ConstrainSearch=ConstrainSearch;
  2367.   fset=suppressSets;
  2368.   MR_SuppressSearch=1;
  2369.   MR_AmbSourceSearch=1;
  2370.   MR_MaintainBackTrace=1;
  2371.   ConstrainSearch=1;
  2372.   maxk = suppressChainLength;
  2373.   incomplete=empty;
  2374.   t=NULL;
  2375. /***  constrain = &(fset[1]); ***/
  2376.   MR_pointerStackReset(&MR_BackTraceStack);
  2377.   TRAV(suppressNode,maxk,&incomplete,t);
  2378.   Tfree(t);
  2379.   require (set_nil(incomplete),"MR_suppressK_client TRAV incomplete");
  2380.   require (MR_BackTraceStack.count == 0,
  2381.             "MR_suppressK_client: MR_BackTraceStack.count != 0");
  2382.   set_free(incomplete);
  2383.   ConstrainSearch=save_ConstrainSearch;
  2384.   fset=save_fset;
  2385.   MR_AmbSourceSearch=0;
  2386.   MR_MaintainBackTrace=0;
  2387.   MR_SuppressSearch=0;
  2388.   return suppressSucceeded;
  2389. }
  2390. #ifdef __STDC__
  2391. Tree * MR_iterateOverTreeSuppressK(Tree *t,int chain[])
  2392. #else
  2393. Tree * MR_iterateOverTreeSuppressK(t,chain)
  2394.   Tree          *t;
  2395.   int           chain[];
  2396. #endif
  2397. {
  2398.   if (t == NULL) return NULL;
  2399.   t->right=MR_iterateOverTreeSuppressK(t->right,&chain[0]);
  2400.   chain[0]=t->token;
  2401.   if (t->down != NULL) {
  2402.     t->down=MR_iterateOverTreeSuppressK(t->down,&chain[1]);
  2403.     if (t->down == NULL) {
  2404.       Tree *u=t->right;
  2405.       t->right=NULL;
  2406.       Tfree(t);
  2407.       chain[0]=0;
  2408.       return u;
  2409.     };
  2410.   } else {
  2411.     MR_suppressK_client(suppressTree,suppressChain);
  2412.     if (suppressSucceeded) {
  2413.       Tree  *u=t->right;
  2414.       t->right=NULL;
  2415.       Tfree(t);
  2416.       chain[0]=0;
  2417.       return u;
  2418.     };
  2419.   };
  2420.   chain[0]=0;
  2421.   return t;
  2422. }
  2423. /* @@@ */
  2424. #ifdef __STDC__
  2425. Predicate * MR_suppressK(Node *j,Predicate *p)
  2426. #else
  2427. Predicate * MR_suppressK(j,p)
  2428.   Node          *j;
  2429.   Predicate     *p;
  2430. #endif
  2431. {
  2432.   Predicate     *result;
  2433.   int           guardPred=0;
  2434.   int           ampersandPred=0;
  2435.   Node          *nodePrime;
  2436.   if (! MRhoistingk) {
  2437.      return p;
  2438.   }
  2439.   if (! MRhoisting) return p;
  2440.   if (CLL_k == 1) return p;
  2441.   if (suppressChain == NULL) {
  2442.     suppressChain=(int *) calloc(CLL_k+2,sizeof(int));
  2443.     require (suppressChain != NULL,"MR_suppressK: can't allocate chain");
  2444.   }
  2445.   if (p == NULL) return NULL;
  2446.   if (j->ntype == nJunction) {
  2447.     nodePrime=(Node *) MR_junctionWithoutP2( (Junction *) j);
  2448.   } else {
  2449.     nodePrime=j;
  2450.   };
  2451.   p->down=MR_suppressK(j,p->down);
  2452.   p->right=MR_suppressK(j,p->right);
  2453.   if (p->down != NULL) {
  2454.     result=p;
  2455.     goto EXIT;
  2456.   };
  2457.   if (p->k == 1) {
  2458.     result=p;
  2459.     goto EXIT;
  2460.   };
  2461.   if (p->source != NULL) {
  2462.     if (p->source->guardpred != NULL) guardPred=1;
  2463.     if (p->source->ampersandPred != NULL) ampersandPred=1;
  2464.   }
  2465.   suppressPredicate=p;
  2466.   suppressNode=nodePrime;   /* was j*/
  2467.   suppressTree=p->tcontext;
  2468.   if (guardPred || ampersandPred) {
  2469.     p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);
  2470.     if (p->tcontext == NULL) {
  2471.       predicate_free(p);
  2472.       result=NULL;
  2473.       goto EXIT;
  2474.     };
  2475.   } else {
  2476.     if (MR_isChain(p->tcontext)) {
  2477.       p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);
  2478.       if (p->tcontext == NULL) {
  2479.         predicate_free(p);
  2480.         result=NULL;
  2481.         goto EXIT;
  2482.       };
  2483.     }
  2484.   }
  2485.   result=p;
  2486. EXIT:
  2487.   return result;
  2488. }
  2489. #ifdef __STDC__
  2490. void MR_suppressSearchReport()
  2491. #else
  2492. void MR_suppressSearchReport()
  2493. #endif
  2494. {
  2495.   int       i;
  2496.   Node      *p;
  2497.   TokNode   *tn;
  2498.   int       depth;
  2499.   set       setAnd;
  2500.   /* number of tokens in back trace stack matches length of chain */
  2501.   depth=0;
  2502.   for (i=0; i < MR_BackTraceStack.count ; i++) {
  2503.     p=(Node *) MR_BackTraceStack.data[i];
  2504.     if (p->ntype == nToken) depth++;
  2505.   };
  2506.   require (depth == suppressChainLength,"depth > suppressChainLength");
  2507.   /* token codes match chain */
  2508.   depth=0;
  2509.   for (i=0; i < MR_BackTraceStack.count ; i++) {
  2510.     p=(Node *) MR_BackTraceStack.data[i];
  2511.     if (p->ntype != nToken) continue;
  2512.     tn=(TokNode *) p;
  2513.     depth++;
  2514.     if (set_nil(tn->tset)) {
  2515.       require(set_el( (unsigned) tn->token,fset[depth]),
  2516.         "MR_suppressSearchReport: no match to #token in chain");
  2517.     } else {
  2518.       setAnd=set_and(fset[depth],tn->tset);
  2519.       require(!set_nil(setAnd),
  2520.         "MR_suppressSearchReport: no match to #token set in chain");
  2521.       set_free(setAnd);
  2522.     };
  2523.   };
  2524.   /* have a match - now remove it from the predicate */
  2525.   suppressSucceeded=1;
  2526.   if (suppressSucceeded) {
  2527.     fprintf(output,"n");
  2528.     fprintf(output,"#if 0n");
  2529.     fprintf(output,"n");
  2530.     fprintf(output,"Part (or all) of predicate with depth > 1 suppressed by ");
  2531.         fprintf(output,"alternative without predicatenn");
  2532.     MR_dumpPred(suppressPredicate,1);
  2533.     fprintf(output,"The token sequence which is suppressed:");
  2534.     fprintf(output," (");
  2535.     for (i=1; i <= suppressChainLength; i++) {
  2536.       fprintf(output," %s",TerminalString(suppressChain[i]));
  2537.     };
  2538.     fprintf(output," )n");
  2539.     fprintf(output,"The sequence of references which generate that sequence of tokens:nn");
  2540.     MR_backTraceDumpItemReset();
  2541.     for (i=0; i < MR_BackTraceStack.count ; i++) {
  2542.        MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);
  2543.     };
  2544.     fprintf(output,"n");
  2545.     fprintf(output,"#endifn");
  2546.   }
  2547. }
  2548. #ifdef __STDC__
  2549. void MR_markCompromisedRule(Node *n)
  2550. #else
  2551. void MR_markCompromisedRule(n)
  2552.   Node *n;
  2553. #endif
  2554. {
  2555.   RuleEntry     *q;
  2556.   Node          *mark=NULL;
  2557.   Junction      *j;
  2558.   if (n->ntype == nRuleRef) {
  2559.     mark=(Node *) MR_ruleReferenced( (RuleRefNode *) n);
  2560.   } else if (n->ntype == nToken) {
  2561.     mark=n;
  2562.   } else if (n->ntype == nJunction) {
  2563.     j=(Junction *)n;
  2564.     switch (j->jtype) {
  2565.       case aOptBlk:
  2566.       case aLoopBlk:
  2567.       case RuleBlk:
  2568.       case EndRule:
  2569.       case aPlusBlk:
  2570.       case aLoopBegin:
  2571.         mark=n;
  2572.         break;
  2573.       default:
  2574.         break;
  2575.     };
  2576.   }
  2577.   if (mark == NULL) return;
  2578.   require (RulePtr != NULL,"RulePtr not initialized");
  2579.   q = (RuleEntry *) hash_get(Rname,mark->rname);
  2580.   require (q != NULL,"RuleEntry not found");
  2581.   set_orel(q->rulenum,&MR_CompromisedRules);
  2582. }
  2583. void MR_alphaBetaTraceReport()
  2584. {
  2585.   int       i;
  2586.   if (! AlphaBetaTrace) return;
  2587.   MR_AlphaBetaMessageCount++;
  2588.   fprintf(output,"n");
  2589.   fprintf(output,"#if 0n");
  2590.   fprintf(output,"n");
  2591.   fprintf(output,"Trace of references leading to attempt to compute the follow set ofn");
  2592.   fprintf(output,"alpha in an "(alpha)? beta" block. It is not possible for antlr ton");
  2593.   fprintf(output,"compute this follow set because it is not known what part of beta hasn");
  2594.   fprintf(output,"already been matched by alpha and what part remains to be matched.n");
  2595.   fprintf(output,"n");
  2596.   fprintf(output,"Rules which make use of the incorrect follow set will also be incorrectn");
  2597.   fprintf(output,"n");
  2598.   MR_backTraceDumpItemReset();
  2599.   for (i=0; i < MR_BackTraceStack.count ; i++) {
  2600.      MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);
  2601.      if (i < MR_BackTraceStack.count-1) {
  2602.         MR_markCompromisedRule( (Node *) MR_BackTraceStack.data[i]);
  2603.      };
  2604.   };
  2605.   fprintf(output,"n");
  2606.   fprintf(output,"#endifn");
  2607. }
  2608. #ifdef __STDC__
  2609. void MR_dumpRuleSet(set s)
  2610. #else
  2611. void MR_dumpRuleSet(s)
  2612.   set   s;
  2613. #endif
  2614. {
  2615.     unsigned    *cursor;
  2616.     unsigned    *origin=set_pdq(s);
  2617.     require(origin != NULL,"set_pdq failed");
  2618.     if (RulePtr == NULL) {
  2619.       fprintf(stderr,"RulePtr[] not yet initialized");
  2620.     } else {
  2621.       for (cursor=origin; *cursor != nil ; cursor++) {
  2622. /****   if (cursor != origin) fprintf(stderr,","); ****/
  2623.         fprintf(stderr,"    %s",RulePtr[*cursor]->rname);
  2624.         fprintf(stderr,"n");
  2625.       };
  2626.       free( (char *) origin);
  2627.     };
  2628. }