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+2expr2+3exprINTEGER1+2expr + 3

+また、それを指定して結合性を維持することで問題を解決することもできます。これにより、新しいトークンのシフト-よりも削減の優先度が高くなります。1+2前文にその行を追加します。

%left '+' '-'

それが役に立てば幸い。

于 2012-10-25T12:20:39.883 に答える