目录
方法一: 使用程序员自定义的栈,适用于listener和visit等
lister的方法没有返回值,将值放到堆栈中。
public static class Evaluator extends LExprBaseListener {
Stack stack = new Stack();
public void exitMult(LExprParser.MultContext ctx) {
int right = stack.pop();
int left = stack.pop();
stack.push( left * right );
}
public void exitAdd(LExprParser.AddContext ctx) {
int right = stack.pop();
int left = stack.pop();
stack.push(left + right);
}
public void exitInt(LExprParser.IntContext ctx) {
stack.push( Integer.valueOf(ctx.INT().getText()) );
}
}
栈方式缺点:
程序要需要保证push和pop正确
栈方式优点:
可以传输多种值和多个返回值
方法二: 使用antlr语法树节点返回值,只适用于visit,lister函数没有返回值
public static class EvalVisitor extends LExprBaseVisitor {
public Integer visitMult(LExprParser.MultContext ctx) {
return visit(ctx.e(0)) * visit(ctx.e(1));
}
public Integer visitAdd(LExprParser.AddContext ctx) {
return visit(ctx.e(0)) + visit(ctx.e(1));
}
public Integer visitInt(LExprParser.IntContext ctx) {
return Integer.valueOf(ctx.INT().getText());
}
}
方法三: 将值存入语法树种的节点上下文中,适用于listener,visit
缺点是,语法树大时,存储的信息太多
方法一:节点上下文有个value字段,只能存放整型
e returns [int value] :
e ‘*’ e # Mult
e ‘+’ e # Add |
INT # Int |
;
public void exitAdd(LExprParser.AddContext ctx) {
*/ e(0).value is the subexpression value of the first e in the alternative
ctx.value = ctx.e(0).value + ctx.e(1).value; /* e ‘+’ e # Add
}
方法二:最容易的方式是使用map,可以存放任意类型
public static class EvaluatorWithProps extends LExprBaseListener {
** maps nodes to integers with Map