ANTLR语法中的无限递归

时间:2012-04-25 23:25:46

标签: java parsing recursion antlr

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

  1. 这是一个文字
  2. [n]这是另一个文本[/ n]
  3. [n] [n]这是一种化合物 表达[/ N] [/ N]
  4. 我的问题是当我总结一个表达式时: [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   : ~(' '|'['|']')*;
    

    我该如何解决?

2 个答案:

答案 0 :(得分:6)

word匹配空字符串,因为在

word
    :    ESPACE* TEXT ESPACE*
    ;

TEXT匹配导致

的空字符串
rawText
    :    word+
    ;

无限循环。

更改

TEXT   : ~(' '|'['|']')*;

TEXT   : ~(' '|'['|']')+;

会使你的语法有限模糊。

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

  1. 零文本标记
  2. 一个长度为0的TEXT令牌。
  3. 两个长度为0的TEXT令牌。
  4. 长度为0的三个TEXT令牌。
  5. ...
  6. 当您遇到语法错误([i])时会出现这种情况,因为它会尝试其中每个替代方案,以查看是否有任何错误解决了错误。


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

    rawText : ign (word (ign word)*)? ign;
    ign     : ESPACE*;
    word    : TEXT;
    

    天真修复的问题是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")

答案 1 :(得分:1)

为什么不这样做:

grammar Test;

expression
 : atom+ EOF
 ;

atom
 : TEXT
 | ESPACE
 | command
 ;

command 
 : simpleCommand
 | compoundCommand
 ;

simpleCommand
 : HELP
 ;

compoundCommand
 : BEGIN atom+ END
 ;

HELP   : '[help]';
BEGIN  : '[n]';
END    : '[/n]';
ESPACE : ' ';
TEXT   : ~(' '|'['|']')+;

会像

那样输入输入
this is [n][n]a [help][n]compound[/n] expression[/n][/n]

进入以下解析树:

enter image description here

(点击图片放大)