2011-09-15 16 views
1

私はC++でCのための再帰的降下パーサーを書いています。私が制作に最初に来る可能性の端子と先読みトークン/文字を比較し、「最初の」-setについて読ん再帰的降下パーサーで最初のセットを使用する

statement: labeled-statement | compound-statement | expression-statement | selection-statement | iteration-statement | jump-statement 

:私は、次の場合は、右の生産を選択する方法がわかりません。現在、私は再帰的な降下パーサーで最初のセットを使用することに固執しています。なぜなら、関数とそれ以外のものはなく、ルールごとのオブジェクトも、ルール/プロダクションを特定できるものもないからです。それは左側に曖昧だから

+1

シフトキーで何か問題がありますか? –

+0

いいえ、うわー。次回はそれを使用します:) – dcast

+0

ありがとう!それはちょうどきちんと見える場所を保つだけで、あなたを助けようとしている人たちへの小さな礼儀です。 –

答えて

1

あなたの文法は、再帰下降構文解析のために無効である:{と識別子と

  • labeled-statement開始
  • compound-statement開始(これは結構です)
  • expression-statement開始と識別子または番号(または(

ここで停止することができますラベル付きのステートメントと式ステートメントの間に衝突があります。左辺のあいまいさを取り除くために文法を変換する必要があります(一般的な部分を含むための一時的な文法ノードによって、先読みのみを使用してどのブランチに行くかを決定できます)。

+0

これを除いて、「最初の」セットと一致しない(パフォーマンスを向上させるために)生産に失敗した場合は、最後の生産または最後の有効な状態に戻すことができますか? btw:左のあいまいさを取り除いた後、私はまだ先読みと比較する最初のセットがないので、どのプロダクションを選択するのかまだ分かりません。良い解決策もありますか? – dcast

+0

バックトラックコンパイラは、小さな入力ファイルでさえも非常に低いパフォーマンスで動作することはありません。左側のあいまいさを取り除いたと仮定すると、最初のセットを作成するのは簡単です(退屈な場合):すべてのブランチのプロダクションを下り、可能な最初の文字セットを作成してください。たとえば、 'statement'の最初のセットは式とラベルの' identifier'、複合文の '{'、式の 'number'(式)、' goto'、 'for'、' if'です。あなたの再帰関数では、各ブランチの最初のセットに対して先読みをチェックするだけです。 – Blindy

+0

明らかでない場合は、1つのプロダクションのブランチ間に*重複があると、文法があいまいです。また、イプシロンプロダクションは、再帰的な降下パーサーの文法には場所がありません。もしあれば、それらを取り除かなければなりません。 – Blindy

関連する問題