2013-08-21 99 views
5

我有這樣的規則定義:ANTLR的令牌優先

reference: volume':'first_page'-'last_page ; 

volume: INTEGER; 
first_page: INTEGER; 
last_page: INTEGER; 

INTEGER: [0-9]+; 

FREE_TEXT_WORD: NON_SPACE+; 

fragment NON_SPACE : ~[ \r\n\t]; 

鑑於輸入 「168:321-331」,我認爲這將匹配參考規則。但實際上,整個字符串被標記爲FREE_TEXT_WORD

我怎樣才能在這情況下,INTEGER令牌採取優先於FREE_TEXT_WORD

謝謝。

回答

4

ANTLR會一直使用較長的令牌在較短的道理,所以要糾正這種情況,你必須做以下事情之一:

  1. 充分利用FREE_TEXT_WORD不匹配多於3個字符輸入168:321-331 ,例如不允許它包含數字,或者可能完全刪除該規則。

    • 您還可以將FREE_TEXT_WORD更改爲FREE_TEXT_CHARACTER。通過將規則限制爲僅匹配單個字符,它永遠不會比另一個標記長,因此其優先級將由其在語法中的位置決定。然後,您將需要創建一個解析器規則的話:

      freeTextWord : FREE_TEXT_CHARACTER+; 
      
  2. 移動FREE_TEXT_WORD令牌到未在您的輸入達到168:321-331點啓用的模式。

0

FREE_TEXT_WORD以其目前的形式捕捉一切。您需要non greedy lexer rule

嘗試改變

FREE_TEXT_WORD: NON_SPACE+;

FREE_TEXT_WORD: NON_SPACE+?;

+1

-1:這不會做它看起來像它正在做的事情。你實際做的是將規則轉換爲'FREE_TEXT_WORD:NON_SPACE;',它允許'INTEGER'規則通過強制'FREE_TEXT_WORD'規則匹配輸入*從不匹配多個字符。 –

+0

@ 280Z28感謝您的評論。我真的覺得這是一個貪婪的問題,我的快速測試解決了OP的問題,因此我提出了一個答案。不過,我昨天買了這本書,所以讓我消化它一段時間。我會在這裏保留答案,並最終將其更新或刪除。 – auselen