当前位置: 首页 > 知识库问答 >
问题:

如何在Python3中捕捉ANTLR4中的外来输入?

彭洲
2023-03-14

是的,这几乎是如何在ANTLR4中捕获无关输入的复制品?-但在Java的情况下,我需要一个Python解决方案,而移植Java解决方案对我来说根本不管用!

ANTLR4正在向控制台写入以下“错误”。我希望这会导致一个硬停止,但解析器会继续并最终重新同步:

line 12:28 extraneous input 'FREDDY' expecting {'AS', ...

我希望这是一个致命的错误。

因此,我定义了自己的错误侦听器,并覆盖了所有4个方法:

class MyErrorListener( ErrorListener ):

    __slots__ = [ 'file_name' ]
    
    def __init__(self, file_name="<stdin>"):
        self.file_name = file_name

    def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
        print(f"{self.file_name} {line}:{column} {msg[0:min(80,len(msg)-1)]}", file=sys.stderr)
        sys.exit(1)
        
    def reportAmbiguity(self, recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs):
        print(f"{self.file_name} {startIndex}-{stopIndex} reportAmbiguity {ambigAlts}", file=sys.stderr)
        sys.exit(1)

    def reportAttemptingFullContext(self, recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs):
        print(f"{self.file_name} {startIndex}-{stopIndex} conflictingAlts {conflictingAlts}", file=sys.stderr)
        sys.exit(1)

    def reportContextSensitivity(self, recognizer, dfa, startIndex, stopIndex, prediction, configs):
        print(f"{self.file_name} {startIndex}-{stopIndex} ContextSensitivity {prediction}", file=sys.stderr)
        sys.exit(1)

我创建了我的lexer,删除了默认的控制台错误监听器,并将我的添加到:

        st = InputStream(upper_case)
        lexer:PlSqlLexer = PlSqlLexer(st)
        # Add your error listener to the lexer if required
        lexer.removeErrorListeners()
        lexer.addErrorListener( MyErrorListener(f) )
        stream = CommonTokenStream(lexer)
        parser = PlSqlParser(stream)
        tree = parser.sql_script()
        printer = PlSqlPrintListener(txt)
        walker = ParseTreeWalker()
        walker.walk(printer, tree)

这是捕获一些错误,例如:

sql_parser.py 1:0 token recognition error at: '"""\n

(这是我把一个Python程序输入到一个SQL解析器中——当然它不应该工作!)

但是我的错误列表没有捕捉到我在顶部报告的错误。

有什么建议吗?

  • ANTLR解析器生成器版本4.9.2

共有1个答案

毕黎昕
2023-03-14

解决方案;Lexer和解析器都是“识别器”。识别器是听者倾听的地方。

因此,我们有两种类型的错误,词法错误和解析错误。我只是将我的侦听器连接到Lexer,我还需要将其连接到解析器。修订代码:

        ...
        lexer:PlSqlLexer = PlSqlLexer(st)
        # Add your error listener to the lexer if required
        lexer.removeErrorListeners()
        lexer.addErrorListener( my_listener )
        
        stream = CommonTokenStream(lexer)
        
        parser = PlSqlParser(stream)
        # Add your error listener to the _parser_ if required
        parser.removeErrorListeners()
        parser.addErrorListener( my_listener )
        ...
 类似资料:
  • 我的ANTLR4有问题。我正在尝试从python 3代码打印AST,但有一些错误,我不知道如何修复它们。 我编写了简单的测试代码: 我运行了程序,但出现了以下错误: 我的主要班级: 我有这个网站的语法:https://github.com/antlr/grammars-v4/tree/master/python3

  • 我需要捕捉用户挂断的事实,但我不知道如何。 有什么建议吗?

  • 问题内容: Swift中的以下代码引发NSInvalidArgumentException异常: 如何捕获异常?据我了解,Swift中的try / catch是针对Swift中引发的错误,而不是针对NSTask之类的对象引发的NSExceptions(我猜是用ObjC编写的)。我是Swift的新手,所以可能我缺少明显的东西… 编辑 :这是该错误的雷达(专门针对NSTask):openradar.a

  • 现在生成的匹配器将'~'捕获为未知,但为输入'~~~'创建3'~'未知标记,而不是单个'~~~'标记。我应该做些什么来告诉lexer为未知的连续字符生成单词标记。我还尝试了“未知:.;”和“未知:.+;”没有结果。 编辑:在当前的antlr版本中。+?现在捕获剩余的单词,所以这个问题似乎得到了解决。

  • 问题内容: 是否可以在Java命令行应用程序中捕获+ 信号?我想在终止程序之前清理一些资源。 问题答案: 您可以将关闭挂钩连接到VM,只要VM关闭,该挂钩便会运行: Java虚拟机将响应以下两种事件而关闭: 当最后一个非守护程序线程退出时,或者调用exit(等效于System.exit)方法时,程序将正常退出,或者 响应于用户中断(例如键入+ )或系统范围的事件(例如用户注销或系统关闭)来终止虚拟

  • 我在一个xml布局文件中声明了许多按钮,并将此布局用于一个片段。 令人失望的是,“onclickbutton”事件被捕捉在主机activity,而不是在我的片段。当然,在我的片段中,我可以手动解决这个问题,如下所示: 有没有显式的方法来处理片段中的onClickbutton事件?