ANTLR V4 + Java8语法 - > OutOfMemoryException

Ron*_*uck 5 java parsing antlr java-8 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
Run Code Online (Sandbox Code Playgroud)

当我试图单独解析该单个文件时,它也会崩溃.

这可以以某种方式解决吗?显然ANTLR V4无法处理超过2000 LOC的文件?这是正确的假设吗?

到目前为止我做了什么:

  • 将分配的内存从256MB更改为4GB的JVM多个步骤- 然后更改为

    java.lang.OutOfMemoryError:Java堆空间

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

Sam*_*ell 8

看起来该存储库中的语法基于我编写的语法.语法依赖于某些功能,这些功能仅在我的"优化"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();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 启用全局上下文DFA(我在前面的代码块中包含了这个,所以你不能错过它)

    parser.getInterpreter().enable_global_context_dfa = true;
    
    Run Code Online (Sandbox Code Playgroud)