Вы поместили 'drop'
и 'put'
в два разных правила лексера:
PUT_SYN : 'put' | 'place' | 'drop'; // drop & put
PUT2_SYN : 'put' | 'douse'; // put
...
DROP_SYN : 'drop' | 'throw' | 'relinquish'; // drop
Когда лексер встречает put
, правило 100 * * всегда будет соответствоватьтаким образом, 'put'
может (или должен) быть удален из правила PUT2_SYN
.
Итак, ваша проблема с синтаксическим анализом строки drop object
: синтаксический анализатор попытается сопоставить drop_a : (DROP_SYN)(ID);
, но "drop"
будет сопоставлено в правиле лексера PUT_SYN
.
РЕДАКТИРОВАТЬ
Эти списки синонимов можно лучше превратить в правила синтаксического анализатора (вместо правил лексера),Вот небольшая демонстрация:
grammar TextAdventure;
parse
: command (EndCommand command)* EOF
;
command
: put_syn_1 OtherWord in_syn OtherWord
| put_syn_2 out_syn_1 OtherWord
| out_syn_2 OtherWord
| Drop Kick OtherWord
| drop_syn OtherWord
;
drop_syn
: Drop
| Throw
| Relinquish
;
in_syn
: In
| Into
| Inside
| Within
;
put_syn_1
: Put
| Place
| Drop
;
put_syn_2
: Put
| Douse
;
out_syn_1
: Out
;
out_syn_2
: Extinguish
| Douse
;
Space : (' ' | '\t' | '\r' | '\n'){$channel=HIDDEN;};
EndCommand : ';';
Put : 'put';
Place : 'place';
Drop : 'drop';
Douse : 'douse';
In : 'in';
Into : 'into';
Inside : 'inside';
Within : 'within';
Out : 'out';
Extinguish : 'extinguish';
Throw : 'throw';
Relinquish : 'relinquish';
Kick : 'kick';
OtherWord : ('a'..'z' | 'A'..'Z')+;
При интерпретации следующего источника:
drop object ; put yourself in myshoes ; place it in avase
вы увидите, что ANTLRWorks генерирует следующее дерево разбора:
![alt text](https://i.stack.imgur.com/nTp2T.png)