Сдвиг / уменьшение конфликта с оператором if ... else

Я пытаюсь создать синтаксический анализатор для языка, похожего на Java, но с помощью оператора else возникает конфликт сдвига / уменьшения. Я пробовал бизона bison_file.y --report=state и результат о конфликте:

Состояние 62 31 заявление: if_statement. 65 if_else_statement: if_statement. Оператор ELSE сдвиг ELSE и переход в состояние 84 ELSE [уменьшить с помощью правила 31 (оператор)] $default уменьшить с помощью правила 31 (оператор)

Я не могу придумать способ избежать конфликта. Есть хорошие идеи? Здесь я отправляю полный код:

%{
#include <stdio.h>
#include <math.h>
void yyerror(char *);
extern int yylval;
extern FILE *yyin;
extern FILE *yyout;
extern yylineno;
extern int yyparse(void);
extern int yylex(void);
extern int yywrap() { return 1; }
extern char* yytext;
int errors;
%}

%debug
%start m_class


%token IF ELSE INT CHAR CLASS NEW GURISE VOID WHILE
%token PUBLIC PROTECTED PRIVATE STATIC FINAL ABSTRACT
%token PLUS MINUS MUL DIV MODULO
%token EQ NEQ GRT LT GREQ LEQ
%token OR AND NOT
%token AR_PAR DEK_PAR AR_AGK DEK_AGK AR_STRO DEK_STRO
%token SEMICOLON ANATHESI COMA
%token MY_INT SINT MY_CHAR ID

%right          ANATHESI
%left           OR AND
%nonassoc       EQ NEQ GRT LT GREQ LEQ
%left           PLUS MINUS MUL DIV MODULO
%right          NOT

%%

m_class: m_class class_declaration
        | class_declaration
        ;

class_declaration: CLASS ID class_body
        ;

class_body: AR_STRO variable_declaration constructor method_declaration DEK_STRO
        ;

variable_declaration:variable variable_declaration
    |variable
    |array_declaration
    |array_declaration variable_declaration
        ;

variable:  var_type ID SEMICOLON
    ;

var_type: INT
        |CHAR
        ;

array_declaration: ID ANATHESI NEW var_type AR_AGK MY_INT DEK_AGK SEMICOLON
    ;


constructor: modifier ID AR_STRO variable_declaration DEK_STRO
        ;

modifier: PUBLIC
        | PROTECTED
        | PRIVATE
        | STATIC
        | FINAL
        | ABSTRACT
        ;
method_declaration: modifier meth_type ID parameters meth_body
        ;

meth_type: VOID
        | var_type
        ;

parameters: AR_PAR par_body DEK_PAR
        ;

par_body: var_type ID
        | par_body COMA var_type ID
        ;

meth_body: AR_STRO bodybuilder DEK_STRO
        ;

bodybuilder: statement GURISE expression SEMICOLON
        |statement bodybuilder
    |statement
        ;

statement: anathesh
        | if_statement
    | if_else_statement
        | while_statement
        ;

statementsss: statement
    |
    ;

anathesh:atath SEMICOLON
        | atath numeric_expression SEMICOLON
        ;

atath: ID ANATHESI orisma
    |ID AR_AGK MY_INT DEK_AGK ANATHESI orisma
    ;

orisma: ID
    |MY_INT
    |SINT
    |MY_CHAR
    ;

expression: testing_expression
        | numeric_expression
        | logical_expression
        | ID
        | MY_INT
        | SINT
        | MY_CHAR
        ;

numeric_expression:  expression PLUS  expression
        | expression MINUS expression
        | expression MUL expression
        | expression DIV expression
        | expression MODULO expression
        ;

testing_expression: expression EQ expression
        | expression NEQ expression
        | expression GRT expression
        | expression LT expression
        | expression GREQ expression
        | expression LEQ expression
        ;
logical_expression: expression OR expression
        | expression AND expression
        | expression NOT expression
        ;

if_statement: IF abc
    |
        ;

if_else_statement: if_statement ELSE statement
        ;

abc: sin8iki statement
    ;

sin8iki: AR_PAR testing_expression DEK_PAR
        | AR_PAR logical_expression DEK_PAR
        ;

while_statement: WHILE sin8iki statement
        ;


%%



void yyerror(char *s) {
        errors++;
printf("\n------- ERROR AT LINE #%d.\n\n", yylineno);
fprintf(stderr, "%d: error: '%s' at '%s', yylval=%u\n", yylineno, s, yytext, yylval);

}
int main (int argc, char **argv) {
        ++argv;
        --argc;
    errors=0;
        if (argc > 0)
                yyin = fopen (argv[0], "r");
        else
                yyin = stdin;
        yyout = fopen ("output","w");
        yyparse ();
    if(errors==0)
        printf("komple");
        return 0;
}

1 ответ

Здесь парсер помещает токены в стек, и когда IF abc выталкиваются и следующий токен ELSE возникнет конфликт, парсер должен уменьшить IF abc в соответствии с if_statement Правило или он должен сдвинуть следующий токен ELSE в стек. Вы должны определить приоритеты своих правил, в этом случае вы должны дать ELSE маркер более приоритетный, чем if_statement используя% nonassoc и% prec. попробуй это:

if_statement: IF abc %prec else_priority

и в области приоритетов:

%nonassoc else_priority
%nonassoc ELSE

Вы должны написать приоритеты в этом порядке (чем больше приоритет, тем меньше). надеюсь, что это решит вашу проблему.

Другие вопросы по тегам