2

以下は私の文法です:

arithmetic_expression : expression + expression
                      | expression - expression

expression            : constant
                      | ID
                      | arithmetic_expression
                      | ternary

ternary               : expression ? expression : expression

この状態で shift-reduce エラーが発生します。

state 126

    (19) ternary -> expression QUESTION_MARK expression COLON expression .
    (27) arithmetic_exp -> expression . PLUS expression
    (28) arithmetic_exp -> expression . MINUS expression
    (19) ternary -> expression . QUESTION_MARK expression COLON expression

  ! shift/reduce conflict for PLUS resolved as shift
  ! shift/reduce conflict for MINUS resolved as shift
  ! shift/reduce conflict for QUESTION_MARK resolved as shift

    PLUS            shift and go to state 86
    MINUS           shift and go to state 88
    QUESTION_MARK   shift and go to state 85

  ! PLUS            [ reduce using rule 19 (ternary -> expression QUESTION_MARK expression COLON expression .) ]
  ! MINUS           [ reduce using rule 19 (ternary -> expression QUESTION_MARK expression COLON expression .) ]
  ! QUESTION_MARK   [ reduce using rule 19 (ternary -> expression QUESTION_MARK expression COLON expression .) ]

私は紛争がそれであると信じています

true ? 1 : false ? 3 : 2

true ? 1 : (false ? 3 : 2)またはとして解釈できます(true ? 1 : false) ? 3 : 2

、 の優先順位を+左結合で、 (右結合に設定した)-よりも高いレベルに設定しました。?

私は何を間違っていますか?

4

2 に答える 2

4

私があなたを正しく理解しているなら、あなたは次のことをしました:

%left '+' '-'
%right '?'

%%

arithmetic_expression : expression + expression
                      | expression - expression
                      ;
ternary               : expression ? expression : expression
                      ;

ternaryプロダクションの優先順位を bison に伝えていないため、これは機能しません。

shift-reduce の競合を解決するために、bison は、削減される可能性のあるプロダクションの優先順位と、シフトされる可能性のある端末の優先順位を比較します。端子「+」、「-」、および「?」の優先順位と、両方のプロダクションの優先順位を で宣言しましたが、プロダクションの優先順位は では宣言してarithmetic_expressionいませんternary

バイソンのマニュアルから引用し、強調を追加しました:

各ルールは、コンポーネントで言及されている最後の終端記号から優先されます。

それは非常に微妙で、最初に気付かなかった人はいないでしょう。

解決策: ターミナルの優先順位を宣言するか、プロダクションに:追加します。%prec '?'ternary

于 2013-07-28T04:55:16.310 に答える
1

正確 - 結合性を指定していません。

C では、文法は次のように述べています。

conditional_expression = logical_or_expression [ '?' expression ':' conditional_expression ];

だから私はあなたが何かを望んでいると信じています

conditional_expression = arithmetic_expression [ '?' expression ':' conditional_expression ];

Cのような動作が必要な場合(したがって、他のプロパティの中でも適切な結合性)。

于 2013-07-28T03:36:38.110 に答える