8

私は(flexとbisonを使用して)独自のコンパイラーを実装する必要があるコンパイラー設計クラスを取っています。私は構文解析(EBNFと再帰下降パーサーの作成)の経験がありますが、コンパイラーを作成するのはこれが初めてです。

言語デザインはかなりオープンエンドです(教授はそれを私たちに任せました)。クラスでは、教授は中間コードの生成をやり直しました。彼は、構文解析中に抽象構文木や構文解析ツリーを構築する必要はなく、途中で中間コードを生成できると述べました。

私はこれを2つの理由で混乱させました:

  • 定義する前に関数を呼び出している場合はどうなりますか?分岐先をどのように解決できますか?関数を使用する前に関数を定義するか、関数を事前に定義する必要があるというルールを作成する必要があると思います(Cのように?)

  • 条件文をどのように扱いますか?if-else、または単にを持っている場合、条件が(進行中にコードを生成している場合)ifの場合の分岐ターゲットをどのように解決できますか?iffalse

関数とブランチターゲットのアドレスを解決するために、ASTを生成し、作成後にツリーをウォークすることを計画しました。これは正しいですか、それとも何かが足りませんか?

4

2 に答える 2

8

両方の問題の一般的な解決策は、「パッチを適用する」必要のあるアドレスのリストを保持することです。コードを生成し、欠落しているアドレスまたはオフセット用の穴を残します。コンパイルユニットの最後に、穴のリストを調べて記入します。

FORTHでは、パッチの「リスト」は制御スタックに保持され、各制御構造が終了するときに巻き戻されます。FORTHディメンションを参照してください

逸話:初期のLispコンパイラ(Lispだったと思います)は、条件の各ブランチのマシンコードのリストへの前方参照を含むシンボリック形式のマシンコード命令のリストを生成しました。次に、リストを逆方向にたどるバイナリコードを生成しました。このようにして、分岐命令を発行する必要があるときに、すべての順方向分岐のコード位置がわかりました。

于 2011-03-19T01:42:20.327 に答える
1

Crenshawチュートリアルは、いかなる種類のASTも使用しない具体的な例です。m68kアセンブリを対象とした即時コード生成を使用して、動作するコンパイラ(明らかに条件文を含む)を構築します。

あなたは午後に文書を読むことができます、そしてそれはそれだけの価値があります。

于 2011-06-11T23:33:12.963 に答える