Бесполезное правило из-за конфликтов в YACC - PullRequest
1 голос
/ 28 февраля 2012

Сообщение об ошибке:

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 ]

3 голосов
/ 28 февраля 2012

Я думаю Перри анализ того, почему у вас проблемы, является правильным.

Мне удалось получить подобные предупреждения с этой полной грамматикой (идентичной вашей, но с правилами %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.

2 голосов
/ 28 февраля 2012

Хорошо, проблема может быть в следующем: вы генерируете парсер LALR (1).Посмотрев один, вы не сможете различить правила field_decl и method_decl.Зачем?Поскольку оба выглядят одинаково, так как на первый взгляд парсер не может отличить тип return_type от типа (оба могут содержать INT или FLOAT).Я не уверен на 100%, поскольку моя память о различиях между LR, LALR и т. Д. Сейчас все нечеткая, но может показаться, что это проблема - на это особенно указывает тот факт, что при попытке удаления field_declошибка исчезла.

...