Зубр: Уменьшить / уменьшить конфликт на не токенах - PullRequest
0 голосов
/ 28 мая 2019

Итак, я нахожусь в процессе создания компилятора для C-- и в настоящее время я создаю таблицы литералов, переменных и функций.

И это правило дает мне конфликт уменьшения / уменьшения:

lval: ID { check_var(); }
| ID { check_var(); } LBRACK NUM RBRACK
| ID { check_var(); } LBRACK ID { check_var(); } RBRACK;

Ошибка следующая:

parser.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
parser.y:104.6-21: warning: rule useless in parser due to conflicts [-Wother]
 | ID { check_var(); } LBRACK ID { check_var(); } RBRACK;
      ^^^^^^^^^^^^^^^^

У меня есть правила приоритета, чтобы избежать ошибок на токенах, но теперь он указывает на не токен, так что не знаете, что мне делать?

Если это случайно поможет, вот мои правила приоритета:

%token INPUT OUTPUT WRITE
%token  RETURN VOID IF ELSE WHILE ASSIGN SEMI COMMA
%token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK
%token NUM ID STRING INT
%left EQ NEQ GE LE GT LT
%left PLUS MINUS
%left TIMES OVER

1 Ответ

5 голосов
/ 28 мая 2019

Bison не проверяет идентичность двух пользовательских блоков кода в вашем синтаксисе. Так что он относится к вашей грамматике как к основному:

lval: ID action_1
    | ID action_2 LBRACK NUM RBRACK
    | ID action_3 LBRACK ID action_4 RBRACK
; 

И Bison (по умолчанию) действует как LALR (1) синтаксический анализатор , что означает, что он смотрит вперед только на один токен, прежде чем принимать решения. Поэтому, когда он видит, что вершина стека является токеном ID, а токен прогнозирования - токеном LBRACK, он не может решить, должен ли он выполнять action_2 или action_3, не осознавая, что это не так. на самом деле не имеет значения.

Решите это, используя подправило, чтобы объединить общее, что должно произойти, когда за ID следует LBRACK (а также в других ситуациях):

id_with_check: ID { check_var(); } ;

lval: id_with_check
    | id_with_check LBRACK NUM RBRACK
    | id_with_check LBRACK id_with_check RBRACK
;
...