我认为这是一个简单的ANTLR问题.我有两种令牌类型:ident和special_ident.我希望我special_ident匹配一个字母后跟一个数字.我希望泛型ident匹配单个字母,可选地后跟任意数量的字母或数字.我的(不正确的)语法如下:
expr
: special_ident
| ident
;
special_ident : LETTER DIGIT;
ident : LETTER (LETTER | DIGIT)*;
LETTER : 'A'..'Z';
DIGIT : '0'..'9';
Run Code Online (Sandbox Code Playgroud)
当我尝试检查这个语法时,我收到了这个警告:
决策可以使用多个替代方案匹配诸如"LETTER DIGIT"之类的输入:1,2.结果,对于该输入禁用了备选方案2
我知道我的语法含糊不清,输入A1可以匹配任何一个ident或者special_ident.我真的只想special_ident在最狭窄的情况下使用它.
这是一些示例输入以及我希望它匹配的内容:
A : ident
A1 : special_ident
A1A : ident
A12 : ident
AA1 : ident
Run Code Online (Sandbox Code Playgroud)
我如何形成我的语法,以便正确识别我的两种类型的标识符?
扩展卡尔的想法,我猜你有四种不同的情况:
只有选项 2 应该是 tokenspecial_ident,其他三个应该是 ident。所有标记都可以仅通过语法来识别。这是我在 ANTLRWorks 中测试的一个快速语法,它似乎对我来说工作正常。我认为 Carl 在尝试检查 AA 时可能会遇到一个错误,但是让你得到 99% 的结果是一个巨大的好处,所以这只是对他的快速想法的一个小小的修改。
prog
: (expr WS)+ EOF;
expr
: special_ident {System.out.println("Found special_ident:" + $special_ident.text + "\n");}
| ident {System.out.println("Found ident:" + $ident.text + "\n");}
;
special_ident : LETTER DIGIT;
ident : LETTER
|LETTER DIGIT (LETTER|DIGIT)+
|LETTER LETTER (LETTER|DIGIT)*;
LETTER : 'A'..'Z';
DIGIT : '0'..'9';
WS
: (' '|'\t'|'\n'|'\r')+;
Run Code Online (Sandbox Code Playgroud)