我试图将ANTLR V4
与公开给出的Java 8
语法一起使用
- https://github.com/antlr/grammars-v4/blob/master/java8/Java8.g4
我生成了类文件,并尝试解析Java 8 JRE
,但不知怎的,java.text.SimpleDateFormat.java
它崩溃了:
java.lang.OutOfMemoryError: GC overhead limit exceeded
当我试图单独解析该单个文件时,崩溃。
这可以以某种方式解决吗?显然ANTLR V4
无法处理超过 2000 LOC 的文件?这是正确的假设吗?
到目前为止我做了什么:
将分配的内存分段更改为JVM
从256MB到4GB - 然后更改为
java.lang.OutOfMemoryError:Java堆空间
确保输入文件没有语法问题 起初我删除了文件的前半部分 - > 解析似乎没问题,然后解除了该操作,删除了文件的后半部分 - > 解析似乎没问题
答案 0 :(得分:8)
看起来该存储库中的语法基于我编写的语法。该语法依赖于某些功能,这些功能仅在我的"optimized" fork of ANTLR 4中可用,才能表现良好。除了使用该版本之外,您还需要执行以下两项操作以最大限度地提高性能:
使用两阶段解析策略。假设您的开始规则称为compilationUnit
,它可能如下所示:
CompilationUnitContext compilationUnit;
try {
// Stage 1: High-speed parsing for correct documents
parser.setErrorHandler(new BailErrorStrategy());
parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
parser.getInterpreter().tail_call_preserves_sll = false;
compilationUnit = parser.compilationUnit();
} catch (ParseCancellationException e) {
// Stage 2: High-accuracy fallback parsing for complex and/or erroneous documents
// TODO: reset your input stream
parser.setErrorHandler(new DefaultErrorStrategy());
parser.getInterpreter().setPredictionMode(PredictionMode.LL);
parser.getInterpreter().tail_call_preserves_sll = false;
parser.getInterpreter().enable_global_context_dfa = true;
compilationUnit = parser.compilationUnit();
}
启用全局上下文DFA(我在前面的代码块中包含了这个,所以你不能错过它)
parser.getInterpreter().enable_global_context_dfa = true;