📄 init.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 + -