2013-08-21 19 views
5

mam definicja reguły tak:antlr żeton priorytet

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

względu na wejście "168: 321-331", myślałem, że to pasuje do odniesienia regułę. Ale w rzeczywistości cały ciąg jest tokenizowany jako FREE_TEXT_WORD.

Jak mogę dokonać INTEGER tokena mają pierwszeństwo nad FREE_TEXT_WORD w tym przypadku?

Dzięki.

Odpowiedz

4

ANTLR będą zawsze wykorzystywać dłuższe żeton w krótszym tokena, tak aby poprawić tę sytuację, należy wykonać jedną z następujących czynności:

  1. Dokonaj FREE_TEXT_WORD nie odpowiadają więcej niż 3 znaki dla wejścia 168:321-331 np nie zezwalając na umieszczenie cyfry lub całkowite usunięcie reguły.

    • Można również zmienić FREE_TEXT_WORD do FREE_TEXT_CHARACTER. Ograniczając regułę tylko do dopasowywania pojedynczego znaku, nigdy nie będzie dłuższy niż inny token, więc jego priorytet będzie zależał od jego pozycji w gramatyce. Będziesz wtedy trzeba utworzyć regułę parsera dla słów:

      freeTextWord : FREE_TEXT_CHARACTER+; 
      
  2. Przesuń FREE_TEXT_WORD żeton w trybie, który nie jest włączona w momencie, gdy Twój wkład osiąga 168:321-331.

0

FREE_TEXT_WORD w swojej obecnej formie przechwytuje wszystko. Potrzebujesz non greedy lexer rule.

Spróbuj zmienić

FREE_TEXT_WORD: NON_SPACE+;

do

FREE_TEXT_WORD: NON_SPACE+?;.

+1

-1: To nie działa tak, jak to wygląda. To, co faktycznie zrobiłeś, przekształca regułę na "FREE_TEXT_WORD: NON_SPACE;", która pozwala regule 'INTEGER' dopasować dane wejściowe, wymuszając regułę' FREE_TEXT_WORD' na * nigdy * dopasowując więcej niż jeden znak. –

+0

@ 280Z28 Dzięki za komentarz. Byłem naprawdę pod wrażeniem, że był to problem chciwości, a mój szybki test rozwiązał problem PO, dlatego przesłałem odpowiedź. Jednak wczoraj kupiłem książkę, więc pozwól mi ją przetrawić przez jakiś czas. Utrzymam odpowiedź tutaj i ewentualnie zaktualizuję ją lub usuniemy. – auselen