⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fset2.c

📁 本工具提供一个词法分析器和语法分析器的集成开发环境
💻 C
📖 第 1 页 / 共 4 页
字号:
/* remove the permutation p from t if present */Tree *#ifdef __STDC__trm_perm( Tree *t, Tree *p )#elsetrm_perm( t, p )Tree *t;Tree *p;#endif{	/*	fprintf(stderr, "trm_perm(");	preorder(t); fprintf(stderr, ",");	preorder(p); fprintf(stderr, " )\n");	*/	if ( t == NULL || p == NULL ) return NULL;	if ( t->token == ALT )	{		t->down = trm_perm(t->down, p);		if ( t->down == NULL ) 				/* nothing left below, rm cur node */		{			Tree *u = t->right;			_Tfree( t );			return trm_perm(u, p);		}		t->right = trm_perm(t->right, p);	/* look for more instances of p */		return t;	}	if ( p->token != t->token )				/* not found, try a sibling */	{		t->right = trm_perm(t->right, p);		return t;	}	t->down = trm_perm(t->down, p->down);	if ( t->down == NULL ) 					/* nothing left below, rm cur node */	{		Tree *u = t->right;		_Tfree( t );		return trm_perm(u, p);	}	t->right = trm_perm(t->right, p);		/* look for more instances of p */	return t;}/* add the permutation 'perm' to the LL_k sets in 'fset' */void#ifdef __STDC__tcvt( set *fset, Tree *perm )#elsetcvt( fset, perm )set *fset;Tree *perm;#endif{	if ( perm==NULL ) return;	set_orel(perm->token, fset);	tcvt(fset+1, perm->down);}/* for each element of ftbl[k], make it the root of a tree with permute(ftbl[k+1]) * as a child. */Tree *#ifdef __STDC__permute( int k, int max_k )#elsepermute( k, max_k )int k, max_k;#endif{	Tree *t, *u;		if ( k>max_k ) return NULL;	if ( ftbl[k][findex[k]] == nil ) return NULL;	t = permute(k+1, max_k);	if ( t==NULL&&k<max_k )		/* no permutation left below for k+1 tokens? */	{		findex[k+1] = 0;		(findex[k])++;			/* try next token at this k */		return permute(k, max_k);	}		u = tmake(tnode(ftbl[k][findex[k]]), t, NULL);	if ( k == max_k ) (findex[k])++;	return u;}/* Compute LL(k) trees for alts alt1 and alt2 of p. * function result is tree of ambiguous input permutations * * ALGORITHM may change to look for something other than LL_k size * trees ==> maxk will have to change. */Tree *#ifdef __STDC__VerifyAmbig( Junction *alt1, Junction *alt2, unsigned **ft, set *fs, Tree **t, Tree **u, int *numAmbig )#elseVerifyAmbig( alt1, alt2, ft, fs, t, u, numAmbig )Junction *alt1;Junction *alt2;unsigned **ft;set *fs;Tree **t;Tree **u;int *numAmbig;#endif{	set rk;	Tree *perm, *ambig=NULL;	Junction *p;	int k;    int    tnodes_at_start=TnodesAllocated;    int    tnodes_at_end;    int    tnodes_used;    set    *save_fs;    int    j;    save_fs=(set *) calloc(CLL_k+1,sizeof(set));    require(save_fs != NULL,"save_fs calloc");    for (j=0; j <= CLL_k ; j++) save_fs[j]=set_dup(fs[j]);	maxk = LL_k;				/* NOTE: for now, we look for LL_k */	ftbl = ft;	fset = fs;	constrain = &(fset[1]);	findex = (int *) calloc(LL_k+1, sizeof(int));	if ( findex == NULL )	{		fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);		fprintf(stderr, " out of memory while analyzing alts %d and %d of %s\n",						CurAmbigAlt1,						CurAmbigAlt2,						CurAmbigbtype);		exit(PCCTS_EXIT_FAILURE);	}	for (k=1; k<=LL_k; k++) findex[k] = 0;	rk = empty;	ConstrainSearch = 1;	/* consider only tokens in ambig sets */	p = analysis_point((Junction *)alt1->p1);	TRAV(p, LL_k, &rk, *t);	*t = tshrink( *t );	*t = tflatten( *t );	*t = tleft_factor( *t );    /* MR10 */	*t = prune(*t, LL_k);	*t = tleft_factor( *t );/***	fprintf(stderr, "after shrink&flatten&prune&left_factor:"); preorder(*t); fprintf(stderr, "\n");*/	if ( *t == NULL )	{/***	fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/		Tfree( *t );	/* kill if impossible to have ambig */		*t = NULL;	}	p = analysis_point((Junction *)alt2->p1);	TRAV(p, LL_k, &rk, *u);	*u = tshrink( *u );	*u = tflatten( *u );	*t = tleft_factor( *t );    /* MR10 */	*u = prune(*u, LL_k);	*u = tleft_factor( *u );/*	fprintf(stderr, "after shrink&flatten&prune&lfactor:"); preorder(*u); fprintf(stderr, "\n");*/	if ( *u == NULL )	{/*		fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/		Tfree( *u );		*u = NULL;	}	for (k=1; k<=LL_k; k++) set_clr( fs[k] );	ambig = tnode(ALT);	k = 0;	if ( *t!=NULL && *u!=NULL )	{		while ( (perm=permute(1,LL_k))!=NULL )		{/*			fprintf(stderr, "chk perm:"); preorder(perm); fprintf(stderr, "\n");*/			if ( tmember(perm, *t) && tmember(perm, *u) )			{/*				fprintf(stderr, "ambig upon"); preorder(perm); fprintf(stderr, "\n");*/				k++;				perm->right = ambig->down;				ambig->down = perm;				tcvt(&(fs[1]), perm);			}			else Tfree( perm );		}	}    for (j=0; j <= CLL_k ; j++) fs[j]=save_fs[j];    free( (char *) save_fs);    tnodes_at_end=TnodesAllocated;    tnodes_used=tnodes_at_end - tnodes_at_start;    if (TnodesReportThreshold > 0 && tnodes_used > TnodesReportThreshold) {      fprintf(stdout,"There were %d tuples whose ambiguity could not be resolved by full lookahead\n",k);      fprintf(stdout,"There were %d tnodes created to resolve ambiguity between:\n\n",tnodes_used);      fprintf(stdout,"  Choice 1: %s  line %d  file %s\n",                                 MR_ruleNamePlusOffset( (Node *) alt1),alt1->line,FileStr[alt1->file]);      fprintf(stdout,"  Choice 2: %s  line %d  file %s\n",                                 MR_ruleNamePlusOffset( (Node *) alt2),alt2->line,FileStr[alt2->file]);      for (j=1; j <= CLL_k ; j++) {        fprintf(stdout,"\n    Intersection of lookahead[%d] sets:\n",j);        MR_dumpTokenSet(stdout,2,fs[j]);      };      fprintf(stdout,"\n");    };	*numAmbig = k;	if ( ambig->down == NULL ) {_Tfree(ambig); ambig = NULL;}	free( (char *)findex );/*	fprintf(stderr, "final ambig:"); preorder(ambig); fprintf(stderr, "\n");*/	return ambig;}static Tree *#ifdef __STDC__bottom_of_chain( Tree *t )#elsebottom_of_chain( t )Tree *t;#endif{    if ( t==NULL ) return NULL;    for (; t->down != NULL; t=t->down) {;}    return t;}/* * Make a tree from k sets where the degree of the first k-1 sets is 1. */Tree *#ifdef __STDC__make_tree_from_sets( set *fset1, set *fset2 )#elsemake_tree_from_sets( fset1, fset2 )set *fset1;set *fset2;#endif{	set inter;	int i;	Tree *t=NULL, *n, *u;	unsigned *p,*q;	require(LL_k>1, "make_tree_from_sets: LL_k must be > 1");	/* do the degree 1 sets first */	for (i=1; i<=LL_k-1; i++)	{		inter = set_and(fset1[i], fset2[i]);		require(set_deg(inter)==1, "invalid set to tree conversion");		n = tnode(set_int(inter));		if (t==NULL) t=n; else tmake(t, n, NULL);		set_free(inter);	}	/* now add the chain of tokens at depth k */	u = bottom_of_chain(t);	inter = set_and(fset1[LL_k], fset2[LL_k]);	if ( (q=p=set_pdq(inter)) == NULL ) fatal_internal("Can't alloc space for set_pdq");	/* first one is linked to bottom, then others are sibling linked */	n = tnode(*p++);	u->down = n;	u = u->down;	while ( *p != nil )	{		n = tnode(*p);		u->right = n;		u = u->right;		p++;	}	free((char *)q);	return t;}/* create and return the tree of lookahead k-sequences that are in t, but not * in the context of predicates in predicate list p. */Tree *#ifdef __STDC__tdif( Tree *ambig_tuples, Predicate *p, set *fset1, set *fset2 )#elsetdif( ambig_tuples, p, fset1, fset2 )Tree *ambig_tuples;Predicate *p;set *fset1;set *fset2;#endif{	unsigned **ft;	Tree *dif=NULL;	Tree *perm;	set b;	int i,k;	if ( p == NULL ) return tdup(ambig_tuples);	ft = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *));	require(ft!=NULL, "cannot allocate ft");	for (i=1; i<=CLL_k; i++)	{		b = set_and(fset1[i], fset2[i]);		ft[i] = set_pdq(b);		set_free(b);	}	findex = (int *) calloc(LL_k+1, sizeof(int));	if ( findex == NULL )	{		fatal_internal("out of memory in tdif while checking predicates");	}	for (k=1; k<=LL_k; k++) findex[k] = 0;#ifdef DBG_TRAV	fprintf(stderr, "tdif_%d[", p->k);	preorder(ambig_tuples);	fprintf(stderr, ",");	preorder(p->tcontext);	fprintf(stderr, "] =");#endif	ftbl = ft;	while ( (perm=permute(1,p->k))!=NULL )	{#ifdef DBG_TRAV		fprintf(stderr, "test perm:"); preorder(perm); fprintf(stderr, "\n");#endif		if ( tmember_constrained(perm, ambig_tuples) &&			 !tmember_of_context(perm, p) )		{#ifdef DBG_TRAV			fprintf(stderr, "satisfied upon"); preorder(perm); fprintf(stderr, "\n");#endif			k++;			if ( dif==NULL ) dif = perm;			else			{				perm->right = dif;				dif = perm;			}		}		else Tfree( perm );	}#ifdef DBG_TRAV	preorder(dif);	fprintf(stderr, "\n");#endif	for (i=1; i<=CLL_k; i++) free( (char *)ft[i] );	free((char *)ft);	free((char *)findex);	return dif;}/* is lookahead sequence t a member of any context tree for any * predicate in p? */static int#ifdef __STDC__tmember_of_context( Tree *t, Predicate *p )#elsetmember_of_context( t, p )Tree *t;Predicate *p;#endif{	for (; p!=NULL; p=p->right)	{		if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST )			return tmember_of_context(t, p->down);		if ( tmember_constrained(t, p->tcontext) ) return 1;		if ( tmember_of_context(t, p->down) ) return 1;	}	return 0;}int#ifdef __STDC__is_single_tuple( Tree *t )#elseis_single_tuple( t )Tree *t;#endif{	if ( t == NULL ) return 0;	if ( t->right != NULL ) return 0;	if ( t->down == NULL ) return 1;	return is_single_tuple(t->down);}/* MR10 Check that a context guard contains only allowed things *//* MR10   (mainly token references).                            */#ifdef __STDC__int contextGuardOK(Node *p,int h,int *hmax)#elseint contextGuardOK(p,h,hmax)  Node  *p;  int   h;  int   *hmax;#endif{    Junction     *j;    TokNode      *tn;    if (p == NULL) return 1;    if (p->ntype == nToken) {      h++;      if (h > *hmax) *hmax=h;      tn=(TokNode *)p;      if (tn->el_label != NULL) {        warnFL(eMsg1("a label (\"%s\") for a context guard element is meaningless",tn->el_label),                             FileStr[p->file],p->line);      };      return contextGuardOK( ( (TokNode *) p)->next,h,hmax);    } else if (p->ntype == nAction) {      goto Fail;    } else if (p->ntype == nRuleRef) {      goto Fail;    } else {      require (p->ntype == nJunction,"Unexpected ntype");      j=(Junction *) p;      if (j->jtype != Generic &&          j->jtype != aSubBlk &&        /* pretty sure this one is allowed *//****     j->jtype != aOptBlk && ****/  /* pretty sure this one is allowed */ /* MR11 not any more ! */          j->jtype != EndBlk) {        errFL("A context guard may not contain an option block: {...} or looping block: (...)* or (...)+",                  FileStr[p->file],p->line);        contextGuardOK(j->p1,h,hmax);        return 0;      };      /* do both p1 and p2 so use | rather than ||  */      return contextGuardOK(j->p2,h,hmax) | contextGuardOK(j->p1,h,hmax);    };Fail:    errFL("A context guard may contain only Token references - guard will be ignored",                             FileStr[p->file],p->line);    contextGuardOK( ( (ActionNode *) p)->next,h,hmax);    return 0;}/* * Look at a (...)? generalized-predicate context-guard and compute * either a lookahead set (k==1) or a lookahead tree for k>1.  The * k level is determined by the guard itself rather than the LL_k * variable.  For example, ( A B )? is an LL(2) guard and ( ID )? * is an LL(1) guard.  For the moment, you can only have a single * tuple in the guard.  Physically, the block must look like this *   --o-->TOKEN-->o-->o-->TOKEN-->o-- ... -->o-->TOKEN-->o-- * An error is printed for any other type. */Predicate *#ifdef __STDC__computePredicateFromContextGuard(Graph blk,int *msgDone)    /* MR10 */#elsecomputePredicateFromContextGuard(blk,msgDone)               /* MR10 */  Graph     blk;  int       *msgDone;                                       /* MR10 */#endif{    Junction *junc = (Junction *)blk.left, *p;    Tree        *t=NULL;	Predicate   *pred = NULL;	set         scontext, rk;    int         ok;    int         hmax=0;    require(junc!=NULL && junc->ntype == nJunction, "bad context guard");/* MR10 Check for anything other than Tokens and generic junctions */    *msgDone=0;                                             /* MR10 */    ok=contextGuardOK( (Node *)junc,0,&hmax);               /* MR10 */    if (! ok) {                                             /* MR10 */      *msgDone=1;                                           /* MR10 */      return NULL;                                          /* MR10 */    };                                                      /* MR10 */    if (hmax == 0) {errFL("guard is 0 tokens long",FileStr[junc->file],junc->line);          /* MR11 */      *msgDone=1;      return NULL;    };    if (hmax > CLL_k) {                                     /* MR10 */errFL(eMsgd2("guard is %d tokens long - lookahead is limited to max(k,ck)==%d", /* MR10 */        hmax,CLL_k),                                        /* MR10 */        FileStr[junc->file],junc->line);                    /* MR10 */      *msgDone=1;                                           /* MR10 */      return NULL;                                          /* MR10 */    };                                                      /* MR10 */	rk = empty;	p = junc;	pred = new_pred();	pred->k = hmax;     /* MR10 should be CLL_k, not LLK ? */	if (hmax > 1 )      /* MR10 was LL_k                   */	{		ConstrainSearch = 0;		ContextGuardTRAV = 1;		TRAV(p, hmax, &rk, t);  /* MR10 was LL_k */		ContextGuardTRAV = 0;		set_free(rk);		t = tshrink( t );		t = tflatten( t );		t = tleft_factor( t );/*		fprintf(stderr, "ctx guard:");		preorder(t);		fprintf(stderr, "\n");*/		pred->tcontext = t;	}	else	{		REACH(p, 1, &rk, scontext);		require(set_nil(rk), "rk != nil");		set_free(rk);/*		fprintf(stderr, "LL(1) ctx guard is:");		s_fprT(stderr, scontext);		fprintf(stderr, "\n");*/		pred->scontext[1] = scontext;	}    list_add(&ContextGuardPredicateList,pred);     /* MR13 */	return pred;}/* MR13   When the context guard is originally computed the   meta-tokens are not known.*/#ifdef __STDC__void recomputeContextGuard(Predicate *pred)#elsevoid recomputeContextGuard(pred)    Predicate   *pred;#endif{    Tree *          t=NULL;	set             scontext;    set             rk;    ActionNode *    actionNode;    Junction *      p;    actionNode=pred->source;    require (actionNode != NULL,"context predicate's source == NULL");    p=actionNode->guardNodes;

⌨️ 快捷键说明

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