Нам действительно нужно увидеть определения FunctionCall и (особенно) Expression, чтобы дать окончательный ответ, но я предполагаю, что Expression может быть либо одним Ref, либо значением.В этом случае он говорит, что не знает (наверняка), нужно ли анализировать Ref / Value на правой стороне присваивания непосредственно как само по себе, или как простое выражение.
Удивительно, чтоFunctionCall не привел к подобной неоднозначности - это, как правило, указывает на то, что ваше определение Expression, вероятно, нечетно, по крайней мере граничит с дефектным.
Если бы я делал это, я бы, вероятно, изменилопределение Assignment выглядит примерно так:
%left '-' '+'
%left '*' '/'
%%
Assignment: Ref '=' Expression;
Expression: Value
| FunctionCall
| Ref
| Expression '+' Expression
| Expression '-' Expression
| Expression '/' Expression
| Expression '*' Expression
| '(' Expression ')'
;
Конечно, вы можете поддерживать больше операторов, чем базовая четверка, но трудно догадаться - я просто попытался добавить достаточно, чтобы датьпо крайней мере, разумная идея.
В любом случае, с этой структурой нет сомнений в том, что правая сторона присваивания имеет как выражение, а выражение может включать три основных элементаВы перечислили, в сочетании с произвольными арифметическими операторами, так что-то вроде:
x[i] = a[2] + 1 + f(3)
Должен стать (постепенно):
Ref = Expression
Ref = Expression '+' Expression
Ref = Expression '+' Expression '+' Expression
Ref = Ref '+' Value '+' FunctionCall
ID '[' ID ']' '=' ID '[' Value ']' '+' Value '+' FunctionCall
(и FunctionCall, вероятно, еще больше уменьшится до чего-то вроде: ID '(' Value ')'
Итог: по крайней мере, эта часть грамматики по существу не подвержена конфликтам S / R - существует явныйоднозначный путь от верхнего уровня Assignment
к отдельным токенам для конкретного задания.Это также помогает уменьшить путаницу для пользователя, поскольку все выражения имеют одинаковый синтаксис.