Как реализовать выражение вычитания в моем расширенном классе прослушивателя Java ANTLR4? - PullRequest
0 голосов
/ 25 мая 2018

У меня есть задача переделать мой проект Java ANTLR4, который использовал посетитель, в тот же проект, который использует слушатель.У меня проблемы с пониманием того, как работает слушатель.

Мой метод вычитания посетителя выглядел следующим образом:

// expression '-' expression                #subtractExpression
@Override
public QuickMathsValue visitSubtractExpression(SubtractExpressionContext ctx) {
    QuickMathsValue lhs = this.visit(ctx.expression(0));
    QuickMathsValue rhs = this.visit(ctx.expression(1));
    if (lhs.isNumber() && rhs.isNumber()) {
        return new QuickMathsValue(lhs.asDouble() - rhs.asDouble());
    }
    throw new EvalException(ctx);
}

Как сделать то же самое, но с помощью Слушателя?Если у кого-нибудь есть примеры, это было бы огромной помощью.

1 Ответ

0 голосов
/ 25 мая 2018

В вашем слушателе вы можете добавить стек, в который вы помещаете свои значения.При выходе из правила вы извлекаете нужные значения из стека, а затем снова вводите их снова (добавленные, умноженные или другие).

Быстрое демо:

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
...