pred.c

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

C
822
字号
						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;
						/* MR30 No need to use first_item_is_guess_block_extra
						   since we know this is an action.
						*/
						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 __USE_PROTOS
Predicate *MR_find_predicates_and_supp(Node *alt)
#else
Predicate *MR_find_predicates_and_supp(alt)
  Node      *alt;
#endif
{
    Predicate   *p;

    p=find_predicates(alt);
    p=MR_suppressK(alt,p);
    return p;
}

Predicate *
#ifdef __USE_PROTOS
new_pred( void )
#else
new_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 __USE_PROTOS
complete_context_sets( RuleRefNode *p, Predicate *a )
#else
complete_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 __USE_PROTOS
complete_context_trees( RuleRefNode *p, Predicate *a )
#else
complete_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 __USE_PROTOS
covered_set( Predicate *p )
#else
covered_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 __USE_PROTOS
void predicate_free(Predicate *p)
#else
void 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 __USE_PROTOS
Predicate * predicate_dup_xxx(Predicate *p,int contextToo)
#else
Predicate * 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 __USE_PROTOS
Predicate * predicate_dup_without_context(Predicate *p)
#else
Predicate * predicate_dup_without_context(p)
  Predicate     *p;
#endif
{
  return predicate_dup_xxx(p,0);
}

#ifdef __USE_PROTOS
Predicate * predicate_dup(Predicate *p)
#else
Predicate * predicate_dup(p)
  Predicate     *p;
#endif
{
  return predicate_dup_xxx(p,1);
}

⌨️ 快捷键说明

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