fset2.c

来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 2,251 行 · 第 1/4 页

C
2,251
字号
			require(p->lock!=NULL, "rJunc: lock array is NULL");
			if ( p->lock[k] ) return NULL;
			p->lock[k] = TRUE;
		}

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
/* MR10 */    };

		TRAV(p->p1, k, rk, tail);

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
/* MR10 */    };

		if ( p->jtype==RuleBlk ) {p->lock[k] = FALSE; return tail;}
		r = tmake(tnode(ALT), tail, NULL);
		for (alt=(Junction *)p->p2; alt!=NULL; alt = (Junction *)alt->p2)
		{
			/* if this is one of the added optional alts for (...)+ then break */
			if ( alt->ignore ) break;

			if ( tail==NULL ) {TRAV(alt->p1, k, rk, tail); r->down = tail;}
			else
			{
/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
/* MR10 */    };

				TRAV(alt->p1, k, rk, tail->right);

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
/* MR10 */    };
				if ( tail->right != NULL ) tail = tail->right;
			}
		}
		if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) p->lock[k] = FALSE;
#ifdef DBG_TREES
		fprintf(stderr, "blk(%s) returns:",((Junction *)p)->rname); preorder(r); fprintf(stderr, "\n");
#endif
		if ( r->down == NULL ) {_Tfree(r); return NULL;}
		return r;
	}

	if ( p->jtype==EndRule )
	{
		if ( p->halt )						/* don't want FOLLOW here? */
		{
/****		if ( ContextGuardTRAV ) return NULL; ****/
			set_orel( (unsigned) k, rk);	/* indicate this k value needed */ /* MR10 cast */
			t = tnode(EpToken);
			t->v.rk = k;
			return t;
		}
		require(p->lock!=NULL, "rJunc: lock array is NULL");
		if ( p->lock[k] ) return NULL;
		/* if no FOLLOW assume k EOF's */
		if ( p->p1 == NULL ) return eofnode(k);
		p->lock[k] = TRUE;
	}

/* MR14 */	if (p->p1 != NULL && p->guess &&  p->guess_analysis_point == NULL) {
/* MR14 */    Node * guess_point;
/* MR14 */    guess_point=(Node *)analysis_point(p);
/* MR14 */    if (guess_point == (Node *)p) {
/* MR14 */      guess_point=p->p1;
/* MR14 */    }
/* MR14 */    p->guess_analysis_point=guess_point;
/* MR14 */  }	

	if ( p->p2 == NULL )
	{

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
/* MR10 */    };

/* M14 */        if (p->guess_analysis_point != NULL) {
/* M14 */ 		   TRAV(p->guess_analysis_point, k, rk,t);
/* M14 */        } else {
        		   TRAV(p->p1, k, rk,t);
/* M14 */        }

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
/* MR10 */    };

		if ( p->jtype==EndRule ) p->lock[k]=FALSE;
		return t;
	}

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
/* MR10 */    };

/* M14 */        if (p->guess_analysis_point != NULL) {
/* M14 */ 		   TRAV(p->guess_analysis_point, k, rk,t);
/* M14 */        } else {
        		   TRAV(p->p1, k, rk,t);
/* M14 */        }

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
/* MR10 */    };

	if ( p->jtype!=RuleBlk && /* MR14 */ !p->guess) TRAV(p->p2, k, rk, u);

	if ( p->jtype==EndRule ) p->lock[k] = FALSE;/* unlock node */

	if ( t==NULL ) return tmake(tnode(ALT), u, NULL);
	return tmake(tnode(ALT), t, u, NULL);
}

Tree *
#ifdef __USE_PROTOS
tRuleRef( RuleRefNode *p, int k, set *rk_out )
#else
tRuleRef( p, k, rk_out )
RuleRefNode *p;
int k;
set *rk_out;
#endif
{
	int k2;
	Tree *t=NULL, *u=NULL;
	Junction *r;
	set rk, rk2;
	int save_halt;
	RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
	
#ifdef DBG_TRAV
	fprintf(stderr, "tRuleRef: %s\n", p->text);
#endif
	if ( q == NULL )
	{
		TRAV(p->next, k, rk_out, t);/* ignore undefined rules */
		return t;
	}
	rk = rk2 = empty;
    if (RulePtr == NULL) fatal("RulePtr==NULL");
	r = RulePtr[q->rulenum];
	if ( r->lock[k] ) return NULL;
	save_halt = r->end->halt;
	r->end->halt = TRUE;		/* don't let reach fall off end of rule here */

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      MR_pointerStackPush(&MR_BackTraceStack,p);
/* MR10 */    };

	TRAV(r, k, &rk, t);

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      MR_pointerStackPop(&MR_BackTraceStack);
/* MR10 */    };

	r->end->halt = save_halt;
#ifdef DBG_TREES
	fprintf(stderr, "after ruleref, t is:"); preorder(t); fprintf(stderr, "\n");
#endif
	t = tshrink( t );
	while ( !set_nil(rk) ) {	/* any k left to do? if so, link onto tree */
		k2 = set_int(rk);
		set_rm(k2, rk);

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      MR_pointerStackPush(&MR_BackTraceStack,p);
/* MR10 */    };

		TRAV(p->next, k2, &rk2, u);

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      MR_pointerStackPop(&MR_BackTraceStack);
/* MR10 */    };

		t = tlink(t, u, k2);	/* any alts missing k2 toks, add u onto end */
        Tfree(u);               /* MR10 */
	}
	set_free(rk);				/* rk is empty, but free it's memory */
	set_orin(rk_out, rk2);		/* remember what we couldn't do */
	set_free(rk2);
	return t;
}

Tree *
#ifdef __USE_PROTOS
tToken( TokNode *p, int k, set *rk )
#else
tToken( p, k, rk )
TokNode *p;
int k;
set *rk;
#endif
{
	Tree *t=NULL, *tset=NULL, *u;

	if (ConstrainSearch) {
      if (MR_AmbSourceSearch) {
		require(constrain>=fset&&constrain<=&(fset[CLL_k]),"tToken: constrain is not a valid set");
      } else {
		require(constrain>=fset&&constrain<=&(fset[LL_k]),"tToken: constrain is not a valid set");
      };
      constrain = &fset[maxk-k+1];
	}

#ifdef DBG_TRAV
        	fprintf(stderr, "tToken(%d): %s\n", k, TerminalString(p->token));
        	if ( ConstrainSearch ) {
        		fprintf(stderr, "constrain is:"); s_fprT(stderr, *constrain); fprintf(stderr, "\n");
        	}
#endif

	/* is it a meta token (set of tokens)? */

	if ( !set_nil(p->tset) )
	{
		unsigned e=0;
		set a;
		Tree *n, *tail = NULL;

		if ( ConstrainSearch ) {
          a = set_and(p->tset, *constrain);
          if (set_nil(a)) {         /* MR10 */
            set_free(a);            /* MR11 */
            return NULL;            /* MR10 */
          };                        /* MR10 */
		} else {
          a = set_dup(p->tset);
        };

		for (; !set_nil(a); set_rm(e, a))
		{
			e = set_int(a);
			n = tnode(e);
			if ( tset==NULL ) { tset = n; tail = n; }
			else { tail->right = n; tail = n; }
		}
		set_free( a );
	}
	else if ( ConstrainSearch && !set_el(p->token, *constrain) )
    {
/*      fprintf(stderr, "ignoring token %s(%d)\n", TerminalString(p->token),
                k);*/
        return NULL;
    }
	else {
        tset = tnode( p->token );
    };

/* MR10 */    if (MR_MaintainBackTrace) {
/* MR10 */      if (k == 1) {
/* MR10 */        MR_pointerStackPush(&MR_BackTraceStack,p);
/* MR13 */        if (MR_SuppressSearch) {
/* MR13 */          MR_suppressSearchReport();
/* MR13 */        } else {
/* MR10 */          MR_backTraceReport();
/* MR13 */        };
/* MR10 */        MR_pointerStackPop(&MR_BackTraceStack);
/* MR11 */        Tfree(tset);
/* MR11 */        return NULL;
/* MR10 */      };
/* MR10 */    };

	if ( k == 1 ) return tset;

    if (MR_MaintainBackTrace) {
      MR_pointerStackPush(&MR_BackTraceStack,p);
    };

	TRAV(p->next, k-1, rk, t);

    if (MR_MaintainBackTrace) {
      Tfree(t);
      Tfree(tset);
      MR_pointerStackPop(&MR_BackTraceStack);
      return NULL;
    };

	/* here, we are positive that, at least, this tree will not contribute
	 * to the LL(2) tree since it will be too shallow, IF t==NULL.
	 * If doing a context guard walk, then don't prune.
	 */
	if ( t == NULL && !ContextGuardTRAV )	/* tree will be too shallow */
	{
		if ( tset!=NULL ) Tfree( tset );
		return NULL;
	}
#ifdef DBG_TREES
	fprintf(stderr, "tToken(%d)->next:",k); preorder(t); fprintf(stderr, "\n");
#endif

	/* if single token root, then just make new tree and return */
    /* MR10 - set_nil(p->tset) isn't a good test because of ConstraintSearch */

	if (tset->right == NULL) return tmake(tset, t, NULL);    /* MR10 */

	/* here we must make a copy of t as a child of each element of the tset;
	 * e.g., "T1..T3 A" would yield ( nil ( T1 A ) ( T2 A ) ( T3 A ) )
	 */
	for (u=tset; u!=NULL; u=u->right)
	{
		/* make a copy of t and hook it onto bottom of u */
		u->down = tdup(t);
	}
	Tfree( t );
#ifdef DBG_TREES
	fprintf(stderr, "range is:"); preorder(tset); fprintf(stderr, "\n");
#endif
	return tset;
}

Tree *
#ifdef __USE_PROTOS
tAction( ActionNode *p, int k, set *rk )
#else
tAction( p, k, rk )
ActionNode *p;
int k;
set *rk;
#endif
{
	Tree        *t=NULL;
    set         *save_fset=NULL;
    int         i;

	/* fprintf(stderr, "tAction\n"); */

/*  An MR_SuppressSearch is looking for things that can be
      reached even when the predicate is false.

    There are three kinds of predicates:
        plain:              r1: <<p>>? r2
        guarded:            r1: (A)? => <<p>>? r2
        ampersand style:    r1: (A)? && <<p>>? r2

    Of the three kinds of predicates, only a guard predicate
      has things which are reachable even when the predicate
      is false.  To be reachable the constraint must *not*
      match the guard.

*/

    if (p->is_predicate && MR_SuppressSearch) {

      Predicate     *pred=p->guardpred;

      if (pred == NULL) {
        t=NULL;
        goto EXIT;
      };
      constrain = &fset[maxk-k+1];
      if (pred->k == 1) {
        set     dif;
        dif=set_dif(*constrain,pred->scontext[1]);
        if (set_nil(dif)) {
          set_free(dif);
          t=NULL;
          goto EXIT;
        };
        set_free(dif);
      } else {
        if (MR_tree_matches_constraints(k,constrain,pred->tcontext)) {
          t=NULL;
          goto EXIT;
        };
      }
    };

    /* The ampersand predicate differs from the
         other predicates because its first set
         is a subset of the first set behind the predicate

            r1: (A)? && <<p>>? r2 ;
            r2: A | B;

       In this case first[1] of r1 is A, even
         though first[1] of r2 is {A B}.
    */

    if (p->is_predicate && p->ampersandPred != NULL) {

      Predicate     *pred=p->ampersandPred;
      Tree          *tAND;
      Tree          *tset;

      if (k <= pred->k) {
        if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);
        TRAV(p->guardNodes,k,rk,t);
        if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
        return t;
      } else {
        require (k>1,"tAction for ampersandpred: k <= 1");
        if (ConstrainSearch) {
          if (MR_AmbSourceSearch) {
    		require(constrain>=fset&&constrain<=&(fset[CLL_k]),
                                "tToken: constrain is not a valid set");
          } else {
    		require(constrain>=fset&&constrain<=&(fset[LL_k]),
                                "tToken: constrain is not a valid set");
          };
          save_fset=(set *) calloc (CLL_k+1,sizeof(set));
          require (save_fset != NULL,"tAction save_fset alloc");
          for (i=1; i <= CLL_k ; i++) {
            save_fset[i]=set_dup(fset[i]);
          };
          if (pred->k == 1) {
            constrain = &fset[maxk-k+1];
            set_andin(constrain,pred->scontext[1]);
            if (set_nil(*constrain)) {
              t=NULL;
              goto EXIT;
            };
          } else {
            constrain = &fset[maxk-k+1];
            if (! MR_tree_matches_constraints(pred->k,constrain,pred->tcontext)) {
               t=NULL;
               goto EXIT;
            };  /* end loop on i          */
          }; /* end loop on pred scontext/tcontext */
        }; /* end if on k > pred->k     */
      }; /* end if on constrain search  */

      TRAV(p->next,k,rk,t);

      if (t != NULL) {
        t=tshrink(t);
        t=tflatten(t);
        t=tleft_factor(t);
        if (pred->tcontext != NULL) {
          tAND=MR_computeTreeAND(t,pred->tcontext);
        } else {
          tset=MR_make_tree_from_set(pred->scontext[1]);
          tAND=MR_computeTreeAND(t,tset);
          Tfree(tset);
        };
        Tfree(t);
        t=tAND;
      };
      goto EXIT;

    }; /* end if on ampersand predicate */

    TRAV(p->next,k,rk,t);

EXIT:
    if (save_fset != NULL) {
      for (i=1 ; i <= CLL_k ; i++) {
        set_free(fset[i]);
        fset[i]=save_fset[i];
      };
      free ( (char *) save_fset);
    };
	return t;
}

/* see if e exists in s as a possible input permutation (e is always a chain) */

int
#ifdef __USE_PROTOS
tmember( Tree *e, Tree *s )
#else
tmember( e, s )
Tree *e;
Tree *s;
#endif
{
	if ( e==NULL||s==NULL ) return 0;
/** fprintf(stderr, "tmember(");
***	preorder(e); fprintf(stderr, ",");
***	preorder(s); fprintf(stderr, " )\n");
*/
	if ( s->token == ALT && s->right == NULL ) return tmember(e, s->down);
	if ( e->token!=s->token )
	{
		if ( s->right==NULL ) return 0;
		return tmember(e, s->right);
	}
	if ( e->down==NULL && s->down == NULL ) return 1;
	if ( tmember(e->down, s->down) ) return 1;
	if ( s->right==NULL ) return 0;
	return tmember(e, s->right);
}

/* see if e exists in s as a possible input permutation (e is always a chain);
 * Only check s to the depth of e.  In other words, 'e' can be a shorter
 * sequence than s.
 */
int
#ifdef __USE_PROTOS
tmember_constrained( Tree *e, Tree *s)
#else
tmember_constrained( e, s )
Tree *e;
Tree *s;
#endif
{
	if ( e==NULL||s==NULL ) return 0;
/**	fprintf(stderr, "tmember_constrained(");
***	preorder(e); fprintf(stderr, ",");
***	preorder(s); fprintf(stderr, " )\n");
**/
	if ( s->token == ALT && s->right == NULL )
		return tmember_constrained(e, s->down);
	if ( e->token!=s->token )
	{
		if ( s->right==NULL ) return 0;
		return tmember_constrained(e, s->right);
	}
	if ( e->down == NULL ) return 1; /* if s is matched to depth of e return */
	if ( tmember_constrained(e->down, s->down) ) return 1;
	if ( s->right==NULL ) return 0;
	return tmember_constrained(e, s->right);
}

/* combine (? (A t) ... (A u) ...) into (? (A t u)) */
Tree *
#ifdef __USE_PROTOS
tleft_factor( Tree *t )
#else
tleft_factor( t )
Tree *t;
#endif
{
	Tree *u, *v, *trail, *w;

	/* left-factor what is at this level */
	if ( t == NULL ) return NULL;
	for (u=t; u!=NULL; u=u->right)
	{
		trail = u;
		v=u->right;
		while ( v!=NULL )
		{
			if ( u->token == v->token )
			{
				if ( u->down!=NULL )
				{
					for (w=u->down; w->right!=NULL; w=w->right) {;}
					w->right = v->down;	/* link children together */
				}
				else u->down = v->down;
				trail->right = v->right;		/* unlink factored node */
				_Tfree( v );
				v = trail->right;
			}
			else {trail = v; v=v->right;}
		}
	}
	/* left-factor what is below */
	for (u=t; u!=NULL; u=u->right) u->down = tleft_factor( u->down );
	return t;
}

/* remove the permutation p from t if present */
Tree *
#ifdef __USE_PROTOS
trm_perm( Tree *t, Tree *p )
#else
trm_perm( t, p )
Tree *t;
Tree *p;
#endif
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?