章节7:计算”1+1”目标执行

40 阅读1分钟

通过语法解析器获取到了语法树,访问语法树执行就能取得想要的结果。

目标执行

// 目标执行器
public class Interpreter {
    private Parser parser; // 语法解析器
    public Interpreter(Parser parser) {
        this.parser = parser;
    }
    public Object visitProgramAst(Ast ast){ // 访问programAst节点
        ProgramAst programAst = (ProgramAst) ast; 
        return programAst.getLeftValue() + programAst.getRightValue(); // 加法计算
    }
    public Object visit(Ast ast){ // 使用反射通过类名调用对应的函数
        String methodName = "visit" + ast.getClass().getSimpleName();
        try {
            Method method = this.getClass().getDeclaredMethod(methodName , Ast.class );
            return method.invoke(this, ast);
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null;
    }
    public Integer expr() {
        Ast ast = parser.parse(); // 获取语法树
        Integer result = (Integer)this.visit(ast); // 遍历获取结果
        return result;
    }
}
  • 函数expr : 解释器入口
  • 函数visit: 使用反射通过节点名称访问每一个语法节点,具体做什么由语法节点函数来实现。
  • 函数visitProgramAst: programAst语法节点的函数,实现加法功能。

核心要点

语法图中的每一个语法节点都会对应一个访问函数,形如visit节点名称,来具体实现功能。

单元测试

private static void testInterpreter() {
    Lexer lexer = new Lexer("1+1");
    Parser parser = new Parser(lexer);
    Interpreter interpreter = new Interpreter(parser);
    Integer result = interpreter.expr();
    System.out.println("计算结果:" + result);
}
测试结果:
"计算结果:2"