我的ANTLR词法分析器如何匹配由另一种令牌的子集组成的字符?

Chr*_*mer 5 grammar antlr

我认为这是一个简单的ANTLR问题.我有两种令牌类型:identspecial_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)

我如何形成我的语法,以便正确识别我的两种类型的标识符?

Way*_*neH 2

扩展卡尔的想法,我猜你有四种不同的情况:

  1. A
  2. 一个
  3. AA(A|N)*
  4. AN(A|N)+

只有选项 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)