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

📄 init.c

📁 unix环境下实现的cmm语言编译器
💻 C
字号:
/*init.c:分析初始化声明符列表*/#include "cmm.h"static int genconst(Tree);static int initarray(int len , Type ty, int lev);/*genconst:根据常量树e生成初始化代码*/static int genconst(Tree e){	assert(e);	for(;;) 		switch(generic(e->op)) {		case ADDRG: 		/*全局的指针变量可以取之前已定义的全局变量的地址		 *做为初始值*/				(*IR->defaddress)(e->u.sym);			return e->type->size;		case CNST:			(*IR->defconst)(ttob(e->type), e->u.v);			return e->type->size;				case CVP:			if(isarith(e->type))				error("cast form '%t' to '%t' is illegal in\				constant expressions\n",				e->kids[0]->type, e->type);		case CVC: case CVI:			e = e->kids[0];			continue;		default:			error("initializer must be constant\n");			genconst(consttree(0,inttype));			return inttype->size;		}}/*initarray:用于分析数组。 *len大于0时,数组的长度已确定。等于0则数组的 *长度侍定,initarray以'{'做为数组结束标志。 */static int initarray(int len , Type ty, int lev){	int n = 0;	do {		initializer(ty, lev);		n+= ty->size;		if((len > 0 && n > len) || t != ',')			break;		t = gettoken();	}while(t != '}');	return n;}/*initend:以'{'开始的初始化列表可以包含可选的','*/static void initend(char follow[]){	if(',' == t)		t = gettoken();	test('}', follow);}/*is_char_array:如果ty是字符数组则返回1,否则返回0*/static int is_char_array(Type ty){	for (; isarray(ty); ty = ty->type)		if (ischar(ty->type))			return 1;	return 0;}/*initializer: *			 const-expression |  * 			'{' initializer {, initializer}[,]'}' *initializer函数分析初始列表并返回最终的 *变量类型。形参ty是说明符分析中已得到的类型。 *由于允许数组形如int a[];的声明,所以需要在 *initializer的分析中确定数组的长度。形参lev *表示嵌套调用的层数。 */Type initializer(Type ty, int lev){	int n = 0;	Tree e;	Type aty = NULL;		static char follow[] = {IF, CHAR, 0};	DEBUG(fprint(2,"initializer start:%d\n",lev));	if (isscalar(ty)) {/*标量类型*/		if ('{' == t) {			t = gettoken();			e = expr(0);			initend(follow);		}else 			e = expr(0);		e = pointer(e);		if ((aty = assign(ty, e)) != NULL)			e = cast(e, aty);		else 			error("invalid initialization type; found '%t'\				expected '%t'\n",e->type, ty);		n = genconst(e);		deallocate(STMT);	}	if (isarray(ty))		aty = ty->type;	if (isarray(ty) && ischar(aty) && SCON == t) { /*字符数组*/			(*IR->defstring)(tsym->type->size, tsym->u.c.v.p);			t = gettoken();		}else if(isarray(ty)) {		if('{' == t) {			t = gettoken();			n = initarray(0, aty, lev+1);			test('}', follow);		}else if(lev > 0 && ty->size > 0)			/*对于二维以上数组,形如             *int a[1][3] = {'a','b','c'}             *的列表,最左边的下标可以省略,initializer             *可以根据对后面的分析以确定最左边数组的长度             *但后面数组的长度必须事先给定。             */			n = initarray(ty->size, aty, lev + 1);		else {			error("missign { in initialization of '%t'\n", ty);			n = initarray(aty->size, aty, lev+1);		}		if (0 == lev && is_char_array(ty))  /*在字符数组后设置结束的标志'\0'*/			def_array_end();	}	if(ty->size) { /*数组声明的长度与初始化提供的数据的长度不一至*/		if(n > ty->size)			error("too many initializers\n");	}else if(isarray(ty) && ty->type->size > 0)		ty = array(ty->type, n/ty->type->size, 0);	else 		ty->size = n;		DEBUG(fprint(2,"initializer finish:%d\n",lev));	return ty;}

⌨️ 快捷键说明

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