Первое, на что нужно обратить внимание, это то, что вы получите почти то же сообщение об ошибке, что и вы, если удалите правило '(' expr ')'
:
expr
: '(' ')' '->' expr
| ID
;
Сообщение об ошибке:
line 1:2 missing ')' at '->'
line 1:4 mismatched input '<EOF>' expecting {'(', ID}
Я полагаю, что вы получаете ошибки, такие как «несоответствующий ввод X, ожидая Y» и «пропущенный X» для грамматик LL (1) и no viable alternative
, когда требуется предварительный просмотр в текущей позиции или что-то в этом роде.
Так что спомните, что мы можем попытаться переписать вашу грамматику на LL (1):
expr
: '(' ( expr ')' | ')' '->' expr )
| ID
;
Тогда появится сообщение об ошибке:
line 1:2 mismatched input '->' expecting {'(', ')', ID}
Это очень близко к тому, что вы хотите.