我有一个非常简单的语法,(我认为(应该只允许添加两个元素,如1+1
或2+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
,但EOF
和simple_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的人对此发表评论。