用简单的计算器语法解决冲突转移/减少

时间:2012-10-25 12:02:30

标签: bison yacc

您好我刚开始在bison / yacc中进行一些解析。现在我的第一个程序已经失败。什么地方出了错?我正在使用以下示例: original source of tutorial

%{
    #include <stdio.h>
    int yylex(void);
    void yyerror(char *);
%}


%token INTEGER

%%

program:
        program expr '\n'         { printf("%d\n", $2); }
        | 
        ;

expr:
        INTEGER                   { $$ = $1; }
        | expr '+' expr           { $$ = $1 + $3; }
        | expr '-' expr           { $$ = $1 - $3; }
        ;

%%

void yyerror(char *s) {
    fprintf(stderr, "%s\n", s);
}

int main(void) {
    yyparse();
    return 0;
}

使用2.4版本的野牛我收到此错误:

conflicts: 4 shift/reduce

1 个答案:

答案 0 :(得分:0)

试试:

expr:
    INTEGER                   { $$ = $1; }
    | expr '+' INTEGER           { $$ = $1 + $3; }
    | expr '-' INTEGER           { $$ = $1 - $3; }

bison / yacc不喜欢正确的递归。如果输入为1+2+3,则当解析器到达1+2+时,它无法决定将1+2缩减为expr还是转移另一个令牌以减少2+3expr。通过在右侧指定INTEGER,它可以决定在1+2只留下expr + 3后再减少,然后再次减少。

您还可以通过指定+-保持关联来解决问题,从而在降低1+2转移新令牌方面提供更高的优先级。在序言中添加该行:

%left '+' '-'

希望它有所帮助。