Reputation: 27886
I've got a rule to match time periods specified in years, months, days, hours, minutes, and seconds. I want to allow any combination of these, so long as there's at least one, and they appear in that order.
for example:
but not:
My current rule is:
period
: years=INTEGER YEARS (LIST_DELIM months=INTEGER MONTHS)? (LIST_DELIM days=INTEGER DAYS)? (LIST_DELIM hours=INTEGER HOURS)? (LIST_DELIM minutes=INTEGER MINUTES)? (LIST_DELIM seconds=INTEGER SECONDS)?
| months=INTEGER MONTHS (LIST_DELIM days=INTEGER DAYS)? (LIST_DELIM hours=INTEGER HOURS)? (LIST_DELIM minutes=INTEGER MINUTES)? (LIST_DELIM seconds=INTEGER SECONDS)?
| days=INTEGER DAYS (LIST_DELIM hours=INTEGER HOURS)? (LIST_DELIM minutes=INTEGER MINUTES)? (LIST_DELIM seconds=INTEGER SECONDS)?
| hours=INTEGER HOURS (LIST_DELIM minutes=INTEGER MINUTES)? (LIST_DELIM seconds=INTEGER SECONDS)?
| minutes=INTEGER MINUTES (LIST_DELIM seconds=INTEGER SECONDS)?
| seconds=INTEGER SECONDS
;
This feels like a fair amount of redundancy. Is there any way to simplify this?
Upvotes: 1
Views: 626
Reputation: 170148
Besides matching more loosely in your grammar and validating in a listener or visitor, no, there is no way to simplify the rule.
For readability, you might want to create separate parser rules so that you don't need to label them:
period
: years (',' months)? (',' days)? (',' hours)? (',' minutes)? (',' seconds)?
| months (',' days)? (',' hours)? (',' minutes)? (',' seconds)?
| ...
| seconds
;
years
: INTEGER YEARS
;
months
: INTEGER MONTHS
;
...
LIST_DELIM : ',';
A related Q&A: ANTLR4: Matching all input alternatives exaclty once
Upvotes: 1