ANTLR4规则中的一个或多个选项*按顺序*

时间:2014-10-10 20:07:26

标签: java parsing antlr4

我有一条规则可以匹配以年,月,日,小时,分钟和秒为单位指定的时间段。我想允许这些的任意组合,只要至少有一个,并且它们按顺序出现。

例如:

  • 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
    ;

这感觉就像是相当多的冗余。有什么方法可以简化这个吗?

1 个答案:

答案 0 :(得分:1)

除了在语法中更松散地匹配并在听众或访问者中进行验证之外,没有,也没有办法简化规则。

为了便于阅读,您可能需要创建单独的解析器规则,以便您不需要标记它们:

period
 : years (',' months)? (',' days)? (',' hours)? (',' minutes)? (',' seconds)?
 | months (',' days)? (',' hours)? (',' minutes)? (',' seconds)?
 | ...
 | seconds
 ;

years
 : INTEGER YEARS 
 ;

months
 : INTEGER MONTHS
 ;

...

LIST_DELIM : ',';

相关的问与答:ANTLR4: Matching all input alternatives exaclty once