Несколько альтернатив с одинаковым ярлыком, только последний получает что-либо назначенное ему - PullRequest
2 голосов
/ 15 августа 2011

У меня есть несколько незарезервированных ключевых слов, которые соответствуют правилам, таким как:

kFOO = {self.input.LT(1).text.lower() == 'foo'}? ID;

Где токен ID - это стандартная буквенно-цифровая строка.Эти виды правил работают отлично, за исключением случаев, когда я пытаюсь сделать что-то вроде этого:

some_rule
@after { do_something_with($t.text) }
  : t=kWORD1
  | t=kWORD2
  | t=kWORD3
  ;

В сгенерированном парсере функции правил kWORD1 и kWORD2 ничего не возвращают, но kWORD3 функция делает.Кроме того, в функции some_rule только блок, пытающийся сопоставить kWORD3, присваивает возвращаемое значение t.Два других вызова никоим образом не ссылаются на t.

(Кроме того, я ожидал, что сработает следующее, но я подозреваю, что это не так, по той же основной причине.

some_rule
@after { do_something_with($t.text) }
  : t=( kWORD1
  | kWORD2
  | kWORD3)
  ; 

Ничто не присваивается t ни при каких условиях.)

Однако, следующие DOES работают должным образом:

some_rule
@after { do_something_with($t1.text or $t2.text or $t3.text) }
  : t1=kWORD1
  | t2=kWORD2
  | t3=kWORD3
  ;

Каждая из соответствующих функций генерируется для возврата значенияи каждый из блоков, соответствующих правилам ключевых слов в some_rule, присваивает возвращаемое значение их метке.Проблема с этим решением в том, что оно становится немного чрезмерным, когда есть еще несколько альтернатив.

Половина меня кричит "БАГ!"но это первый проект antlr, который я сделал, поэтому, скорее всего, есть кое-что, чего я не понимаю.

Какой лучший способ сделать то, что я пытаюсь сделать здесь?

1 Ответ

1 голос
/ 20 января 2012

Помимо того, что .toLower() никогда не совпадает с FOO, я полагаю, что это связано с тем, что kWORD1 является другим типом кВтORD2 и т. Д., Но кое-что, что может работать, таково:

kWORD [String pre]
: {self.input.LT(1).text.lower() == $pre}? ID;

some_rule
@after { do_something_with($t.text) }
  : t=kWORD['word1']
  | t=kWORD['word2']
  | t=kWORD['word3']
  ;

хотя не проверено.

...