Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ANTLR4中解析非常大的表达式时出现堆栈溢出_Antlr4 - Fatal编程技术网

在ANTLR4中解析非常大的表达式时出现堆栈溢出

在ANTLR4中解析非常大的表达式时出现堆栈溢出,antlr4,Antlr4,我正在ANTLR4中重新实现现有的DSL。现有的源代码主体有一些非常大的表达式。似乎ALL(*)逻辑中的递归意味着我可以解析的表达式的大小有一个限制 示例语法:(刚好可以在此处复制错误错误) 样本输入: V0 AND 0 OR V1 AND 1 OR ... (MANY rows elided) V3999 AND 3999 OR V4000 AND 4000 堆栈跟踪: Exception in thread "main" java.lang.reflect.Invoc

我正在ANTLR4中重新实现现有的DSL。现有的源代码主体有一些非常大的表达式。似乎ALL(*)逻辑中的递归意味着我可以解析的表达式的大小有一个限制

示例语法:(刚好可以在此处复制错误错误)

样本输入:

V0 AND 0 OR
V1 AND 1 OR
...  (MANY rows elided)
V3999 AND 3999 OR
V4000 AND 4000
堆栈跟踪:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.antlr.v4.runtime.misc.TestRig.process(TestRig.java:249)
    at org.antlr.v4.runtime.misc.TestRig.process(TestRig.java:211)
    at org.antlr.v4.runtime.misc.TestRig.main(TestRig.java:143)
Caused by: java.lang.StackOverflowError
    at java.util.Arrays.equals(Arrays.java:1869)
    at org.antlr.v4.runtime.atn.ArrayPredictionContext.equals(ArrayPredictionContext.java:101)
    at java.util.HashMap.getEntry(HashMap.java:471)
    at java.util.LinkedHashMap.get(LinkedHashMap.java:301)
    at org.antlr.v4.runtime.misc.DoubleKeyMap.get(DoubleKeyMap.java:62)
    at org.antlr.v4.runtime.atn.PredictionContext.mergeArrays(PredictionContext.java:418)
    at org.antlr.v4.runtime.atn.PredictionContext.merge(PredictionContext.java:199)
    at org.antlr.v4.runtime.atn.ATNConfigSet.add(ATNConfigSet.java:175)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1126)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)

限制表达式的大小不是一个选项。他们用当前的技术编译得很好,所以我们必须支持它


为了避免极高的堆栈利用率,我是否必须排除这个问题上的左递归?或者,有一个更简单的答案吗?

ANTLR 4.2将通过合并来改善这种情况。由于ANTLR 4尚未发布,我建议从源代码构建最新版本的ANTLR 4,并再次尝试您的输入。

您可以尝试更大的JVM堆栈:我已经这样做了,这会有所不同,但最终只是将突破点推了一点,所以我很难称之为解决方案。看起来很有希望。我来看看。我已经删除了左递归,在一个简单的测试中,我对性能的提高感到震惊,所以我希望只保留没有左递归的版本。您的更改是否会使性能接近我通过删除左递归得到的结果?如果有性能的话,我更愿意回到更简单的语法(和更简单的AST),我已经在GitHub上从源代码构建了最新的语法。看起来这可能会防止(或肯定会改善)堆栈溢出的情况。我现在正在编译单个表达式,java内存利用率正在逐渐增加。这就是说,看起来我可能是在创造一个强迫性的案例,让O(n4)(或接近那个)表现。带左递归分解的语法运行得非常快(可能是次秒;我还没有计时);但是,使用左递归语法运行已经运行了6个多小时,仍然没有完成。@MikeCargal您能给我发送您的语法和演示问题的示例输入吗?我想对它进行一些测试。而且,唯一的O(n⁴) 我们能够创建的案例涉及一个非常明显的结构不良的模糊规则。我们所见过的最糟糕的模糊语法是O(n³).使用您的示例语法和最新的ANTLR 4.2工作输入,我发现即使输入的大小是您在第一篇文章中列出的输入的400倍,也可以在15秒内完成。感谢您的帮助。我不确定我做错了什么。在重新完成构建过程后,我能够再次运行测试并完成测试很明显,我没有正确地构建一些东西,或者没有正确地指出我的构建结果。现在效果很好。
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.antlr.v4.runtime.misc.TestRig.process(TestRig.java:249)
    at org.antlr.v4.runtime.misc.TestRig.process(TestRig.java:211)
    at org.antlr.v4.runtime.misc.TestRig.main(TestRig.java:143)
Caused by: java.lang.StackOverflowError
    at java.util.Arrays.equals(Arrays.java:1869)
    at org.antlr.v4.runtime.atn.ArrayPredictionContext.equals(ArrayPredictionContext.java:101)
    at java.util.HashMap.getEntry(HashMap.java:471)
    at java.util.LinkedHashMap.get(LinkedHashMap.java:301)
    at org.antlr.v4.runtime.misc.DoubleKeyMap.get(DoubleKeyMap.java:62)
    at org.antlr.v4.runtime.atn.PredictionContext.mergeArrays(PredictionContext.java:418)
    at org.antlr.v4.runtime.atn.PredictionContext.merge(PredictionContext.java:199)
    at org.antlr.v4.runtime.atn.ATNConfigSet.add(ATNConfigSet.java:175)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1126)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closureCheckingStopState(ParserATNSimulator.java:1111)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.closure_(ParserATNSimulator.java:1164)