pred.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 822 行 · 第 1/2 页
C
822 行
else
{
ConstrainSearch = 0;
/* MR11 */ if (p->ampersandPred != NULL) {
/* MR11 */ TRAV(p,
/* MR11 */ pred->k,
/* MR11 */ &(pred->completionTree), t);
/* MR11 */ } else {
TRAV(p->next,
pred->k,
&(pred->completionTree), t);
};
pred->tcontext = t;
MR_check_pred_too_long(pred,pred->completionTree);
#ifdef DBG_PRED
fprintf(stderr, "LL(%d) context:", pred->k);
preorder(t);
fprintf(stderr, "\n");
#endif
}
}
else if ( HoistPredicateContext && pred->k == 1 )
{
pred->scontext[1] = empty;
/* MR30 No need to use first_item_is_guess_block_extra
since we know this is an action.
*/
if ( first_item_is_guess_block((Junction *)p->next) )
{
warnFL("cannot compute context of predicate in front of (..)? block",
FileStr[p->file], p->line);
}
else
{
REACH((Junction *)p->next,
1,
&(pred->completionSet),
pred->scontext[1]);
MR_check_pred_too_long(pred,pred->completionSet);
#ifdef DBG_PRED
fprintf(stderr, "LL(1) context:");
s_fprT(stderr, pred->scontext[1]);
fprintf(stderr, "\n");
#endif
}
}
}
{
Predicate *d = find_predicates(p->next);
Predicate *root;
/* Warning: Doesn't seem like the up pointers will all be set correctly;
* TJP: that's ok, we're not using them now.
*/
if ( d!=NULL )
{
root = new_pred();
root->expr = PRED_AND_LIST;
root->down = pred;
pred->right = d;
pred->up = root;
d->left = pred;
d->up = pred->up;
return root;
}
}
return pred;
}
return NULL;
}
case nRuleRef :
{
Predicate *a;
RuleRefNode *p = (RuleRefNode *) alt;
Junction *r;
Junction *save_MR_RuleBlkWithHalt;
RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
if ( q == NULL )
{
warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );
return NULL;
}
r = RulePtr[q->rulenum];
if ( r->pred_lock[1] )
{
/* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis
* must have seen it earlier.
*/
return NULL;
}
/* MR10 There should only be one halt set at a time. */
/* MR10 Life would have been easier with a global variable */
/* MR10 (at least for this particular need) */
/* MR10 Unset the old one and set the new one, later undo. */
require(r->end->halt == FALSE,"should only have one halt at a time");
/* MR10 */ require(MR_RuleBlkWithHalt == NULL ||
/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or does not have halt set");
/* MR10 */ if (MR_RuleBlkWithHalt != NULL) {
/* MR10 */ MR_RuleBlkWithHalt->end->halt=FALSE;
/* MR10 */ };
/*** fprintf(stderr,"\nSetting halt on junction #%d\n",r->end->seq); ***/
require(r->end->halt == FALSE,"rule->end->halt already set");
save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
/* MR10 */ MR_pointerStackPush(&MR_RuleBlkWithHaltStack,MR_RuleBlkWithHalt);
/* MR10 */ MR_pointerStackPush(&MR_PredRuleRefStack,p);
r->end->halt = TRUE;
/* MR10 */ MR_RuleBlkWithHalt=r;
a = find_predicates((Node *)r);
require(r->end->halt == TRUE,"rule->end->halt not set");
r->end->halt = FALSE;
/* MR10 */ MR_pointerStackPop(&MR_PredRuleRefStack);
/* MR10 */ MR_RuleBlkWithHalt=(Junction *) MR_pointerStackPop(&MR_RuleBlkWithHaltStack);
require (MR_RuleBlkWithHalt==save_MR_RuleBlkWithHalt,
"RuleBlkWithHaltStack not consistent");
/* MR10 */ require(MR_RuleBlkWithHalt == NULL ||
/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == FALSE),
/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or has no halt set");
/* MR10 */ if (MR_RuleBlkWithHalt != NULL) {
/* MR10 */ MR_RuleBlkWithHalt->end->halt=TRUE;
/* MR10 */ };
/*** fprintf(stderr,"\nRestoring halt on junction #%d\n",r->end->seq); ***/
if ( a==NULL ) return NULL;
/* attempt to compute the "local" FOLLOW just like in normal lookahead
* computation if needed
*/
complete_context_sets(p,a);
complete_context_trees(p,a);
/* MR10 */ MR_cleanup_pred_trees(a);
return a;
}
case nToken :
break;
}
return NULL;
}
#ifdef __USE_PROTOS
Predicate *MR_find_predicates_and_supp(Node *alt)
#else
Predicate *MR_find_predicates_and_supp(alt)
Node *alt;
#endif
{
Predicate *p;
p=find_predicates(alt);
p=MR_suppressK(alt,p);
return p;
}
Predicate *
#ifdef __USE_PROTOS
new_pred( void )
#else
new_pred( )
#endif
{
Predicate *p = (Predicate *) calloc(1,sizeof(Predicate)); /* MR10 */
require(p!=NULL, "new_pred: cannot alloc predicate");
p->scontext[0]=empty;
p->scontext[1]=empty;
p->completionTree=empty;
p->completionSet=empty;
p->plainSet=empty;
return p;
}
static void
#ifdef __USE_PROTOS
complete_context_sets( RuleRefNode *p, Predicate *a )
#else
complete_context_sets( p, a )
RuleRefNode *p;
Predicate *a;
#endif
{
set rk2, b;
int k2;
#ifdef DBG_PRED
fprintf(stderr, "enter complete_context_sets\n");
#endif
for (; a!=NULL; a=a->right)
{
if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
{
complete_context_sets(p,a->down);
continue;
}
rk2 = b = empty;
while ( !set_nil(a->completionSet) )
{
k2 = set_int(a->completionSet);
set_rm(k2, a->completionSet);
REACH(p->next, k2, &rk2, b);
set_orin(&(a->scontext[1]), b);
set_free(b);
}
set_orin(&(a->completionSet), rk2);/* remember what we couldn't do */
set_free(rk2);
#ifdef DBG_PRED
fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a);
s_fprT(stderr, a->scontext[1]);
fprintf(stderr, "\n");
#endif
/* complete_context_sets(p, a->down);*/
}
#ifdef DBG_PRED
fprintf(stderr, "exit complete_context_sets\n");
#endif
}
static void
#ifdef __USE_PROTOS
complete_context_trees( RuleRefNode *p, Predicate *a )
#else
complete_context_trees( p, a )
RuleRefNode *p;
Predicate *a;
#endif
{
set rk2;
int k2;
Tree *u;
#ifdef DBG_PRED
fprintf(stderr, "enter complete_context_trees\n");
#endif
for (; a!=NULL; a=a->right)
{
if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
{
complete_context_trees(p, a->down);
continue;
}
rk2 = empty;
/* any k left to do? if so, link onto tree */
while ( !set_nil(a->completionTree) )
{
k2 = set_int(a->completionTree);
set_rm(k2, a->completionTree);
u = NULL;
TRAV(p->next, k2, &rk2, u);
/* any subtrees missing k2 tokens, add u onto end */
a->tcontext = tlink(a->tcontext, u, k2);
Tfree(u); /* MR10 */
}
set_orin(&(a->completionTree), rk2);/* remember what we couldn't do */
set_free(rk2);
#ifdef DBG_PRED
fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k);
preorder(a->tcontext);
fprintf(stderr, "\n");
#endif
/* complete_context_trees(p, a->down);*/
}
#ifdef DBG_PRED
fprintf(stderr, "exit complete_context_trees\n");
#endif
}
/* Walk a list of predicates and return the set of all tokens in scontext[1]'s */
set
#ifdef __USE_PROTOS
covered_set( Predicate *p )
#else
covered_set( p )
Predicate *p;
#endif
{
set a;
a = empty;
for (; p!=NULL; p=p->right)
{
if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST )
{
set_orin(&a, covered_set(p->down));
continue;
}
set_orin(&a, p->scontext[1]);
set_orin(&a, covered_set(p->down));
}
return a;
}
/* MR10 predicate_free()
MR10 Don't free the leaf nodes since they are part of the action node
*/
#ifdef __USE_PROTOS
void predicate_free(Predicate *p)
#else
void predicate_free(p)
Predicate *p;
#endif
{
if (p == NULL) return;
predicate_free(p->right);
predicate_free(p->down);
if (p->cloned ||
p->source == NULL ||
p->source->guardpred == NULL ||
p->expr == PRED_AND_LIST ||
p->expr == PRED_OR_LIST) {
set_free(p->scontext[1]);
set_free(p->completionSet);
set_free(p->completionTree);
set_free(p->plainSet);
Tfree(p->tcontext);
free( (char *) p);
} else {
p->right=NULL;
p->down=NULL; /* MR13 *** debug */
};
}
/* MR10 predicate_dup() */
#ifdef __USE_PROTOS
Predicate * predicate_dup_xxx(Predicate *p,int contextToo)
#else
Predicate * predicate_dup_xxx(p,contextToo)
Predicate *p;
int contextToo;
#endif
{
Predicate *q;
if (p == NULL) return NULL;
q=new_pred();
q->down=predicate_dup(p->down);
q->right=predicate_dup(p->right);
/*
don't replicate expr - it is read-only
and address comparison is used to look
for identical predicates.
*/
q->expr=p->expr;
q->k=p->k;
q->source=p->source;
q->cloned=1;
q->ampersandStyle=p->ampersandStyle;
q->inverted=p->inverted;
q->predEntry=p->predEntry;
q->plainSet=set_dup(p->plainSet);
if (contextToo) {
q->tcontext=tdup(p->tcontext);
q->scontext[0]=set_dup(p->scontext[0]);
q->scontext[1]=set_dup(p->scontext[1]);
q->completionTree=set_dup(p->completionTree);
q->completionSet=set_dup(p->completionSet);
};
/* don't need to dup "redundant" */
return q;
}
#ifdef __USE_PROTOS
Predicate * predicate_dup_without_context(Predicate *p)
#else
Predicate * predicate_dup_without_context(p)
Predicate *p;
#endif
{
return predicate_dup_xxx(p,0);
}
#ifdef __USE_PROTOS
Predicate * predicate_dup(Predicate *p)
#else
Predicate * predicate_dup(p)
Predicate *p;
#endif
{
return predicate_dup_xxx(p,1);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?