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 + -
显示快捷键?