其实这个问题和我之前的问题Catching ANTLR's NoViableAltException in Java and ANTLRWorks Debugger有关。 ,但由于症状不同,我决定将它们分开。
问题在于向 ANTLR 输入文本提供信息,其中包含未知标记。例如,考虑一下我们的语法对以 @
符号开头的标记一无所知。如果我们尝试将此类文本提供给 ANTLRWorks
解释器,我们将在结果图中收到 NoViableAltException
。
但是,如果我们使用 Java 生成和编译的语法并尝试用它解析此类无效文本,我们可以收到以下结果之一(这取决于我们将这个未知标记放置在哪里,即我们“深度”如何)将其放入文本中):
1)没有错误,并且顶级 CommonTree
对象的 chidlren
字段中的 null
值(所提到的问题正是关于这个案例);
2) java.lang.OutOfMemoryError: Java 堆空间
错误。
这个问题是关于第二种情况的。我们如何防止 ANTLR 解析器的这种行为?例如,在生产中,客户端可能会因为向 DSL 解析器提供不正确的字符序列而意外导致系统崩溃。
最佳答案
当词法分析器包含可以匹配空字符串的规则时,通常会发生这种情况。例如,考虑以下规则:
WS : (' ' | '\t')*;
此规则可以创建一个总共包含 0 个空格和/或制表符的 WS
标记,这意味着您输入中的任何其他标记之间可以有无限数量的空格和/或制表符。在某些涉及无效输入的情况下,错误恢复过程可能会被迫进入无限循环,该循环将缓冲 token ,直到 Java 内存不足。
解决这种情况的第一步是检查每个词法分析器规则以确保这种情况不会发生。 WS
应该这样写,以确保消耗至少 1 个空格和/或制表符。
WS : (' ' | '\t')+;
PS:ANTLR 4 对语法执行静态检查,如果发生这种情况,会产生错误 (4.0) 或警告 (4.0.1+)。
关于java - 在 ANTLR 中解析不正确的输入时出现 OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15385650/