ANTLR V4 + Java8 语法 -> OutOfMemoryException
ANTLR V4 + Java8 Grammar -> OutOfMemoryException
我正在尝试将 ANTLR V4
与公开给出的 Java 8
语法一起使用
- https://github.com/antlr/grammars-v4/blob/master/java8/Java8.g4
我生成了 class 文件并尝试解析 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堆space
确保输入文件没有句法问题
起初我 删除了文件的前半部分 -> 解析似乎没问题 ,
然后撤消该操作 删除了文件的后半部分 -> 解析似乎没问题
看起来那个存储库中的语法是基于我写的一个。语法依赖于某些功能,这些功能仅在我的 "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;
我正在尝试将 ANTLR V4
与公开给出的 Java 8
语法一起使用
- https://github.com/antlr/grammars-v4/blob/master/java8/Java8.g4
我生成了 class 文件并尝试解析 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堆space
确保输入文件没有句法问题
起初我 删除了文件的前半部分 -> 解析似乎没问题 ,
然后撤消该操作 删除了文件的后半部分 -> 解析似乎没问题
看起来那个存储库中的语法是基于我写的一个。语法依赖于某些功能,这些功能仅在我的 "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;