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

📄 enode.c

📁 unix环境下实现的cmm语言编译器
💻 C
字号:
/*enode.c:进行语义处理并建立抽象语法树*/#include "cmm.h"static Tree addtree(int op, Tree l,Tree r);static Tree cmptree(int op, Tree l, Tree r);static int compatible(Type ty1, Type ty2);static int isnullptr(Tree e);static Tree subtree(int op, Tree l, Tree r);static Tree multree(int op, Tree l, Tree r);Tree (*optree[])(int op, Tree l, Tree r) = {/*二元表达式处理函数*/#define xx(a,b,c,d,e,f,g)	f,#define yy(a,b,c,d,e,f,g)	f,#include "token.h"};/*call:为函数调用生成调用树。 *call用函数原型对实参进行类型检查。 */Tree call(Tree f, Type fty, Coordinate *src){	int n = 0;	Tree args = NULL;	Type *proto, rty = freturn(fty);		DEBUG(fprint(2,"function call begin\n")); 	proto = fty->proto;	if (t != ')')		for (;;) {			Tree q = pointer(expr(0));			if (proto && *proto && *proto != voidtype) {				Type aty;				aty = assign(*proto,q);				if (aty)					q = cast(q, aty);				else 					error("type error in argument %d to\					 %s;found '%t'\expected '%t'\n", 					n+1,funcname(f),q->type,*proto);				if (ischar(q->type)) /*将字符参数类型提升为整形*/					q = cast(q, promote(q->type));				proto++;			}			else {				if (NULL == proto || NULL == *proto|| *proto == voidtype)					error("too many arguments to %s\n",funcname(f));			}			args = tree(ARG + ttob(q->type),q->type,q,args);			n++;			if(t != ',')				break;			t = gettoken();		}		expect(')');		if (proto && *proto)			error("insufficient number of arguments to %s\n",			funcname(f));	DEBUG(fprint(2,"function call end\n")); 	return  tree(CALL + ttob(rty), promote(rty),args,f);}/*addtree:为加运算生成树*/static Tree addtree(int op, Tree l,Tree r){	Type ty = inttype;		if (isarith(l->type) && isarith(r->type)) {		ty = binary(l->type, r->type);		l = cast(l,ty);		r = cast(r,ty);	}else if(isptr(l->type) && isarith(r->type))		return addtree(op, r, l);	else if(isptr(r->type) && isarith(l->type)	 &&!isfunc(r->type->type)) {		/*对于指针与算术类型的运算,总是使指针成为右操作数*/		int n;		ty = r->type;		n = ty->type->size;		if(0 == n)			error("unknown size for type '%t' \n",ty->type);		l = cast(l, promote(l->type));		if(n > 1) /*计算偏移量*/			l = multree(MUL, consttree(n,inttype),l);		return simplify(ADD+P, ty, l, r);	}else		typeerror(op, l,r);	return simplify(op, ty, l, r);			}/*consttree:生成类型为ty值为n的常量树*/Tree consttree(int n, Type ty){	Tree p;		if(isarray(ty))		ty = atop(ty);	p = tree(CNST+ttob(ty),ty,NULL,NULL);	p->u.v.i = n;	return p;}/*cmptree:为比较运算生成树*/static Tree cmptree(int op, Tree l, Tree r){	Type ty = inttype;	if(isarith(l->type) && isarith(r->type)) {		ty = binary(l->type, r->type);		l = cast(l,ty);		r = cast(r,ty);	}else if(compatible(l->type,r->type)){		/*比较可以兼容的指针类型,并把它们转换成无符号数的比较*/		ty = unsignedtype;				 		l = cast(l, ty);		r = cast(r,ty);		}else 		typeerror(op,l,r);		return simplify(op + ttob(ty),inttype,l,r);	}static int compatible(Type ty1, Type ty2){	return (isptr(ty1) && !isfunc(ty1->type)			&& isptr(ty2) && !isfunc(ty2->type)			&& eqtype(ty1->type,ty2->type));}static int isnullptr(Tree e){	return (isint(e->type) && CNST == generic(e->op)		&& 0 == e->u.v.i) 		|| (isvoidptype(e->type) && CNST+P == e->op		 &&NULL == e->u.v.p);}Tree eqtree(int op, Tree l, Tree r){	Type xty = l->type, yty = r->type;	if((isptr(xty) && isnullptr(r))	|| (isptr(xty) && !isfunc(xty->type) && isvoidptype(yty))	|| (isptr(xty) && isptr(yty) && eqtype(xty->type,yty->type))) {		Type ty = unsignedtype;		l = cast(l, ty);		r = cast(r, ty);		return simplify(op + ttob(ty),inttype, l, r);	}else if((isptr(yty) && isnullptr(l))	|| (isptr(yty) && !isfunc(yty->type) && isvoidptype(xty))) {		return eqtree(op, r, l);		}	return cmptree(op, l, r);}Type assign(Type xty, Tree e){	if(isarith(e->type) && isarith(xty))		return xty;	else if(isptr(xty) && isnullptr(e))		return xty;	else if((isvoidptype(xty) && isptr(e->type))	|| (isvoidptype(e->type) && isptr(xty)))		return xty;	else if(isptr(xty) && isptr(e->type)	&& eqtype(xty, e->type))		return xty;	return NULL;}/*asgntree:生成赋值树*/Tree asgntree(int op, Tree l, Tree r){	Type  ty;		r = pointer(r);/*将数组和函数做为指针*/	ty = assign(l->type, r);	if(ty)		r = cast(r, ty);	else {		typeerror(ASGN, l,r);		if(r->type == voidtype)			r = retype(r, inttype);		ty = r->type;	}	l = lvalue(l); /*使用l的左值*/	return tree(op + ttob(ty), ty, l, r);}Tree asgn(Symbol p, Tree e){	if(isarray(p->type)) /*对局部数组进行初始化赋值*/		e = tree(ASGN + A, p->type, idtree(p),			tree(INDIR + A, e->type, e, NULL));	else  		e = asgntree(ASGN, idtree(p),e);	return e;	}/*subtree:处理减法运算*/static Tree subtree(int op, Tree l, Tree r){	Type ty = inttype;	int n;	DEBUG(fprint(2,"subtree begin\n")); 	if(isarith(l->type) && isarith(r->type)) {		l = cast(l, ty);		r = cast(r, ty);		}else if(isptr(l->type) && !isfunc(l->type->type) && isarith(r->type)) { /*指针减去一个整形数后其结果为指针*/		ty = l->type;		n = ty->size;		if(0 == n)			error("unknown size for type '%t'\n",ty->type);		if(n > 1)			r = multree(MUL, consttree(n, inttype), r);		return simplify(SUB+P, ty, l, r);	}else if(compatible(l->type, r->type)) {		/*兼容指针相减的结果为指针引用元素的个数*/		ty = l->type;		n = ty->type->size;		if(0 == n)			error("unknown size for type '%t'\n", ty->type);		l = simplify(SUB+I, inttype, cast(l,unsignedtype),cast(r,unsignedtype));		return simplify(DIV+I,inttype,l, consttree(n,inttype));	}else		typeerror(op,l,r);	DEBUG(fprint(2,"subtree end\n")); 	return simplify(op, ty,l,r);}/*multree:处理乘法,除法,求余运算*/static Tree multree(int op, Tree l, Tree r){	Type ty = inttype;	if(isarith(l->type) && isarith(r->type)) {		l = cast(l, inttype);		r = cast(r, inttype);	}else		typeerror(op, l, r);	return simplify(op, ty, l, r);}void typeerror(int op, Tree l, Tree r){	int i;	static struct {int op; char *name;} ops[] = {		{ASGN, "="},	{INDIR, "*"},	{NEG, "-"},		{ADD, "+"},	{SUB, "-"},	{MOD, "%"},		{DIV, "/"},	{MUL, "*"},	{EQ, "=="},		{GE, ">="},	{GT, ">"},	{LE, "<="},		{LT, "<"},	{NE, "!="},	{NOT, "!"},		{0,0}	};	op = generic(op);	for(i = 0; ops[i].op; i++)		if(op == ops[i].op)			break;	assert(ops[i].name);	if(r)		error("operands of %s have illegal types '%t' and '%t'\n",		ops[i].name, l->type, r->type);	else		error("operand of unary %s has illegal type '%t'\n",		ops[i].name,l->type);	}

⌨️ 快捷键说明

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