1

私は現在、グローバル変数とネストされたサブルーチン機能を持つ言語用のコンパイラを構築しています。以前は、ネストされたサブルーチンのないローカル変数のみを持つ言語用のコンパイラしか構築していませんでした。

コード生成フェーズのセマンティック解析フェーズで埋められたシンボル テーブルを再利用する方法に問題があります。リンク リストのスタックとしてシンボル テーブルを作成します。各リンク リストは、特定のスコープで宣言された識別子を表します。スコープに入るたびに、新しいリストが作成されてスタックにプッシュされ、現在のスコープになります。同様に、スコープを離れるたびに、スタックの一番上のリストがポップされます。最終的に、意味解析が終了すると、開始時と同じように、実質的に空のシンボル テーブルができます。ただし、コード ジェネレーターは、コードを正しく生成するために、完全に埋められたシンボル テーブルを必要とします。意味解析中に行われたこと (つまり、記号テーブルへの識別子の入力) をやり直すことなく、これを行うにはどうすればよいでしょうか?

4

2 に答える 2

5

最適化とコード生成をサポートするために、コンパイラが保持するコンテキストの量を決定する必要があります。

そのスコープのために生成しようとしているすべてのコード (または IR) を生成した場合、スコープを離れるときにシンボル テーブル情報を破棄する純粋なオンザフライ コード ジェネレーターを構築できます。これは、高速で汚れたコンパイラを構築している場合に機能し、コンピューターに多くのメモリがない場合に役立ちます。(最近の PC では、後者の引数を作成できません)。

解析プロセスの最後に到達するまで、コード分析/最適化/IR またはコード生成を行わない場合は、スコープごとのシンボル テーブルの情報をより長く保持する必要があります。この場合、AST にも依存する必要があることがわかります。そうしないと、コードを生成するものが何もなくなります。(最新の PC では、これは問題ではありません)。

単純なアーキテクチャでコンパイラを構築するには、解析、セマンティック分析、およびコード生成パスをとにかく分離する必要があります。この場合、パーサーが実行され、AST が構築されます。シンボル テーブルを作成する必要はありません。Pass Two はツリーをたどり、AST の部分に対応するシンボル テーブルを構築し、その関係を維持します。これで、AST と関連するシンボル テーブルができました。パス 3 では、AST をウォークし、シンボル情報を使用して IR を生成できます。パス 4 は IR を最適化します。型情報と可能な記憶場所の割り当てで装飾されたシンボルテーブルエントリを参照する場合があります。その後、最適化と最終的なコード生成を行うことができます。

これらすべての要点は、シンボル テーブルを捨てないことです。それらを保存し、コード生成に必要なコード構造に関連付けます。それらを保存するためのメモリがたくさんあります。

于 2016-02-07T04:14:58.610 に答える
2

あなたのコンパイラの内部データ構造について具体的なことは何も知らないので、これは少し抽象的になります。

スコープをポップするときは、削除するのではなく、スコープ データへのポインターを、そのスコープのコード生成の基礎となるデータのメンバーに割り当てます。これにより、コード ジェネレーターがそれにアクセスできるようになります。 .

于 2016-02-07T00:10:49.530 に答える