⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interpreter.java

📁 A very smaller script interpretor that java based system. Can work on j2se / j2me / win C++ platform
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

        //出错,需处理
        throw new Exception(STRS_ERR[ERR_ILLEGAL]);

    }
    return resultDt;
  }

  /**
   * 求出表达式中变量和过程调用的值
   *
   * @param expr Stack
   * @param varList Hashtable
   * @return Stack
   * @throws Exception
   */
  private Vector preCalc(Vector expr, Hashtable varList) throws Exception {
    Vector tgt = new Vector();

    while (expr.size() > 0) {
      Object o = vPopFront(expr);
      //是串,包括变量,方法,符号,字符串
      String s = (String) o;

      if (s.charAt(0) == '"') { // 是字符串
        s = s.substring(1, s.length() - 1);
        o = new Str(s);

      }
      else if (isSymbol(s.charAt(0))) { //是符号
        o = new Symb(s);
        if ( ( (Symb) o).getVal() == Symb.NONE) {
          throw new Exception(s + STRS_ERR[ERR_OPSYMB]);
        }
      }
      else if (isNumeric(s.charAt(0))) { //是数字
        o = new Int(s);

      }
      else if (s.charAt(s.length() - 1) == ')') { //是过调用
        o = callSub(s, varList);
      }
      else if (s.charAt(s.length() - 1) == ']') { //是数组
        o = _getArr(s, varList);
      }
      else if (Bool.isBool(s)) { //是BOOL值
        o = new Bool(s);
      }
      else { //是变量
        o = _getVar(s, varList);
        if (o == null) {
          throw new Exception(s + STRS_ERR[ERR_NO_VAR]);
        }
      }
      vPushBack(tgt, o);
    }
    return tgt;
  }

  /**
   * 字符串运算,只支持连接操作
   *
   * @param expr Stack
   */
  private void calcExprStrImpl(Vector expr) {
    StringBuffer sb = new StringBuffer();
    while (expr.size() > 0) { //不停的运算
      Object ts = vPopFront(expr); //这里有可能是integer型,不能用强制转换
      if (! (ts instanceof Symb)) { //如果不是符号
        sb.append( ( (DataType) ts).getString());
      }
    }
    vPushFront(expr, new Str(sb.toString()));
  }

  /**
   * 求值运算实现
   *
   * @param expr Stack
   */
  private void calcExprNumImpl(Vector expr) {
    if (expr.size() == 1) { //单独变量
      return;
    }
    else { //表达式
      //按优先级进行计算,优先级如下:() 取负(正)值  */ + - %
     Object element1 = vPopFront(expr);
      if (element1 instanceof Symb) {
        if ( ( (Symb) element1).getVal() == Symb.LP) {
          calcExprNumImpl(expr);
          Object element2 = vPopFront(expr);
          Object element3 = vPopFront(expr);
          if (element3 instanceof Symb && ( (Symb) element3).getVal() == Symb.RP) { //扔掉反括号
            vPushFront(expr, element2);
          }
          else { //括号中如果仍未计算完成,则继续
            vPushFront(expr, element3);
            vPushFront(expr, element2);
            vPushFront(expr, element1);
            calcExprNumImpl(expr); //再算括号中的内容
          }
        }
        else //取正值
        if ( ( (Symb) element1).getVal() == Symb.ADD) {
          calcExprNumImpl(expr);
        }
        else //取负值
        if ( ( (Symb) element1).getVal() == Symb.SUB) {
          Object element2 = vPopFront(expr);
          if (element2 instanceof Int) { //立即数
            element2 = new Int( - ( (Int) element2).getVal());
            vPushFront(expr, element2);
          }
          else { //表达式
            vPushFront(expr, element2);
            calcExprNumImpl(expr);
            vPushFront(expr, element1);
            calcExprNumImpl(expr);
          }
        }
      }
      else //是数字
      if (element1 instanceof Int) {
        Symb element2 = (Symb) vPopFront(expr); //应是操作符
        Object element3 = vPopFront(expr); // 可能是操作数或操作符
        //四则运算
        if ( ( (Symb) element2).getVal() == Symb.MUL
            || ( (Symb) element2).getVal() == Symb.DIV) {
          if (element3 instanceof Int) {
            int n1 = ( (Int) element1).getVal();
            int n2 = ( (Int) element3).getVal();
            Int val = new Int( ( (Symb) element2).getVal() == Symb.MUL ? n1 * n2 : n1 / n2);
            vPushFront(expr, val);
          }
          else {
            vPushFront(expr, element3);
            calcExprNumImpl(expr);
            vPushFront(expr, element2);
            vPushFront(expr, element1);
            calcExprNumImpl(expr);
          }
        }
        else
        if ( ( (Symb) element2).getVal() == Symb.ADD
            || ( (Symb) element2).getVal() == Symb.SUB) {

          boolean calc = false;
          if (element3 instanceof Int) {
            if (expr.size() == 0) { //无更多操作符和操作数时计算
              calc = true;
            }
            else {
              Object element4 = vPopFront(expr);
              if (element4 != null) {
                if ( ( (Symb) element4).getVal() != Symb.MUL
                    && ( (Symb) element4).getVal() != Symb.DIV
                    ) {
                  calc = true;
                }
                vPushFront(expr, element4);
              }
            }
          }
          if (calc) {
            int n1 = ( (Int) element1).getVal();
            int n2 = ( (Int) element3).getVal();
            Int val = new Int( ( (Symb) element2).getVal() == Symb.ADD ? n1 + n2 : n1 - n2);
            vPushFront(expr, val);
          }
          else {
            //先算右边的表达式
            vPushFront(expr, element3); //放回去
            calcExprNumImpl(expr); //计算

            vPushFront(expr, element2);
            vPushFront(expr, element1);
            calcExprNumImpl(expr);
          }
        }
        else if (element2.getVal() == Symb.RP) { //是右括号
          if (element3 != null) {
            vPushFront(expr, element3);
          }
          vPushFront(expr, element2);
          vPushFront(expr, element1);
          return;
        }

      }
    }
  }

  /**
   * 逻辑运算实现
   *
   * @param expr Stack
   */
  private void calcExprLgcImpl(Vector expr) {
    //计算逻辑表达式
    if (expr.size() == 1) { //单独变量
      return;
    }
    else { //表达式
      //按优先级进行计算,优先级如下:() 取负(正)值  */ + - %
     Object element1 = vPopFront(expr);
      if (element1 instanceof Symb) { //括号
        if ( ( (Symb) element1).getVal() == Symb.LP) {
          calcExprLgcImpl(expr);
          Object element2 = vPopFront(expr);
          Object element3 = vPopFront(expr);
          if (element3 instanceof Symb && ( (Symb) element3).getVal() == Symb.RP) { //扔掉反括号
            vPushFront(expr, element2);
          }
          else { //括号中如果仍未计算完成,则继续
            vPushFront(expr, element3);
            vPushFront(expr, element2);
            vPushFront(expr, element1);
            calcExprLgcImpl(expr); //再算括号中的内容
          }
        }
        else
        if ( ( (Symb) element1).getVal() == Symb.NOT) { //取反
          Object element2 = vPopFront(expr);
          if (element2 instanceof Bool) { //立即数
            element2 = new Bool(! ( (Bool) element2).getVal());
            vPushFront(expr, element2);
          }
          else { //表达式
            vPushFront(expr, element2);
            calcExprLgcImpl(expr);
            vPushFront(expr, element1);
            calcExprLgcImpl(expr);
          }
        }
      }
      else
      if (element1 instanceof Int) { //><=
        int n1, n2;

        n1 = ( (Int) element1).getVal();

        Object element2 = vPopFront(expr); ; //应是操作符
        Object element3 = vPopFront(expr); // 操作数或操作符 >= <=

        Symb operator = (Symb) element2;
        n2 = ( (Int) element3).getVal();

        boolean result = false;
        if (operator.getVal() == Symb.GRE) {
          result = n1 > n2;
        }
        else
        if (operator.getVal() == Symb.LES) {
          result = n1 < n2;
        }
        else
        if (operator.getVal() == Symb.GE) {
          result = n1 >= n2;
        }
        else
        if (operator.getVal() == Symb.LE) {
          result = n1 <= n2;
        }
        else
        if (operator.getVal() == Symb.NE) {
          result = n1 != n2;
        }
        else
        if (operator.getVal() == Symb.EQU) {
          result = n1 == n2;
        }
        vPushFront(expr, new Bool(result));
      }
      else
      if (element1 instanceof Bool) { //&|
        Symb element2 = (Symb) vPopFront(expr); //应是操作符
        Object element3 = vPopFront(expr); // 操作数或操作符 >= <=
        if (element2.getVal() == Symb.AND) {
          if (element3 instanceof Bool) {
            boolean result = ( (Bool) element1).getVal() && ( (Bool) element3).getVal();
            vPushFront(expr, new Bool(result));
          }
          else {
            vPushFront(expr, element3);
            calcExprLgcImpl(expr);
            vPushFront(expr, element2);
            vPushFront(expr, element1);
            calcExprLgcImpl(expr);
          }
        }
        else
        if (element2.getVal() == Symb.OR) {
          boolean calc = false;
          if (element3 instanceof Bool) {
            if (expr.size() == 0) {
              calc = true;
            }
            else {
              Object element4 = vPopFront(expr); // 操作数或操作符 >= <=
              if (element4 instanceof Symb) {
                if ( ( (Symb) element4).getVal() != Symb.AND) {
                  calc = true;
                }
              }
              vPushFront(expr, element4);
            }
          }
          if (calc) {
            boolean result = ( (Bool) element1).getVal() || ( (Bool) element3).getVal();
            vPushFront(expr, new Bool(result));
          }
          else {
            vPushFront(expr, element3);
            calcExprLgcImpl(expr);
            vPushFront(expr, element2);
            vPushFront(expr, element1);
            calcExprLgcImpl(expr);
          }

        }
        else if (element2.getVal() == Symb.RP) { //是右括号
          if (element3 != null) {
            vPushFront(expr, element3);
          }
          vPushFront(expr, element2);
          vPushFront(expr, element1);
          return;
        }

      }

    }
  }

//---------------------------过程调用------------------------------

  /**
   * 过程调用
   * 写在脚本中的参数,a(p1,p2,p3)   在传递的vector中 p3,p2,p1  的顺序排列
   * @param instruct String
   * @param varList Hashtable
   * @throws Exception
   * @return Object
   */

  private Object callSub(String instruct, Hashtable varList) throws Exception {
    if (instruct == null) {
      return _sub(null, 0);
    }
    else {
      String paraVal = instruct.substring(instruct.indexOf('(') + 1, instruct.lastIndexOf(')'));
      Vector paraStack = new Vector();
      if (paraVal.length() != 0) { //分解参数

        Vector sValue = parseInstruct(paraVal);
        while (sValue.size() > 0) {

          //解析出每个表达式串,以','为分隔符
          StringBuffer exprStrBuf = new StringBuffer();
          while (sValue.size() > 0) {
            String tmps = vPopFront(sValue).toString();
            if (tmps.charAt(0) != ',') {
              exprStrBuf.append(tmps);
            }
            else {
              break;
            }
          }
          String exprStr = exprStrBuf.toString();

          //计算表达式的值
          Object v = calcExpr(exprStr, varList);
          if (v != null) {
            vPushFront(paraStack, v); //参数入栈
          }
          else {
            throw new Exception(STRS_ERR[ERR_PARA_CALC] + exprStr);
          }

        } //end while
      }

      //查找脚本中的过程
      String subName = getFirstWord(instruct);
      Object addr = subAddr.get(subName);
      if (addr != null) {
        int ip = ( (Int) addr).getVal(); //得到过程行号
        return _sub(paraStack, ip); //过程调用
      }
      else {
        //查找系统标准过程和用户扩充过程表
        for (int i = 0; i < extSubList.size(); i++) {
          Lib ext = (Lib) extSubList.elementAt(i);
          int mID = ext.getMethodID(subName);
          if (mID >= 0) {

            //调用外部过程
            Object re = ext.call(paraStack, mID);

            return re;
          }
        }

        //仍没有找到,报错
        throw new Exception(STRS_ERR[ERR_NOSUB]);

      }
    }
  }

//---------------------------  数组处理  ------------------------------
  /**
   * 解析数组参数 比如 arrName[a+b][35-4]
   * @param arrStr String
   * @param varList Hashtable
   * @throws Exception
   * @return Stack   反回 a+b  , 35-4
   */
  private Vector parseArrayPos(String arrStr, Hashtable varList) throws Exception {
    Vector stack = new Vector();

    arrStr = arrStr.substring(arrStr.indexOf('['));
    int leftQ = 0;
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < arrStr.length(); i++) {
      char ch = arrStr.charAt(i);
      if (ch == '[') {
        leftQ++;
      }
      else
      if (ch == ']') {
        leftQ--;
        Object o = calcExpr(sb.toString(), varList);
        if (o instanceof String) { //数组维数不能为串
          throw new Exception(STRS_ERR[ERR_TYPE_INVALID]);
        }
        vPushBack(stack, o);
        sb.setLength(0);
      }
      else {
        sb.append(ch);
      }
    }
    return stack;
  }

  /**
   * 创建数组变量或赋值   语句是:arr[3+2][2]:i    或 arr[3][2]:s   或arr[1][2]=3
   * @param instruct String
   * @param varList Hashtable
   * @throws Exception
   */
  private void _setArr(String instruct, Hashtable varList) throws Exception {
    Vector stack = parseInstruct(instruct);
    String leftStr = (String) vPopFront(stack);

    String arrName = getFirstWord(leftStr); //取得数组的名字
    arrName = arrName.toLowerCase();
    Vector paraStack = parseArrayPos(leftStr, varList); //分解参数
    int deepth = paraStack.size(); //数组深度

    //把每一维的参数放进数组里
    int[] dimPara = new int[deepth];
    for (int i = dimPara.length - 1; i >= 0; i--) {
      dimPara[i] = ( (Int) vPopBack(paraStack)).getVal();
    }

    if (stack.size() == 0
        || (stack.size() != 0 && ( (String) vPopFront(stack)).charAt(0) == ':')
        ) { //创建

      //创建数组对象,放入变量表
      Array arr = new Array(dimPara);
      varList.put(arrName, arr); //放入变量表中
    }
    else { //赋值
      Object arr = varList.get(arrName);
      if (arr != null && arr instanceof Array) {
        String exprStr = instruct.substring(instruct.indexOf('=') + 1);
        ( (Array) arr).setValue(dimPara, calcExpr(exprStr, varList)); //赋值
      }
    }
  }

  /**
   * 取数组的值
   *
   * @param arrExpr String
   * @param varList Hashtable
   * @throws Exception
   * @return Object
   */
  private Object _getArr(String arrExpr, Hashtable varList) throws Exception {

    String arrName = getFirstWord(arrExpr); //取得数组的名字
    arrName = arrName.toLowerCase();
    Vector paraStack = parseArrayPos(arrExpr, varList); //分解参数
    int deepth = paraStack.size(); //数组深度

    //把每一维的参数放进数组里
    int[] dimPara = new int[deepth];
    for (int i = dimPara.length - 1; i >= 0; i--) {
      dimPara[i] = ( (Int) vPopBack(paraStack)).getVal();
    }

    Object arr = varList.get(arrName);
    if (arr != null && arr instanceof Array) {
      return ( (Array) arr).getValue(dimPara); //取值
    }
    return null;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -