Я реализую синтаксический анализатор с ANTLR для D. Этот язык основан на C, поэтому существует некоторая двусмысленность вокруг объявлений и выражений.Учтите это:
a* b = c; // This is a declaration of the variable d with a pointer-to-a type.
c = a * b; // as an expression is a multiplication.
Поскольку второй пример мог появиться только справа от выражения присваивания, я попытался решить эту проблему с помощью следующего фрагмента:
expression
: left = assignOrConditional
(',' right = assignOrConditional)*
;
assignOrConditional
: ( postfixExpression ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '~=' | '<<=' | '>>=' | '>>>=' | '^^=') )=> assignExpression
| conditionalExpression
;
assignExpression
: left = postfixExpression
( op = ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '~=' | '<<=' | '>>=' | '>>>=' | '^^=')
right = assignOrExpression
)?
;
conditionalExpression
: left = logicalOrExpression
('?' e1 = conditionalExpression ':' e2 = conditionalExpression)?
;
Насколько мойПонимание идет, это должно сделать трюк, чтобы избежать двусмысленности, но тесты не проходят.Если я передаю интерпретатору какие-либо входные данные, начиная с правила assignOrConditional, он завершится с NoViableAltException.входные данные были
a = b
b-=c
d
Может быть, я неправильно понимаю, как работают предикаты, поэтому было бы здорово, если бы кто-то мог исправить мое объяснение к коду: если входные данные могут быть прочитаны как выражение postfixExpression, он проверит,следующий токен после выражения postfixExpression является одним из операторов присваивания, и, если это так, он будет анализировать правило как выражение присваивания.(Обратите внимание, что assignmentExpression и conditionalExpression работают хорошо).Если следующий токен не принадлежит им, он пытается проанализировать его как условное выражение.
РЕДАКТИРОВАТЬ [решено] Теперь есть еще одна проблема с этим решением, которую я мог бы реализовать:assignmentExpression должен выбрать в правой части выражения, что это снова задание (то есть, после него следует постфикс и оператор присваивания), если оно объединено в цепочку.
Есть идеи, что не так с моим пониманием?