2013-08-21 3 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' к * never * соответствовать более одного символа. –

+0

@ 280Z28 Спасибо за комментарий. У меня действительно сложилось впечатление, что это проблема жадности, и мой быстрый тест решил проблему OP, поэтому я представил ответ. Однако вчера я купил книгу, поэтому дайте мне немного переварить ее. Я сохраню ответ здесь и в конечном итоге обновит его или удалю. – auselen

Смежные вопросы