我有以下语法:
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' | '_')*
;
Run Code Online (Sandbox Code Playgroud)
如果我在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' | '_')*
;
Run Code Online (Sandbox Code Playgroud)
但我想知道这是不是一个错误.为什么range元素不能用于解析器规则?这是在ANTLR v3.4上.
在解析器规则中,..它不像词法分析器规则中那样充当字符的范围运算符。另请注意,即使您在解析器规则中定义了文字,ANTLR 也会动态地为它们创建词法分析器规则,如下所示:
my_cmd
: 'start' '0'..'9'+ Name_string
;
Run Code Online (Sandbox Code Playgroud)
相当于:
my_cmd
: Start D0..D9+ Name_string
;
Start : 'start';
D0 : '0';
D9 : '9';
Run Code Online (Sandbox Code Playgroud)
如果我没记错的话,早期版本的 ANTLR v3 支持解析器规则内的范围运算符,意思是:匹配 和 之间的任何标记D0,D9但这非常脆弱。D0在和之间添加规则D9会改变它的含义:
D0 : '0';
FOO : 'foo';
D9 : '9';
Run Code Online (Sandbox Code Playgroud)
解析器规则:
my_cmd
: '0'..'9'+
;
Run Code Online (Sandbox Code Playgroud)
现在将匹配以下标记之一:D0、FOO或D9。
解析器规则内部的这种..支持已从(至少)v3.3 及更高版本中删除。因此,不要使用..内部解析器规则。