Antlr 4.7 不再为输入流末尾的输入生成错误节点

Antlr 4.7 no longer generates errorNodes for input at the end of an inputstream

我有一个像这样的简单语法:

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+xx5xx)。使用 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 也不会产生错误。

我是否需要在某处设置一些特殊标志以指示输入流应该恰好是一个生成器并且没有任何尾随标记?

Is there some special flag that I need to set somewhere to indicate that an input stream should be exactly one generator and not have any trailing tokens?

是的,这正是 EOF 令牌的作用:

generator : expression EOF;

这样一来,无论 ANTLR 的版本如何或是否包含 expression '+' expression 规则,您总是会在额外标记上出错。