mrhoist.c
资源名称:pccts133.zip [点击查看]
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:77k
源码类别:
编译器/解释器
开发平台:
Others
- /*
- * mrhoist.c
- *
- * SOFTWARE RIGHTS
- *
- * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
- * Set (PCCTS) -- PCCTS is in the public domain. An individual or
- * company may do whatever they wish with source code distributed with
- * PCCTS or the code generated by PCCTS, including the incorporation of
- * PCCTS, or its output, into commerical software.
- *
- * We encourage users to develop software with PCCTS. However, we do ask
- * that credit is given to us for developing PCCTS. By "credit",
- * we mean that if you incorporate our source code into one of your
- * programs (commercial product, research project, or otherwise) that you
- * acknowledge this fact somewhere in the documentation, research report,
- * etc... If you like PCCTS and have developed a nice tool with the
- * output, please mention that you developed it using PCCTS. In
- * addition, we ask that this header remain intact in our source code.
- * As long as these guidelines are kept, we expect to continue enhancing
- * this system and expect to make other tools available as they are
- * completed.
- *
- * ANTLR 1.33MR10
- *
- */
- #include <stdio.h>
- #ifdef __cplusplus
- #ifndef __STDC__
- #define __STDC__
- #endif
- #endif
- #include "set.h"
- #include "syn.h"
- #include "hash.h"
- #include "generic.h"
- #include "dlgdef.h"
- #include <ctype.h>
- #ifdef __STDC__
- void dumppred(Predicate *);
- #else
- void dumppred();
- #endif
- /*
- Try to determine whether predicate "first" is true for
- all cases where "second" is true. Comparison takes place
- without regard to context.
- Assumes that predicate symbols have been expanded.
- Assumes that there are no NAND or NOR nodes
- */
- #ifdef __STDC__
- int MR_secondPredicateUnreachable(Predicate *first,Predicate *second)
- #else
- int MR_secondPredicateUnreachable(first,second)
- Predicate *first;
- Predicate *second;
- #endif
- {
- Predicate *f;
- Predicate *s;
- if (first == NULL) {
- return 1;
- } else if (second == NULL) {
- return 0;
- } else if (first->down == NULL && second->down == NULL) {
- if (first->source == second->source &&
- first->inverted == second->inverted) {
- return 1; /* look identical - will never reach alt2 */
- } else {
- return 0; /* look different */
- };
- } else if (first->down == NULL && second->down != NULL) {
- if (second->expr == PRED_AND_LIST) {
- /* unreachable if first covers any child of second */
- for (s=second->down; s != NULL; s=s->right) {
- if (MR_secondPredicateUnreachable(first,s)) {
- return 1;
- };
- };
- return 0;
- } else if (second->expr == PRED_OR_LIST) {
- /* unreachable if first covers every child of second */
- for (s=second->down; s != NULL; s=s->right) {
- if (!MR_secondPredicateUnreachable(first,s)) {
- return 0;
- };
- };
- return 1;
- } else {
- require (0,"Illegal pred->expr");
- };
- } else if (first->down != NULL && second->down == NULL) {
- if (first->expr == PRED_AND_LIST) {
- /* unreachable if every child of first covers second */
- for (f=first->down; f != NULL; f=f->right) {
- if (!MR_secondPredicateUnreachable(f,second)) {
- return 0;
- };
- };
- return 1;
- } else if (first->expr == PRED_OR_LIST) {
- /* unreachable if any child of first covers second */
- for (f=first->down; f != NULL; f=f->right) {
- if (MR_secondPredicateUnreachable(f,second)) {
- return 1;
- };
- };
- return 0;
- } else {
- require (0,"Illegal predicate->expr");
- };
- } else {
- if (first->expr == PRED_AND_LIST && second->expr == PRED_AND_LIST) {
- /* unreachable if each child of first covers at least one child of second */
- for (f=first->down; f != NULL ; f=f->right) {
- for (s=second->down; s != NULL ; s=s->right) {
- if (MR_secondPredicateUnreachable(f,s)) goto A_next_f;
- };
- return 0;
- A_next_f:
- continue;
- };
- return 1;
- } else if (first->expr == PRED_AND_LIST && second->expr == PRED_OR_LIST) {
- /* unreachable if each child of first covers ALL of second's children */
- for (f=first->down; f != NULL ; f=f->right) {
- for (s=second->down; s != NULL ; s=s->right) {
- if (!MR_secondPredicateUnreachable(f,s)) return 0;
- };
- };
- return 1;
- } else if (first->expr == PRED_OR_LIST && second->expr == PRED_AND_LIST) {
- /* unreachable if any child of second is covered by any child of first */
- for (f=first->down; f != NULL ; f=f->right) {
- for (s=second->down; s != NULL ; s=s->right) {
- if (MR_secondPredicateUnreachable(f,s)) return 1;
- };
- };
- return 0;
- } else if (first->expr == PRED_OR_LIST && second->expr == PRED_OR_LIST) {
- /* unreachable if every child of second is covered by some child of first */
- for (f=first->down; f != NULL ; f=f->right) {
- for (s=second->down; s != NULL ; s=s->right) {
- if (MR_secondPredicateUnreachable(f,s)) goto B_next_f;
- };
- return 0;
- B_next_f:
- continue;
- };
- return 1;
- } else {
- require (0,"Illegal predicate->expr");
- };
- };
- }
- #ifdef __STDC__
- void MR_xxxIndent(FILE *f,int depth)
- #else
- void MR_xxxIndent(f,depth)
- FILE *f;
- int depth;
- #endif
- {
- int i;
- for (i=0; i<depth ; i++) {
- fprintf(f," ");
- };
- }
- #ifdef __STDC__
- void MR_stderrIndent(int depth)
- #else
- void MR_stderrIndent(depth)
- int depth;
- #endif
- {
- MR_xxxIndent(stderr,depth);
- }
- #ifdef __STDC__
- void MR_outputIndent(int depth)
- #else
- void MR_outputIndent(depth)
- int depth;
- #endif
- {
- MR_xxxIndent(output,depth);
- }
- #ifdef __STDC__
- void MR_set_reuse(set *s)
- #else
- void MR_set_reuse(s)
- set *s;
- #endif
- {
- set_free(*s);
- *s=empty;
- }
- #ifdef __STDC__
- void MR_dumpPredRuleRefStack(FILE *iounit,int indent)
- #else
- void MR_dumpPredRuleRefStack(iounit,indent)
- FILE *iounit;
- int indent;
- #endif
- {
- int i;
- int j;
- int count=MR_PredRuleRefStack.count;
- RuleRefNode *rrn=NULL;
- Junction *lastOne;
- if (count == 0) {
- fprintf(iounit,"emptyn");
- return;
- };
- for (i=0; i < count; i++) {
- rrn=(RuleRefNode *) MR_PredRuleRefStack.data[i];
- for (j=0; j<indent; j++) fprintf(iounit," ");
- fprintf(iounit,"#%-2d in rule %s (line %d %s) to rule %sn",
- i,rrn->rname,rrn->line,FileStr[rrn->file],rrn->text);
- };
- lastOne=MR_ruleReferenced(rrn);
- if (lastOne != NULL) {
- for (j=0; j<indent; j++) fprintf(iounit," ");
- fprintf(iounit,"#%-2d in rule %s (line %d %s)n",
- count,lastOne->rname,lastOne->line,FileStr[lastOne->file]);
- };
- }
- #ifdef __STDC__
- void MR_dumpTreeF(FILE *f,int depth,Tree *tree,int across)
- #else
- void MR_dumpTreeF(f,depth,tree,across)
- FILE *f;
- Tree *tree;
- int depth;
- int across;
- #endif
- {
- int newAcross=across;
- if (tree == NULL ) return;
- if (tree->down != NULL ) {
- fprintf(output,"n");
- MR_outputIndent(depth);
- fprintf(output, "(root =");
- };
- if (tree->token == ALT ) {
- fprintf(output," %-16s","Alt");
- } else if (tree->token==EpToken ) {
- fprintf(output,"(%d)%13s",tree->v.rk," ");
- } else {
- fprintf(output," %-16s",TerminalString(tree->token));
- };
- if (tree->down != NULL) {
- fprintf(output,"n");
- MR_outputIndent(depth+1);
- MR_dumpTreeF(f,depth+1,tree->down,1);
- newAcross=0;
- fprintf(output,"n");
- MR_outputIndent(depth);
- fprintf(output,")");
- };
- if (newAcross > 3) {
- fprintf(output,"n");
- MR_outputIndent(depth);
- newAcross=0;
- };
- MR_dumpTreeF(f,depth,tree->right,newAcross+1);
- }
- #ifdef __STDC__
- void MR_dumpTreeX(int depth,Tree *tree,int across)
- #else
- void MR_dumpTreeX(depth,tree,across)
- Tree *tree;
- int depth;
- int across;
- #endif
- {
- MR_dumpTreeF(output,depth,tree,across);
- }
- #ifdef __STDC__
- void MR_dumpTokenSet(FILE *f,int depth,set s)
- #else
- void MR_dumpTokenSet(f,depth,s)
- FILE *f;
- int depth;
- set s;
- #endif
- {
- int i;
- int j;
- unsigned *pdq;
- if (set_nil(s)) {
- fprintf(f,"n");
- MR_xxxIndent(f,depth+1);
- fprintf(f,"niln");
- return;
- };
- pdq=set_pdq(s);
- require(pdq != NULL,"set_pdq failed");
- i=0;
- for (i=0 ; ; i=i+4) {
- fprintf(f,"n");
- MR_xxxIndent(f,depth+1);
- for (j=0; j < 4 ; j++) {
- if (pdq[i+j] == nil) break;
- fprintf(f," %-16s",TerminalString(pdq[i+j]));
- };
- if (pdq[i+j] == nil) break;
- };
- fprintf(f,"n");
- free( (char *) pdq);
- }
- #ifdef __STDC__
- void MR_dumpPred1(int depth,Predicate *p,int withContext)
- #else
- void MR_dumpPred1(depth,p,withContext)
- int depth;
- Predicate *p;
- int withContext;
- #endif
- {
- unsigned k;
- if (p == NULL) {
- MR_outputIndent(depth);
- fprintf(output,"The predicate is empty (or always true)nn");
- return;
- };
- if (p->down != NULL) {
- MR_outputIndent(depth);
- if (p->inverted) {
- if (p->expr == PRED_AND_LIST) fprintf(output,"%s NAND (not AND) exprnn");
- if (p->expr == PRED_OR_LIST) fprintf(output,"%s NOR (not OR) exprnn");
- } else {
- fprintf(output,"%s exprnn",p->expr);
- };
- } else {
- MR_outputIndent(depth);
- fprintf(output,"pred %s <<%s>>?n",
- (p->inverted ? " *not*" : ""),
- (p->expr == NULL ? "null expr" : p->expr));
- MR_outputIndent(depth+1);
- fprintf(output," ");
- fprintf(output," depth=k=%d",p->k);
- if (p->source != NULL && p->source->guardpred) {
- fprintf(output," ("=>" guard)");
- }
- if (p->source != NULL && p->source->ampersandPred != NULL) {
- fprintf(output," ("&&" guard)");
- };
- k=set_int(p->completionSet);
- if (k != nil) {
- fprintf(output," Incomplete Set at k=%d !",k);
- };
- k=set_int(p->completionTree);
- if (k != nil) {
- fprintf(output," Incomplete Tree at k=%d !",k);
- };
- if (p->source != NULL) {
- fprintf(output," rule %s line %d %s",
- p->source->rname,p->source->line,FileStr[p->source->file]);
- };
- fprintf(output,"n");
- if (withContext &&
- (HoistPredicateContext ||
- ! set_nil(p->scontext[1]) ||
- p->tcontext != NULL)) {
- if (p->k == 1) {
- MR_outputIndent(depth+1);
- fprintf(output,"set context: ");
- MR_dumpTokenSet(output,depth+1,p->scontext[1]);
- }
- if (p->k != 1) {
- MR_outputIndent(depth+1);
- fprintf(output,"tree context:");
- if (p->tcontext == NULL) {
- fprintf(output," null");
- } else {
- MR_dumpTreeX(depth+2,p->tcontext,0);
- };
- fprintf(output,"n");
- };
- };
- fprintf(output,"n");
- };
- if (p->down != NULL) {
- MR_dumpPred1(depth+1,p->down,withContext);
- };
- if (p->right != NULL) {
- MR_dumpPred1(depth,p->right,withContext);
- };
- }
- #ifdef __STDC__
- void MR_dumpPred(Predicate *p,int withContext)
- #else
- void MR_dumpPred(p,withContext)
- Predicate *p;
- int withContext;
- #endif
- {
- MR_dumpPred1(0,p,withContext);
- }
- #ifdef __STDC__
- Tree * MR_make_tree_from_set(set s)
- #else
- Tree * MR_make_tree_from_set(s)
- set s;
- #endif
- {
- Tree *t=NULL;
- Tree *node;
- Tree **tp=&t;
- int i;
- unsigned *pdq=set_pdq(s);
- if (pdq != NULL) {
- for (i=0 ; pdq[i] != nil ; i++) {
- node=tnode( (int) pdq[i]);
- *tp=node;
- tp=&(node->right);
- };
- *tp=NULL;
- free ( (char *) pdq);
- };
- return t;
- }
- #ifdef __STDC__
- void MR_check_pred_too_long(Predicate *p,set completion)
- #else
- void MR_check_pred_too_long(p,completion)
- Predicate *p;
- set completion;
- #endif
- {
- if (p != NULL &&
- p->source != NULL &&
- ! p->source->predTooLong) {
- if ( !set_nil(completion)) {
- p->source->predTooLong=1;
- warnFL("It is unusual (but ok) for a semantic predicate to test context past the end of its own rule",
- FileStr[p->source->file],p->source->line);
- };
- };
- }
- #ifdef __STDC__
- int MR_predicate_context_completed(Predicate *p)
- #else
- int MR_predicate_context_completed(p)
- Predicate *p;
- #endif
- {
- if (p == NULL) return 1;
- if (p->expr != PRED_AND_LIST &&
- p->expr != PRED_OR_LIST) {
- if ( ! set_nil(p->completionSet)) return 0;
- if ( ! set_nil(p->completionTree)) return 0;
- };
- return MR_predicate_context_completed(p->down) &
- MR_predicate_context_completed(p->right);
- }
- #ifdef __STDC__
- Node * MR_advance(Node *n)
- #else
- Node * MR_advance(n)
- Node *n;
- #endif
- {
- if (n == NULL) return NULL;
- switch (n->ntype) {
- case nJunction: return ((Junction *)n)->p1;
- case nToken: return ((TokNode *)n)->next;
- case nRuleRef: return ((RuleRefNode *)n)->next;
- case nAction: return ((ActionNode *)n)->next;
- };
- }
- #ifdef __STDC__
- Junction * MR_find_endRule(Node *n)
- #else
- Junction * MR_find_endRule(n)
- Node *n;
- #endif
- {
- Node *next;
- if (n == NULL) return NULL;
- for (next=n; next != NULL; next=MR_advance(next)) {
- if (next->ntype == nJunction &&
- ( (Junction *) next)->jtype == EndRule) {
- break;
- };
- };
- return (Junction *)next;
- }
- /*
- Intersection: a branch which is shorter is chosen
- over one which is longer: (A B C) intersect (A B) yields (A B).
- AND: a branch which is longer is chosen over the one
- which is shorter: (A B C) AND (A B) yields (A B C)
- */
- #ifdef __STDC__
- Tree *MR_computeTreeIntersection(Tree *l,Tree *r)
- #else
- Tree *MR_computeTreeIntersection(l,r)
- Tree *l;
- Tree *r;
- #endif
- {
- Tree *result=NULL;
- Tree **tail;
- Tree *p;
- Tree *q;
- Tree *match;
- if (l == NULL || r == NULL) return NULL;
- for (p=l; p != NULL; p=p->right) {
- require(p->token != EpToken,"MR_computeTreeIntersection: p->EpToken unexpectedn");
- require (p->token != ALT,"MR_computeTreeIntersection: p->ALT unexpectedn");
- };
- for (q=r; q != NULL; q=q->right) {
- require(q->token != EpToken,"MR_computeTreeIntersection: q->EpToken unexpectedn");
- require(q->token != ALT,"MR_computeTreeIntersection: q->ALT unexpectedn");
- };
- result=tnode(ALT);
- tail=&(result->down);
- for (p=l; p != NULL ; p=p->right) {
- for (q=r; q != NULL ; q=q->right) {
- if (p->token == q->token) {
- match=tnode(p->token);
- match->down=MR_computeTreeIntersection(p->down,q->down);
- *tail=match;
- tail=&(match->right);
- };
- };
- };
- *tail=NULL;
- result=tshrink(result);
- result=tflatten( result );
- result=tleft_factor( result );
- return result;
- }
- /* the predicates which are ANDed together have a common
- context: they must all have common roots. Thus the
- AND operation is more like an OR operation because
- branches which are longer are grafted onto shorter
- branches of the AND tree. For instance combining
- (A B C) with (A B C D) gives (A B C D). There
- should never be a case of (A B C) and (A B D) because
- they have the same context.
- Actually, this may not be true once one throws in
- guard predicates which are defined by the user, not
- the context.
- */
- /* requires input trees to be in "canonical" format */
- #ifdef __STDC__
- Tree *MR_computeTreeAND(Tree *l,Tree *r)
- #else
- Tree *MR_computeTreeAND(l,r)
- Tree *l;
- Tree *r;
- #endif
- {
- Tree *result=NULL;
- Tree **tail;
- Tree *p;
- Tree *q;
- Tree *match;
- if (l == NULL) return tdup(r);
- if (r == NULL) return tdup(l);
- for (p=l; p != NULL; p=p->right) {
- /**** require(p->token != EpToken,"MR_computeTreeAND: p->EpToken unexpectedn"); ****/
- require (p->token != ALT,"MR_computeTreeAND: p->ALT unexpectedn");
- };
- for (q=r; q != NULL; q=q->right) {
- /**** require(q->token != EpToken,"MR_computeTreeAND: q->EpToken unexpectedn"); ****/
- require(q->token != ALT,"MR_computeTreeAND: q->ALT unexpectedn");
- };
- result=tnode(ALT);
- tail=&(result->down);
- for (p=l; p != NULL ; p=p->right) {
- for (q=r; q != NULL ; q=q->right) {
- if (p->token == q->token) {
- match=tnode(p->token);
- match->down=MR_computeTreeAND(p->down,q->down);
- *tail=match;
- tail=&(match->right);
- };
- };
- };
- *tail=NULL;
- result=tshrink(result);
- result=tflatten( result );
- result=tleft_factor( result );
- return result;
- }
- #ifdef __STDC__
- void MR_union_plain_sets1(Predicate *p,set *theUnion)
- #else
- void MR_union_plain_sets1(p,theUnion)
- Predicate *p;
- set *theUnion;
- #endif
- {
- if (p == NULL) return;
- MR_union_plain_sets1(p->down,theUnion);
- MR_union_plain_sets1(p->right,theUnion);
- set_orin(theUnion,p->plainSet);
- return;
- }
- #ifdef __STDC__
- set MR_union_plain_sets(Predicate *p)
- #else
- set MR_union_plain_sets(p)
- Predicate *p;
- #endif
- {
- set theUnion;
- theUnion=empty;
- MR_union_plain_sets1(p,&theUnion);
- return theUnion;
- }
- /* does NOT left factor: do not want to merge
- (A B) with (A) to get (A B)
- in fact the opposite: (A B) with (A) gives (A)
- */
- #ifdef __STDC__
- Tree *MR_compute_pred_tree_ctxXX(Predicate *p)
- #else
- Tree *MR_compute_pred_tree_ctxXX(p)
- Predicate *p;
- #endif
- {
- Tree *result=NULL;
- Predicate *q;
- Tree *t;
- if (p == NULL) return NULL;
- /* this appears strange: why do we OR the context
- of and AND predicate ? It is because of the way
- that predicates are evaluated: if the context is
- wrong then it's the same as if the predicate was
- true. That means that even when one leg of an
- AND has unmatched context, if the other leg has
- matched context and is true then the predicate
- succeeds. It's only when all the legs have unmatched
- context that this one can skip evaluation of the
- predicates.
- */
- if (p->expr == PRED_OR_LIST ||
- p->expr == PRED_AND_LIST) {
- for (q=p->down; q != NULL ; q=q->right) {
- t=MR_compute_pred_tree_ctxXX(q);
- result=tappend(result,t);
- t=NULL;
- };
- result=tshrink(result);
- result=tflatten( result );
- /* does NOT left factor: do not want to merge
- (A B) with (A) to get (A B)
- in fact the opposite: (A B) with (A) gives (A)
- */
- /**** result=tleft_factor( result ); ****/
- return result;
- };
- #if 0
- ** if (p->expr == PRED_AND_LIST) {
- **
- ** Predicate *l;
- ** Predicate *r;
- ** Tree *l1;
- ** Tree *r1;
- ** Tree *prevl1;
- **
- ** l=p->down;
- ** require (l->right != NULL,"MR_compute_pred_tree - AND has only one child");
- **
- **/* l1 and r1 should already be in "canonical" format */
- **
- ** l1=MR_compute_pred_tree(l);
- ** for (r=l->right; r != NULL; r=r->right) {
- ** r1=MR_compute_pred_tree(r);
- ** prevl1=l1;
- ** l1=MR_computeTreeAND(l1,r1);
- ** Tfree(r1);
- ** Tfree(prevl1);
- ** };
- **
- **/* result from computeTreeAND should be in "canonical" format */
- **
- ** result=l1;
- **
- **/* result of MR_computeTreeAND should be in "canonical" format */
- **
- ** return result;
- ** };
- #endif
- if (p->k == 1) {
- result=MR_make_tree_from_set(p->scontext[1]);
- } else {
- result=tdup(p->tcontext);
- result=MR_remove_epsilon_from_tree(result);
- result=tshrink(result);
- result=tflatten(result);
- result=tleft_factor(result);
- };
- return result;
- }
- #ifdef __STDC__
- void MR_pred_depth(Predicate *p,int *maxDepth)
- #else
- void MR_pred_depth(p,maxDepth)
- Predicate *p;
- int *maxDepth;
- #endif
- {
- if (p == NULL) return;
- if (p->expr != PRED_OR_LIST &&
- p->expr != PRED_AND_LIST) {
- if (p->k > *maxDepth) *maxDepth=p->k;
- };
- MR_pred_depth(p->down,maxDepth);
- MR_pred_depth(p->right,maxDepth);
- }
- /* this computes the OR of all the contexts */
- #ifdef __STDC__
- set MR_compute_pred_set(Predicate *p)
- #else
- set MR_compute_pred_set(p)
- Predicate *p;
- #endif
- {
- set result;
- Predicate *q;
- result=empty;
- if (p == NULL) return empty;
- if (p->expr == PRED_OR_LIST ||
- p->expr == PRED_AND_LIST) { /* yes, I do mean PRED_AND_LIST ! */
- /* remember: r1: (A)? => <<p>>? r2; */
- /* r2: (B)? => <<q>>? r3; */
- set t;
- t=empty;
- result=empty;
- for (q=p->down; q != NULL; q=q->right) {
- t=MR_compute_pred_set(q);
- set_orin(&result,t);
- set_free(t);
- };
- return result;
- } else if (p->k > 1) {
- return empty;
- } else {
- return set_dup(p->scontext[1]);
- };
- }
- #ifdef __STDC__
- set MR_First(int ck,Junction *j,set *incomplete)
- #else
- set MR_First(ck,j,incomplete)
- int ck;
- Junction *j;
- set *incomplete;
- #endif
- {
- Junction *p;
- set tokensUsed;
- tokensUsed=empty;
- require(j->ntype==nJunction, "MR_First: non junction passed");
- p = analysis_point((Junction *)j->p1);
- REACH(p,ck,incomplete,tokensUsed);
- return tokensUsed;
- }
- #ifdef __STDC__
- void MR_cleanup_pred_trees(Predicate *p)
- #else
- void MR_cleanup_pred_trees(p)
- Predicate *p;
- #endif
- {
- Tree *t;
- if (p == NULL) return;
- if (p->expr != PRED_OR_LIST &&
- p->expr != PRED_AND_LIST) {
- t=p->tcontext;
- t=tshrink(t);
- t=tflatten(t);
- t=tleft_factor(t);
- p->tcontext=t;
- };
- MR_cleanup_pred_trees(p->down);
- MR_cleanup_pred_trees(p->right);
- }
- /* does NOT return canonical tree */
- #ifdef __STDC__
- Tree * MR_remove_epsilon_from_tree(Tree *t)
- #else
- Tree * MR_remove_epsilon_from_tree(t)
- Tree *t;
- #endif
- {
- if (t == NULL) return NULL;
- /* I think ALT can be ignored as a special case */
- if (t->token != EpToken) {
- t->down=MR_remove_epsilon_from_tree(t->down);
- t->right=MR_remove_epsilon_from_tree(t->right);
- return t;
- } else {
- Tree *u;
- u=MR_remove_epsilon_from_tree(t->right);
- t->right=NULL;
- Tfree(t);
- return u;
- };
- }
- #ifdef __STDC__
- void MR_complete_set(int predDepth,set *tokensUsed,set *incomplete)
- #else
- void MR_complete_set(predDepth,tokensUsed,incomplete)
- int predDepth;
- set *tokensUsed;
- set *incomplete;
- #endif
- {
- int i;
- RuleRefNode *ruleRef;
- set rk2;
- set b;
- int k2;
- Junction *save_MR_RuleBlkWithHalt;
- if (set_int(*incomplete) > (unsigned) predDepth) {
- return;
- };
- require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,
- "RuleRefStack and RuleBlkWithHaltStack not same size");
- require(MR_RuleBlkWithHalt == NULL ||
- (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
- "RuleBlkWithHalt has no halt set");
- save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
- if (MR_RuleBlkWithHalt != NULL) {
- MR_RuleBlkWithHalt->end->halt=FALSE;
- };
- for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {
- ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];
- if (ruleRef == NULL) continue;
- MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];
- if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;
- rk2=empty;
- b=empty;
- while ( !set_nil(*incomplete) ) {
- k2=set_int(*incomplete);
- if (k2 > predDepth) break; /* <=== another exit from loop */
- set_rm(k2,*incomplete);
- REACH(ruleRef->next,k2,&rk2,b);
- set_orin(tokensUsed,b);
- set_free(b);
- };
- if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;
- set_orin(incomplete,rk2); /* remember what we couldn't do */
- set_free(rk2);
- if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */
- };
- MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;
- if (MR_RuleBlkWithHalt != NULL) {
- MR_RuleBlkWithHalt->end->halt=TRUE;
- };
- }
- #ifdef __STDC__
- void MR_complete_tree(int predDepth,Tree **t,set *incomplete)
- #else
- void MR_complete_tree(predDepth,t,incomplete)
- int predDepth;
- Tree **t;
- set *incomplete;
- #endif
- {
- int i;
- RuleRefNode *ruleRef;
- set rk2;
- Tree *u;
- unsigned k2;
- Junction *save_MR_RuleBlkWithHalt;
- int saveConstrainSearch;
- if (set_int(*incomplete) > (unsigned) predDepth) {
- return;
- };
- require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,
- "RuleRefStack and RuleBlkWithHaltStack not same size");
- require(MR_RuleBlkWithHalt == NULL ||
- (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
- "RuleBlkWithHalt has no halt set");
- save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
- saveConstrainSearch=ConstrainSearch;
- ConstrainSearch=0;
- if (MR_RuleBlkWithHalt != NULL) {
- MR_RuleBlkWithHalt->end->halt=FALSE;
- };
- for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {
- ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];
- if (ruleRef == NULL) continue;
- MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];
- if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;
- rk2=empty;
- while ( !set_nil(*incomplete) ) {
- k2 = set_int(*incomplete);
- if (k2 > (unsigned) predDepth) break; /* <=== another exit from loop */
- set_rm(k2,*incomplete);
- u = NULL;
- TRAV(ruleRef->next,k2,&rk2,u);
- /* any subtrees missing k2 tokens, add u onto end */
- *t=tlink(*t,u,k2);
- Tfree(u);
- }
- set_orin(incomplete,rk2); /* remember what we couldn't do */
- set_free(rk2);
- if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;
- if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */
- };
- MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;
- if (MR_RuleBlkWithHalt != NULL) {
- MR_RuleBlkWithHalt->end->halt=TRUE;
- };
- ConstrainSearch=saveConstrainSearch;
- }
- #ifdef __STDC__
- void MR_complete_predicates(int predDepth,Predicate *pred)
- #else
- void MR_complete_predicates(predDepth,pred)
- int predDepth;
- Predicate *pred;
- #endif
- {
- if (pred == NULL) return;
- if (pred->expr != PRED_AND_LIST &&
- pred->expr != PRED_OR_LIST) {
- MR_complete_set(predDepth,&(pred->scontext[1]),&(pred->completionSet));
- MR_complete_tree(predDepth,&(pred->tcontext),&(pred->completionTree));
- };
- MR_complete_predicates(predDepth,pred->down);
- MR_complete_predicates(predDepth,pred->right);
- }
- #ifdef __STDC__
- Junction * MR_junctionWithoutP2(Junction *j)
- #else
- Junction * MR_junctionWithoutP2(j)
- Junction *j;
- #endif
- {
- Junction *thisAlt;
- /* don't want to follow p2 to the next alternative of this rule */
- /* insert a generic node with null p2 if necessary */
- /* however FIRST requires a junction */
- thisAlt=j;
- if (thisAlt->p2 != NULL) {
- if (thisAlt->p1->ntype == nJunction) {
- thisAlt=(Junction *) thisAlt->p1;
- } else {
- thisAlt=newJunction();
- thisAlt->p1=j->p1;
- thisAlt->rname=j->rname;
- thisAlt->file=j->file;
- thisAlt->line=j->line;
- j->p1=(Node *)thisAlt;
- };
- };
- return thisAlt;
- }
- #ifdef __STDC__
- int MR_tree_equ(Tree *big, Tree *small) {
- #else
- int MR_tree_equ(big,small)
- Tree *big;
- Tree *small;
- {
- #endif
- Tree *b;
- Tree *s;
- int bcount=0;
- int scount=0;
- if (small == NULL && big == NULL) return 1;
- if (small == NULL) return 0;
- if (big == NULL) return 0;
- if (small->token == ALT) {
- require(small->right == NULL,
- "MR_tree_equ: small: ALT node has siblings");
- return MR_tree_equ(big,small->down);
- };
- if (big->token == ALT) {
- require(big->right == NULL,
- "MR_tree_equ: big: ALT node has siblings");
- return MR_tree_equ(big->down,small);
- };
- for (s=small; s != NULL; s=s->right) {
- scount++;
- require(s->token != EpToken,"MR_tree_equ: s->EpToken unexpectedn");
- };
- for (b=big; b != NULL; b=b->right) {
- bcount++;
- require(b->token != EpToken,"MR_tree_equ: b->EpToken unexpectedn");
- };
- if (bcount != scount) return 0;
- for (s=small; s != NULL; s=s->right) {
- for (b=big; b!= NULL; b=b->right) {
- if (s->token == b->token) {
- if (MR_tree_equ(b->down,s->down)) goto next_s;
- };
- };
- return 0;
- next_s:
- continue;
- };
- return 1;
- }
- /* this does not compare sources - only contexts ! */
- #ifdef __STDC__
- int MR_identicalContext(Predicate *p,Predicate *q)
- #else
- int MR_identicalContext(p,q)
- Predicate *p;
- Predicate *q;
- #endif
- {
- if (p->k != q->k) return 0;
- require ( (p->tcontext == NULL) == (q->tcontext == NULL),
- "tcontext inconsistent");
- if (p->k == 1) {
- return set_equ(p->scontext[1],q->scontext[1]);
- } else {
- return MR_tree_equ(p->tcontext,q->tcontext);
- };
- }
- #ifdef __STDC__
- void MR_reportSetSuppression(int predDepth,
- set predSet,set plainSet,Junction *jPred,Junction *jPlain,Predicate *p)
- #else
- void MR_reportSetSuppression(predDepth,predSet,plainSet,jPred,jPlain,p)
- int predDepth;
- set predSet;
- set plainSet;
- Junction *jPred;
- Junction *jPlain;
- Predicate *p;
- #endif
- {
- if (InfoP) {
- fprintf(output,"n#if 0nn");
- fprintf(output,"Hoisting of predicate suppressed by alternative without predicate.n");
- fprintf(output,"The alt without the predicate includes all cases where the predicate is false.nn");
- fprintf(output," WITH predicate: line %d %sn",jPred->line,FileStr[jPred->file]);
- if (jPlain != NULL) {
- fprintf(output," WITHOUT predicate: line %d %sn",jPlain->line,FileStr[jPlain->file]);
- } else {
- fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)n");
- };
- if (predDepth == 1) {
- fprintf(output,"nThe context set for the predicate:n");
- MR_dumpTokenSet(output,1,predSet);
- };
- fprintf(output,"nThe lookahead set for the alt WITHOUT the semantic predicate:n");
- MR_dumpTokenSet(output,1,plainSet);
- fprintf(output,"nThe predicate:nn");
- MR_dumpPred1(1,p,1);
- fprintf(output,"Chain of referenced rules:nn");
- MR_dumpPredRuleRefStack(output,4);
- fprintf(output,"n#endifn");
- };
- }
- #ifdef __STDC__
- void MR_reportSetRestriction(int predDepth,set predSet,set plainSet,
- Junction *jPred,Junction *jPlain,Predicate *origPred,Predicate *newPred)
- #else
- void MR_reportSetRestriction(predDepth,predSet,plainSet,jPred,jPlain,origPred,newPred)
- int predDepth;
- set predSet;
- set plainSet;
- Junction *jPred;
- Junction *jPlain;
- Predicate *origPred;
- Predicate *newPred;
- #endif
- {
- set intersect;
- intersect=empty;
- if (! InfoP) return;
- fprintf(output,"n#if 0nn");
- fprintf(output,"Restricting the context of a predicate because of overlap in the lookahead setn");
- fprintf(output," between the alternative with the semantic predicate and one withoutn");
- fprintf(output,"Without this restriction the alternative without the predicate could notn");
- fprintf(output," be reached when input matched the context of the predicate and the predicaten");
- fprintf(output," was false.nn");
- fprintf(output," WITH predicate: line %d %sn",jPred->line,FileStr[jPred->file]);
- if (jPlain != NULL) {
- fprintf(output," WITHOUT predicate: line %d %sn",jPlain->line,FileStr[jPlain->file]);
- } else {
- fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)n");
- };
- if (predDepth == 1) {
- fprintf(output,"nThe original context set for the predicate:n");
- MR_dumpTokenSet(output,1,predSet);
- };
- fprintf(output,"nThe lookahead set for the alt WITHOUT the semantic predicate:n");
- MR_dumpTokenSet(output,1,plainSet);
- if (predDepth == 1) {
- fprintf(output,"nThe intersection of the two setsn");
- intersect=set_and(predSet,plainSet);
- MR_dumpTokenSet(output,1,intersect);
- set_free(intersect);
- };
- fprintf(output,"nThe original predicate:nn");
- MR_dumpPred1(1,origPred,1);
- fprintf(output,"The new (modified) form of the predicate:nn");
- MR_dumpPred1(1,newPred,1);
- fprintf(output,"#endifn");
- }
- /* don't use Pass3 by itself unless you know that inverted is not important */
- #ifdef __STDC__
- Predicate * MR_removeRedundantPredPass3(Predicate *p)
- #else
- Predicate * MR_removeRedundantPredPass3(p)
- Predicate *p;
- #endif
- {
- Predicate *q;
- if (p == NULL) return NULL;
- p->right=MR_removeRedundantPredPass3(p->right);
- p->down=MR_removeRedundantPredPass3(p->down);
- if (p->redundant) {
- q=p->right;
- p->right=NULL;
- predicate_free(p);
- return q;
- };
- if (p->expr == PRED_AND_LIST ||
- p->expr == PRED_OR_LIST) {
- if (p->down == NULL) {
- q=p->right;
- p->right=NULL;
- predicate_free(p);
- return q;
- };
- if (p->down != NULL && p->down->right == NULL) {
- q=p->down;
- q->right=p->right;
- p->right=NULL;
- p->down=NULL;
- return q;
- };
- };
- return p;
- }
- #ifdef __STDC__
- void MR_removeRedundantPredPass2(Predicate *p)
- #else
- void MR_removeRedundantPredPass2(p)
- Predicate *p;
- #endif
- {
- Predicate *q;
- if (p == NULL) return;
- if (p->expr == PRED_AND_LIST) {
- for (q=p->down ; q != NULL ; q=q->right) {
- MR_removeRedundantPredPass2(q);
- if (q->isConst) {
- if (q->constValue == 0) {
- p->isConst=1;
- p->constValue=0;
- return;
- } else {
- q->redundant=1;
- };
- };
- };
- };
- if (p->expr == PRED_OR_LIST) {
- for (q=p->down ; q != NULL ; q=q->right) {
- MR_removeRedundantPredPass2(q);
- if (q->isConst) {
- if (q->constValue == 0) {
- q->redundant=1;
- } else {
- p->isConst=1;
- p->constValue=1;
- return;
- };
- };
- };
- };
- return;
- }
- #if 0
- this totally ignores the implications of guarded predicates
- in which the part after the guard could possibly cover a predicate.
- that would be much harder:
- rule : (A)? => <<p>>? sub1; /* 1 */
- | (B)? => <<r>>? sub2 /* 2 */
- sub1 : (A)? => <<q>>? A B /* 3 */
- | B /* 4 - suppresses line 2 */
- ;
- #endif
- #ifdef __STDC__
- void MR_apply_restriction1(Predicate *pred,set *plainSet,int *changed)
- #else
- void MR_apply_restriction1(pred,plainSet,changed)
- Predicate *pred;
- set *plainSet;
- int *changed;
- #endif
- {
- if (pred == NULL) return;
- MR_apply_restriction1(pred->right,plainSet,changed);
- if (pred->down != NULL) {
- MR_apply_restriction1(pred->down,plainSet,changed);
- } else {
- set t;
- if (pred->k == 1) {
- t=set_dif(pred->scontext[1],*plainSet);
- if (*changed == 0 &&
- !set_equ(t,pred->scontext[1])) {
- *changed=1;
- };
- if (set_nil(t)) {
- pred->redundant=1;
- };
- set_free(pred->scontext[1]);
- pred->scontext[1]=t;
- };
- };
- }
- #ifdef __STDC__
- void MR_orin_plainSet(Predicate *p,set plainSet)
- #else
- void MR_orin_plainSet(p,plainSet)
- Predicate *p;
- set plainSet;
- #endif
- {
- if (p == NULL) return;
- MR_orin_plainSet(p->down,plainSet);
- MR_orin_plainSet(p->right,plainSet);
- set_orin(&p->plainSet,plainSet);
- }
- Predicate *PRED_SUPPRESS;
- #ifdef __STDC__
- Predicate * MR_find_in_aSubBlk(Junction *alt)
- #else
- Predicate * MR_find_in_aSubBlk(alt)
- Junction *alt;
- #endif
- {
- Predicate *root=NULL;
- Predicate **tail=NULL;
- Junction *p;
- int nAlts=0;
- Junction **jList;
- Predicate **predList;
- int *matchList;
- set predSet;
- int i;
- int j;
- int m;
- int predDepth;
- set incomplete;
- set union_plainSet;
- set setChange;
- int changed;
- Predicate *newPred;
- set setDif;
- Predicate *origPred;
- int depth1=1; /* const int */
- set *plainContext;
- set plainSet;
- predSet=empty;
- incomplete=empty;
- union_plainSet=empty;
- setChange=empty;
- setDif=empty;
- plainSet=empty;
- if (PRED_SUPPRESS == NULL) {
- PRED_SUPPRESS=new_pred();
- PRED_SUPPRESS->expr="Predicate Suppressed";
- };
- /* this section just counts the number of "interesting" alternatives */
- /* in order to allocate arrays */
- for (p=alt; p!=NULL; p=(Junction *)p->p2) {
- /* ignore empty alts */
- if ( p->p1->ntype != nJunction ||
- ((Junction *)p->p1)->jtype != EndBlk ) {
- nAlts++;
- };
- };
- /* if this is a (...)+ block then don't count the last alt because
- it can't be taken until at least one time through the block.
- In other words it isn't a real choice until the (...)+ is entered
- at which point the hoisting issue is moot.
- Maybe look at "ignore" instead ?
- */
- if (alt->jtype == aPlusBlk) {
- nAlts--;
- };
- jList=(Junction **)calloc(nAlts,sizeof(Junction *));
- require(jList!=NULL,"cannot allocate MR_find_in_aSubBlk jList");
- plainContext=(set *)calloc(nAlts,sizeof(set));
- require(plainContext!=NULL,"cannot allocate MR_find_in_aSubBlk plainContext");
- for (m=0; m < nAlts; m++) plainContext[m]=empty;
- predList=(Predicate **)calloc(nAlts,sizeof(Predicate *));
- require(predList!=NULL,"cannot allocate MR_find_in_aSubBlk predList");
- matchList=(int *)calloc(nAlts,sizeof(int));
- require(matchList!=NULL,"cannot allocate MR_find_in_aSubBlk matchList");
- /* this section just fills in the arrays previously allocated */
- /* the most interesting one is matchList[] */
- /* */
- /* bit 0 => this alt has a semantic pred which is "covered" */
- /* by an alt without a semantic pred. Don't hoist. */
- for (i=0,p=alt;
- p!=NULL && i<nAlts;
- i++,p=(Junction *)p->p2) {
- /* ignore empty alts */
- if ( p->p1->ntype != nJunction ||
- ((Junction *)p->p1)->jtype != EndBlk ) {
- jList[i]=MR_junctionWithoutP2(p);
- predList[i]=find_predicates(p->p1); /* should be jList ????? */
- if (predList[i] != NULL) {
- MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */
- plainContext[i]=MR_union_plain_sets(predList[i]);
- } else {
- MR_set_reuse(&plainSet);
- MR_set_reuse(&incomplete);
- plainSet=MR_First(depth1,jList[i],&incomplete);
- MR_complete_set(depth1,&plainSet,&incomplete);
- require(set_nil(incomplete),"couldn't complete k=1");
- plainContext[i]=plainSet;
- plainSet=empty;
- };
- set_orin(&union_plainSet,plainContext[i]);
- };
- };
- if (nAlts == 1) {
- goto EXIT_SIMPLE;
- };
- /*
- * Looking for cases where alt i has a semantic pred and alt j does not.
- * Don't care about cases where lookahead for semantic predicates overlap
- * because normal predicate hoisting does the correct thing automatically.
- * Don't care about cases where lookahead for alts without semantic predicates
- * overlap because normal prediction does the correct thing automatically.
- *
- * When we find such a case check for one of three subcases:
- *
- * 1. if lookahead for alt i is contained in the lookahead for any
- * alt j then ignore semantic predicate of alt i
- * 2. if lookahead for alt i is not contained in the lookahead for
- * any alt j then add add predicate i to the OR list to be hoisted
- * 3. if lookahead for alt i overlaps the lookahead for some alt j then
- * add a dummy semantic predicate for alt j
- *
- * There is an implicit assumption that the context of all alternatives following
- * the rule being processed here are identical (but may vary from hoist to
- * hoist depending on the place where the rule was invoked that led to hoisting
- * these predicates. In othere words in the fragment:
- *
- * ( <<a>>? a1 a2 a3 | <<b>>? b1 b2 b3 )
- *
- * both a3 and b3 have the same follow sets because they are both at the end of
- * alternatives in the same block.
- */
- for (i=0; i < nAlts; i++) {
- if (jList[i] == NULL) continue;
- if (predList[i] == NULL) continue;
- /* if the predicate depth turns out to be one token only */
- /* then it is can be easily represented as a set and */
- /* compared to the junction set create by MR_First() */
- predDepth=0;
- MR_pred_depth(predList[i],&predDepth);
- require (predDepth >= 1,"MR_find_in_aSubBlk: pred depth < 1");
- require (predDepth <= CLL_k,"MR_find_in_aSubBlk: predDepth > CLL_k");
- /* complete predicates to predDepth
- If completed to depth=1 then the context would be incomplete.
- The context would be truncated and the predicate simplify routine
- would have incomplete information. It would lead to
- either false matches of failure to find true matches.
- */
- MR_complete_predicates(predDepth,predList[i]);
- if (predList[i] != NULL) {
- MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */
- };
- /* If the predicate depth is 1 then it is possible to suppress
- a predicate completely using a single plain alt. Check for suppression
- by a single plain alt first because it gives better messages. If that
- fails try the union of all the plain alts.
- */
- if (predDepth == 1) {
- MR_set_reuse(&predSet);
- predSet=MR_compute_pred_set(predList[i]); /* ignores k>1 predicates */
- for (j=0; j < nAlts; j++) {
- if (jList[j] == NULL) continue;
- if (j == i) continue;
- MR_set_reuse(&setDif);
- setDif=set_dif(predSet,plainContext[j]);
- if (set_nil(setDif)) {
- matchList[i] |= 1;
- MR_reportSetSuppression(predDepth,predSet,plainContext[j],jList[i],jList[j],predList[i]);
- predicate_free(predList[i]);
- predList[i]=PRED_SUPPRESS;
- goto next_i;
- };
- }; /* end loop on j */
- changed=0;
- /* predicate_dup is only to give good error messages */
- /* remember to do a predicate_free() */
- origPred=predicate_dup(predList[i]);
- MR_apply_restriction1(predList[i],&union_plainSet,&changed);
- if (changed) {
- /* don't use Pass3 by itself unless you know that inverted is not important */
- newPred=MR_removeRedundantPredPass3(predList[i]);
- newPred=MR_predSimplifyALL(newPred);
- if (newPred == NULL) {
- matchList[i] |= 1;
- MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],
- NULL,origPred);
- predList[i]=PRED_SUPPRESS;
- } else {
- MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],
- NULL,origPred,newPred);
- predList[i]=newPred;
- };
- };
- predicate_free(origPred);
- origPred=NULL;
- };
- /*
- If the predicate depth is > 1 then it can't be suppressed completely
- because the code doesn't support inspection of such things. They're
- much messier than k=1 sets.
- */
- if (predDepth > 1 ) {
- changed=0;
- /* predicate_dup is only to give good error messages */
- /* remember to do a predicate_free() */
- origPred=predicate_dup(predList[i]);
- MR_apply_restriction1(predList[i],&union_plainSet,&changed);
- if (changed) {
- newPred=MR_removeRedundantPredPass3(predList[i]);
- newPred=MR_predSimplifyALL(newPred);
- if (newPred == NULL) {
- matchList[i] |= 1;
- MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],
- NULL,origPred);
- predList[i]=PRED_SUPPRESS;
- } else {
- MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],
- NULL,origPred,newPred);
- predList[i]=newPred;
- };
- };
- predicate_free(origPred);
- origPred=NULL;
- };
- next_i:
- continue;
- };
- EXIT_SIMPLE:
- root = new_pred();
- root->expr=PRED_OR_LIST;
- tail = &(root->down);
- for (i=0 ; i< nAlts ; i++) {
- if (jList[i] == NULL) continue;
- if (predList[i] == NULL) {
- continue;
- } else if ( (matchList[i] & 1) != 0) {
- if (predList[i] != PRED_SUPPRESS) {
- predicate_free(predList[i]);
- };
- continue;
- };
- /* make an OR list of predicates */
- *tail=predList[i];
- tail=&(predList[i]->right);
- };
- /* if just one pred, remove OR root */
- if (root->down == NULL) {
- predicate_free(root);
- root=NULL;
- } else if (root->down->right == NULL) {
- Predicate *p=root->down;
- root->down=NULL;
- predicate_free(root);
- root=p;
- }
- root=MR_predSimplifyALL(root);
- MR_orin_plainSet(root,union_plainSet);
- set_free(predSet);
- set_free(union_plainSet);
- set_free(incomplete);
- set_free(setChange);
- set_free(setDif);
- for (m=0; m < nAlts; m++) set_free(plainContext[m]);
- free ( (char *) jList);
- free ( (char *) predList);
- free ( (char *) matchList);
- free ( (char *) plainContext);
- return root;
- }
- #ifdef __STDC__
- void MR_predContextPresent(Predicate *p,int *allHaveContext,int *noneHaveContext)
- #else
- void MR_predContextPresent(p,allHaveContext,noneHaveContext)
- Predicate *p;
- int *allHaveContext;
- int *noneHaveContext;
- #endif
- {
- if (p == NULL) return;
- MR_predContextPresent(p->right,allHaveContext,noneHaveContext);
- if (p->expr != PRED_AND_LIST &&
- p->expr != PRED_OR_LIST) {
- if (set_nil(p->scontext[1]) == 0 ||
- (p->tcontext != NULL)) {
- *noneHaveContext=0;
- } else {
- *allHaveContext=0;
- };
- };
- MR_predContextPresent(p->down,allHaveContext,noneHaveContext);
- }
- #ifdef __STDC__
- int MR_pointerStackPush(PointerStack *ps,void *dataPointer)
- #else
- int MR_pointerStackPush(ps,dataPointer)
- PointerStack *ps;
- void *dataPointer;
- #endif
- {
- void **newStack;
- int newSize;
- int i;
- if (ps->count == ps->size) {
- newSize=20+ps->size*2;
- newStack=(void **)calloc(newSize,sizeof(void *));
- require (newStack != NULL,"cannot allocate PointerStack");
- for (i=0; i < ps->size; i++) {
- newStack[i]=ps->data[i];
- };
- if (ps->data != NULL) free( (char *) ps->data);
- ps->data=newStack;
- ps->size=newSize;
- };
- ps->data[ps->count]=dataPointer;
- ps->count++;
- return ps->count-1;
- }
- #ifdef __STDC__
- void * MR_pointerStackPop(PointerStack *ps)
- #else
- void * MR_pointerStackPop(ps)
- PointerStack *ps;
- #endif
- {
- void *dataPointer;
- require(ps->count > 0,"MR_pointerStackPop underflow");
- dataPointer=ps->data[ps->count-1];
- ps->data[ps->count-1]=NULL;
- (ps->count)--;
- return dataPointer;
- }
- #ifdef __STDC__
- void * MR_pointerStackTop(PointerStack *ps)
- #else
- void * MR_pointerStackTop(ps)
- PointerStack *ps;
- #endif
- {
- require(ps->count > 0,"MR_pointerStackTop underflow");
- return ps->data[ps->count-1];
- }
- #ifdef __STDC__
- void MR_pointerStackReset(PointerStack *ps)
- #else
- void MR_pointerStackReset(ps)
- PointerStack *ps;
- #endif
- {
- int i;
- if (ps->data != NULL) {
- for (i=0; i < ps->count ; i++) {
- ps->data[i]=NULL;
- };
- };
- ps->count=0;
- }
- #ifdef __STDC__
- Junction *MR_nameToRuleBlk(char *name)
- #else
- Junction *MR_nameToRuleBlk(name)
- char *name;
- #endif
- {
- RuleEntry *q;
- require (RulePtr != NULL,"MR_nameToRule: RulePtr not initialized");
- if (name == NULL) return NULL;
- q = (RuleEntry *) hash_get(Rname,name);
- if ( q == NULL ) {
- return NULL;
- } else {
- return RulePtr[q->rulenum];
- };
- }
- #ifdef __STDC__
- Junction * MR_ruleReferenced(RuleRefNode *rrn)
- #else
- Junction * MR_ruleReferenced(rrn)
- RuleRefNode *rrn;
- #endif
- {
- return MR_nameToRuleBlk(rrn->text);
- }
- #ifdef __STDC__
- void MR_comparePredLeaves(Predicate *me,Predicate *myParent,Predicate *him,Predicate *hisParent)
- #else
- void MR_comparePredLeaves(me,myParent,him,hisParent)
- Predicate *me;
- Predicate *myParent;
- Predicate *him;
- Predicate *hisParent;
- #endif
- {
- if (me == NULL) return;
- if (me == him) {
- MR_comparePredLeaves(me->right,myParent,him,hisParent);
- return;
- } else if (me->expr == PRED_AND_LIST ||
- me->expr == PRED_OR_LIST) {
- MR_comparePredLeaves(me->down,me,him,hisParent);
- MR_comparePredLeaves(me->right,myParent,him,hisParent);
- return;
- } else {
- if (me->source != NULL) {
- /* predicate->invert can be set only in the predEntry predicates */
- /* thus they are only visible after the predEntry predicates have been "unfolded" */
- int sameSource=(me->source == him->source);
- int sameInvert=1 &
- (1 + me->inverted + him->inverted + me->source->inverted + him->source->inverted);
- int samePredEntry=(me->source->predEntry != NULL
- && him->source->predEntry != NULL
- && me->source->predEntry == him->source->predEntry);
- if (sameInvert && (sameSource || samePredEntry)) {
- if (MR_identicalContext(me,him)) {
- /* identical predicates */
- if (hisParent->expr == PRED_OR_LIST &&
- myParent->expr == PRED_OR_LIST) {
- me->redundant=1;
- } else if (hisParent->expr == PRED_AND_LIST &&
- myParent->expr == PRED_AND_LIST) {
- me->redundant=1;
- } else if ( (hisParent->expr == PRED_OR_LIST &&
- myParent->expr == PRED_AND_LIST)
- ||
- (hisParent->expr == PRED_AND_LIST &&
- myParent->expr == PRED_OR_LIST)
- ) {
- myParent->redundant=1;
- } else {
- require (0,"MR_comparePredLeaves: not both PRED_LIST");
- };
- };
- }; /* end same source or same predEntrr with same invert sense */
- /* same predEntry but opposite invert sense */
- if (!sameInvert && (sameSource || samePredEntry)) {
- if (MR_identicalContext(me,him)) {
- if (hisParent->expr == PRED_OR_LIST &&
- myParent->expr == PRED_OR_LIST) {
- myParent->isConst=1;
- myParent->constValue=1;
- } else if (hisParent->expr == PRED_AND_LIST &&
- myParent->expr == PRED_AND_LIST) {
- myParent->isConst=1;
- myParent->constValue=0;
- } else if ( (hisParent->expr == PRED_OR_LIST &&
- myParent->expr == PRED_AND_LIST)
- ||
- (hisParent->expr == PRED_AND_LIST &&
- myParent->expr == PRED_OR_LIST)
- ) {
- me->redundant=1;
- } else {
- require (0,"MR_comparePredLeaves: not both PRED_LIST");
- };
- };
- }; /* end same predEntry with opposite invert sense */
- };
- MR_comparePredLeaves(me->right,myParent,him,hisParent);
- return;
- };
- }
- #ifdef __STDC__
- void MR_removeRedundantPredPass1(Predicate *me,Predicate *myParent)
- #else
- void MR_removeRedundantPredPass1(me,myParent)
- Predicate *me;
- Predicate *myParent;
- #endif
- {
- if (me == NULL) return;
- if (me->redundant) {
- MR_removeRedundantPredPass1(me->right,myParent);
- return;
- };
- if (me->expr == PRED_AND_LIST ||
- me->expr == PRED_OR_LIST) {
- MR_removeRedundantPredPass1(me->down,me);
- MR_removeRedundantPredPass1(me->right,myParent);
- } else {
- require (me->source != NULL,"me->source == NULL");
- if (myParent != NULL) {
- MR_comparePredLeaves(myParent->down,myParent,me,myParent);
- };
- MR_removeRedundantPredPass1(me->right,myParent);
- };
- }
- /* pretty much ignores things with the inverted bit set */
- #ifdef __STDC__
- Predicate *MR_predFlatten(Predicate *p)
- #else
- Predicate *MR_predFlatten(p)
- Predicate *p;
- #endif
- {
- if (p == NULL) return NULL;
- if (p->expr == PRED_OR_LIST
- || p->expr == PRED_AND_LIST) {
- Predicate *child;
- Predicate *gchild;
- Predicate **tail;
- Predicate *next;
- char *PRED_XXX_LIST=p->expr;
- require (p->down != NULL,"MR_predFlatten AND/OR no child");
- p->down=MR_predFlatten(p->down);
- p->right=MR_predFlatten(p->right);
- child=p->down;
- if (child->right == NULL) {
- child->right=p->right;
- p->right=NULL;
- p->down=NULL;
- if (p->inverted) child->inverted=!child->inverted;
- predicate_free(p);
- return child;
- };
- /* make a single list of all children and grandchildren */
- tail=&(p->down);
- for (child=p->down; child != NULL; child=next) {
- if (child->expr != PRED_XXX_LIST
- || child->inverted
- || child->predEntry != NULL) {
- *tail=child;
- tail=&(child->right);
- next=child->right;
- } else {
- for (gchild=child->down;
- gchild != NULL;
- gchild=gchild->right) {
- *tail=gchild;
- tail=&(gchild->right);
- };
- next=child->right;
- child->right=NULL;
- child->down=NULL;
- predicate_free(child);
- };
- };
- *tail=NULL;
- return p;
- } else {
- p->right=MR_predFlatten(p->right);
- return p;
- };
- }
- static char *alwaysFalseWarning=NULL;
- #ifdef __STDC__
- Predicate *checkPredicateConflict(Predicate *p)
- #else
- Predicate *checkPredicateConflict(p)
- Predicate *p;
- #endif
- {
- if (p->isConst) {
- if (p->constValue == 1) {
- predicate_free(p);
- return NULL;
- } else {
- if (InfoP && !p->conflictReported) {
- p->conflictReported=1;
- fprintf(output,"n#if 0nn");
- fprintf(output,"The following predicate expression will always be false:nn");
- MR_dumpPred1(1,p,1);
- fprintf(output,"n#endifn");
- };
- if (alwaysFalseWarning != CurRule) {
- alwaysFalseWarning=CurRule;
- if (InfoP) {
- warnNoFL(eMsg1("one (or more) predicate expression hoisted into rule "%s" are always false
- - see output file for more information",CurRule));
- } else {
- warnNoFL(eMsg1("one (or more) predicate expressions hoisted into rule "%s" are always false
- - use "-info p" for more information",CurRule));
- };
- };
- };
- };
- return p;
- }
- #ifdef __STDC__
- int MR_countPredNodes(Predicate *p)
- #else
- int MR_countPredNodes(p)
- Predicate *p;
- #endif
- {
- if (p == NULL) return 0;
- return 1 + MR_countPredNodes(p->down) + MR_countPredNodes(p->right);
- }
- #ifdef __STDC__
- Predicate *MR_predSimplifyALLX(Predicate *p,int skipPass3)
- #else
- Predicate *MR_predSimplifyALLX(p,skipPass3)
- Predicate *p;
- int skipPass3;
- #endif
- {
- int countBefore;
- int countAfter;
- countAfter=MR_countPredNodes(p);
- do {
- if (p == NULL) return NULL;
- if (p->right == NULL && p->down == NULL) return p;
- countBefore=countAfter;
- MR_simplifyInverted(p,0);
- p=MR_predFlatten(p);
- MR_removeRedundantPredPass1(p,NULL);
- MR_removeRedundantPredPass2(p);
- if (! skipPass3) {
- p=checkPredicateConflict(p);
- p=MR_removeRedundantPredPass3(p);
- };
- countAfter=MR_countPredNodes(p);
- } while (countBefore != countAfter);
- return p;
- }
- #ifdef __STDC__
- Predicate *MR_predSimplifyALL(Predicate *p)
- #else
- Predicate *MR_predSimplifyALL(p)
- Predicate *p;
- #endif
- {
- return MR_predSimplifyALLX(p,0);
- }
- #ifdef __STDC__
- void MR_releaseResourcesUsedInRule(Node *n)
- #else
- void MR_releaseResourcesUsedInRule(n)
- Node *n;
- #endif
- {
- Node *next;
- Junction *j;
- int i;
- if (n == NULL) return;
- if (n->ntype == nJunction) {
- j=(Junction *) n;
- if (j->predicate != NULL) {
- predicate_free(j->predicate);
- j->predicate=NULL;
- };
- for (i=0; i< CLL_k; i++) {
- set_free(j->fset[i]);
- j->fset[i]=empty;
- };
- if (j->ftree != NULL) {
- Tfree(j->ftree);
- j->ftree=NULL;
- };
- if (j->jtype == EndRule) return;
- if (j->jtype != RuleBlk && j->jtype != EndBlk) {
- if (j->p2 != NULL && !j->ignore) { /* MR11 */
- MR_releaseResourcesUsedInRule(j->p2);
- };
- };
- };
- next=MR_advance(n);
- MR_releaseResourcesUsedInRule(next);
- }
- #ifdef __STDC__
- int MR_allPredLeaves(Predicate *p)
- #else
- int MR_allPredLeaves(p)
- Predicate *p;
- #endif
- {
- Predicate *q;
- if (p == NULL) return 1;
- for (q=p; q != NULL; q=q->right) {
- if (q->down != NULL) return 0;
- };
- return 1;
- }
- /* make sure it works for the last rule in a file */
- #ifdef __STDC__
- int MR_offsetFromRule(Node *n)
- #else
- int MR_offsetFromRule(n)
- Node *n;
- #endif
- {
- Junction *j;
- int offset=(-1);
- for (j=SynDiag; j != NULL; j=(Junction *)j->p2) {
- require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block");
- if (n->file < j->file) {
- return offset;
- };
- if (n->file == j->file) {
- if (n->line < j->line) {
- return (offset < 0) ? 0 : offset;
- } else {
- offset=n->line - j->line;
- if (offset == 0) return 0;
- };
- };
- };
- return offset;
- }
- #define ruleNameMax 50
- static char ruleNameStatic1[ruleNameMax];
- static char ruleNameStatic2[ruleNameMax+10];
- #ifdef __STDC__
- char * MR_ruleNamePlusOffset(Node *n)
- #else
- char * MR_ruleNamePlusOffset(n)
- Node *n;
- #endif
- {
- int offset=MR_offsetFromRule(n);
- strncpy(ruleNameStatic1,n->rname,ruleNameMax);
- if (offset < 0) {
- sprintf(ruleNameStatic2,"%s/?",ruleNameStatic1);
- } else {
- sprintf(ruleNameStatic2,"%s/%d",ruleNameStatic1,offset+1);
- };
- return ruleNameStatic2;
- }
- #ifdef __STDC__
- int MR_max_height_of_tree(Tree *t)
- #else
- int MR_max_height_of_tree(t)
- Tree *t;
- #endif
- {
- int h;
- int height=0;
- Tree *u;
- if (t == NULL) return 0;
- require (t->token != ALT && t->token != EpToken,"MR_max_height_of_tree ALT or EpToken");
- for (u=t; u != NULL; u=u->right) {
- h=MR_max_height_of_tree(u->down)+1;
- if (h > height) height=h;
- };
- return height;
- }
- #ifdef __STDC__
- int MR_all_leaves_same_height(Tree *t,int depth)
- #else
- int MR_all_leaves_same_height(t,depth)
- Tree *t;
- int depth;
- #endif
- {
- if (t == NULL) {
- return (depth==0);
- };
- require (t->token != ALT && t->token != EpToken,"MR_all_leaves_same_height ALT or EpToken");
- if (depth == 0) {
- return 0;
- } else {
- if ( ! MR_all_leaves_same_height(t->down,depth-1)) {
- return 0;
- };
- if (t->right == NULL) {
- return 1;
- } else {
- return MR_all_leaves_same_height(t->right,depth);
- };
- };
- }
- #ifdef __STDC__
- void MR_projectTreeOntoSet(Tree *tree,int ck,set *ckset)
- #else
- void MR_projectTreeOntoSet(tree,ck,ckset)
- Tree *tree;
- int ck;
- set *ckset;
- #endif
- {
- if (tree == NULL) return;
- require(tree->token != EpToken,"MR_projectTreeOntoSet: EpToken unexpectedn");
- MR_projectTreeOntoSet(tree->right,ck,ckset);
- if (tree->token == ALT) {
- MR_projectTreeOntoSet(tree->down,ck,ckset);
- } else {
- if (ck > 1) {
- MR_projectTreeOntoSet(tree->down,ck-1,ckset);
- } else {
- set_orel(tree->token,ckset);
- };
- };
- }
- #ifdef __STDC__
- int MR_comparePredicates(Predicate *a,Predicate *b)
- #else
- int MR_comparePredicates(a,b)
- Predicate *a;
- Predicate *b;
- #endif
- {
- Predicate *p;
- Predicate *q;
- if (a == b) return 1;
- if (a == NULL || b == NULL ) return 0;
- if (a->down == NULL && b->down == NULL) {
- /* predicate->invert can be set only in the predEntry predicates */
- /* thus they are only visible after the predEntry predicates have been "unfolded" */
- int sameSource=(a->source == b->source);
- int sameInvert= 1 & (1 +a->inverted + b->inverted +
- a->source->inverted + b->source->inverted);
- int samePredEntry=(a->source->predEntry != NULL
- && b->source->predEntry != NULL
- && a->source->predEntry == b->source->predEntry);
- if (sameInvert && (sameSource || samePredEntry)) {
- if (MR_identicalContext(a,b)) {
- return 1;
- };
- };
- return 0;
- };
- if (a->down == NULL || b->down == NULL) return 0;
- if (a->expr != b->expr) return 0;
- for (p=a->down; p != NULL; p=p->right) {
- for (q=b->down; q != NULL; q=q->right) {
- if (MR_comparePredicates(p,q)) goto NEXT_P;
- };
- return 0;
- NEXT_P:
- continue;
- };
- return 1;
- }
- /*
- * action->inverted can be set only when a predicate symbol appears in
- * a rule: "rule : <<!XXX>>? X". It cannot be set under any
- * other circumstances. In particular it cannot be set by
- * "#pred NotA !A" or by "#pred Nota <<!A>>?". The first case
- * creates a predEntry and the predicate expression of that predEntry
- * has inverted set. In the second case, the code for handling "!"
- * is only present in buildAction, which is not called by the #pred
- * semantic routines, only when a <<...>>? is recognized as part of
- * a rule definition.
- *
- * predicate->inverted can only be set by a predicate created by a #pred
- * expression, such as "#pred NotA !A" or "#pred NotXY ! (X && Y) or
- * "#pred XbarY !(X && Y)". In particular, it cannot be set by any
- * predicate expression occurring under any other circumstances.
- * The #pred predicate expresssions are stored with in predEntry->pred
- * and do not normally appear anywhere else until the predicates are
- * "unfolded" in order to recognize redundancies, conflicts, and
- * tautologies.
- *
- * The unfold routine expands all references to #pred expressions.
- *
- * The simplifyInvert goes through and propagates the invert bit so that
- * all OR and AND nodes are un-inverted.
- *
- * Note that !(A and B) => (!A or !B)
- * !(A or B) => (!A and !B)
- *
- * MR_unfold() is called to expand predicate symbols by replacing predicates
- * that reference predicate entries with the copies of the predicate entries.
- * Each reference receives a duplicate of the original. This is necessary
- * because the next phase involves simplification and removal of redundant
- * predicate nodes. Anyway, the point I'm making is that predicate->invert
- * should not be set in any predicate until it has been expanded.
- *
- * This is a recursive structure, but there is no need for "recursive expansion"
- * by which I mean a predicate symbol refers to other predicate symbols which
- * must also be expanded.
- *
- * Recursive expansion is *not* performed by this routine because it is not
- * necessary. Expansion of references is performed by predPrimary when
- * a new predicate symbol is created by referring to others in the pred expr.
- */
- #ifdef __STDC__
- Predicate *MR_unfold(Predicate *pred)
- #else
- Predicate *MR_unfold(pred)
- Predicate *pred;
- #endif
- {
- Predicate *result;
- if (pred == NULL) return NULL;
- pred->right=MR_unfold(pred->right);
- if (pred->down == NULL) {
- if (pred->source->predEntry != NULL) {
- if (pred->source->predEntry->pred == NULL) {
- ; /* do nothing */ /* a reference to a literal #pred (perhaps with "!" */
- } else {
- result=predicate_dup_without_context(pred->source->predEntry->pred);
- if (pred->inverted) {
- result->inverted=!result->inverted;
- };
- if (pred->source->inverted) {
- result->inverted=!result->inverted;
- };
- result->right=pred->right;
- pred->right=NULL;
- predicate_free(pred);
- /*** result=MR_unfold(result); *** not necessary */ /* recursive expansion */
- return result;
- };
- } else {
- ; /* do nothing */ /* an inline literal predicate */
- };
- } else {
- pred->down=MR_unfold(pred->down);
- };
- return pred;
- }
- /* this should be called immediately after MR_unfold() and
- at no other times
- */
- #ifdef __STDC__
- void MR_simplifyInverted(Predicate *pred,int inverted)
- #else
- void MR_simplifyInverted(pred,inverted)
- Predicate *pred;
- int inverted;
- #endif
- {
- int newInverted;
- if (pred == NULL) return;
- MR_simplifyInverted(pred->right,inverted);
- newInverted= 1 & (inverted + pred->inverted);
- if (pred->down == NULL) {
- pred->inverted=newInverted;
- } else {
- if (newInverted != 0) {
- if (pred->expr == PRED_AND_LIST) {
- pred->expr=PRED_OR_LIST;
- } else {
- pred->expr=PRED_AND_LIST;
- };
- };
- pred->inverted=0;
- MR_simplifyInverted(pred->down,newInverted);
- };
- }
- /* only remove it from AND and OR nodes, not leaves */
- #ifdef __STDC__
- void MR_clearPredEntry(Predicate *p)
- #else
- void MR_clearPredEntry(p)
- Predicate *p;
- #endif
- {
- if (p == NULL) return;
- MR_clearPredEntry(p->down);
- MR_clearPredEntry(p->right);
- if (p->down != NULL) p->predEntry=NULL;
- }
- #ifdef __STDC__
- void MR_orphanRules(FILE *f)
- #else
- void MR_orphanRules(f)
- FILE *f;
- #endif
- {
- set a;
- Junction *p;
- unsigned e;
- RuleEntry *re;
- a=empty;
- if (! InfoO) return;
- for (p=SynDiag; p!=NULL; p = (Junction *)p->p2) {
- if ( (Junction *) (p->end)->p1 == NULL) {
- re=(RuleEntry *) hash_get(Rname,p->rname);
- require (re != NULL,"RuleEntry == NULL");
- set_orel(re->rulenum, &a);
- }
- }
- if (set_deg(a) > 1) {
- fprintf(f,"note: Start rules: {");
- for (; !set_nil(a); set_rm(e,a)) {
- e=set_int(a);
- fprintf(f," %s",RulePtr[e]->rname);
- };
- fprintf(f," }n");
- };
- set_free( a );
- }
- /* merge (X Y) and (X) to create (X) */
- static int *mergeChain;
- static Tree *mergeTree;
- #ifdef __STDC__
- Tree *MR_merge_tree_contexts_client(Tree *t,int chain[])
- #else
- Tree *MR_merge_tree_contexts_client(t,chain)
- Tree *t;
- int chain[];
- #endif
- {
- if (t == NULL) return NULL;
- if (chain[0] == 0) {
- Tree *u=t->right;
- t->right=NULL;
- Tfree(t);
- return MR_merge_tree_contexts_client(u,&chain[0]);
- }
- if (chain[0] == t->token) {
- t->down=MR_merge_tree_contexts_client(t->down,&chain[1]);
- };
- t->right=MR_merge_tree_contexts_client(t->right,&chain[0]);
- return t;
- }
- #ifdef __STDC__
- void MR_iterateOverTreeContexts(Tree *t,int chain[])
- #else
- void MR_iterateOverTreeContexts(t,chain)
- Tree *t;
- int chain[];
- #endif
- {
- if (t == NULL) return;
- chain[0]=t->token;
- if (t->down != NULL) {
- MR_iterateOverTreeContexts(t->down,&chain[1]);
- } else {
- MR_merge_tree_contexts_client(mergeTree,mergeChain);
- };
- MR_iterateOverTreeContexts(t->right,&chain[0]);
- chain[0]=0;
- }
- #ifdef __STDC__
- Tree *MR_merge_tree_contexts(Tree *t)
- #else
- Tree *MR_merge_tree_contexts(t)
- Tree *t;
- #endif
- {
- int h=MR_max_height_of_tree(t);
- mergeTree=t;
- mergeChain=(int *) calloc(h+1,sizeof(int));
- require (mergeChain != NULL,"MR_merge_tree_contexts: can't alloc chain");
- MR_iterateOverTreeContexts(t,mergeChain);
- t=tshrink(t);
- t=tflatten(t);
- t=tleft_factor(t);
- free ( (char *) mergeChain);
- mergeChain=NULL;
- return t;
- }
- #ifdef __STDC__
- Tree *MR_compute_pred_tree_context(Predicate *p)
- #else
- Tree *MR_compute_pred_tree_context(p)
- Predicate *p;
- #endif
- {
- Tree *t;
- t=MR_compute_pred_tree_ctxXX(p);
- MR_merge_tree_contexts(t);
- return t;
- }
- #ifdef __STDC__
- void MR_guardPred_plainSet(ActionNode *anode,Predicate *pred)
- #else
- void MR_guardPred_plainSet(anode,pred)
- ActionNode *anode;
- Predicate *pred;
- #endif
- {
- Junction *j;
- Predicate *workPred;
- set maskSet;
- maskSet=empty;
- if (!MRhoisting) return;
- /* it doesn't really matter whether the predicate has
- depth k=1 or k>1 because we're not really looking
- at the predicate itself, just the stuff "behind"
- the predicate.
- */
- /* shouldn't have to worry about REACHing off the end
- of the rule containing the predicate because the
- Rule->end->halt should have been set already by the
- the code which handles RuleRef nodes.
- We don't want to REACH off the end of the rule because
- this would give the "global" follow context rather than
- the "local" context.
- r1a : (A)? => <<p>>? r2 (A|B)
- r1b : (A)? => <<p>>? r2 (A|C)
- r2 : ();
- For r1a we want follow of predicate = {A B}
- we want plainSet = {B}
- For r1b we want follow of predicate = {A C}
- we want plainSet = {C}
- */
- require (anode->next->ntype == nJunction,"MR_guardpred_plainSet not Junction");
- j=(Junction *)(anode->next);
- workPred=predicate_dup_without_context(pred);
- workPred->k=1;
- workPred->scontext[1]=MR_First(1,j, &(workPred->completionSet) );
- MR_complete_predicates(1,workPred);
- if (pred->k == 1) {
- maskSet=pred->scontext[1];
- } else {
- MR_projectTreeOntoSet(pred->tcontext,1,&maskSet);
- }
- pred->plainSet=set_dif(workPred->scontext[1],maskSet);
- predicate_free(workPred);
- }
- /*******************************************************************************/
- static Tree * suppressTree;
- static int * suppressChain; /* element 0 not used */
- static set * suppressSets;
- static Node * suppressNode;
- static int suppressChainLength;
- int MR_SuppressSearch=0;
- static int suppressSucceeded;
- static Predicate * suppressPredicate;
- #ifdef __STDC__
- int MR_isChain(Tree *t)
- #else
- int MR_isChain(t)
- Tree *t;
- #endif
- {
- Tree *u;
- for (u=t; u != NULL; u=u->down) {
- if (u->right != NULL) return 0;
- }
- return 1;
- }
- #ifdef __STDC__
- int MR_suppressK_client(Tree *tree,int tokensInChain[])
- #else
- int MR_suppressK_client(tree,tokensInChain)
- Tree *tree;
- int tokensInChain[];
- #endif
- {
- int i;
- set *save_fset;
- int save_ConstrainSearch;
- set incomplete;
- Tree *t;
- suppressSucceeded=0; /* volatile */
- if (suppressSets == NULL) {
- suppressSets=(set *) calloc (CLL_k+1,sizeof(set));
- require (suppressSets != NULL,"MR_suppressK_client: suppressSets alloc");
- };
- for (suppressChainLength=1;
- tokensInChain[suppressChainLength+1] != 0;
- suppressChainLength++) {};
- require (suppressChainLength != 0,"MR_suppressK_client: chain empty");
- for (i=1 ; i <= suppressChainLength ; i++) {
- set_clr(suppressSets[i]);
- set_orel( (unsigned) tokensInChain[i],
- &suppressSets[i]);
- };
- save_fset=fset;
- save_ConstrainSearch=ConstrainSearch;
- fset=suppressSets;
- MR_SuppressSearch=1;
- MR_AmbSourceSearch=1;
- MR_MaintainBackTrace=1;
- ConstrainSearch=1;
- maxk = suppressChainLength;
- incomplete=empty;
- t=NULL;
- /*** constrain = &(fset[1]); ***/
- MR_pointerStackReset(&MR_BackTraceStack);
- TRAV(suppressNode,maxk,&incomplete,t);
- Tfree(t);
- require (set_nil(incomplete),"MR_suppressK_client TRAV incomplete");
- require (MR_BackTraceStack.count == 0,
- "MR_suppressK_client: MR_BackTraceStack.count != 0");
- set_free(incomplete);
- ConstrainSearch=save_ConstrainSearch;
- fset=save_fset;
- MR_AmbSourceSearch=0;
- MR_MaintainBackTrace=0;
- MR_SuppressSearch=0;
- return suppressSucceeded;
- }
- #ifdef __STDC__
- Tree * MR_iterateOverTreeSuppressK(Tree *t,int chain[])
- #else
- Tree * MR_iterateOverTreeSuppressK(t,chain)
- Tree *t;
- int chain[];
- #endif
- {
- if (t == NULL) return NULL;
- t->right=MR_iterateOverTreeSuppressK(t->right,&chain[0]);
- chain[0]=t->token;
- if (t->down != NULL) {
- t->down=MR_iterateOverTreeSuppressK(t->down,&chain[1]);
- if (t->down == NULL) {
- Tree *u=t->right;
- t->right=NULL;
- Tfree(t);
- chain[0]=0;
- return u;
- };
- } else {
- MR_suppressK_client(suppressTree,suppressChain);
- if (suppressSucceeded) {
- Tree *u=t->right;
- t->right=NULL;
- Tfree(t);
- chain[0]=0;
- return u;
- };
- };
- chain[0]=0;
- return t;
- }
- /* @@@ */
- #ifdef __STDC__
- Predicate * MR_suppressK(Node *j,Predicate *p)
- #else
- Predicate * MR_suppressK(j,p)
- Node *j;
- Predicate *p;
- #endif
- {
- Predicate *result;
- int guardPred=0;
- int ampersandPred=0;
- Node *nodePrime;
- if (! MRhoistingk) {
- return p;
- }
- if (! MRhoisting) return p;
- if (CLL_k == 1) return p;
- if (suppressChain == NULL) {
- suppressChain=(int *) calloc(CLL_k+2,sizeof(int));
- require (suppressChain != NULL,"MR_suppressK: can't allocate chain");
- }
- if (p == NULL) return NULL;
- if (j->ntype == nJunction) {
- nodePrime=(Node *) MR_junctionWithoutP2( (Junction *) j);
- } else {
- nodePrime=j;
- };
- p->down=MR_suppressK(j,p->down);
- p->right=MR_suppressK(j,p->right);
- if (p->down != NULL) {
- result=p;
- goto EXIT;
- };
- if (p->k == 1) {
- result=p;
- goto EXIT;
- };
- if (p->source != NULL) {
- if (p->source->guardpred != NULL) guardPred=1;
- if (p->source->ampersandPred != NULL) ampersandPred=1;
- }
- suppressPredicate=p;
- suppressNode=nodePrime; /* was j*/
- suppressTree=p->tcontext;
- if (guardPred || ampersandPred) {
- p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);
- if (p->tcontext == NULL) {
- predicate_free(p);
- result=NULL;
- goto EXIT;
- };
- } else {
- if (MR_isChain(p->tcontext)) {
- p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);
- if (p->tcontext == NULL) {
- predicate_free(p);
- result=NULL;
- goto EXIT;
- };
- }
- }
- result=p;
- EXIT:
- return result;
- }
- #ifdef __STDC__
- void MR_suppressSearchReport()
- #else
- void MR_suppressSearchReport()
- #endif
- {
- int i;
- Node *p;
- TokNode *tn;
- int depth;
- set setAnd;
- /* number of tokens in back trace stack matches length of chain */
- depth=0;
- for (i=0; i < MR_BackTraceStack.count ; i++) {
- p=(Node *) MR_BackTraceStack.data[i];
- if (p->ntype == nToken) depth++;
- };
- require (depth == suppressChainLength,"depth > suppressChainLength");
- /* token codes match chain */
- depth=0;
- for (i=0; i < MR_BackTraceStack.count ; i++) {
- p=(Node *) MR_BackTraceStack.data[i];
- if (p->ntype != nToken) continue;
- tn=(TokNode *) p;
- depth++;
- if (set_nil(tn->tset)) {
- require(set_el( (unsigned) tn->token,fset[depth]),
- "MR_suppressSearchReport: no match to #token in chain");
- } else {
- setAnd=set_and(fset[depth],tn->tset);
- require(!set_nil(setAnd),
- "MR_suppressSearchReport: no match to #token set in chain");
- set_free(setAnd);
- };
- };
- /* have a match - now remove it from the predicate */
- suppressSucceeded=1;
- if (suppressSucceeded) {
- fprintf(output,"n");
- fprintf(output,"#if 0n");
- fprintf(output,"n");
- fprintf(output,"Part (or all) of predicate with depth > 1 suppressed by ");
- fprintf(output,"alternative without predicatenn");
- MR_dumpPred(suppressPredicate,1);
- fprintf(output,"The token sequence which is suppressed:");
- fprintf(output," (");
- for (i=1; i <= suppressChainLength; i++) {
- fprintf(output," %s",TerminalString(suppressChain[i]));
- };
- fprintf(output," )n");
- fprintf(output,"The sequence of references which generate that sequence of tokens:nn");
- MR_backTraceDumpItemReset();
- for (i=0; i < MR_BackTraceStack.count ; i++) {
- MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);
- };
- fprintf(output,"n");
- fprintf(output,"#endifn");
- }
- }
- #ifdef __STDC__
- void MR_markCompromisedRule(Node *n)
- #else
- void MR_markCompromisedRule(n)
- Node *n;
- #endif
- {
- RuleEntry *q;
- Node *mark=NULL;
- Junction *j;
- if (n->ntype == nRuleRef) {
- mark=(Node *) MR_ruleReferenced( (RuleRefNode *) n);
- } else if (n->ntype == nToken) {
- mark=n;
- } else if (n->ntype == nJunction) {
- j=(Junction *)n;
- switch (j->jtype) {
- case aOptBlk:
- case aLoopBlk:
- case RuleBlk:
- case EndRule:
- case aPlusBlk:
- case aLoopBegin:
- mark=n;
- break;
- default:
- break;
- };
- }
- if (mark == NULL) return;
- require (RulePtr != NULL,"RulePtr not initialized");
- q = (RuleEntry *) hash_get(Rname,mark->rname);
- require (q != NULL,"RuleEntry not found");
- set_orel(q->rulenum,&MR_CompromisedRules);
- }
- void MR_alphaBetaTraceReport()
- {
- int i;
- if (! AlphaBetaTrace) return;
- MR_AlphaBetaMessageCount++;
- fprintf(output,"n");
- fprintf(output,"#if 0n");
- fprintf(output,"n");
- fprintf(output,"Trace of references leading to attempt to compute the follow set ofn");
- fprintf(output,"alpha in an "(alpha)? beta" block. It is not possible for antlr ton");
- fprintf(output,"compute this follow set because it is not known what part of beta hasn");
- fprintf(output,"already been matched by alpha and what part remains to be matched.n");
- fprintf(output,"n");
- fprintf(output,"Rules which make use of the incorrect follow set will also be incorrectn");
- fprintf(output,"n");
- MR_backTraceDumpItemReset();
- for (i=0; i < MR_BackTraceStack.count ; i++) {
- MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);
- if (i < MR_BackTraceStack.count-1) {
- MR_markCompromisedRule( (Node *) MR_BackTraceStack.data[i]);
- };
- };
- fprintf(output,"n");
- fprintf(output,"#endifn");
- }
- #ifdef __STDC__
- void MR_dumpRuleSet(set s)
- #else
- void MR_dumpRuleSet(s)
- set s;
- #endif
- {
- unsigned *cursor;
- unsigned *origin=set_pdq(s);
- require(origin != NULL,"set_pdq failed");
- if (RulePtr == NULL) {
- fprintf(stderr,"RulePtr[] not yet initialized");
- } else {
- for (cursor=origin; *cursor != nil ; cursor++) {
- /**** if (cursor != origin) fprintf(stderr,","); ****/
- fprintf(stderr," %s",RulePtr[*cursor]->rname);
- fprintf(stderr,"n");
- };
- free( (char *) origin);
- };
- }