📄 fset.c
字号:
#ifdef DBG_LL1 fprintf(stderr, "rToken: %s\n", (TokenString(p->token)!=NULL)?TokenString(p->token): ExprString(p->token));#endif if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); if (MR_AmbSourceSearch && (k-1) == 0) { set localConstrain; set intersection; localConstrain=fset[maxk-k+1]; if (! set_nil(p->tset)) { intersection=set_and(localConstrain,p->tset); if (! set_nil(intersection)) { MR_backTraceReport(); }; set_free(intersection); } else { if (set_el( (unsigned) p->token,localConstrain)) { MR_backTraceReport(); } }; }; if ( k-1 == 0 ) { if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); if ( !set_nil(p->tset) ) { return set_dup(p->tset); } else { return set_of(p->token); }; } REACH(p->next, k-1, rk, a); if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); return a;}set#ifdef __STDC__rAction( ActionNode *p, int k, set *rk )#elserAction( p, k, rk )ActionNode *p;int k;set *rk;#endif{ set a; require(p!=NULL, "rJunc: NULL node"); require(p->ntype==nAction, "rJunc: not action"); /* MR11 */ if (p->is_predicate && p->ampersandPred != NULL) {/* MR11 */ Predicate *pred=p->ampersandPred;/* MR11 */ if (k <= pred->k) {/* MR11 */ REACH(p->guardNodes,k,rk,a);/* MR11 */ return a;/* MR11 */ };/* MR11 */ }; /* it might be a good idea when doing an MR_AmbSourceSearch to *not* look behind predicates under some circumstances we'll look into that later */ REACH(p->next, k, rk, a); /* ignore actions */ return a;} /* A m b i g u i t y R e s o l u t i o n */void#ifdef __STDC__dumpAmbigMsg( set *fset, FILE *f, int want_nls )#elsedumpAmbigMsg( fset, f, want_nls )set *fset;FILE *f;int want_nls;#endif{ int i; set copy; /* MR11 */ if ( want_nls ) fprintf(f, "\n\t"); else fprintf(f, " "); for (i=1; i<=CLL_k; i++) { copy=set_dup(fset[i]); /* MR11 */ if ( i>1 ) { if ( !want_nls ) fprintf(f, ", "); } if ( set_deg(copy) > 3 && elevel == 1 ) { int e,m; fprintf(f, "{"); for (m=1; m<=3; m++) { e=set_int(copy); fprintf(f, " %s", TerminalString(e)); set_rm(e, copy); } fprintf(f, " ... }"); } else s_fprT(f, copy); if ( want_nls ) fprintf(f, "\n\t"); set_free(copy); } fprintf(f, "\n");}static void#ifdef __USE_PROTOSverify_context(Predicate *predicate)#elseverify_context(predicate)Predicate *predicate;#endif{ if ( predicate == NULL ) return; if ( predicate->expr == PRED_OR_LIST || predicate->expr == PRED_AND_LIST ) { verify_context(predicate->down); verify_context(predicate->right); /* MR10 */ return; } if ( !predicate->source->ctxwarned && predicate->source->guardpred==NULL && ((predicate->k > 1 && !is_single_tuple(predicate->tcontext)) || ( predicate->k == 1 && set_deg(predicate->scontext[1])>1 )) ) {/* MR9 Suppress annoying messages caused by our own clever(?) fix */ fprintf(stderr, ErrHdr, FileStr[predicate->source->file], predicate->source->line); fprintf(stderr, " warning: predicate applied for >1 lookahead %d-sequences\n", predicate->k); fprintf(stderr, ErrHdr, FileStr[predicate->source->file], predicate->source->line); fprintf(stderr, " predicate text: \"%s\"\n", (predicate->expr == NULL ? "(null)" : predicate->expr) ); fprintf(stderr, ErrHdr, FileStr[predicate->source->file], predicate->source->line); fprintf(stderr, " You may only want one lookahead %d-sequence to apply\n", predicate->k); fprintf(stderr, ErrHdr, FileStr[predicate->source->file], predicate->source->line); fprintf(stderr, " Try using a context guard '(...)? =>'\n"); predicate->source->ctxwarned = 1; } verify_context(predicate->right); /* MR10 */}/* * If delta is the set of ambiguous lookahead sequences, then make sure that * the predicate(s) for productions alt1,alt2 cover the sequences in delta. * * For example, * a : <<PRED1>>? (A B|A C) * | b * ; * b : <<PRED2>>? A B * | A C * ; * * This should give a warning that (A C) predicts both productions and alt2 * does not have a predicate in the production that generates (A C). * * The warning detection is simple. Let delta = LOOK(alt1) intersection LOOK(alt2). * Now, if ( delta set-difference context(predicates-for-alt1) != empty then * alt1 does not "cover" all ambiguous sequences. * * If ambig is nonempty, then ambig in LL(k) sense -> use tree info; else use fset * info. Actually, sets are used only if k=1 for this grammar. */static void#ifdef __USE_PROTOSensure_predicates_cover_ambiguous_lookahead_sequences ( Junction *alt1, Junction *alt2, char *sub, Tree *ambig )#elseensure_predicates_cover_ambiguous_lookahead_sequences( alt1, alt2, sub, ambig )Junction *alt1;Junction *alt2;char *sub;Tree *ambig;#endif{ if ( !ParseWithPredicates ) return; if ( ambig!=NULL ) { Tree *non_covered = NULL; if ( alt1->predicate!=NULL ) non_covered = tdif(ambig, alt1->predicate, alt1->fset, alt2->fset); if ( (non_covered!=NULL || alt1->predicate==NULL) && WarningLevel>1 ) { fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", alt1->altnum, sub); if ( alt1->predicate!=NULL && non_covered!=NULL ) { fprintf(stderr, " upon"); preorder(non_covered); } else if ( alt1->predicate==NULL ) { fprintf(stderr, " upon"); preorder(ambig->down); } fprintf(stderr, "\n"); } Tfree(non_covered); non_covered = NULL; if ( alt2->predicate!=NULL ) non_covered = tdif(ambig, alt2->predicate, alt1->fset, alt2->fset); if ( (non_covered!=NULL || alt2->predicate==NULL) && WarningLevel>1 ) { fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line); fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", alt2->altnum, sub); if ( alt2->predicate!=NULL && non_covered!=NULL ) { fprintf(stderr, " upon"); preorder(non_covered); } else if ( alt2->predicate==NULL ) { fprintf(stderr, " upon"); preorder(ambig->down); } fprintf(stderr, "\n"); } Tfree(non_covered); } else if ( !set_nil(alt1->fset[1]) ) { set delta, non_covered; delta = set_and(alt1->fset[1], alt2->fset[1]); non_covered = set_dif(delta, covered_set(alt1->predicate)); if ( set_deg(non_covered)>0 && WarningLevel>1 ) { fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", alt1->altnum, sub); if ( alt1->predicate!=NULL ) { fprintf(stderr, " upon "); s_fprT(stderr, non_covered); } fprintf(stderr, "\n"); } set_free( non_covered ); non_covered = set_dif(delta, covered_set(alt2->predicate)); if ( set_deg(non_covered)>0 && WarningLevel>1 ) { fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line); fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", alt2->altnum, sub); if ( alt2->predicate!=NULL ) { fprintf(stderr, " upon "); s_fprT(stderr, non_covered); } fprintf(stderr, "\n"); } set_free( non_covered ); set_free( delta ); } else fatal_internal("productions have no lookahead in predicate checking routine");}#ifdef __STDC__void MR_doPredicatesHelp(int inGuessBlock,Junction *alt1,Junction *alt2,int jtype,char *sub)#elsevoid MR_doPredicatesHelp(inGuessBlock,alt1,alt2,jtype,sub) int inGuessBlock; Junction *alt1; Junction *alt2; int jtype; char *sub;#endif{ int doMsg=0; Predicate *p1; Predicate *p2; Junction *parentRule=MR_nameToRuleBlk(alt1->rname); if (inGuessBlock && WarningLevel <= 1) return; /* let antlr give the usual error message */ if (alt1->predicate == NULL && alt2->predicate == NULL) return; if ( (jtype == RuleBlk || jtype == aSubBlk) && (alt1->predicate == NULL && alt2->predicate != NULL)) { fprintf(stderr, ErrHdr, FileStr[parentRule->file],parentRule->line); fprintf(stderr," warning: alt %d line %d and alt %d line %d of %s\n%s%s%s", alt1->altnum, alt1->line, alt2->altnum, alt2->line, sub, " These alts have ambig lookahead sequences resolved by a predicate for\n", " the second choice. The second choice may not be reachable.\n", " You may want to use a complementary predicate or rearrange the alts\n" ); return; }; /* first do the easy comparison. then do the hard one */ if (MR_comparePredicates(alt1->predicate,alt2->predicate)) { if (jtype == aLoopBegin || jtype == aPlusBlk ) { /* I'm not sure this code is reachable. Predicates following a (...)+ or (...)* block are probably considered validation predicates and therefore not participate in the predication expression */ fprintf(stderr, ErrHdr,FileStr[parentRule->file],parentRule->line); fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s", "the predicates used to disambiguate optional/exit paths of ", sub, CurRule, FileStr[alt1->file], alt1->altnum, alt1->line, alt2->altnum, alt2->line, " are identical and have no resolving power\n"); } else { fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s", "the predicates used to disambiguate", CurRule, FileStr[alt1->file], alt1->altnum, alt1->line, alt2->altnum, alt2->line, " are identical and have no resolving power\n"); }; } else { p1=predicate_dup_without_context(alt1->predicate); p1=MR_unfold(p1); MR_clearPredEntry(p1); MR_simplifyInverted(p1,0); p1=MR_predSimplifyALL(p1); p2=predicate_dup_without_context(alt2->predicate); p2=MR_unfold(p2); MR_clearPredEntry(p2); MR_simplifyInverted(p2,0); p2=MR_predSimplifyALL(p2); if (MR_comparePredicates(p1,p2)) { if (jtype == aLoopBegin || jtype == aPlusBlk ) { fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", "the predicates used to disambiguate optional/exit paths of ", sub, CurRule, FileStr[alt1->file], alt1->altnum, alt1->line, alt2->altnum, alt2->line,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -