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的文件?这是一个正确的假设吗?

到目前为止我做了什么:

看起来那个存储库中的语法是基于我写的一个。语法依赖于某些功能,这些功能仅在我的 "optimized" fork of ANTLR 4 中可用才能正常运行。除了使用该版本之外,您还需要执行以下两项操作以最大限度地提高性能:

  1. 使用两阶段解析策略。假设您的开始规则称为 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();
    }
    
  2. 启用全局上下文 DFA(我将其包含在前面的代码块中,因此您不会错过它)

    parser.getInterpreter().enable_global_context_dfa = true;