YACC сдвиг уменьшить проблему - PullRequest
2 голосов
/ 13 февраля 2010

У меня есть то, что я считаю простой частью моей грамматики, это ошибка от yacc. я знаю, что мне нужно добавить% prec где-то, но не совсем уверен, где.

Assignment : Ref '=' Ref
           | Ref '=' Expression
           | Ref '=' Value
           | Ref '=' FunctionCall
           ;

Ref : ID
    | ID '[' Expression ']'
    ;

Value : INT
      | BOOLEAN
      | CHAR
      | STRING
      ;

Ошибка, которую я получаю:

 warning: rule never reduced because of conflicts: Assignment: Ref '=' Ref
 warning: rule never reduced because of conflicts: Assignment: Ref '=' Value

То есть ID - это просто имя переменной, а Ref - ссылка на переменную.

Ответы [ 4 ]

1 голос
/ 14 февраля 2010

Нам действительно нужно увидеть определения 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 к отдельным токенам для конкретного задания.Это также помогает уменьшить путаницу для пользователя, поскольку все выражения имеют одинаковый синтаксис.

1 голос
/ 13 февраля 2010

Проблема с Assignment : Ref '=' Ref в Ref = Ref = Ref неоднозначна (о которой вы, вероятно, уже знаете); попробуйте определить токен '=' с помощью ключевого слова %right (при условии, что вы хотите, чтобы "=" ассоциировалось справа):

%right '='

Что касается Assignment: Ref '=' Value, мне нужно увидеть определение для ID и различных Value тел, хотя определения '=' в качестве правой ассоциативности может быть достаточно.

1 голос
/ 13 февраля 2010

хмм не уверен, будут ли FunctionCall, Value и Ref также выражениями? возможно, если это работает, когда Expression удалено, это может означать, что Expression также содержит один из них ...

0 голосов
/ 13 февраля 2010

Может показаться, что синтаксический анализатор не может различить различные строки Assignment в грамматике в пределах (довольно строгих) ограничений на просмотр.

Если бы произведения ID и Value было легко разобрать, я не думаю, что у вас возникнет эта проблема. Вы вполне могли бы сгруппировать все производства Assignment в одно, что, по крайней мере, упростило бы сокращение этого одного правила и сделало бы проблему более очевидной.

...