0

您好,我刚刚开始在 bison/yacc 中进行一些解析。现在我的第一个程序已经失败了。什么地方出了错?我使用的示例来自: 教程的原始来源

%{
    #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.1 的野牛我收到此错误:

conflicts: 4 shift/reduce
4

1 回答 1

0

试试看:

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

bison/yacc 不喜欢右递归。如果输入是1+2+3,当解析器到达时,1+2+它不能决定减少1+2expr或移动另一个标记以减少2+3expr。通过INTEGER在右边指定,它可以决定一看到1+2离开expr + 3就减少,然后再减少。

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

%left '+' '-'

希望能帮助到你。

于 2012-10-25T12:20:39.883 回答