Range元素不能用于解析器规则?

时间:2012-12-08 15:53:11

标签: antlr

我有以下语法:

grammar tryout;

tryout :  my_cmd
        ;

my_cmd
    : 'start'   '0'..'9'+  Name_string
    ;

Digit
    : '0'..'9'
    ;

Name_string
    : ('A'..'Z' | 'a'..'z')  ('A'..'Z' | 'a'..'z' | '0'..'9' | '_')*
    ;

如果我在ANTLRworks中看到图表,'0'..'9'+显示为空元素,因此Java代码编译失败,因为生成的代码具有“if()”语句;如果我在命令行运行,编译也会失败。

修复方法是将'0'..'9'+移动到词法分析器规则。

grammar tryout;

tryout :  my_cmd
        ;

my_cmd
    : 'start'   Digit+  Name_string
    ;

Digit
    : '0'..'9'
    ;

Name_string
    : ('A'..'Z' | 'a'..'z')  ('A'..'Z' | 'a'..'z' | '0'..'9' | '_')*
    ;

但我想知道这是不是一个错误。为什么range元素不能用于解析器规则?这是在ANTLR v3.4上。

1 个答案:

答案 0 :(得分:1)

在解析器规则内部,..不能作为字符的范围运算符,因为它在词法分析器规则中。另请注意,即使您在解析器规则中定义了文字,ANTLR也会为它们动态创建词法规则,如下所示:

my_cmd
 : 'start' '0'..'9'+ Name_string
 ;

相当于:

my_cmd
 : Start D0..D9+ Name_string
 ;

Start : 'start';
D0    : '0';
D9    : '9';

如果内存为我服务,早期版本的ANTLR v3支持解析器规则中的范围运算符表示:匹配D0D9之间的任何标记,但这是非常脆弱的。在D0D9之间添加规则会改变其含义:

D0    : '0';
FOO   : 'foo';
D9    : '9';

解析器规则:

my_cmd
 : '0'..'9'+
 ;

现在会匹配以下其中一个令牌:D0FOOD9

解析器规则中的..支持已从(至少)v3.3及更高版本中删除。因此,不要在解析器规则中使用..