通过语法解析器获取到了语法树,访问语法树执行就能取得想要的结果。
目标执行
// 目标执行器
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"