如何检查ANTLR 3中的数字范围?
我知道这可能最终成为语言特定的,Java或Python解决方案是可以接受的。如何检查ANTLR 3中的数字范围?
鉴于语法
MONTH : DIGIT DIGIT ;
DIGIT : ('0'..'9') ;
我要上MONTH
检查约束,以确保值是01
和12
之间我从哪里开始找,以及如何指定此约束的规则?
您可以通过围绕它包装{
和}
来嵌入自定义代码。所以,你可以这样做:
MONTH
: DIGIT DIGIT
{
int month = Integer.parseInt(getText());
// do your check here
}
;
正如你所看到的,我叫getText()
获得令牌的匹配文本的保持。
请注意,我认为您是从另一个词法分析规则引用此MONTH
规则。如果你要抛出一个异常,如果1 > month > 12
,那么只要你的源文件包含非法的月份值,就不会匹配任何解析器规则。虽然词法分析器和解析器规则可以混合在一个.g
语法文件中,但输入源首先基于词法分析器规则进行标记,一旦发生,就只有解析器规则匹配。
我无法让'super.getText()'调用起作用; '$ month.text'确实有效。但是我对将日期解析逻辑放在语法中持怀疑态度,如果您尝试并支持所有可选符号和边界情况,ISO 8061规范会变得相当复杂。 – 2011-05-03 15:41:42
@Jarrod,嗯,也许ANTLR只接受'getText()'而没有'super'关键字。没有测试过,对不起。 – 2011-05-03 15:43:31
您可以使用此免费在线实用程序Regex_For_Range为任何连续整数范围生成正则表达式。对于值01-12(允许有前导0)的实用工具为:
0*([1-9]|1[0-2])
从这里你可以看到,如果要约束这仅仅是2位数的字符串“01”到“12”然后调整这个阅读:
0[1-9]|1[0-2]
对于天01-31我们得到:
0*([1-9]|[12][0-9]|3[01])
而且对于几年2000-2099表达的无非是:
20[0-9]{2}
尽管这很酷且令人讨厌,但这使得我更像一个维护噩梦,而ANTLR并没有使用正则表达式来匹配,而是一个LL解析器。我不可能知道哪里会比使用自编文件的本地语言数字比较更好。 **如果你有问题,现在用正则表达式解决,你有两个问题!** – 2011-05-03 15:39:04
这取决于其他标记的定义。什么应该'13'被标记为? – 2011-05-03 06:29:31
在这种情况下,任何' 12'都应该抛出一个错误,这将嵌入另一个规则中,该规则指定格式化规则中的MONTH。 – 2011-05-03 06:32:09