ANTLR V4 + Java8语法 - > OutOfMemoryException异常

时间:2015-10-02 14:55:07

标签: java parsing java-8 antlr antlr4

我试图将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堆空间

  • 确保输入文件没有语法问题   起初我删除了文件的前半部分 - > 解析似乎没问题,然后解除了该操作,删除了文件的后半部分 - > 解析似乎没问题

1 个答案:

答案 0 :(得分:8)

看起来该存储库中的语法基于我编写的语法。该语法依赖于某些功能,这些功能仅在我的"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;