Бесполезное правило из-за конфликтов в YACC
Сообщение об ошибке:
bison -vdy tjc.y
conflicts: 2 shift/reduce
tjc.y:72.26-29: warning: rule useless in parser due to conflicts: return_type: type
РЕДАКТИРОВАТЬ 2: дальнейшее сокращение грамматики до следующих правил. Та же ошибка из-за того же конфликта. Если я удалю field_decl в правилах, конфликт исчезнет.
member_decl: field_decl | method_decl;
field_decl: STATIC type IDENT EQ SEMI;
method_decl: STATIC return_type IDENT LPAR RPAR;
type: INT | FLOAT;
return_type: type | VOID;
Вот раздел с конфликтом сдвига / уменьшения в y.output:
state 18
7 field_decl: STATIC type . IDENT EQ SEMI
14 return_type: type .
IDENT shift, and go to state 23
IDENT [reduce using rule 14 (return_type)]
Пожалуйста, помогите мне увидеть, что здесь происходит не так.
2 ответа
Я думаю, что анализ Perry того, почему у вас проблемы, является правильным.
Мне удалось получить аналогичные предупреждения с этой полной грамматикой (идентичной вашей, но с %token
правила на месте, чтобы я мог его скомпилировать):
%token STATIC IDENT FLOAT INT VOID LPAR RPAR EQ SEMI
%%
member_decl: field_decl | method_decl;
field_decl: STATIC type IDENT EQ SEMI;
method_decl: STATIC return_type IDENT LPAR RPAR;
type: INT | FLOAT;
return_type: type | VOID;
%%
Учитывая анализ, я бы, наверное, исправил это так:
%token STATIC IDENT FLOAT INT VOID LPAR RPAR EQ SEMI
%%
member_decl: field_decl | method_decl;
field_decl: STATIC type IDENT EQ SEMI;
method_decl: STATIC type IDENT LPAR RPAR;
type: INT | FLOAT | VOID;
%%
Компилируется без ошибок в Bison. Вам просто нужно добавить семантическую проверку в обработке для field_decl
что гарантирует, что соответствующие type
($2
) не является VOID
,
Итак, проблема может быть в следующем: вы генерируете синтаксический анализатор LALR(1). Посмотрев один раз, вы не сможете различить правила field_decl и method_decl. Зачем? Поскольку оба выглядят одинаково, так как на первый взгляд парсер не может отличить тип return_type от типа (оба могут содержать INT или FLOAT). Я не уверен на 100%, поскольку моя память о различиях между LR, LALR и т. Д. Сейчас все нечеткая, но может показаться, что это проблема - на это особенно указывает тот факт, что при попытке удаления field_decl ошибка исчезла.