我想在 Python Unittest 中测试我的 lexerparser。为此,我想让 antlr 在每当任何东西出错时都以 Exception 失败。实现这个目的的最优雅的方法是什么?
我读过 ANTLR大型教程在那里,他们写了一个 ErrorListener
覆盖 syntaxError()
来保存最后一个违规符号,然后在最后检查是否遇到了违规符号。
我看到有不同的 错误策略 班级和 BailErrorStrategy
听起来这是我需要的。但后来我读到 如何在python ANTLR生成的解析器中第一次语法错误时失败,同时保留错误信息? 我想问的是,这个策略并不总是抛出一个Exception。
我目前最好的办法是在下面的程序中抛出一个Exception 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运行时的任何地方都没有被捕捉到,因此它直接冒出了你自己的代码。
如果你使用正常的错误处理程序default策略,它将总是尝试从语法错误中恢复,以允许继续解析运行。
但即使使用 BailErrorStrategy
的地方,你可以有一个错误监听器来获取第一个(也是唯一的)出现的错误。对于错误信息,我建议附加你自己的错误监听器类来生成你自己版本的错误信息,就像我做的那样。在这段C++代码中