答えの一部は、 からの出力ファイルをよく見ることですbison -v
。最初の文法については、次の抜粋を入手しました。
State 8 conflicts: 1 shift/reduce
State 9 conflicts: 1 shift/reduce
State 10 conflicts: 1 shift/reduce
State 11 conflicts: 1 shift/reduce
State 12 conflicts: 1 shift/reduce
Grammar
0 $accept: expr $end
1 expr: NUMBER
2 | expr '+' expr
3 | expr '-' expr
4 | expr '*' expr
5 | expr '/' expr
6 | expr expr
したがって、文法には 5 つのシフト/リデュースの競合があります。これらは、それほど深刻ではないタイプの紛争です。%expect 5
文法が行っていることが正しいと確信している場合は、文法でそれらを期待していると述べることができます。
state 0
0 $accept: . expr $end
NUMBER shift, and go to state 1
expr go to state 2
state 1
1 expr: NUMBER .
$default reduce using rule 1 (expr)
state 2
0 $accept: expr . $end
2 expr: expr . '+' expr
3 | expr . '-' expr
4 | expr . '*' expr
5 | expr . '/' expr
6 | expr . expr
$end shift, and go to state 3
'+' shift, and go to state 4
'-' shift, and go to state 5
'*' shift, and go to state 6
'/' shift, and go to state 7
NUMBER shift, and go to state 1
expr go to state 8
state 3
0 $accept: expr $end .
$default accept
state 4
2 expr: expr '+' . expr
NUMBER shift, and go to state 1
expr go to state 9
状態 5、6、7 は状態 4 を模倣しますが、他の演算子が異なります。状態 8 は、シフト/リデュースの競合が発生した最初の状態です。ルールの.
(ドット) は、パーサーがこの状態に達したときの場所を示していることに注意してください。
state 8
2 expr: expr . '+' expr
3 | expr . '-' expr
4 | expr . '*' expr
5 | expr . '/' expr
6 | expr . expr
6 | expr expr .
NUMBER shift, and go to state 1
NUMBER [reduce using rule 6 (expr)]
$default reduce using rule 6 (expr)
expr go to state 8
state 9
2 expr: expr . '+' expr
2 | expr '+' expr .
3 | expr . '-' expr
4 | expr . '*' expr
5 | expr . '/' expr
6 | expr . expr
'*' shift, and go to state 6
'/' shift, and go to state 7
NUMBER shift, and go to state 1
NUMBER [reduce using rule 2 (expr)]
$default reduce using rule 2 (expr)
expr go to state 8
これら 2 つの状態には相違点と類似点がありますが、状態 10、11、12 は状態 9 と一致しますが、あいまいさの点が異なります。
問題は、文法が見たときです:
NUMBER OP NUMBER NUMBER
それを次のように解析するかどうかはわかりません。
( NUMBER OP NUMBER ) NUMBER expr expr
またはとして:
NUMBER OP ( NUMBER NUMBER )
expr OP expr
いずれの場合もシフト/リデュースの競合であるため、シフトを選択します。それが必要な場合は、を追加して%expect 5
、生活を続けてください。それがあなたの望むものでないなら、文法を再考する必要があります。隣接する数字のペアは何を示していますか? また、数字を区切るのに演算子文字 (おそらくコンマやコロン) は必要ありませんか?
以下を使用して、欠落している演算子の優先順位を上げてみました。
%left MISSING
他の優先順位宣言の後、次を使用します。
expr expr %prec MISSING
これは何も変わりませんでした。MISSING を他の演算子の前にリストして、MISSING の優先順位を非常に低くすることもありません。
次のような式をどのように解析する必要があるかを考えると、問題が少しわかります。
NUMBER OP NUMBER NUMBER NUMBER OP NUMBER NUMBER OP NUMBER
OPは各登場で同じところ。脳が痛い!さんもそうですbison
!