0

そのため、文法で恐ろしいシフト/削減エラーが発生していました。最小限のテスト ケースを次に示します。

%token PLUS MINUS TIMES DIVIDE NUMBER
%token EQUAL NEQUAL GREATER LESS NOT

%left   EQUAL   NEQUAL
%left   GREATER LESS
%left   PLUS    MINUS
%left   TIMES   DIVIDE
%left   UMINUS  NOT

%%

exp             : exp binop exp
                | unop exp
                | NUMBER
                ;

binop           : MINUS
                | PLUS
                | TIMES
                | DIVIDE
                | EQUAL
                | NEQUAL
                | GREATER
                | LESS
                ;

unop            : MINUS %prec UMINUS
                | NOT
                ;

%%

しかし、実験を通して、私はどうにかして問題を解決することができました:

%token PLUS MINUS TIMES DIVIDE NUMBER
%token EQUAL NEQUAL GREATER LESS NOT

%left   EQUAL   NEQUAL
%left   GREATER LESS
%left   PLUS    MINUS
%left   TIMES   DIVIDE
%left   UMINUS  NOT

%%

exp             : binops
                | unops
                | NUMBER
                ;

unops           : MINUS exp %prec UMINUS
                | NOT exp
                ;

binops          : exp MINUS exp
                | exp PLUS exp
                | exp TIMES exp
                | exp DIVIDE exp
                | exp EQUAL exp
                | exp NEQUAL exp
                | exp GREATER exp
                | exp LESS exp
                ;

%%

そもそもシフト/リデュースエラーが発生した理由と、これが機能した理由を誰かが説明できますか? これも適切な解決策ですか?そうでない場合、何ですか?

4

1 に答える 1

2

最初の文法では、優先順位宣言はまったく何もしません。優先順位は、優先順位を持つ端子を含む代替にのみ適用されます。あなたの最初の文法では、それは と のプロダクションにbinopなりunopます。しかし、これらの作品の代替案は完全に明白です。PLUSに還元することを決定するのに優先順位は必要ありませんbinop

binops2 番目の文法では、競合するあいまいな代替 (およびの生成unops) が終端を直接含むため、優先関係は効果があります。

つまり、優先順位は非終端記号を「調べ」ません。

于 2013-06-02T04:58:17.010 に答える