yyqng

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

在下面的指令中选择power解释,其他指令类似

typedef enum {
/*----------------------------------------------------------------------
name        args    description
------------------------------------------------------------------------*/
//......
OP_ADD,/*    A B C    R(A) := RK(B) + RK(C)                */
OP_SUB,/*    A B C    R(A) := RK(B) - RK(C)                */
OP_MUL,/*    A B C    R(A) := RK(B) * RK(C)                */
OP_DIV,/*    A B C    R(A) := RK(B) / RK(C)                */
OP_MOD,/*    A B C    R(A) := RK(B) % RK(C)                */
OP_POW,/*    A B C    R(A) := RK(B) ^ RK(C)                */
OP_UNM,/*    A B    R(A) := -R(B)                    */
OP_NOT,/*    A B    R(A) := not R(B)                */
//......
} OpCode;

 

 lparser. c: priority[] 用来存储左右优先级,数字越大优先级越高。

比如 , power操作符优先级:左边 > 右边,即右结合的。2^1^2=2^(1^2)

static const struct {
  lu_byte left;  /* left priority for each binary operator */
  lu_byte right; /* right priority */
} priority[] = {  /* ORDER OPR */
   {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7},  /* `+' `-' `/' `%' */
   {10, 9}, {5, 4},                 /* power and concat (right associative) */
   {3, 3}, {3, 3},                  /* equality and inequality */
   {3, 3}, {3, 3}, {3, 3}, {3, 3},  /* order */
   {2, 2}, {1, 1}                   /* logical (and/or) */
};

#define UNARY_PRIORITY    8  /* priority for unary(一元) operators */

 

优先级处理主要在subexpr中

/*
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
*/
static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
  BinOpr op;
  UnOpr uop;
  enterlevel(ls);
  uop = getunopr(ls->t.token);
  if (uop != OPR_NOUNOPR) {
    //一元操作符
    luaX_next(ls);
    subexpr(ls, v, UNARY_PRIORITY);
    luaK_prefix(ls->fs, uop, v);
  }
  else simpleexp(ls, v);
  /* expand while operators have priorities higher than `limit' */
  op = getbinopr(ls->t.token);
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
    expdesc v2;
    BinOpr nextop;
    luaX_next(ls);
    luaK_infix(ls->fs, op, v);
    /* read sub-expression with higher priority */
    // 归调用函数 subexpr 来处理二元操作符左边的式子
    nextop = subexpr(ls, &v2, priority[op].right);
    luaK_posfix(ls->fs, op, v, &v2);
    op = nextop;
  }
  leavelevel(ls);
  return op;  /* return first untreated operator */
}

 

以2^1^2为例,伪代码:

subexpr(0)
  read "2"
  simpleexp()//解析2
  read "^"
  if left_priority > limit ://操作符 power 的左优先级10大于当前函数的优先级0
    subexpr(9) //传入操作符 power 的右优先级9
      read "1"
      simpleexp() //解析 1
      read "^"
      if left_priority > limit: // 操作符 power 的左优先级 10 大于当前函数的优先级9
        subexpr(9) //传入操作符 power 的右优先级9
          read ” 2 ”
          simpleexp()//解析 2

 

posted on 2021-06-06 12:05  zziii  阅读(47)  评论(0编辑  收藏  举报