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

来源:互联网 发布:google编程挑战赛题目 编辑:程序博客网 时间:2024/05/17 08:23
前面分析了基本表达式,主要由常量和变量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行里就返回表达式树节点。
每个一元运算符与基本表达式就组一个树节点。
  <script type="text/javascript"><!--google_ad_client = "pub-0904655026211899";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_type = "text_image";google_ad_channel = "";google_color_border = "336699";google_color_bg = "FFFFFF";google_color_link = "0000FF";google_color_text = "000000";google_color_url = "008000";//--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击