我不确定,但我认为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'Line 1:3 required(…)+ loop在输入"
处不匹配任何内容,但我希望看到三倍的OTHER,因为如果第一个规则失败,输入应该匹配第二个规则。
这没有任何意义。为什么解析器在看到最后一个字符不是'C'时没有回溯?不过,这对《ACD》来说还可以。
有人能帮我解决这个问题吗?谢谢你的时间!!
选项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
: .
;
另一个解决方案。这可能是一个更简单的解决方案。我使用了"句法谓词"
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 : .;