mrhoist.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 2,360 行 · 第 1/5 页
C
2,360 行
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 unexpected\n");
};
for (b=big; b != NULL; b=b->right) {
bcount++;
require(b->token != EpToken,"MR_tree_equ: b->EpToken unexpected\n");
};
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 __USE_PROTOS
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 __USE_PROTOS
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 0\n\n");
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.\n\n");
fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]);
if (jPlain != NULL) {
fprintf(output," WITHOUT predicate: line %d %s\n",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:\n\n");
MR_dumpPred1(1,p,1);
fprintf(output,"Chain of referenced rules:\n\n");
MR_dumpPredRuleRefStack(output,4);
fprintf(output,"\n#endif\n");
};
}
#ifdef __USE_PROTOS
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 0\n\n");
fprintf(output,"Restricting the context of a predicate because of overlap in the lookahead set\n");
fprintf(output," between the alternative with the semantic predicate and one without\n");
fprintf(output,"Without this restriction the alternative without the predicate could not\n");
fprintf(output," be reached when input matched the context of the predicate and the predicate\n");
fprintf(output," was false.\n\n");
fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]);
if (jPlain != NULL) {
fprintf(output," WITHOUT predicate: line %d %s\n",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 sets\n");
intersect=set_and(predSet,plainSet);
MR_dumpTokenSet(output,1,intersect);
set_free(intersect);
};
fprintf(output,"\nThe original predicate:\n\n");
MR_dumpPred1(1,origPred,1);
fprintf(output,"The new (modified) form of the predicate:\n\n");
MR_dumpPred1(1,newPred,1);
fprintf(output,"#endif\n");
}
/* don't use Pass3 by itself unless you know that inverted is not important */
#ifdef __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
Predicate * MR_find_in_aSubBlk(Junction *alt)
#else
Predicate * MR_find_in_aSubBlk(alt)
Junction *alt;
#endif
{
Predicate *root=NULL;
Predicate **tail=NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?