zoukankan      html  css  js  c++  java
  • 《lua设计与实现》第6章 指令的解析与执行--6.5 数值计算类指令

    在下面的指令中选择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
  • 相关阅读:
    内存初始化
    时钟初始化
    auto,register,static分析
    基本数据类型
    LED驱动简单设计
    核心初始化程序
    核心初始化基本介绍
    链接器脚本
    !带有指针的类和struct赋值的本质
    添加thrust的库后出错
  • 原文地址:https://www.cnblogs.com/yyqng/p/14854986.html
Copyright © 2011-2022 走看看