为什么 ANTLR C# 自动生成的解析器不匹配 EOF?
Why is ANTLR C# autogenerated parser not matching EOF?
我有一个非常简单的语法,(我认为)应该只允许添加两个元素,例如 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:\Users\Me\source\repos\ConsoleApp2\ConsoleApp2\dumbCalculator.g4 -o C:\Users\Me\source\repos\ConsoleApp2\ConsoleApp2\Dumb -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 的人对此发表评论。
我有一个非常简单的语法,(我认为)应该只允许添加两个元素,例如 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:\Users\Me\source\repos\ConsoleApp2\ConsoleApp2\dumbCalculator.g4 -o C:\Users\Me\source\repos\ConsoleApp2\ConsoleApp2\Dumb -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 的人对此发表评论。