我有一个规则来匹配以年、月、天、小时、分钟和秒为单位指定的时间段。我想允许这些的任何组合,只要至少有一个,并且它们按顺序出现。
例如:
- 3年5天
- 2个月17秒
但不是:
- 1天,1个月
- 5分钟,2小时
我目前的规则是:
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
;
这感觉像是相当多的冗余。有什么方法可以简化这一点吗?
除了在语法中进行更松散的匹配并在侦听器或访问者中进行验证之外,没有任何方法可以简化规则。
为了可读性,您可能需要创建单独的解析器规则,这样就不需要标记它们:
period
: years (',' months)? (',' days)? (',' hours)? (',' minutes)? (',' seconds)?
| months (',' days)? (',' hours)? (',' minutes)? (',' seconds)?
| ...
| seconds
;
years
: INTEGER YEARS
;
months
: INTEGER MONTHS
;
...
LIST_DELIM : ',';
相关问答;A: ANTLR4:匹配所有输入备选方案检查一次