使用Java写的解释器(一)

解释器

解释器(英语:Interpreter),又译为直译器,是一种电脑程序,能够把高级编程语言一行一行直接转译运行。解释器不会一次把整个程序转译出来,只像一位“中间人”,每次运行程序时都要先转成另一种语言再作运行,因此解释器的程序运行速度比较缓慢。它每转译一行程序叙述就立刻运行,然后再转译下一行,再运行,如此不停地进行下去。
例如 JavaScript,在浏览器中就是用解释器进行处理运行,还有很多,这里就不一一举例。

目的

写这个解释器的目的的?就是为了方便游戏对象操作,我们都知道,一个游戏对象,有着很多的属性,如果开发者想要开发一个新玩法,就必须更改其模型,然而,这样来说是不现实的,如果新的玩法需要记录的数据只是一次性的,即领个礼包什么的,获得只是这个新玩法自带的,那我们更改模型这样的不对了,所以,我想写一个解释器,用来进行这方面数据的处理。

第一步: 表达式计算

思考一下,简单的加减乘除实现都很简单,那么,如果进行可扩展的呢?如果里面可以写变量呢?

package util;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.util.Pair;

/**
 *
 * @author lol
 */
public final class NumberGet {

    private Map<String, Map<String, Object>> pro;

    public NumberGet(Map<String, Object> u) {
        pro = new HashMap();
        pro.put("u", u);
    }

    public NumberGet(Map<String, Object> u, Map<String, Object> o) {
        pro = new HashMap();
        pro.put("u", u);
        pro.put("o", o);
    }

    public NumberGet() {
        pro = new HashMap();
    }

    public void setPro(Map<String, Map<String, Object>> pro) {
        this.pro = pro;
    }

    public Object operation(String str) throws OperationException {
        if (str.charAt(0) == '#') {
            return str.substring(1);
        } else {
            return (int) Double.parseDouble(operation(str, 0).getValue().toString());
        }
    }

    // 获取属性值
    private Pair getNumOfV(String str, int index) throws OperationException {
        String tempStr = new String();
        int i;
        char t;
        String owner = ""; // 属性所有者
        for (i = index; i < str.length(); i++) {
            t = str.charAt(i);
            if (t == '.') {
                i++;
                break;
            }
            owner += t;
        }
        // System.out.println("归属(NumberGet.65):" + owner);
        for (; i < str.length(); i++) {
            t = str.charAt(i);
            if (t == 'v' && i < str.length() && str.charAt(i + 1) == '(') {
                Pair p = getNumOfV(str, i + 2);
                i = Integer.parseInt(p.getKey().toString());
                tempStr += p.getValue().toString();
            } else if (Character.isLetterOrDigit(t) || t == '_') {
                tempStr += t;
            } else if (t == ')') {
                break;
            } else if (t == '(') {
                throw new OperationException("小括号不匹配---( " + str.substring(0, i) + " )");
            } else {
                throw new OperationException("只能是字符数字和下划线('_')---( " + str.substring(0, i) + " )");
            }
        }
        if (i == str.length()) {
            throw new OperationException("未找到匹配的右花括号---( " + str.substring(0, i) + " )");
        }
        Map<String, Object> own = pro.get(owner);
        if (own == null) {
            pro.put(owner, new HashMap());
            own = pro.get(owner);
        }
        Object o = own.get(tempStr);
        if (o == null) {
            pro.get(owner).put(tempStr, "0");
            o = pro.get(owner).get(tempStr);
        }
        return new Pair(i, (int) Double.parseDouble(o.toString()));
    }

    // 获取属性值
    private Pair getNum(String str, int index) throws OperationException {
        String tempStr = new String();
        int i;
        char t;
        String owner = ""; // 属性所有者
        for (i = index; i < str.length(); i++) {
            t = str.charAt(i);
            if (t == '.') {
                i++;
                break;
            }
            owner += t;
        }
        // System.out.println("归属(NumberGet.112):" + owner);
        for (; i < str.length(); i++) {
            t = str.charAt(i);
            if (t == 'v' && i < str.length() && str.charAt(i + 1) == '(') {
                Pair p = getNumOfV(str, i + 2);
                i = Integer.parseInt(p.getKey().toString());
                tempStr += p.getValue().toString();
            } else if (Character.isLetterOrDigit(t) || t == '_') {
                tempStr += t;
            } else if (t == '}') {
                break;
            } else if (t == '{') {
                throw new OperationException("花括号不匹配---( " + str.substring(0, i) + " )");
            } else {
                throw new OperationException("只能是字符数字和下划线('_')---( " + str.substring(0, i) + " )");
            }
        }
        if (i == str.length()) {
            throw new OperationException("未找到匹配的右花括号---( " + str.substring(0, i) + " )");
        }
        Map<String, Object> own = pro.get(owner);
        if (own == null) {
            pro.put(owner, new HashMap());
            own = pro.get(owner);
        }
        Object o = own.get(tempStr);
        if (o == null) {
            pro.get(owner).put(tempStr, "0");
            o = pro.get(owner).get(tempStr);
        }

        return new Pair(i, Double.parseDouble(o.toString()));
    }


    // 获取属性值,不存在花括号
    private Pair getNumWithoutLR(String str, int index) throws OperationException {
        int i = index;
        char t;
        int length = str.length();
        char[] chars = str.toCharArray();
        String leftStr = new String();
        for (; i < length; i++) {
            if (!Character.isLetterOrDigit(chars[i]) && chars[i] != '.') {
                break;
            }
            leftStr += chars[i];
        }
        String owner = "t"; // 属性所有者
        if (leftStr.indexOf('.') != -1) {
            owner = leftStr.substring(0, leftStr.indexOf('.'));
            leftStr = leftStr.substring(leftStr.indexOf('.') + 1);
        }
        Map<String, Object> own = pro.get(owner);
        if (own == null) {
            pro.put(owner, new HashMap());
            own = pro.get(owner);
        }
        Object o = own.get(leftStr);
        if (o == null) {
            pro.get(owner).put(leftStr, "0");
            o = pro.get(owner).get(leftStr);
        }
        return new Pair(i, Double.parseDouble(o.toString()));
    }

    // 计算二个数
    private double getNum(double a, Object opr, double b) throws OperationException {
        //Thread.sleep(1);
        //System.out.println("\t\t" + a + opr.toString() + b);
        if (opr.equals("==")) {
            if (a == b) {
                return 1;
            } else {
                return 0;
            }
        } else if (opr.equals("!=")) {
            if (a == b) {
                return 0;
            } else {
                return 1;
            }
        } else if (opr.equals(">=")) {
            if (a >= b) {
                return 1;
            } else {
                return 0;
            }
        } else if (opr.equals("<=")) {
            if (a <= b) {
                return 1;
            } else {
                return 0;
            }
        } else if (opr.equals("&&")) {
            if (a != 0 && b != 0) {
                return 1;
            } else {
                return 0;
            }
        } else if (opr.equals("||")) {
            if (a != 0 || b != 0) {
                return 1;
            } else {
                return 0;
            }
        } else if (opr.equals('>')) {
            if (a > b) {
                return 1;
            } else {
                return 0;
            }
        } else if (opr.equals('<')) {
            if (a < b) {
                return 1;
            } else {
                return 0;
            }
        } else if (opr.equals('+')) {
            return a + b;
        } else if (opr.equals('-')) {
            return a - b;
        } else if (opr.equals('*')) {
            return a * b;
        } else if (opr.equals('/')) {
            return a / b;
        }  else if (opr.equals('%')) {
            return a % b;
        } else if (opr.equals('=')) {
            return a;
        } else {
            throw new OperationException("非法运算符---( " + opr + " )");
        }
    }

    // 获取上一个数字和运算符
    private void getNum(Stack s, double num) throws OperationException {
        if (!s.empty()) {
            Object op = s.pop();
            Object leftNum = s.pop();
            num = getNum(Double.parseDouble(leftNum.toString()), op, num);
        }
        s.add(num);
    }

    // 是否为运算符
    private boolean isOp(char t) {
        if (t == '!' || t == '=' || t == '<' || t == '>' || t == '+' || t == '-' || t == '/' || t == '*' || t == '%') {
            return true;
        } else {
            return false;
        }
    }

    // 计算
    private Pair operation(String str, int index) throws OperationException {
        Stack s = new Stack();
        double num = 0, num3 = 10, temp;
        boolean flag = false;
        boolean isTrue = true;
        int i;
        char t;
        for (i = index; i < str.length(); i++) {
            t = str.charAt(i);
            if (t == '(') {
                Pair p = operation(str, i + 1);
                if (isTrue) {
                    num = Double.parseDouble(p.getValue().toString());
                }
                i = Integer.parseInt(p.getKey().toString());
            } else if (t == ')') {
                break;
            } else if (t == '?') {
                if (!s.empty()) {
                    Object op = s.pop();
                    Object leftNum = s.pop();
                    num = getNum(Double.parseDouble(leftNum.toString()), op, num);
                }
                if (num == 0) {
                    isTrue = false;
                }
                num = 0;
                num3 = 10;
                flag = false;
            } else if (t == ':') {
                if (!isTrue) {
                    num = 0;
                    num3 = 10;
                    flag = false;
                    isTrue = true;
                } else {
                    isTrue = false;
                }
            } else if (!isTrue) {
                // doNothing
            } else if (t == '{') {
                Pair p = getNum(str, i + 1);
                num = Double.parseDouble(p.getValue().toString());
                i = Integer.parseInt(p.getKey().toString());
            } else if (t == '.') {
                if (!flag) {
                    flag = true;
                } else {
                    throw new OperationException("非法小数点---( " + str.substring(0, i + 1) + " )");
                }
            } else if (Character.isDigit(t)) {
                if (!flag) {
                    num *= 10;
                    num += t - '0';
                } else {
                    temp = t - '0';
                    temp /= num3;
                    num3 *= 10;
                    num += temp;
                }
            } else if (isOp(t)) {
                if ((i + 1) < str.length() && isOp(str.charAt(i + 1))) {
                    getNum(s, num);
                    s.add(t + String.valueOf(str.charAt(i + 1)));
                    i++;
                } else {
                    getNum(s, num);
                    s.add(t);
                }
                num = 0;
                num3 = 10;
                flag = false;
            } else if (t == '|') {
                if (str.charAt(i + 1) != t) {
                    throw new OperationException("非法条件运算符---( " + str.substring(0, i + 1) + " )");
                }
                getNum(s, num);
                s.add("||");
                Pair p = operationOfAndOr(str, i + 2);
                System.out.println(p);
                num = Double.parseDouble(p.getValue().toString());
                i = Integer.parseInt(p.getKey().toString());
            }  else if (t == '&') {
                if (str.charAt(i + 1) != t) {
                    throw new OperationException("非法条件运算符---( " + str.substring(0, i + 1) + " )");
                }
                getNum(s, num);
                s.add("&&");
                Pair p = operationOfAndOr(str, i + 2);
                num = Double.parseDouble(p.getValue().toString());
                i = Integer.parseInt(p.getKey().toString());
            } else if (Character.isLetter(t)){
                Pair p = getNumWithoutLR(str, i);
                num = Double.parseDouble(p.getValue().toString());
                i = Integer.parseInt(p.getKey().toString());
                i--;
            }
        }
        while (s.size() > 1) {
            Object op = s.pop();
            Object leftNum = s.pop();
            num = getNum(Double.parseDouble(leftNum.toString()), op, num);
        }
        return new Pair(i, num);
    }

    // 计算&& 和 ||
    private Pair operationOfAndOr(String str, int index) throws OperationException {
        Stack s = new Stack();
        double num = 0, num3 = 10, temp;
        boolean flag = false;
        boolean isTrue = true;
        int i;
        char t;
        for (i = index; i < str.length(); i++) {
            t = str.charAt(i);
            if (t == '(') {
                Pair p = operation(str, i + 1);
                if (isTrue) {
                    num = Double.parseDouble(p.getValue().toString());
                }
                i = Integer.parseInt(p.getKey().toString());
            } else if (t == ')') {
                break;
            } else if (t == '?') {
                if (!s.empty()) {
                    Object op = s.pop();
                    Object leftNum = s.pop();
                    num = getNum(Double.parseDouble(leftNum.toString()), op, num);
                }
                if (num == 0) {
                    isTrue = false;
                }
                num = 0;
                num3 = 10;
                flag = false;
            } else if (t == ':') {
                if (!isTrue) {
                    num = 0;
                    num3 = 10;
                    flag = false;
                    isTrue = true;
                } else {
                    isTrue = false;
                }
            } else if (!isTrue) {
                // doNothing
            } else if (t == '{') {
                Pair p = getNum(str, i + 1);
                num = Double.parseDouble(p.getValue().toString());
                i = Integer.parseInt(p.getKey().toString());
            } else if (t == '.') {
                if (!flag) {
                    flag = true;
                } else {
                    throw new OperationException("非法小数点---( " + str.substring(0, i + 1) + " )");
                }
            } else if (Character.isDigit(t)) {
                if (!flag) {
                    num *= 10;
                    num += t - '0';
                } else {
                    temp = t - '0';
                    temp /= num3;
                    num3 *= 10;
                    num += temp;
                }
            } else if (isOp(t)) {
                if ((i + 1) < str.length() && isOp(str.charAt(i + 1))) {
                    getNum(s, num);
                    s.add(t + String.valueOf(str.charAt(i + 1)));
                    i++;
                } else {
                    getNum(s, num);
                    s.add(t);
                }
                num = 0;
                num3 = 10;
                flag = false;
            } else if (Character.isLetter(t)){
                Pair p = getNumWithoutLR(str, i);
                num = Double.parseDouble(p.getValue().toString());
                i = Integer.parseInt(p.getKey().toString());
                i--;
            } else if (t == '|' || t == '&' || t == '?' || t == ':') {
                i--;
                break;
            }
        }
        while (s.size() > 1) {
            Object op = s.pop();
            Object leftNum = s.pop();
            num = getNum(Double.parseDouble(leftNum.toString()), op, num);
        }
        return new Pair(i, num);
    }

    public static void main(String[] args) {
        Map<String, Object> u = new HashMap();
        u.put("gjl", 100);
        u.put("temp_100_lvl", 6);
        Map<String, Object> o = new HashMap();
        o.put("fyl", 100);
        NumberGet ng = new NumberGet(u, o);
        try {
            System.out.println(ng.operation("u.gjl+u.gjl"));
        } catch (OperationException ex) {
            ex.printStackTrace();
        }
    }
}

我去除了乘除法的优先级,优先级由括号进行控制,上面就可以实现我们所需要的表达式计算了。

第二步: 多行处理(赋值、条件、循环)

这里我们用上面的表达式计算进行计算处理,这里其实还是很简单的,我们只需要利用Java写好的if for while即可。

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.util.Pair;

/**
 *
 * @author lol
 */
public class GC {

    private Map<String, Map<String, Object>> pro;

    static Map<String, Integer> keyword = null;

    public GC() {
        if (keyword == null) {
            keyword = new HashMap();
            keyword.put("for", 3);
            keyword.put("while", 2);
            keyword.put("if", 1);
        }
        pro = new HashMap();
    }

    // 去除空格
    private int clearSpace(char[] chars, int start, int end) {
        int length = end;
        int i = start;
        // 去空格
        for (; i < length; i++) {
            if (chars[i] != ' ' && chars[i] != '\t' && chars[i] != '\n' && chars[i] != '\r') {
                break;
            }
        }
        return i;
    }

    // 获得左边操作语句
    private Pair getLeftStr(char[] chars, int start, int end) {
        int length = end;
        int i = start;
        String leftStr = new String();
        for (; i < length; i++) {
            if (!Character.isLetterOrDigit(chars[i]) && chars[i] != '.') {
                break;
            }
            leftStr += chars[i];
        }
        Pair p = new Pair(i, leftStr);
        return p;
    }

    // 获得右边操作语句
    private Pair getRightStr(char[] chars, int start, int end) {
        int length = end;
        int i = start;
        String rightStr = new String();
        for (; i < length; i++) {
            if (chars[i] == ';') {
                break;
            }
            rightStr += chars[i];
        }
        Pair p = new Pair(i, rightStr);
        return p;
    }

    // 获得左右括号匹配
    private Pair getLeftAndRight(char[] chars, int start, int end, char cLeft, char cRight) {
        // System.out.println("括号匹配:" + cLeft + "|" + cRight + "=====" + String.valueOf(chars).substring(start, end));
        int length = end;
        int i = start;
        int lefts = 0;
        int left = -1;
        int right = -1;
        for (int j = i; j < length; j++) {
            if (chars[j] == cLeft) {
                if (lefts == 0) {
                    left = j;
                }
                lefts++;
            } else if (chars[j] == cRight) {
                if (lefts == 1) {
                    right = j;
                    break;
                } else {
                    lefts--;
                }
            }
        }
        return new Pair(left, right);
    }

    // 处理单行赋值运算
    private Pair getValue(String line, int start, int end) throws OperationException {
        char[] chars = line.toCharArray();
        int length = end;

        int i = start;
        // 去空格
        i = clearSpace(chars, i, length);
        Pair p;

        String leftStr = new String(); // 左边操作对象
        String centerStr = new String(); // 中间操作符
        String rightStr = new String(); // 左边操作对象
        // 检测左边操作对象
        p = getLeftStr(chars, i, length);
        leftStr = (String) p.getValue();
        i = (int) p.getKey();
        //System.out.println("左边操作对象为: " + leftStr);

        // 去空格
        i = clearSpace(chars, i, length);

        // 检测中间操作符
        for (; i < length; i++) {
            if (Character.isLetterOrDigit(chars[i]) || chars[i] == ' ') {
                break;
            }
            centerStr += chars[i];
        }
        //System.out.println("中间操作符为: " + centerStr);

        // 去空格
        i = clearSpace(chars, i, length);

        // 右边操作对象
        p = getRightStr(chars, i, length);
        rightStr = (String) p.getValue();
        i = (int) p.getKey();
        // System.out.println("右边的操作对象为: " + rightStr);
        String own = "t";
        if (leftStr.indexOf('.') != -1) {
            own = leftStr.substring(0, leftStr.indexOf('.'));
            leftStr = leftStr.substring(leftStr.indexOf('.') + 1);
        }
        Map<String, Object> t = pro.get(own);
        if (t == null) {
            pro.put(own, new HashMap());
        }

        t = pro.get(own);

        NumberGet numberGet = new NumberGet();
        numberGet.setPro(pro); // 将数据导入

        if ("=".equals(centerStr)) { // 计算等式
            t.put(leftStr, numberGet.operation(rightStr));
        }
        p = new Pair(i, t.get(leftStr));
        return p;
    }

    // 执行if 和 else
    private int runIFAndElse(String line, int start, int end) throws OperationException {
        char[] chars = line.toCharArray();
        int length = end;
        int i = start;
        Pair p;
        i = clearSpace(chars, i, length);
        p = getLeftAndRight(chars, i, length, '(', ')');
        int left = (int) p.getKey();
        int right = (int) p.getValue();
        // System.out.println("if 的 左右括号为:" + left + "," + right);
        i = clearSpace(chars, right + 1, length);
        // 寻找if范围
        p = getLeftAndRight(chars, i, length, '{', '}');
        int tStartOfIf = (int) p.getKey();
        int tEndOfIf = (int) p.getValue();
        i = clearSpace(chars, tEndOfIf + 1, length);
        p = getLeftStr(chars, i, length);
        String tStr = (String) p.getValue();
        int ti = (int) p.getKey();
        int tStartOfElse = -1;
        int tEndOfElse = -1;
        // 寻找else范围
        if ("else".equals(tStr)) {
            i = clearSpace(chars, ti, length);
            p = getLeftAndRight(chars, i, length, '{', '}');
            tStartOfElse = (int) p.getKey();
            tEndOfElse = (int) p.getValue();
            i = tEndOfElse;
        } else {
            i = tEndOfIf;
        }
        NumberGet numberGet = new NumberGet();
        numberGet.setPro(pro); // 将数据导入

        if (Integer.parseInt(numberGet.operation(line.substring(left + 1, right)).toString()) != 0) { // 执行if 语句
            readLine(line.substring(tStartOfIf + 1, tEndOfIf));
        } else { // 执行else 语句
            if (tStartOfElse != -1 && tEndOfElse != -1) {
                readLine(line.substring(tStartOfElse + 1, tEndOfElse));
            }
        }
        return i;
    }

    // 执行while
    private int runWhile(String line, int start, int end) throws OperationException {
        char[] chars = line.toCharArray();
        int length = end;
        int i = start;
        i = clearSpace(chars, i, length);
        // 获取()内的内容
        Pair p = getLeftAndRight(chars, i, length, '(', ')');
        int left = (int) p.getKey();
        int right = (int) p.getValue();
        i = clearSpace(chars, right + 1, length);
        // 获取{}内的内容
        p = getLeftAndRight(chars, i, length, '{', '}');
        int startOfWhile = (int) p.getKey();
        int endOfWhile = (int) p.getValue();
        NumberGet numberGet = new NumberGet();
        numberGet.setPro(pro); // 将数据导入
        // 执行while循环
        while (Integer.parseInt(numberGet.operation(line.substring(left + 1, right)).toString()) != 0) {
            readLine(line.substring(startOfWhile + 1, endOfWhile));
        }
        return endOfWhile;
    }

    // 执行for
    private int runFor(String line, int start, int end) throws OperationException {
        char[] chars = line.toCharArray();
        int length = end;
        int i = start;
        i = clearSpace(chars, i, length);
        // 获取()内的内容
        Pair p = getLeftAndRight(chars, i, length, '(', ')');
        int left = (int) p.getKey();
        int right = (int) p.getValue();
        // 分析()内的内容
        String temp = line.substring(left + 1, right);
        String firstStr = temp.substring(0, temp.indexOf(';'));
        temp = temp.substring(temp.indexOf(';') + 1);
        String secondStr = temp.substring(0, temp.indexOf(';'));
        String thirdStr = temp.substring(temp.indexOf(';') + 1);
        i = clearSpace(chars, right + 1, length);
        // 获取{}内的内容
        p = getLeftAndRight(chars, i, length, '{', '}');
        int startOfFor = (int) p.getKey();
        int endOfFor = (int) p.getValue();
        NumberGet numberGet = new NumberGet();
        numberGet.setPro(pro); // 将数据导入

        // 执行for循环
        for (readLine(firstStr, 0, firstStr.length()); Integer.parseInt(numberGet.operation(secondStr).toString()) != 0; readLine(thirdStr, 0, thirdStr.length())) {
            readLine(line.substring(startOfFor + 1, endOfFor));
        }
        return endOfFor;
    }
    // 计算从start到end的识别,主要识别关键字。

    public Map<String, Map<String, Object>> getPro() {
        return pro;
    }

    public Object readLine(String line, int start, int end) throws OperationException {
        // System.out.println("当前运行语句为:" + line);
        char[] chars = line.toCharArray();
        int length = end;
        int i = start;
        Pair p = new Pair(0, "None");
        // 去空格
        i = clearSpace(chars, i, length);

        String leftStr = new String(); // 左边操作对象,有可能是关键字。

        // 检测
        p = getLeftStr(chars, i, length);
        leftStr = (String) p.getValue();
        i = (int) p.getKey();

        // 判断关键字,进行相应操作
        if (keyword.get(leftStr) != null) {
            // System.out.println("关键字:" + leftStr);
            switch (keyword.get(leftStr)) {
                case 1: // if else
                    i = runIFAndElse(line, i, length);
                    break;
                case 2: // while
                    i = runWhile(line, i, length);
                    break;
                case 3: // for
                    i = runFor(line, i, length);
                    break;
            }
        } else {
            int tEnd = line.indexOf(';', start);
            if (tEnd == -1) {
                tEnd = end;
            }
            p = getValue(line, start, tEnd);
            i = (int) p.getKey();
            // System.out.println("当前结果为:" + line.substring((int) p.getKey()) + "||" + p);
        }

        if (i + 1 >= length) {
            return p.getValue();
        } else {
            String str = line.substring(i + 1, length);
            return readLine(str, 0, str.length());
        }
    }

    public Object readLine(String line) throws OperationException {
        return readLine(line, 0, line.length());
    }

    public Object readLineFromFile(String fileName) throws OperationException, UnsupportedEncodingException, FileNotFoundException, IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
        StringBuffer out = new StringBuffer();
        String line = null;
        while ((line = in.readLine()) != null) {
            out.append(line);
        }
        String str = out.toString();
        return readLine(str, 0, str.length());
    }

    public static void main(String[] args) throws OperationException, FileNotFoundException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        GC gc = new GC();
        String fileName = "C:\\Users\\lol\\Desktop\\do.txt";
        Class c = Class.forName("util.User");
        Object o= c.newInstance();
        System.out.println(o);
        gc.readLineFromFile(fileName);
        System.out.println(gc.getPro());
    }
}

第三步: 函数处理

还记得上面的if else for while 嘛?这个其实就是函数,只不过调用的方法有点奇特,其实是一样的,根据上面的代码,我们只需要增加函数定义,并把函数加入到关键字判断即可。

那么有人问了,那函数是可动态加载的还是静态内置的呢?这个问题的话,你可以加一些常用的函数,作为静态内置。
动态加载的,都是利用我们这个解释器语言(还没有起名字- -)写的,那么我们只需要记住他的起始点和结束点即可,其他的只需要调用readLine即可啦。

函数处理这个部分就交给读者自己先研发研发啦~,先留个悬念- -

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 不好意思,我不知道怎么用Python一个Java解释器。不过我可以给你一些参考资料,你可以查看一下:https://realpython.com/python-java-interoperability/ 。 ### 回答2: 使用Python编一个完整的Java解释器是一个非常复杂和庞大的任务,几乎是不可能的。Java是一种高级编程语言,有其自己的语法和语义规则,并且运行在Java虚拟机上。要完全实现Java解释器,需要考虑以下几个关键方面: 1. 词法分析和语法分析:需要编一个能够将Java代码转换为抽象语法树(Abstract Syntax Tree, AST)的模块。这个模块需要扫描输入的Java代码,识别出关键字、标识符、运算符等词法单元,并将其组织成语法正确的语句和表达式。 2. 语义分析:在构建AST之后,需要对其进行语义分析。这包括检查变量的作用域、类型检查、语句的合法性等。还需要实现Java的面向对象特性,如类和对象的定义、方法的调用等。 3. 中间代码生成和优化:在分析和检查完AST后,需要将其转换为中间代码。这可以是Java字节码(Java Bytecode)或其他形式的中间表示。中间代码需要进行优化,以提高程序的执行效率。 4. 运行时环境:最后,需要实现一个Java虚拟机(JVM),用于加载和执行生成的中间代码。JVM负责管理内存、执行字节码指令、处理异常等。 以上只是对实现Java解释器所需的最基本功能的简要概述。实际上,Java解释器的开发远比以上内容复杂。由于Python语言的特性与Java语法差异较大,使用Python编Java解释器的复杂性进一步增加。 总结来说,使用Python编一个完整的Java解释器是一个巨大的工程,需要非常深入地理解Java语法和语义规则,并具备大量的编译器实现知识和经验。因此,实际上很少有人会尝试使用Python编一个完整的Java解释器。 ### 回答3: 要用Python编一个Java解释器是一项相当复杂和庞大的任务。由于Python和Java在语法和执行方式上存在较大的差异,因此仅仅使用Python编一个完整的Java解释器是非常困难的。然而,可以借助一些现有的工具和库来实现一个基本的Java解释器。 首先,可以使用ANTLR(ANother Tool for Language Recognition)来构建一个Java语法解析器。ANTLR是一个强大的解析器生成器,可以根据给定的语法规则生成解析器代码。通过编Java语法的规则文件,ANTLR可以自动生成解析器代码,以便将Java代码分解为语法树。 然后,使用Python编一个代码分析器,它将使用ANTLR生成的解析器来读取和处理Java代码的语法树。该代码分析器可以执行诸如语义分析、类型检查和符号表构建等任务,以确保Java代码的正确性。 接下来,可以使用Python的动态执行功能来解释和执行Java代码。Python的`exec`函数可以接受Java代码作为字符串,然后调用Java的编译器将其编译为字节码并执行。但是需要注意的是,由于Python是解释型语言,其执行Java代码的效率可能会较低。 最后,要完善Java解释器,还需要实现Java标准库的一部分,以便支持Java代码中使用的常见类和方法。这可以通过使用Python的库来实现。 总的来说,用Python编一个完整的Java解释器是一个巨大的工程,需要深入理解Java语法和执行模型,以及使用Python的解析、代码分析和动态执行功能。尽管可能实现一个基本的Java解释器,但要实现一个与真正的Java解释器功能和性能相当的解释器则非常困难。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值