2

shift/reduce エラーの解決に関するドキュメントやハウツーは確かにたくさんあります。bison のドキュメントでは、正しい解決策は通常、それらを単に期待して対処することであると示唆しています。

あなたがこのようなものを持っているとき:

S: S 'b' S | 't'

次のように簡単に解決できます。

S: S 'b' T | T
T: 't'

私の質問は次のとおりです。文法を少しあいまいにして %expect shift/reduce の問題を残す方が良いですか、それとも文法を調整してそれらを回避する方が良いですか? バランスがあり、作者のニーズに基づいているのではないかと思いますが、よくわかりません。

4

4 に答える 4

2

演算子の優先順位を使用して、競合の解決を導くことができます。左結合演算子または右結合演算子として宣言'b'すると、少なくともそのケースはカバーされます。

より複雑なパターンの場合、最終的なパーサーがすべてのケースで正しい結果を生成する限り、警告はそれほど心配する必要はありません。ただし、宣言を使用して正しい結果を得ることができない場合は、文法を書き直す必要があります。

于 2009-03-01T13:06:04.990 に答える
2

私がそれを読んだとき、あなたの質問は「あいまいな文法や生産規則はいつOKですか?」です。

まず、あなたが説明している言語を考えてください。あいまいな生産規則を言語に許可することの意味は何でしょう。

あなたの例は、次のような式を含む可能性のある言語を説明しています。t b t b t b t

2番目の例のように解決された式は になります(((( t ) b t) b t ) b t )が、あいまいな文法では( t b ( t b ( t b ( t))))または になることさえあり( t b t ) b ( t b t )ます。どちらが有効かは、言語によって異なります。演算子が減算をモデル化する場合b、実際にはあいまいであってはなりませんが、加算の場合は問題ない可能性があります。これは本当に言語に依存します。

考慮すべき 2 番目の質問は、競合が解決された後、結果として得られる文法ソース ファイルがどのようになるかということです。他のソースコードと同様に、文法は人間が読むことを意図しており、二次的にコンピュータも読むことを意図しています。パーサーが文法から何をしようとしているのかをより明確に説明する表記法を優先してください。つまり、パーサーが定義されていない可能性のある動作を実行している場合 (たとえば、熱心な言語での関数の引数の評価順序など)、文法があいまい に見えます。

于 2009-04-04T01:15:30.073 に答える
1

前学期の私のコンパイラ コースでは、bison を使用し、pascal のサブセット用のコンパイラを作成しました。

言語が十分に複雑な場合、いくつかのエラーが発生します。それらが存在する理由と、それらを削除するために何をしなければならないかを理解している限り、問題はありません。何かがそこにあったとしても、動作は私たちが望んでいたように機能し、それを価値のあるものにするために多くのことを考えて作業する必要があるため (また、文法を複雑にするため)、そのままにしておきました。エラーを完全に理解していることを確認し、どこかに (自分用であっても) 文書化して、何が起こっているのかを常に把握できるようにしてください。

物事が実際に関係するようになったら、それは費用対効果の分析ですが、IMHO、それを修正することを最初に検討する必要があります。次に、実際に作業が何であるかを把握し(そして、その作業が他の何かを壊したり、他の何かを難しくしたりする場合)、そこの。それらをありふれたものとして決して見過ごしてはなりません。

于 2009-04-02T06:57:12.570 に答える
1

文法が明確であることを証明する必要がある場合、まず構文解析式文法として記述し、プロジェクトで使用しているツール セットが必要とする文法タイプに手動で変換する傾向があります。私の経験では、このレベルの証明の必要性は非常にまれですが、私が遭遇したほとんどのシフト/リデュースの競合は、(あなたの例の順序で) 正しさを示すのにかなり些細なものだったからです。

于 2009-04-04T00:52:51.003 に答える