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

📄 macro.c

📁 主要用于大规模的测试生成方法
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* once a 'collector' or 'optional' is found, */		/* following ones must be of the same type */		if (!coll && formal_type==Kcollector ||		    !opt  && formal_type==Koptional)		{	fprintf( stderr,			   "%s Evaluation of keywordDefine of (%s:\n",			   lineno(), keywords[curr_macro]);			fprintf( stderr,			   "    (formal %s must also have (%s attached!\n",			   f->data.tree->data.token, keywords[formal_type]);			err_count++;		}	}	DEBUG(6) "macro: definition has %d args (%d collector, %d optional)\n",		cnt, ncolls, nopts);	if (ncolls>0 && nopts>0) return(NULL); /*Illegal, message already made*/	if (ncolls>0) keywordlevelused=3;	result = NULL;	/* repeat to fill collector type arguments */	for (cnt=0; call && (cnt==0||ncolls>0); cnt++)	/* scan over the formals, one assignment for each */	for (f=formal, rp= &result; f; f=f->next, rp= &((*rp)->next)) 	{	formal_asgn = f->data.tree->data.token;		coll = (ncolls)?locate( f, Kcollector, 0):0;		opt = (nopts)?locate( f, Koptional, 0):0;		if (!call && !opt) break; /* error: no actual args for non-opt*/		if (cnt>0 && !coll) continue; /*skip non-coll after 1st round*/		if (cnt==0) /*create list to contain result*/		{	*rp = get_parsetree();			(*rp)->type = Kformal; /*misuse type field as forEach flag*/			(*rp)->data.tree = get_parsetree();			(*rp)->data.tree->type = IDENT; /* attach par name */			(*rp)->data.tree->data.token = formal_asgn;		}		DEBUG(7) "macro: attaching value %d to formal argument '%s'\n",			cnt+1, formal_asgn);		for (vp= &((*rp)->data.tree->next); *vp; vp= &((*vp)->next));			/* locate end of values list */		if (call) /* value available*/			*vp = cpy_parsetree( call);		else	/* use (optional field */		{	DEBUG(7) "macro: no actual, evaluate '(optional'\n");			*vp = buildmacro( result, opt->data.tree);			if (!(*vp) || (*vp)->next)			{	fprintf( stderr,				   "%s Evaluation of keywordDefine of (%s:\n",				   lineno(), keywords[curr_macro]);				fprintf( stderr,				   "    (formal %s (optional returns %s!\n",				   formal_asgn, (*vp)?"several values":"empty value");				err_count++;			}		}		if (call) call = call->next;	}	formal_asgn = NULL;	if (call || f)	{		fprintf( stderr,			"%s macro call (%s has too %s arguments!\n",			lineno(), keywords[curr_macro],			call ? "many" : "few");		err_count++;	}	if (debug>=4)	for (rp= &result; *rp; rp= &((*rp)->next))	{	fprintf( stderr, "call (%s, arg '%s' =",		   keywords[curr_macro], (*rp)->data.tree->data.token);		for (vp= &((*rp)->data.tree->next); *vp; vp= &((*vp)->next))			fprintf( stderr, " %s", treetxt(*vp));		fprintf( stderr, "\n");	}	return( result);}/* create parsetree from a macro-body definition and an assigned parameter set*/static PARSETREE *buildmacro( args, body)PARSETREE *args, *body;{	PARSETREE *result, **pr, *pf, *pa, **pp;	char *parname;	int i, n;	DEBUG(5) "Entering buildmacro: curr_macro=%s, formal_asgn=%s\n",		keywords[curr_macro], formal_asgn?formal_asgn:"-");	for (result=NULL, pr= &result; body; body=body->next)	switch( body->type)	{ case Kbuild:		DEBUG(6) "    processing (build %s\n",			body->data.tree->data.token);		*pr = get_parsetree();		(*pr)->type = key_hash( body->data.tree->data.token, 0);		if ((*pr)->type == KEYWORD) /* yet unknown keyword: edif input error */		{	fprintf( stderr,				"%s and %d: (build of unknown keyword '%s', form skipped!\n",				lineno(), body->line, body->data.tree->data.token);			err_count++;			put_parsetree( *pr);			*pr = NULL;		} else /* O.K. */		{	(*pr)->data.tree = buildmacro( args, body->data.tree->next);			pr = &((*pr)->next);		}		break;	  case Kactual:		DEBUG(6) "    processing (actual %s\n",			body->data.tree->data.token);		parname = body->data.tree->data.token;		pf = find_actual( args, parname);		if (!pf) break; /* error message already generated */		if (pf->type==KforEach) /* take one element of forEach*/		{	*pr = cpy_parsetree( pf->data.tree->next);			pr = &((*pr)->next);		}		else	/* take actual list*/		{	for (pf=pf->data.tree->next; pf; pf=pf->next)			{	*pr = cpy_parsetree( pf);				pr = &((*pr)->next);			}		}		break;	  case Kliteral:		DEBUG(6) "    processing (literal ...\n");		for (pf=body->data.tree; pf; pf = pf->next)		{	*pr = cpy_parsetree( pf);			pr = &((*pr)->next);		}		break;	  case KforEach:		keywordlevelused = 3;		/*** initialise loop ****/		DEBUG(6) "    starting (forEach\n");		pa = NULL;		pf = body->data.tree;		if (pf->type == KformalList) pf = pf->data.tree;		while (pf && pf->type==IDENT)		{	pa = find_actual( args, pf->data.token);			if (!pa) break;			/* set forEach loop flag */			pa->type = KforEach;			/* create cycle of actual values, count items*/			n=0;			for (pp= &(pa->data.tree->next); *pp;			     pp= &((*pp)->next)) n++;			*pp = pa->data.tree->next;			pf = pf->next;		}		if (!pa) break;		/***** iterate body ******/		for (i=0; i<n; i++)		{			*pr = buildmacro( args, body->data.tree->next);			while (*pr) pr = &((*pr)->next);						/* next actual values  by rotating list */			pf = body->data.tree;			if (pf->type == KformalList) pf = pf->data.tree;			while (pf && pf->type==IDENT)			{	pa = find_actual( args, pf->data.token);				pa = pa->data.tree;				pa->next = pa->next->next;				pf = pf->next;			}			DEBUG(6) "    foreach: cycle %d finished\n", i);		}		/***** terminate loop ******/		pf = body->data.tree;		if (pf->type == KformalList) pf = pf->data.tree;		while (pf && pf->type==IDENT)		{	pa = find_actual( args, pf->data.token);			pa->type = Kformal;			/* break cycle again in normal list*/			for (pp= &(pa->data.tree->next), i=0;			     i<n;			     pp= &((*pp)->next), i++);			*pp = NULL;			pf = pf->next;		}		break;	  case Kcomment:		break;	}	DEBUG(5) "buildmacro exit: makes )\n");	return( result);}static PARSETREE *find_actual( args, name)PARSETREE *args;char *name;{	PARSETREE *pf;	for (pf=args;	     pf && pf->data.tree->data.token != name;	     pf = pf->next);  /* find actual argument */	if (!pf)	{	fprintf( stderr,		   "%s Evaluating keywordDefinition '(%s':\n",		   lineno(), keywords[curr_macro]);		if (formal_asgn)			fprintf( stderr,			"   (formal %s illegally references %s!\n",			formal_asgn, name);		else	fprintf( stderr,			"   formal parameter %s unknown!\n",			name);		err_count++;	}	return(pf);}static PARSETREE  *cpy_parsetree( org)PARSETREE *org;{	PARSETREE *cpy, **p;	if (!org) return(NULL);	cpy = get_parsetree();	cpy->type = org->type;	switch( cpy->type)	{ case IDENT:	  case STRING:		cpy->data.token = org->data.token; break;	  case NUMBER:		cpy->data.ival = org->data.ival; break;	}	if (!ISKEYWORD(org->type)) return(cpy);	for (org=org->data.tree, p= &(cpy->data.tree);	     org; org = org->next, p= &((*p)->next))		*p = cpy_parsetree( org);	return( cpy);}/**** aid for generating err messages ***/char *lineno(){	static char buf[20];	if (mlines[1]>mlines[0])		sprintf( buf, "Line %d-%d:", mlines[0], mlines[1]);	else	sprintf( buf, "Line %d:", yy_create_edf_lineno);	return(buf);}char *tokentxt(){	char c1, c2, *pc;	switch(token->type)	{ case STRING:		if (mlines[0]) strcpy( yy_create_edf_text, token->data.token);		if (strlen(yy_create_edf_text)>25) strcpy( yy_create_edf_text+22, "...");		return( yy_create_edf_text);	  case IDENT:		if (mlines[0]) return( token->data.token);		else return( yy_create_edf_text);	  case NUMBER:		if (mlines[0])			sprintf( yy_create_edf_text, "%d", token->data.ival);		return( yy_create_edf_text);	  case ENDLIST:		return(")");	  case ENDFILE:		return("<end-of-file>");	  default: /* must be keyword*/		if (mlines[0])			sprintf( yy_create_edf_text, "(%s", keywords[token->type]);		else	/* insert '(' */		{	for (c1='(', pc=yy_create_edf_text; c1; c2= *pc, *pc++ =c1, c1=c2);			*pc = '\0';		}		return( yy_create_edf_text);	}}

⌨️ 快捷键说明

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