我正在尝试创建包含数字和字符串的语法,如下所示:
日期:2013年3月2日
我创建了一组规则,或多或少地适应了这一点:
Date:
'Date': DAY Month YEAR
;
terminal DAY:
('1'..'9') | (('1'..'3')('0'..'9'))
;
Month:
name = ('Jan'|'Feb'|'Mar'|'Apr)
;
terminal YEAR
('0'..'2)('0'..'9')('0'..'9')('0'..'9')
;
这套规则似乎有很多问题:
编写的日期规则似乎会生成错误:“无法在规则中更改类型两次”。我不知道这意味着什么,除了Xtext显然不允许在同一规则中使用数字和选择字符串。
如果我从Date中删除Month规则,则Xtext会编译,但语法似乎无法正常工作。 DAY规则应该提供从1到9的单个数字和两位数字之间的选择,但由于某种原因它只接受两位数字。因此,虽然我可以输入如下行:
日期:2013年12月
已被接受,但日期如下:
日期:2013年2月
不是。
我是否在违反终端规则的规则中发现了一个错误?或者是否有一些缺失会导致忽略“|”在我的号码?另外:地球上的“无法在规则内两次更改类型”错误意味着什么,我该如何解决?
有人请指教。
答案 0 :(得分:1)
这里有设计问题。通常,您必须尽可能少地使用自定义终端。自定义终端会对语法产生全局影响,使语法不灵活,错误恢复效率低下。
我理解你的意图:你想限制你的DSL以防止解析不敏感的数据。这是一个好主意,但定制终端不是为这种任务而设计的。经验法则是:
在您的场景中,我建议使用以下简单语法:
Date:
'Date': day=INT month=Month year=INT
;
enum Month:
JANUARY='Jan'
| FEBRUARY='Feb'
| MARCH='Mar'
| APRIL='Apr'
;
如果日期和年份在允许的范围内,我会实施自定义验证器来检查。 这是一个文档,如何做到: