为什么ANTLR C#自动生成的解析器与EOF不匹配



我有一个非常简单的语法,(我认为(应该只允许添加两个元素,如1+12+3

grammar dumbCalculator;
expression: simple_add EOF;
simple_add: INT ADD INT;
INT:('0'..'9');
ADD : '+';

我使用官方的ANTLR jar文件生成我的C#类

java -jar "antlr-4.9-complete.jar" C:UsersMesourcereposConsoleApp2ConsoleApp2dumbCalculator.g4 -o C:UsersMesourcereposConsoleApp2ConsoleApp2Dumb -Dlanguage=CSharp -no-listener -visitor

无论我尝试什么,解析器都会不断添加尾随元素,尽管它们不应该被允许。

例如,"1+1+1"被正确解析为AST:

expression
simple_add
1
+
1
+
1

虽然我特别写了expression必须是simple_add,但EOFsimple_add只是INT ADD INT。我不知道为什么剩下的都被接受了,我希望ANTLR能在这方面破例。

这就是我测试解析器的方式:

var inputStream = new AntlrInputStream("1+1+1");
var lexer = new dumbCalculatorLexer(inputStream);
lexer.RemoveErrorListeners();
lexer.AddErrorListener(new ThrowExceptionErrorListener());
var commonTokenStream = new CommonTokenStream(lexer);
var parser = new dumbCalculatorParser(commonTokenStream);
parser.RemoveErrorListeners();
parser.AddErrorListener(new ThrowExceptionErrorListener());
var ex = parser.expression();
ExploreAST(ex);

为什么其他输出被接受

经典场景,我在Stack Overflow上发帖5分钟后发现了错误。

对于遇到类似情况的人来说,之所以会发生这种情况,是因为我没有在解析器上显式设置ErrorHandler

天真地,我希望所有的AddErrorListener都能处理错误,但不知何故,如果您需要在访问树之前处理错误,那么需要做一件特定的事情。

我需要添加

parser.ErrorHandler = new BailErrorStrategy();

在这之后,我确实得到了错误输入字符串的异常。

这可能不是正确的做法,我会让更了解ANTLR的人对此发表评论。

相关内容

  • 没有找到相关文章

最新更新