Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Nand2tetris 11

27 views

Published on

for study

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Nand2tetris 11

  1. 1. コンピュータシステムの理論と実装 11章 コンパイラ#2 : コード生成
  2. 2. アジェンダ • コンパイラについて(復習) • シンボルテーブルについて • 課題
  3. 3. コンパイラ コンパイラは以下の順で、高級言語を機械語(もしくはVMコード)に変換する 1. 構文解析 • 前回は構文解析器を作成した 2. コード生成
  4. 4. コンパイラとシンボルテーブル • コンパイラは各変数に対して、その変数の型(type)を対象のプラットフォームに合わせて マッピングする必要がある • コンパイラは変数のライフサイクルとスコープについて管理する必要がある -> コンパイラは、識別子が何を表しているのか記録・判断するために、「シンボルテーブル」 を用いる
  5. 5. シンボルテーブル • コンパイラは識別子(identifier)を見つけると、 シンボルテーブルを用いて記録する • 例) var int i; • 番号のカウントは属性ごと 名前(name) 型(type) 属性(kind) 番号 nAccounts int static 0 id int field 0 name String field 1 balance int fileld 2 sum int argument 0 status boolean local 0
  6. 6. シンボルテーブルとスコープ • 「同じ識別子名だがスコープが違う識別子」は区別する必要がある • 以下の例(JavaScript)だと、console.log()で出力される a はすべてスコープが異なる (a => { console.log(a); (() => { const a = 0; { const a = 1; console.log(a); { const a = 2; console.log(a); } } console.log(a); })(); })(100); /** 100 1 2 0 */
  7. 7. シンボルテーブルとスコープ • 各識別子について、識別子のスコープを記録しておく必要がある • データ構造として「ハッシュテーブルのリスト」を使う • ハッシュテーブルは単一のスコープ(class、subroutineなど)を示す
  8. 8. シンボルテーブルまとめ • 識別子(identifier)の • 名前(name) • 型(type) • 属性(kind) • 番号 をスコープ別のハッシュテーブルに記録する • 番号は同じスコープの各属性ごとに0からカウントアップして付番する
  9. 9. その他 データ変換で必要な操作 • 今回(シンボルテーブルの実装)とは直接は関係ないので軽く紹介だけ • 変数操作 • 配列操作 • オブジェクト操作
  10. 10. 変数操作 • コンパイラは様々は型の変数について、対象とする プラットフォームへ対応付け(メモリ割り当て)を行う 必要がある • が、7章と8章で低レベルのメモリ管理を行うための VMは作成済み! • コンパイラは変数を仮想メモリセグメントにマッピング し、それらを操作する高水準コマンドをVMコマンドを 使って表現すればよい -> 詳しくは次回!
  11. 11. 配列操作 (p.254 - p.255) • 配列は連続したメモリ領域に格納される • 配列名はポインタとして扱われる • その配列が格納されたRAMのベースアドレスを指す • bar[k] = 19 のような文をコンパイラが変換するためには、関節アドレス指定のようなメ カニズムが必要 -> 詳しくは次回!
  12. 12. オブジェクト操作 (p.257 - p.258) • データに関して、低レベルにおける操作は配列と似ている • オブジェクトのフィールドは連続したメモリ領域に格納される • オブジェクトはベースアドレスを格納したポインタ変数によって表される -> 詳しくは次回!
  13. 13. コマンド変換 (p.258 - p.260) • 高水準のコマンドを対象とする言語に変換する • 式の評価 • 構文解析器で構文木へと変換し、(スタックベースのプラットフォームなら)後置表記法(逆ポーランド表 記法)で出力する • フロー制御 • if, while, switch等のフロー制御を、「条件付きgoto」と「無条件goto」のふたつで表現する -> 詳しくは次回!
  14. 14. 実装 • コンパイラ全体は以下5つのモジュールから構成される • JackCompiler • セットアップや他のモジュールの呼び出しを行うモジュール。前回作成した。 • JackTokenizer • トークナイザ。前回作成した。 • SymbolTable • シンボルテーブル。今回作成する。 • VMWriter • VMコードを生成するための出力モジュール。次回作成する。 • CompilationEngine • 再帰によるトップダウン式の解析器。前回作成し、今回は機能を発展させる。
  15. 15. 課題:第1段階 シンボルテーブル • 前回作成した構文解析機に機能を追加 • 識別子について、 • 識別子のカテゴリ(var, argument, static, field, class, subroutine) • 識別子を定義(宣言)しているのか、使用しているのか • 識別子のカテゴリが(var, argument, static, field)の場合、シンボルテーブルによって割り当てられ た実行時のインデックス の情報を追加 フォーマットは自由にしてよい
  16. 16. 課題:第1段階 シンボルテーブル • シンボルテーブルに現れる可能性のある識別子の属性は次の4つ • static、field、argument、var • (class、subroutineはシンボルテーブルに記録する必要はない) • 詳細はp.266 - p.277
  17. 17. SymbolTableモジュールのAPI ルーチン 引数 戻り値 機能 コンストラクタ - - 空のシンボルテーブルを生成する startSubroutine name, type, kind (STATIC, FIELD, ARG, VAR) - 新しいサブルーチンのスコープを開始する(つまり、 サブルーチンのシンボルテーブルをリセットする) define kind (STATIC, FIELD, ARG, VAR) - 引数の名前、型、属性で指定された新しい識別子を 定義し、それに実行インデックスを割り当てる。 STATICとFIELD属性の識別子はクラスのスコープを 持ち、ARGとVAR属性の識別子はサブルーチンのス コープを持つ varCount name (文字列) 整数 引数で与えられた属性について、それが現在のス コープで定義されている数を返す kindOf name (文字列) (STATIC, FIELD, ARG, VAR, NONE) 引数で与えられた名前の識別子を現在のスコープで 探し、その属性を返す。その識別子が現在のスコー プで見つからなければ、NONEを返す typeOf name (文字列) 文字列 引数で与えられた名前の識別子を現在のスコープで 探し、その型を返す indexOf name (文字列) 整数 引数で与えられた名前の識別子を現在のスコープで 探し、そのインデックスを返す
  18. 18. サブルーチンのコンパイル(p.261) • Yyyというクラスのxxx()というサブルーチンは、Yyy.xxxで呼ばれるVM関数へとコンパイ ル • k 個の引数を持つ function または constructor は、k 個の引数を扱うVM関数へと コンパイル • k 個の引数を持つ method は k+1 個の引数を扱うVM関数へとコンパイル • 最初の引数(引数番号 0)は this オブジェクトを参照する (第1段階ではここだけ気にしていればOK)
  19. 19. シンボルテーブルのテスト • テスト用として、10章で使用したJackプログラムを使う • 構文解析器の出力が先の情報を含んでいればOK
  20. 20. 実装サンプル • Python3での実装(コードが汚い…(-_-;)) • https://github.com/khashii/nand2tetris/tree/master/projects/11/JackCo mpiler

×