Зубр: Конфликты: 1 сдвиг / ошибка уменьшения - PullRequest
0 голосов
/ 03 декабря 2011

Я пытаюсь создать парсер с бизоном и сузил все свои ошибки до одной сложной.

Вот отладочный вывод bison с состоянием, в котором лежит ошибка:

state 120

   12 statement_list: statement_list . SEMICOLON statement
   24 if_statement: IF conditional THEN statement_lists ELSE statement_list .

    SEMICOLON  shift, and go to state 50

    SEMICOLON  [reduce using rule 24 (if_statement)]
    $default   reduce using rule 24 (if_statement)

Вот правила перевода в источнике parser.y

%%

program              : ID COLON block ENDP ID POINT
                     ;
block                : CODE statement_list
                     | DECLARATIONS declaration_block CODE statement_list
                     ;
declaration_block    : id_list OF TYPE type SEMICOLON
                     | declaration_block id_list OF TYPE type SEMICOLON
                     ;
id_list              : ID
                     | ID COMMA id_list
                     ;
type                 : CHARACTER
                     | INTEGER
                     | REAL
                     ;
statement_list       : statement
                     | statement_list SEMICOLON statement
                     ;
statement_lists      : statement
                     | statement_list SEMICOLON statement
                     ;
statement            : assignment_statement
                     | if_statement
                     | do_statement
                     | while_statement
                     | for_statement
                     | write_statement
                     | read_statement
                     ;
assignment_statement : expression OUTPUTTO ID
                     ;
if_statement         : IF conditional THEN statement_lists ENDIF
                     | IF conditional THEN statement_lists ELSE statement_list
                     ;
do_statement         : DO statement_list WHILE conditional ENDDO
                     ;
while_statement      : WHILE conditional DO statement_list ENDWHILE
                     ;
for_statement        : FOR ID IS expression BY expressions TO expression DO statement_list ENDFOR
                     ;
write_statement      : WRITE BRA output_list KET
                     | NEWLINE
                     ;
read_statement       : READ BRA ID KET
                     ;
output_list          : value
                     | value COMMA output_list
                     ;
condition            : expression comparator expression
                     ;
conditional          : condition
                     | NOT conditional
                     | condition AND conditional
                     | condition OR conditional
                     ;
comparator           : ASSIGNMENT
                     | BETWEEN
                     | LT
                     | GT
                     | LESSEQUAL
                     | GREATEREQUAL
                     ;
expression           : term
                     | term PLUS expression
                     | term MINUS expression
                     ;
expressions          : term
                     | term PLUS expressions
                     | term MINUS expressions
                     ;
term                 : value
                     | value MULTIPLY term
                     | value DIVIDE term
                     ;
value                : ID
                     | constant
                     | BRA expression KET
                     ;
constant             : number_constant
                     | CHARCONST
                     ;
number_constant      : NUMBER
                     | MINUS NUMBER
                     | NUMBER POINT NUMBER
                     | MINUS NUMBER POINT NUMBER
                     ;              
%%

Когда я удаляю правило if_statement, ошибок нет, поэтому я значительно его сузил, но все еще не могу устранить ошибку.

Спасибо за любую помощь.

Ответы [ 2 ]

3 голосов
/ 03 декабря 2011

Рассмотрим следующее утверждение: если условие, то s2, иначе s3; s4

Существует две интерпретации:

if condition then
   s1;
else 
   s2;
s3;

Другой:

if condition then
   s1;
else
   s2;
   s3;

В первом список составления состоит из операторов if и s3. Тогда как другое утверждение состоит только из одного оператора if. Отсюда и двусмысленность. Bison предпочитает сдвиг уменьшать, когда существует конфликт сдвиг-уменьшение, поэтому в приведенном выше случае анализатор выберет сдвиг s3.

Поскольку в вашем операторе if-then есть ENDIF, попробуйте ввести в свой оператор if-then-else ENDIF, тогда проблема решена.

2 голосов
/ 03 декабря 2011

Я думаю, что вам не хватает ENDIF в правиле IF-THEN-ELSE-ENDIF.

...