それで、私はこのプロジェクトを割り当てられ、古い大学で試してみましたが、どうすればいいのか少し迷っています。アイデアは、次の形式の文法を含む txt ファイルが与えられることです。
- V: S、A、B、C
- タブ
- S:S
- パ:
- S -> aAaA|aABBA
- A -> AaaA|$
- B -> bB|bbC
- C -> B
テストされるのはこれらのプロダクション ルールだけではありませんが、これは単なる例です。
したがって、最初のステップはプログラムを読み込むことです。次のステップは、Lambda ($) プロダクションを削除することです。最後のステップは、ユニット生産を削除することです。
私は...ラムダプロダクションを削除する方法は、私が考える最良の方法ではありません。
これが私がやっている方法です。
まず、getline を使用してファイルを読み込みます。次に、いくつかのループを使用してファイルを調べます。
これで、ラムダ生成のルールに対応する非端末を配列に格納したので、覚えておいてください。
そのため、各プロダクションの各文字を調べながら、その文字が、ラムダ プロダクションを示す非ターミナルの配列内の文字と同じかどうかを確認します (インデックス 0 はプロダクションの開始であるため除外します)。
一致が見つかった場合は、そのインデックスにマークを付けます
S を通り抜けると言ってください。
S -> a (問題なし) s -> aA (少し問題あり)
Aを書く代わりに、しないでください。それをスキップしてから、別のループを使用して、その生産規則の残りのチャンクを出力します (つまり、バーに到達するまで出力します)。したがって、S -> aaA が得られます。
今棒を引く
S -> aaA| このチャンクの最初の文字へのインデックスを返します。ここでは a です。そこから、最初に非端末を打ったところまで文字を書き直します。
S -> aaA|aA
ラムダである次の非端末を見つけるためにループを続けます
S -> aaA | ああ(ここにいます)
バーを描く
S -> aaA | ああ |
最初に戻り、次に進みます
S -> aaA | ああ | ああああ
文法を読み続けて各文字を出力し、このプロセスを繰り返して取得します
S -> aaA | ああ | ああああ | aABB | アバ | アバ
すべてのコードの最後に、文法の元の小節をチェックする 2 つのループがあり (私が行ったときにそれらを ! に置き換えます)、最後に、すべてのラムダ生成をラムダとして与えるフォームを出力します。
S -> aaA | ああ | ああああ | ああ | aABB | アバ | アバ | aBB
ここにコードを含めますが、注意してください... ラフです。ここのコーディングブロックにうまく収まらないほど大雑把なので、リンクします。
このプロジェクトをどのように行うか、または私が露骨に間違っているかどうかについてのアイデアをいただければ幸いです。
コードは現在、いくつかのエラーをスローします(これは、どこかで空の文字を読んでいる原因であると確信しています)が、それらを無視すると、正しいことをコンソールに吐き出します...ほとんど。
この混乱をすべて読むために時間を割いていただきありがとうございます。