Unittest 中的 ANTLR4 Python:如何中止任何错误
ANTLR4 Python in Unittest: how to abort on any error
我想在 Python 单元测试中测试我的 lexer/parser。为此,我希望 antlr 每次出现异常时都以异常失败。实现此目的最优雅的方法是什么?
我读过 ANTLR Mega Tutorial,他们写了一个 ErrorListener
覆盖 syntaxError()
来保存最后一个违规符号,然后最后,他们检查是否有任何违规符号遇到了。
我看到有不同的 ErrorStrategy classes and BailErrorStrategy
sounds like this is what I need. But then I read How can I fail on first syntax error in a python ANTLR generated parser while keeping the error message? 说这个策略并不总是抛出异常。
到目前为止我最好的想法是在 ErrorListener.syntxError()
中抛出一个异常:
import unittest
from antlr4 import *
from antlr.myLexer import myLexer
from antlr.myParser import myParser
from antlr4.error.ErrorListener import ErrorListener
class MyErrorListener(ErrorListener):
def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
raise Exception("ERROR: when parsing line %d column %d: %s\n" % \
(line, column, msg))
class TestMyParser(unittest.TestCase):
def test_with_testfile(self):
error_listener = MyErrorListener()
input_stream = FileStream("testfile")
lexer = myLexer(input_stream)
lexer.removeErrorListeners()
lexer.addErrorListener(error_listener)
stream = CommonTokenStream(lexer)
parser = myParser(stream)
parser.removeErrorListeners()
parser.addErrorListener(error_listener)
tree = parser.startrule()
if __name__ == '__main__':
unittest.main()
您最好的选择是 BailErrorStategy
。它使用了一个在 ANTLR4 运行time 的任何地方都没有捕获到的异常,因此直接冒泡到您自己的代码中。
如果您使用普通错误 handler/default 策略,它将始终尝试从语法错误中恢复以允许继续解析 运行。
但即使 BailErrorStrategy
到位,您也可以有一个错误侦听器来获取出现的第一个(也是唯一一个)错误。对于错误消息,我建议附加您自己的错误侦听器 class 以生成您自己的错误消息版本,就像我所做的那样 in this C++ code
我想在 Python 单元测试中测试我的 lexer/parser。为此,我希望 antlr 每次出现异常时都以异常失败。实现此目的最优雅的方法是什么?
我读过 ANTLR Mega Tutorial,他们写了一个 ErrorListener
覆盖 syntaxError()
来保存最后一个违规符号,然后最后,他们检查是否有任何违规符号遇到了。
我看到有不同的 ErrorStrategy classes and BailErrorStrategy
sounds like this is what I need. But then I read How can I fail on first syntax error in a python ANTLR generated parser while keeping the error message? 说这个策略并不总是抛出异常。
到目前为止我最好的想法是在 ErrorListener.syntxError()
中抛出一个异常:
import unittest
from antlr4 import *
from antlr.myLexer import myLexer
from antlr.myParser import myParser
from antlr4.error.ErrorListener import ErrorListener
class MyErrorListener(ErrorListener):
def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
raise Exception("ERROR: when parsing line %d column %d: %s\n" % \
(line, column, msg))
class TestMyParser(unittest.TestCase):
def test_with_testfile(self):
error_listener = MyErrorListener()
input_stream = FileStream("testfile")
lexer = myLexer(input_stream)
lexer.removeErrorListeners()
lexer.addErrorListener(error_listener)
stream = CommonTokenStream(lexer)
parser = myParser(stream)
parser.removeErrorListeners()
parser.addErrorListener(error_listener)
tree = parser.startrule()
if __name__ == '__main__':
unittest.main()
您最好的选择是 BailErrorStategy
。它使用了一个在 ANTLR4 运行time 的任何地方都没有捕获到的异常,因此直接冒泡到您自己的代码中。
如果您使用普通错误 handler/default 策略,它将始终尝试从语法错误中恢复以允许继续解析 运行。
但即使 BailErrorStrategy
到位,您也可以有一个错误侦听器来获取出现的第一个(也是唯一一个)错误。对于错误消息,我建议附加您自己的错误侦听器 class 以生成您自己的错误消息版本,就像我所做的那样 in this C++ code