2014-10-10 33 views
1

我有一條規則來匹配年,月,日,小時,分鐘和秒指定的時間段。我想要允許這些的任何組合,只要至少有一個,並且它們按照該順序出現。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

除了在語法中更加鬆散地匹配,並在偵聽器或訪問者中進行驗證,否則無法簡化規則。

爲了增強可讀性,你可能想使你不需要進行標記,創建單獨的語法規則:

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

years 
: INTEGER YEARS 
; 

months 
: INTEGER MONTHS 
; 

... 

LIST_DELIM : ','; 

一個相關的Q &答:ANTLR4: Matching all input alternatives exaclty once