在下面的指令中选择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