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

📄 interpreter.java

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

import java.io.*;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;

/**
 * 解释器 Interpreter , can execute script that like basic language phrase.
 *
 * the next version would be comment with english all , sorry
 *
 *   KNOWN ISSUE:
 *
 *  MODIFY LOG :
 *  20070117  修改了load()方法,使支持本地文件载入,使可以支持GB2312文件
 *            修改了start()方法,使外部传进来的环境变量都变为小写,否则可能无法找到此变量
 *            修改了calcExprLogImpl()方法,修正计算 (true) 表达式的错误
 *            修改了calcExprNumImpl()方法,修正计算 (true) 表达式的错误
 *            修正了Stdlib中一些标准方法的错误,因上0.8.0中修改了容器,所以弹出的先后顺序有误
 *            修正了load中,对行尾注释的错误处理
 *
 *
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2007</p>
 * <p>Company: </p>
 * @author Gust
 * @version 0.9.0     sourceforge opened first version.
 * @ lastModify 20071109
 */

public class Interpreter {

  static private final String[] STRS_RESERVED = {
      "if", "else", "endif", "while", "loop", "sub", "ret"};
  static private final String STR_SYMBOL = "+-*/><()=, []:&|!\'";
  static private final String STR_NUMERIC = "0123456789";

  //关键字代码
  static private final int
      KEYWORD_IF = 0
      , KEYWORD_ELSE = 1
      , KEYWORD_ENDIF = 2
      , KEYWORD_WHILE = 3
      , KEYWORD_LOOP = 4
      , KEYWORD_SUB = 5
      , KEYWORD_RET = 6
      ;

  public static final int
      ERR_ILLEGAL = 0
      , ERR_VAR = 1
      , ERR_TYPE_INVALID = 2
      , ERR_NOSUB = 3
      , ERR_NO_VAR = 4
      , ERR_PARA_CALC = 5
      , ERR_PAESEPARA = 6
      , ERR_NO_SRC = 7
      , ERR_OPSYMB = 8
      , ERR_ARR_OUT = 9
      ;
  public static final String[] STRS_ERR = {
      " Illegal statment ,"
      , " Invalid variable name "
      , " Data type error "
      , " No such method "
      , " No such variable "
      , " Method parameter error "
      , " Parameter count error "
      , " Code not load yet "
      , " Operation symbol error  "
      , " Array out of bounds  "
  };

  //源码字符串数组
  private String[] srcCode;

  //变量范围控制
  private boolean isTopCall; //是否是顶级调用
  private Hashtable golbleVar; //全局变量,在init()中初始化

  //脚本中过程首地址  ,sub address in script
  private Hashtable subAddr;

  //系统过程及扩充过程列表 ,extend method lib
  private Vector extSubList;

  /**
   * 构造方法
   */
  public Interpreter() {
  }

  /**
   *初始化类
   */
  private void init() {
    srcCode = null;
    //脚本中过程首地址
    subAddr = new Hashtable();
    //系统过程及扩充过程列表
    extSubList = new Vector();

    //加入标准库
    Stdlib stdlib = new Stdlib();
    register(stdlib);
  }

  /**
   * 装载脚本
   * @param path String
   */
  public void load(String path) {

    //初始化
    init();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
      //File ipFile = new File(path); //j2se使用此方法
      //FileInputStream is = new FileInputStream(ipFile);

      InputStream is = new Object().getClass().getResourceAsStream(path);   //j2me使用
      int ch = 0;
      while ( (ch = is.read()) != -1) {
        baos.write(ch);
      }
    }
    catch (Exception ex) {
    }
    byte[] srcBytes = baos.toByteArray();

    //求出总行数,去掉0x0d标识,win和xnix下的换行不统一
    int lineCount = 1; //增加一行,留下余地
    for (int i = 0; i < srcBytes.length; i++) {
      int ch = srcBytes[i];
      if (ch == 0x0a) {
        lineCount++;
      }
      if (ch == 0x0d || ch == 0x09) { //预处理0x0d0a=0x20,0x09=0x20
        srcBytes[i] = 0x20;
      }
    }

    //转换为String数组
    ByteArrayOutputStream line = new ByteArrayOutputStream();
    //StringBuffer sb = new StringBuffer();
    srcCode = new String[lineCount];
    lineCount = 0;
    for (int i = 0; i < srcBytes.length; i++) {
      if (srcBytes[i] == 0x0a || i + 1 == srcBytes.length) { //行结束,或者文件结束
        try {
          String s = new String(line.toByteArray());    //j2me使用
          //String s = new String(line.toByteArray(), "GB2312"); //j2se使用
          s = s.trim();
          srcCode[lineCount++] = s;
        }
        catch (Exception ex1) {
        }
        line.reset();
      }
      else {
        line.write(srcBytes[i]);
      }
    }
    //预处理
    for (int i = 0; i < srcCode.length; i++) {
      //校验是否有空串
      if (srcCode[i] == null) {
        srcCode[i] = "";
      }
      //去掉注释
      if (srcCode[i].indexOf('\'') >= 0) {
        int dqCount = 0; //双引号计数
        for (int m = 0; m < srcCode[i].length(); m++) {
          char ch = srcCode[i].charAt(m);
          if (ch == '\"') {
            dqCount++;
          }
          if (ch == '\'' && (dqCount % 2) == 0) { //如果 ' 不在双引号内,则说明是注释
            srcCode[i] = srcCode[i].substring(0, m);
            break;
          }
        }
        srcCode[i] = srcCode[i].trim();
      }

      //找过程起始行号
      String ins = srcCode[i];
      if (ins.startsWith(STRS_RESERVED[KEYWORD_SUB] + " ")) {
        String subName = getFirstWord(ins.substring(ins.indexOf(STRS_RESERVED[KEYWORD_SUB]) + STRS_RESERVED[KEYWORD_SUB].length()));
        subAddr.put(subName, new Int(i)); //放入过程表中
      }
    }

  }

  /**
   * 启动执行
   *
   * @return Object
   */
  public Object start() {
    return start(null);
  }

  /**
   *
   * @param env Hashtable
   * @return Object
   */
  public Object start(Hashtable env) {
    //变量范围控制
    isTopCall = true; //是否是顶级调用
    golbleVar = new Hashtable();
    //开始执行代码

    try {
      if (srcCode == null) {
        errout(0, STRS_ERR[ERR_NO_SRC]);
      }
      else {
        //如果环境变量存在
        if (env != null) {
          for (Enumeration e = env.keys(); e.hasMoreElements(); ) {
            Object key = e.nextElement();
            Object val = env.get(key);
            key = ( (String) key).toLowerCase();
            golbleVar.put(key, val);
          }
        }
        //执行脚本
        return callSub(null, null);
      }
    }
    catch (Exception ex) {
    }
    return null;
  }

  /**
   * 过程解析,脚本执行体
   *
   * @param paraStack Hashtable
   * @param instrucPointer int
   * @return Object
   */
  private Object _sub(Vector paraStack, int instrucPointer) {
    int ip = instrucPointer; //运行行号
    //构建变量表
    Hashtable localVar; //本方法的变量表,键是变量名,值是变量值
    //把当前方法的变量表压入stack
    if (isTopCall) {
      localVar = golbleVar; //顶级方法的局部变量为全局变量
      isTopCall = false;
    }
    else {
      localVar = new Hashtable(); //非顶级调用,则是局部方法
    }

    //把参数放进列表

    try {
      String inst = srcCode[ip];

      if (getFirstWord(inst).equals(STRS_RESERVED[KEYWORD_SUB])) { //是子过程

        String paraName = inst.substring(inst.indexOf('(') + 1, inst.lastIndexOf(')'));
        Vector sName = parseInstruct(paraName); //先弹左边参数
        while (sName.size() > 0) {
          String pName = (String) vPopFront(sName);
          if (pName.charAt(0) != ',') {
            localVar.put(pName, vPopBack(paraStack));
          }
        }

        ip++; //跳到下一行
      }
      else { //是主过程,和子过程的区别是,没有sub开头的语句

      }
    }
    catch (Exception ex1) {
      errout(ip, STRS_ERR[ERR_PAESEPARA]);
    }

    while (ip < srcCode.length) {
      try {
        String instruct = srcCode[ip];

        //print(ip + " " + instruct);

        if (instruct.length() != 0) { //非空行

          int keywordCode = getKeywordCode(getFirstWord(instruct));
          if (keywordCode >= 0) { //是关键字语句
            switch (keywordCode) {
              case KEYWORD_WHILE:
                Bool wb = (Bool) calcExpr(instruct.substring(STRS_RESERVED[KEYWORD_WHILE].length()), localVar);
                if (wb.getVal() == false) { //如果为假,则查else或endif
                  int countWhile = 1;
                  for (int i = ip + 1; i < srcCode.length; i++) {
                    String tmpHead = getFirstWord(srcCode[i]);
                    if (tmpHead.equals(STRS_RESERVED[KEYWORD_WHILE])) {
                      countWhile++;
                    }
                    else
                    if (tmpHead.equals(STRS_RESERVED[KEYWORD_LOOP])) {
                      countWhile--;
                    }
                    //跳转
                    if (tmpHead.equals(STRS_RESERVED[KEYWORD_LOOP]) && countWhile == 0) {
                      ip = i;
                      break;
                    }
                  }
                }
                break;
              case KEYWORD_LOOP:
                int countWhile = 1;
                for (int i = ip - 1; i > 0; --i) {
                  String tmpHead = getFirstWord(srcCode[i]);
                  if (tmpHead.equals(STRS_RESERVED[KEYWORD_WHILE])) {
                    countWhile--;
                  }
                  else
                  if (tmpHead.equals(STRS_RESERVED[KEYWORD_LOOP])) {
                    countWhile++;
                  }
                  //跳转
                  if (tmpHead.equals(STRS_RESERVED[KEYWORD_WHILE]) && countWhile == 0) {
                    ip = i - 1;
                    break;
                  }
                }
                break;
              case KEYWORD_IF: //if分支
                Bool ib = (Bool) calcExpr(instruct.substring(STRS_RESERVED[KEYWORD_IF].length()), localVar);
                if (ib.getVal() == false) { //如果为假,则查else或endif
                  int countIf = 1;
                  for (int i = ip + 1; i < srcCode.length; i++) {
                    String tmpHead = getFirstWord(srcCode[i]);
                    if (tmpHead.equals(STRS_RESERVED[KEYWORD_IF])) {
                      countIf++;
                    }
                    else
                    if (tmpHead.equals(STRS_RESERVED[KEYWORD_ENDIF])) {
                      countIf--;
                    }

                    //跳转
                    if (tmpHead.equals(STRS_RESERVED[KEYWORD_ELSE]) && countIf == 1) {
                      ip = i;
                      break;
                    }
                    else
                    if (tmpHead.equals(STRS_RESERVED[KEYWORD_ENDIF]) && countIf == 0) {
                      ip = i;
                      break;
                    }
                  }
                }
                break;
              case KEYWORD_ELSE:
                int countIf = 1;
                for (int i = ip + 1; i < srcCode.length; i++) {
                  String tmpHead = getFirstWord(srcCode[i]);
                  if (tmpHead.equals(STRS_RESERVED[KEYWORD_IF])) {
                    countIf++;
                  }
                  else
                  if (tmpHead.equals(STRS_RESERVED[KEYWORD_ENDIF])) {
                    countIf--;
                  }
                  //跳转
                  if (tmpHead.equals(STRS_RESERVED[KEYWORD_ENDIF]) && countIf == 0) {
                    ip = i;
                    break;
                  }
                }

                break;
              case KEYWORD_SUB:
                return null;
              case KEYWORD_RET: //过程结束
                if (instruct.length() > STRS_RESERVED[KEYWORD_RET].length()) {
                  return calcExpr(instruct.substring(instruct.indexOf(" ")), localVar);
                }
                else {
                  return null;
                }
            }
          }
          else
          if (isArr(instruct)) { //数组
            _setArr(instruct, localVar);
          }
          else
          if (isSubCall(instruct)) { //过程
            callSub(instruct, localVar);
          }
          else
          if (isVar(instruct)) { //是赋值语句
            _setVar(instruct, localVar);
          }
          else {
            errout(ip, STRS_ERR[ERR_ILLEGAL]);
          }
        }
      }
      catch (Exception ex) {
        errout(ip, STRS_ERR[ERR_ILLEGAL] + ex.getMessage());
        ex.printStackTrace();
        break;
      }
      //指针自动加一
      ip++;
    } //end while

    return null;
  }

  /**
   * 注册扩充方法库
   * @param lib Lib
   */
  public void register(Lib lib) {
    extSubList.addElement(lib);
  }

//;----------------------------------------------------------------------------
//;                                  工具方法
//;----------------------------------------------------------------------------

  /**
   * 得到第一个单词
   * @param instruct String
   * @return String
   */
  private String getFirstWord(String instruct) {
    instruct = instruct.trim();
    StringBuffer tsb = new StringBuffer();
    for (int i = 0; i < instruct.length(); i++) {
      if (isSymbol(instruct.charAt(i))) {
        break;
      }
      tsb.append(instruct.charAt(i));
    }
    return tsb.toString().trim().toLowerCase();
  }

  /**
   * 是否是关键字
   * @param s String
   * @return boolean
   */
  private int getKeywordCode(String s) {
    if (s == null || s.length() == 0) {
      return -1;
    }
    for (int i = 0; i < STRS_RESERVED.length; i++) {
      if (s.equals(STRS_RESERVED[i])) {
        return i;
      }
    }
    return -1;
  }

  /**
   * 是否是过程调用
   * @param s String
   * @return boolean
   */
  private boolean isSubCall(String s) {
    if (getInstructType(s) == '(') {
      return true;
    }
    return false;
  }

  /**
   * 是变量
   * @param s String
   * @return boolean
   */
  private boolean isVar(String s) {
    if (getInstructType(s) == '=') {
      return true;
    }

    return false;
  }

  /**
   * 是数组
   * @param s String
   * @return boolean
   */
  private boolean isArr(String s) {
    if (getInstructType(s) == '[') {
      return true;
    }

    return false;
  }

  /**
   * 得到第一个符号,由此可判别出是一条什么语句
   * @param instruct String
   * @return String
   */
  private char getInstructType(String instruct) {
    for (int i = 0; i < instruct.length(); i++) {
      if ("(=[".indexOf(instruct.charAt(i)) >= 0) {

⌨️ 快捷键说明

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