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