📄 pred.c
字号:
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; 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 __STDC__Predicate *MR_find_predicates_and_supp(Node *alt)#elsePredicate *MR_find_predicates_and_supp(alt) Node *alt;#endif{ Predicate *p; p=find_predicates(alt); p=MR_suppressK(alt,p); return p;}Predicate *#ifdef __STDC__new_pred( void )#elsenew_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 __STDC__complete_context_sets( RuleRefNode *p, Predicate *a )#elsecomplete_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 __STDC__complete_context_trees( RuleRefNode *p, Predicate *a )#elsecomplete_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 __STDC__covered_set( Predicate *p )#elsecovered_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 __STDC__void predicate_free(Predicate *p)#elsevoid 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 __STDC__Predicate * predicate_dup_xxx(Predicate *p,int contextToo)#elsePredicate * 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 __STDC__Predicate * predicate_dup_without_context(Predicate *p)#elsePredicate * predicate_dup_without_context(p) Predicate *p;#endif{ return predicate_dup_xxx(p,0);}#ifdef __STDC__Predicate * predicate_dup(Predicate *p)#elsePredicate * predicate_dup(p) Predicate *p;#endif{ return predicate_dup_xxx(p,1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -