mrhoist.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 2,360 行 · 第 1/5 页
C
2,360 行
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 0\n\n");
fprintf(output,"The following predicate expression will always be false:\n\n");
MR_dumpPred1(1,p,1);
fprintf(output,"\n#endif\n");
};
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
Predicate *MR_predSimplifyALL(Predicate *p)
#else
Predicate *MR_predSimplifyALL(p)
Predicate *p;
#endif
{
return MR_predSimplifyALLX(p,0);
}
#ifdef __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 __USE_PROTOS
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 unexpected\n");
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 __USE_PROTOS
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.
*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?