ANTLR4在更长的文件上抛出java.lang.StackOverflowError

Dav*_*vid 1 java stack-overflow parsing antlr4

我正在研究一种语法,该语法分析潜在的大型降价式文本。文本的“代码”部分用于构建要评估的AST,而其余文本则被忽略。我的实现方式是读取文本,直到找到“`”符号(重音符号),然后再推“代码”模式,该模式负责解析允许的表达式。下一个重音将弹出此模式并继续循环。

问题是读取较大的文本块时出现堆栈溢出错误:

Exception in thread "main" java.lang.StackOverflowError
    at org.antlr.v4.runtime.CommonToken.<init>(CommonToken.java:113)
    at org.antlr.v4.runtime.CommonTokenFactory.create(CommonTokenFactory.java:94)
    at org.antlr.v4.runtime.CommonTokenFactory.create(CommonTokenFactory.java:40)
    at org.antlr.v4.runtime.Lexer.emit(Lexer.java:269)
    at org.antlr.v4.runtime.Lexer.nextToken(Lexer.java:180)
    at org.antlr.v4.runtime.BufferedTokenStream.fetch(BufferedTokenStream.java:187)
    at org.antlr.v4.runtime.BufferedTokenStream.sync(BufferedTokenStream.java:170)
    at org.antlr.v4.runtime.BufferedTokenStream.consume(BufferedTokenStream.java:154)
    at org.antlr.v4.runtime.Parser.consume(Parser.java:588)
    at org.antlr.v4.runtime.Parser.match(Parser.java:220)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:160)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.start_line(TestGrammarParser.java:113)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:168)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.start_line(TestGrammarParser.java:113)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:168)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    at decimill.parser.TestGrammarParser.line(TestGrammarParser.java:161)
    ...
Run Code Online (Sandbox Code Playgroud)

下面是一个语法减到绝对最低限度,重现了我的问题。实际上,我将所有内容都放在一个语法文件中,以方便重现该错误:

grammar TestGrammar;

@header {
    package decimill.parser;
}

parse
    : start_line
    ;

start_line
    : line
    ;

line
    : ANY line
    | EOL start_line
    | EOF
    ;

EOL     : [\n\r]+;
ANY     : ~[\n\r];
Run Code Online (Sandbox Code Playgroud)

输入300行以上的任何文本都会导致上述错误(至少在我的机器上)。我怀疑我做错了什么,但是由于我是ANTLR的新手,并且正在构建自定义语法解析器,因此我无法弄清楚它是什么。请帮忙。

Sam*_*ell 5

ANTLR生成递归下降解析器。除少数例外,解析所需的评估堆栈深度直接对应于您在语法中编写的规则调用的深度。

例子:

每个字符需要一个堆栈帧。

line
  : Character line
  | EOF
  ;
Run Code Online (Sandbox Code Playgroud)

这总共需要一个堆栈帧。

line
  : Character* EOF
  ;
Run Code Online (Sandbox Code Playgroud)