3

Yacc/Bison でシフト/リデュースの競合が発生した場合、その競合を希望どおりに解決することは可能ですか? 言い換えれば、シフトまたはリデュースを優先するように明示的に強制することは可能ですか?

私が読んだことについては、デフォルトの解像度に満足している場合は、ジェネレーターに文句を言わないように伝えることができます。あなたの合理的な選択を曖昧にするので、私はこれが本当に好きではありません.

別のオプションは、文法を書き直して問題を修正することです。これが常に可能かどうかはわかりませんが、多くの場合、これにより理解がはるかに難しくなります。

最後に、これを修正できる優先ルールを読みました。私は無知にそれを多くの方法で試しましたが、うまくいきませんでした。そのために優先ルールを使用することは可能ですか? どのように?

私のあいまいな文法は非常に異なっていますが、Bison マニュアルの古典的な if-then-else を使用して具体的な例を示すことができます。

 %token IF THEN ELSE variable
 %%
 stmt:
   expr
 | if_stmt
 ;

 if_stmt:
   IF expr THEN stmt
 | IF expr THEN stmt ELSE stmt
 ;

 expr:
   variable
 ;
4

2 に答える 2

1

シフト/リデュースの競合のデフォルトの解決策はシフトすることなので、それが必要な場合は、何もする必要はありません (警告を無視する以外は)。

削減によってシフト/削減の競合を解決したい場合は、優先ルールを使用できます。削減されるルールが、シフトされるトークンよりも高い優先順位であることを確認してください。注意が必要なのは、同じルールとトークンに関連するシフト/リデュースの競合が複数ある場合です。ルールとトークンのグローバルに一貫した優先順位のセットを見つけて、希望どおりに解決することができない場合があります。

于 2012-08-27T22:09:02.557 に答える
1

私が知る限り、削減を選択して S/R 競合を解決するようにパーサーに指示することはできません。私が間違っているかもしれませんが、とにかくこのように進めるのはおそらく賢明ではありません。したがって、唯一の可能性は、文法を書き直すか、シフトによって競合を解決することです。

THEN次のとの正しい優先順位の使用法はELSE、ステートメントの望ましい動作if-then-else(つまりelse、最も内側のifステートメントとの関連付け) を示しています。

%token IF THEN ELSE variable
%right THEN ELSE

%%

stmt
    : expr
    | if_stmt
    ;

if_stmt
    : IF expr THEN stmt
    | IF expr THEN stmt ELSE stmt
    ;

expr
    : variable
    ;

上記のトークンの正しい関連付けを選択すると、次のシーケンスになります。

IF expr1 THEN IF expr2 THEN IF expr3 THEN x ELSE y

次のように解析されます。

IF expr1 THEN (IF expr2 THEN (IF expr3 THEN (x ELSE (y))))

バイソンはもはやこの事件について不平を言うことはありません。

生成されたパーサー ステート マシンが正しいかどうかを確認するために、いつでも実行bison file.y -r allして検査できることに注意してください。file.output

于 2012-08-27T20:36:37.400 に答える