您的位置:首页 > 其它

[转载]LCC编译器的源程序分析(23)一元运算表达式

2007-08-21 12:51 477 查看
前面分析了基本表达式,主要由常量和变量ID组成。接着下来,就需要分析优先级比较高的一元运算表达式了,主要由第1级和第2级运算符组成的运算,一般只需要一个操作数就可以运算的表达式。
在LCC里处理一元运算表达式的代码如下:
#001 static Tree unary(void)
#002 {
#003 Tree p;
#004
#005 switch (t)
#006 {
#007 case '*':
#008 t = gettok();
#009 p = unary();
#010 p = pointer(p);
#011
#012 if (isptr(p->type)
#013 && (isfunc(p->type->type) || isarray(p->type->type)))
#014 p = retype(p, p->type->type);
#015 else
#016 {
#017 if (YYnull)
#018 p = nullcheck(p);
#019 p = rvalue(p);
#020 }
#021
#022 break;
#023
第7行是处理指针运算表达式。比如像int a = b + *p;
第8行获取下一个记号。
第9行是递归调用一元运算表达式函数。
第10行是创建数组指针,或者函数指针,还是一般的指针区分。
第12行如果类型指针,就返回类型树节点。
第19行是返回右值类型的树节点。

#024 case '&':
#025 t = gettok();
#026 p = unary();
#027 if (isarray(p->type) || isfunc(p->type))
#028 p = retype(p, ptr(p->type));
#029 else
#030 p = lvalue(p);
#031
#032 if (isaddrop(p->op) && p->u.sym->sclass == REGISTER)
#033 error("invalid operand of unary &; `%s' is declared register/n", p->u.sym->name);
#034
#035 else if (isaddrop(p->op))
#036 p->u.sym->addressed = 1;
#037 break;
上面处理取地址运算符。

#038 case '+':
#039 t = gettok();
#040 p = unary();
#041 p = pointer(p);
#042
#043 if (isarith(p->type))
#044 p = cast(p, promote(p->type));
#045 else
#046 typeerror(ADD, p, NULL);
#047 break;
#048
上面处理正号运算符。

#049 case '-':
#050 t = gettok();
#051 p = unary();
#052 p = pointer(p);
#053 if (isarith(p->type))
#054 {
#055 Type ty = promote(p->type);
#056 p = cast(p, ty);
#057 if (isunsigned(ty))
#058 {
#059 warning("unsigned operand of unary -/n");
#060 p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL));
#061 }
#062 else
#063 p = simplify(NEG, ty, p, NULL);
#064 }
#065 else
#066 typeerror(SUB, p, NULL);
#067 break;
上面是处理负号运算符。

#068 case '~':
#069 t = gettok();
#070 p = unary();
#071 p = pointer(p);
#072
#073 if (isint(p->type))
#074 {
#075 Type ty = promote(p->type);
#076 p = simplify(BCOM, ty, cast(p, ty), NULL);
#077 }
#078 else
#079 typeerror(BCOM, p, NULL);
#080 break;
上面是处理按位取反运算符。

#081 case '!':
#082 t = gettok();
#083 p = unary();
#084 p = pointer(p);
#085
#086 if (isscalar(p->type))
#087 p = simplify(NOT, inttype, cond(p), NULL);
#088 else
#089 typeerror(NOT, p, NULL);
#090 break;
上面是处理逻辑非运算符。

#091 case INCR:
#092 t = gettok();
#093 p = unary();
#094 p = incr(INCR, pointer(p), consttree(1, inttype));
#095 break;
上面是处理自增运算符。

#096 case DECR:
#097 t = gettok();
#098 p = unary();
#099 p = incr(DECR, pointer(p), consttree(1, inttype));
#100 break;
#101
上面是处理自减运算符。

#102 case TYPECODE:
#103 case SIZEOF:
#104 {
#105 int op = t;
#106 Type ty;
#107 p = NULL;
#108 t = gettok();
#109
#110 if (t == '(')
#111 {
#112 t = gettok();
#113 if (istypename(t, tsym))
#114 {
#115 ty = typename();
#116 expect(')');
#117 }
#118 else
#119 {
#120 p = postfix(expr(')'));
#121 ty = p->type;
#122 }
#123 }
#124 else
#125 {
#126 p = unary();
#127 ty = p->type;
#128 }
#129 assert(ty);
#130 if (op == TYPECODE)
#131 p = cnsttree(inttype, (long)ty->op);
#132 else
#133 {
#134 if (isfunc(ty) || ty->size == 0)
#135 error("invalid type argument `%t' to `sizeof'/n", ty);
#136 else if (p && rightkid(p)->op == FIELD)
#137 error("`sizeof' applied to a bit field/n");
#138 p = cnsttree(unsignedlong, (unsigned long)ty->size);
#139 }
#140 }
#141 break;
上面是处理类型码和类型长度运算符。

#142 case '(':
#143 t = gettok();
#144 if (istypename(t, tsym))
#145 {
#146 Type ty, ty1 = typename(), pty;
#147 expect(')');
#148 ty = unqual(ty1);
#149 if (isenum(ty))
#150 {
#151 Type ty2 = ty->type;
#152 if (isconst(ty1))
#153 ty2 = qual(CONST, ty2);
#154 if (isvolatile(ty1))
#155 ty2 = qual(VOLATILE, ty2);
#156 ty1 = ty2;
#157 ty = ty->type;
#158 }
#159
#160 p = pointer(unary());
#161 pty = p->type;
#162 if (isenum(pty))
#163 pty = pty->type;
#164
#165 if (isarith(pty) && isarith(ty)
#166 || isptr(pty) && isptr(ty))
#167 {
#168 explicitCast++;
#169 p = cast(p, ty);
#170 explicitCast--;
#171 }
#172 else if (isptr(pty) && isint(ty)
#173 || isint(pty) && isptr(ty))
#174 {
#175 if (Aflag >= 1 && ty->size < pty->size)
#176 warning("conversion from `%t' to `%t' is compiler dependent/n", p->type, ty);
#177
#178 p = cast(p, ty);
#179 }
#180 else if (ty != voidtype)
#181 {
#182 error("cast from `%t' to `%t' is illegal/n",
#183 p->type, ty1);
#184 ty1 = inttype;
#185 }
#186
#187 if (generic(p->op) == INDIR || ty->size == 0)
#188 p = tree(RIGHT, ty1, NULL, p);
#189 else
#190 p = retype(p, ty1);
#191
#192 }
#193 else
#194 p = postfix(expr(')'));
#195
#196 break;
上面是处理类型转换运算符。

#197 default:
#198 p = postfix(primary());
一元运算符后面跟着的就是基本表达式,最后跟着后缀运算符。比如像
++a[2];

#199 }
#200 return p;
#201 }
最后在第200行里就返回表达式树节点。
每个一元运算符与基本表达式就组一个树节点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: