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

时间:2010-01-31 21:39:43

标签: antlr grammar

我认为这是一个简单的ANTLR问题。我有两种令牌类型:identspecial_ident。我希望我的special_ident匹配一个字母后跟一个数字。我希望通用ident匹配单个字母,可选地后跟任意数量的字母或数字。我的(不正确的)语法如下:

expr 
    : special_ident
    | ident
    ;

special_ident : LETTER DIGIT;
ident         : LETTER (LETTER | DIGIT)*;

LETTER : 'A'..'Z';
DIGIT  : '0'..'9';

当我尝试检查这个语法时,我收到了这个警告:

  

决策可以使用多种替代方案匹配输入,例如“LETTER DIGIT”:1,2。   结果,对该输入禁用了备选方案2

我理解我的语法含糊不清,A1之类的输入可以与identspecial_ident匹配。我真的只想在最狭窄的情况下使用special_ident

以下是一些示例输入以及我希望匹配的内容:

A      : ident
A1     : special_ident
A1A    : ident
A12    : ident
AA1    : ident

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

2 个答案:

答案 0 :(得分:3)

似乎你有3个案例:

  • A
  • AN
  • A(A|N)(A|N)+

您可以将中间一个归类为special_ident,将另外两个归类为ident;似乎应该这样做。

我对ANTLR有点生疏,我希望这个提示已经足够了。我可以尝试为你写出表达,但它们可能是错的:

long_ident    : LETTER (LETTER | DIGIT) (LETTER | DIGIT)+
special_ident : LETTER DIGIT;
ident         : LETTER | long_ident;

答案 1 :(得分:2)

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

  1. A
  2. AN
  3. AA(A | N)*
  4. AN(A | N)+
  5. 只有选项2应该是令牌special_ident,其他三个应该是ident。所有令牌都可以通过语法单独识别。这是我能够在ANTLRWorks中测试的快速语法,它似乎适合我。我认为卡尔在尝试检查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')+;