【问题标题】:OutOfMemoryError when parsing incorrect input in ANTLR在 ANTLR 中解析不正确的输入时出现 OutOfMemoryError
【发布时间】:2013-03-13 12:40:39
【问题描述】:

其实这个问题和我之前的问题Catching ANTLR's NoViableAltException in Java and ANTLRWorks Debugger有关,但是因为症状不同,我决定把它们分开。

问题在于提供给包含未知标记的 ANTLR 输入文本。例如,考虑到我们的语法对以@ 符号开头的标记一无所知。如果我们尝试将此类文本提供给ANTLRWorks 解释器,我们将在结果图中收到NoViableAltException

但是如果我们使用 Java 中生成和编译的语法并尝试用它来解析这些无效文本,我们会收到以下结果之一(这取决于我们将这个未知标记放置在哪里,即我们有多“深入”将其放入文本中):

1) 没有错误,并且顶级CommonTree 对象中chidlren 字段中的null 值(提到的问题正是关于这种情况);

2) java.lang.OutOfMemoryError: Java heap space 错误。

这个问题是关于第二种情况的。我们如何防止ANTLR 解析器的这种行为?例如,在生产环境中,客户端可能会通过向 DSL 解析器提供不正确的字符序列而意外崩溃系统。

【问题讨论】:

    标签: java antlr out-of-memory


    【解决方案1】:

    这通常发生在词法分析器包含可以匹配空字符串的规则时。例如,考虑以下规则:

    WS : (' ' | '\t')*;
    

    此规则可以创建一个WS 标记,总共包含 0 个空格和/或制表符,这意味着在您的输入中的任何其他标记之间可以有无数个空格和/或制表符。在某些涉及无效输入的情况下,错误恢复过程可能会被强制进入一个无限循环,该循环将缓冲令牌,直到 Java 内存不足。

    解决这种情况的第一步是检查每个词法分析器规则,以确保不会发生这种情况。 WS 应改为这样编写,以确保消耗至少 1 个空格和/或制表符。

    WS : (' ' | '\t')+;
    

    PS:ANTLR 4 对语法进行静态检查,如果发生这种情况,会产生错误 (4.0) 或警告 (4.0.1+)。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    相关资源
    最近更新 更多