ANTLR语法中的无限递归

dav*_*tto 6 java recursion parsing antlr

我写一个简单的语法来识别一些表达.在这里,我发布了一个更简单的版本,我写的只是为了简化我的解释.这个更简单的版本可以识别如下表达式:

  1. 这是一篇文章
  2. [n]这是另一个文本[/ n]
  3. [n] [n]这是一个复合表达式[/ n] [/ n]

我的问题是当我总结一个表达式时:[i]这应该只生成一个识别异常[/ n]

抛出一个识别异常,但是解析器进入infinte递归,因为它匹配'[',但是当它与'i'匹配时,它就会丢失.我认为这种情况正在发生,因为我的语法文本组件不能包含方括号.所以,我发布了语法.

grammar ErrorTest;

expression
    :    rawText EOF
    |    command EOF
    ;

rawText
    :    word+
    ;

word
    :    ESPACE* TEXT ESPACE*
    ;

command 
    :    simpleCommand
    |    compoundCommand
    ;

simpleCommand
    :    HELP
    ;

compoundCommand
    :    rawText
    |    BEGIN compoundCommand END
    ;

HELP   : '[help]';

BEGIN  : '[n]';
END    : '[/n]';

ESPACE : ' ';
TEXT   : ~(' '|'['|']')*;
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

Mik*_*uel 6

word匹配空字符串,因为在

word
    :    ESPACE* TEXT ESPACE*
    ;
Run Code Online (Sandbox Code Playgroud)

TEXT匹配导致的空字符串

rawText
    :    word+
    ;
Run Code Online (Sandbox Code Playgroud)

无限循环.

更改

TEXT   : ~(' '|'['|']')*;
Run Code Online (Sandbox Code Playgroud)

TEXT   : ~(' '|'['|']')+;
Run Code Online (Sandbox Code Playgroud)

这将使你的语法有限模糊.

考虑这个问题的方法是rawText可以在很多方面匹配空字符串

  1. 零TEXT令牌
  2. 一个长度为0的TEXT令牌.
  3. 两个长度为0的TEXT令牌.
  4. 三个TEXT标记,长度为0.
  5. ...

当您遇到语法错误([i])时会出现这种情况,因为它会尝试其中每个替代方案,以查看是否有任何错误解决了错误.


要摆脱任何二次行为,你应该真正使它完全明确.

rawText : ign (word (ign word)*)? ign;
ign     : ESPACE*;
word    : TEXT;
Run Code Online (Sandbox Code Playgroud)

天真修复的问题是rawText可以"foo"通过以下几种方式匹配:

  1. TEXT("foo")
  2. TEXT("fo"), ESPACE(""), TEXT("o")
  3. TEXT("f"), ESPACE(""), TEXT("oo")
  4. TEXT("f"), ESPACE(""), TEXT("o"), ESPACE(""), TEXT("o")