Reputation: 2274
I am attempting to create a syntax that contains numbers and strings, as in the following:
Date: 2 Mar 2013
I have created a set of rules that more- or- less accommodate this:
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')
;
This set of rules seems to have a number of problems:
The Date rule, as written, seems to generate an error: "Cannot change type twice within a rule". I have no idea what that means, except that Xtext will apparently not allow numbers and choice strings in the same rule.
If I remove the Month rule from Date, Xtext compiles, but the syntax doesn't seem to work right. The DAY rule is supposed to provide a choice between a single digit from 1 to 9 and a two- digit number, but for some reason it only accepts a two- digit number. So while I can enter a line like:
Date: 12 2013
is accepted but a date like:
Date: 2 2013
is not.
Have I found a bug in the rules that breaks numbers in terminal rules? Or is there something missing that causes the ignoring of the '|' in my numbers? Also: what on Earth does the "Cannot change type twice within a rule" error mean and how can I fix it???
Someone please advise.
Upvotes: 0
Views: 1125
Reputation: 8695
Here you have a design problem. Generally, you have to use custom terminals as little as possible. Custom terminals have a global impact on your grammar, makes the syntax less flexible and error recovery inefficient.
I understand your intentions: you want to constraint your DSL to prevent insensible data to be parsed. This is a good idea, but custom terminals are not designed for this kind of task. The rules of thumb are:
In your scenario I would suggest the following simple grammar:
Date:
'Date': day=INT month=Month year=INT
;
enum Month:
JANUARY='Jan'
| FEBRUARY='Feb'
| MARCH='Mar'
| APRIL='Apr'
;
Than I would implement a custom validator to check, if the day and the year are within the allowed ranges. Here is a documentation, how to do it:
Upvotes: 1