2

实际上,这个问题与我之前的问题Catching ANTLR's NoViableAltException in Java and ANTLRWorks Debugger 有关,但由于症状不同,我决定将它们分开。

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

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

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

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

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

4

1 回答 1

4

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

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

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

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

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

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

于 2013-03-13T13:26:49.500 回答