Antlr回溯选项不起作用

时间:2011-08-09 14:13:44

标签: antlr

我不确定,但我认为Antlr回溯选项无法正常运行......

这是我的语法:

grammar Test;
options {
  backtrack=true;
  memoize=true;
}

prog:   (code)+;

code
    :   ABC {System.out.println("ABC");}
    |   OTHER {System.out.println("OTHER");}
    ;

ABC : 'ABC';
OTHER : .;

如果输入流是“ABC”,那么我会看到ABC打印。

如果输入流是“ACD”,那么我会看到3次OTHER打印。

但如果输入流是“ABD”,那么我会看到 第1行:2个不匹配的字符'D'期待'C' 第1行:第3行必需(...)+循环与输入'

中的任何内容都不匹配

但我希望看到其他三次,因为如果第一条规则失败,输入应与第二条规则匹配。

这没有任何意义。为什么解析器在看到最后一个字符不是“C”时没有回溯?但是,“ACD”没问题。

有人可以帮我解决这个问题吗? 谢谢你的时间!!!

2 个答案:

答案 0 :(得分:3)

选项backtrack=true仅适用于解析器规则,而不适用于词法分析器规则。

修改

我所知道的唯一解决方法是让"AB"后跟除"C"以外的其他字符匹配在同一ABC规则中,然后手动发出其他令牌

演示:

grammar Test;

@lexer::members {
  List<Token> tokens = new ArrayList<Token>();

  public void emit(int type, String text) {
    state.token = new CommonToken(type, text);
    tokens.add(state.token);
  }

  public Token nextToken() {
    super.nextToken();
    if(tokens.size() == 0) {
      return Token.EOF_TOKEN;
    }
    return tokens.remove(0);
  }
}

prog
  :  code+
  ;

code
  :   ABC   {System.out.println("ABC");}
  |   OTHER {System.out.println("OTHER");}
  ;

ABC
  :  'ABC'
  |  'AB' t=~'C' 
     {
       emit(OTHER, "A"); 
       emit(OTHER, "B"); 
       emit(OTHER, String.valueOf((char)$t));
     }
  ;

OTHER 
  :  . 
  ;

答案 1 :(得分:1)

另一种解决方案。这可能是一个更简单的解决方案。我使用了“句法谓词”。

grammar ABC;

@lexer::header {package org.inanme.antlr;}
@parser::header {package org.inanme.antlr;}

prog: (code)+ EOF;
code: ABC {System.out.println($ABC.text);}
    | OTHER {System.out.println($OTHER.text);};

ABC : ('ABC') => 'ABC' | 'A';
OTHER : .;