Antlr 4.7 больше не генерирует errorNodes для ввода в конце входного потока

#antlr #antlr4

#antlr #antlr4

Вопрос:

У меня есть простая грамматика, такая:

 grammar Test;
generator : expression;

expression
    : NUMBER                         # Number
    | ID                             # String
    | expression ' ' expression      # Add
    ;

NUMBER: [0-9]  [0-9]*;
ID : [a-zA-Z_]  [a-zA-Z0-9_]* ;
  

Я хочу, чтобы выражение 5xx считалось ошибкой (поскольку оно должно быть 5 xx или 5 или xx ). С Antlr 4.6 это могло бы произойти, но с antlr 4.7 этого не происходит.

Вот мой полный тест:

     @Test()
    public void doATest() {
        TestLexer lexer = new TestLexer(new ANTLRInputStream("5xx"));
        TestParser parser = new TestParser(new CommonTokenStream(lexer));

        //Walk the tree and throw if there are any error nodes.
        ParseTreeWalker.DEFAULT.walk(new TestBaseListener() {
            @Override public void visitErrorNode(ErrorNode node) {
                //Throws with 4.6, not with 4.7
                throw new RuntimeException("Hit error node: "   node);
            }
        }, parser.generator());
    }
  

Другое странное наблюдение, которое у меня есть, заключается в том, что включение expression ' ' expression правила важно, без этого 4.6 также не будет генерировать ошибку.

Есть ли какой-нибудь специальный флаг, который мне нужно где-нибудь установить, чтобы указать, что входной поток должен состоять ровно из одного генератора и не иметь завершающих токенов?

Ответ №1:

Есть ли какой-нибудь специальный флаг, который мне нужно где-нибудь установить, чтобы указать, что входной поток должен состоять ровно из одного генератора и не иметь завершающих токенов?

Да, это именно то, что EOF делает токен:

 generator : expression EOF;
  

Таким образом, вы всегда будете получать ошибку для дополнительных токенов, независимо от версии ANTLR или от того, включаете ли вы expression ' ' expression правило.

Комментарии:

1. Боже, спасибо! Вы не поверите, сколько времени я потратил на это: p