fset.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 1,556 行 · 第 1/4 页
C
1,556 行
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 __USE_PROTOS
rAction( ActionNode *p, int k, set *rk )
#else
rAction( 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 __USE_PROTOS
dumpAmbigMsg( set *fset, FILE *f, int want_nls )
#else
dumpAmbigMsg( 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_PROTOS
verify_context(Predicate *predicate)
#else
verify_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_PROTOS
ensure_predicates_cover_ambiguous_lookahead_sequences
( Junction *alt1, Junction *alt2, char *sub, Tree *ambig )
#else
ensure_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 __USE_PROTOS
void MR_doPredicatesHelp(int inGuessBlock,Junction *alt1,Junction *alt2,int jtype,char *sub)
#else
void MR_doPredicatesHelp(inGuessBlock,alt1,alt2,jtype,sub)
int inGuessBlock;
Junction *alt1;
Junction *alt2;
int jtype;
char *sub;
#endif
{
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,
" are identical when compared without context and may have no\n",
" resolving power for some lookahead sequences.\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%s",
"the predicates used to disambiguate",
CurRule,
FileStr[alt1->file],
alt1->altnum,
alt1->line,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?