#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