В вашем слушателе вы можете добавить стек, в который вы помещаете свои значения.При выходе из правила вы извлекаете нужные значения из стека, а затем снова вводите их снова (добавленные, умноженные или другие).
Быстрое демо:
Expression.g4
grammar Expression;
expression
: expression op=( MUL | DIV ) expression #expressionMul
| expression op=( ADD | MIN ) expression #expressionAdd
| '(' expression ')' #expressionNested
| NUMBER #expressionNumber
;
MUL : '*';
DIV : '/';
ADD : '+';
MIN : '-';
NUMBER : [0-9]+ ( '.' [0-9]+ )?;
SPACE : [ \t\r\n] -> skip;
Main.java
public class Main {
public static void main(String[] args) {
String expression = "(1 + 2) * 14";
ExpressionLexer lexer = new ExpressionLexer(CharStreams.fromString(expression));
ExpressionParser parser = new ExpressionParser(new CommonTokenStream(lexer));
EvalListener evaluator = new EvalListener();
ParseTreeWalker.DEFAULT.walk(evaluator, parser.expression());
System.out.printf("%s = %s\n", expression, evaluator.stack.pop());
}
static class EvalListener extends ExpressionBaseListener {
final Stack<Double> stack = new Stack<>();
@Override
public void exitExpressionAdd(ExpressionParser.ExpressionAddContext ctx) {
Double rhs = stack.pop();
Double lhs = stack.pop();
this.stack.push(ctx.op.getType() == ExpressionLexer.ADD ? (lhs + rhs) : (lhs - rhs));
}
@Override
public void exitExpressionMul(ExpressionParser.ExpressionMulContext ctx) {
Double rhs = stack.pop();
Double lhs = stack.pop();
this.stack.push(ctx.op.getType() == ExpressionLexer.MUL ? (lhs * rhs) : (lhs / rhs));
}
@Override
public void enterExpressionNumber(ExpressionParser.ExpressionNumberContext ctx) {
this.stack.push(Double.valueOf(ctx.getText()));
}
}
}
Запуск класса Main
приведет к следующему выводу:
(1 + 2) * 14 = 42.0