1 / 35

B 演習 ( 言語処理系演習 ) 第 8 回 評価器

B 演習 ( 言語処理系演習 ) 第 8 回 評価器. 田浦. すでにそろっている材料. すでにそろっている材料 構文木 ( 実行すべきプログラムの文面を表したデータ構造 ) Python 値の表現や構築方法 mk_py_int(5), mk_py_float(3.3), … 最終ステージ : 評価器 プログラムを実行  言われた Python 値を作ったり,表示したり, etc. 概要. 環境の概念 式を評価する 演算子,組み込み関数の実装法 文を評価する 実行時エラーの表示. 最終課題について. いずれも規定課題の 正しい実行 + 性能測定

yeva
Download Presentation

B 演習 ( 言語処理系演習 ) 第 8 回 評価器

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. B演習(言語処理系演習)第8回評価器 田浦

  2. すでにそろっている材料 • すでにそろっている材料 • 構文木(実行すべきプログラムの文面を表したデータ構造) • Python値の表現や構築方法 • mk_py_int(5), mk_py_float(3.3), … • 最終ステージ : 評価器 • プログラムを実行  言われたPython値を作ったり,表示したり,etc.

  3. 概要 • 環境の概念 • 式を評価する • 演算子,組み込み関数の実装法 • 文を評価する • 実行時エラーの表示

  4. 最終課題について • いずれも規定課題の正しい実行+性能測定 • 選択肢 • ○ mini-Python • △ sub-Python = mini-Python – 辞書,リスト,タプル,文字列 • ◎ mini-Python + α • αの例 • 性能向上 • オリジナルなmini-Pythonプログラム(大きめ) • GC

  5. sub-Python • サポートするデータ型が • 整数,浮動小数点数,None, 関数(Python, native)だけ • おまけとして for 文もなくなる(文字列,タプル,リストのどれかがないと実行できないため) • これでも評価器の大部分を作ることにはなるが,組み込み関数・演算子の数が激減し,各々の演算子の動作も単純になる

  6. 式を評価する • py_val_t eval_expr(expr_t e, …) 評価値のデータ表現 構文木 構文木評価値のデータ表現

  7. 全体像 • py_val_t eval_expr(expr_t e, …) { switch (e->kind) { case expr_kind_var: … case expr_kind_literal_int: … case expr_kind_literal_float: … … }}

  8. 最も簡単な場合の例(intリテラル) • case expr_kind_literal_int: return mk_py_int(e->u.lit_i); 構文木中にある整数 mini-Pythonのデータ表現への変換(pyvalues.c)

  9. 環境 簡単にいかない例: 変数 • case expr_kind_var: … e->u.var … ?? • 構文木を見ただけではその変数の値は分からない • 「変数名  値に関する情報」が必要

  10. 環境 • 変数名とその値の対応を保持しているもの • ある式の評価値はそれだけでは定まらず,環境があってはじめて値が決まる • 式を「環境の下」で評価する • 同じ変数名でも関数が違えば異なる値を保持している • それらは「環境が違う」 • eval_exprは「環境」を引数として受け取る • 変数のスコープ規則(局所変数,大域変数)などを正確に述べる上でも役に立つ概念

  11. 大域変数zへの代入 局所変数yへの代入 局所変数zへの代入 大域変数zへの代入 Pythonの変数,スコープ規則 • 局所変数と大域変数 • z = 10def f(): y = 20def g(): z = 30def h(): global z z = 40

  12. 局所変数zを参照 大域変数zを参照 変数参照 • まず局所変数を,なければ大域変数を参照する • z = 10def f(): z = 5 return zdef g(): return z

  13. 環境による説明 • プログラム全体で唯一,大域環境が作られる • 毎関数呼び出し時に,その呼び出し用の「局所環境」が作られる • あらゆる式・文は,局所環境,大域環境の下で評価される(便宜上,トップレベルは局所環境=大域環境と考える)

  14. eval_exprのインタフェース 局所環境 大域環境 • py_val_t eval_expr(expr_t e, env_t lenv, env_t genv, stack_trace_t bt) スタックトレース(関数呼び出し履歴) エラーメッセージの表示用(後述)

  15. 変数への代入, global • global x • 局所環境で「xは大域変数である」とマーク • x = v • 局所環境のxをvにセット • ただし,xが大域変数であるとマークされていれば大域環境のxをvにセット

  16. 変数の参照 • 局所環境を探索 • 見つからなければ,またはその変数が大域変数であるとマークされていれば大域環境を探索 • 見つかればそれが評価値 • 見つからなければ実行時エラー

  17. 環境のインタフェース • env_t mk_env() • env_set(env_t env, char* key, py_val_t val) • py_val_t env_lookup(env_t env, char * key) • void env_set_global(env_t env, char * key) • int env_is_global(env_t env, char * key)

  18. 変数参照の評価(まとめ) • py_val_t env_lookup_var( env_t lenv, env_t genv, char * key, …) { py_val_t v = env_lookup(lenv, key); if (v != py_val_not_found && v != py_val_global) return v; v = env_lookup(genv, key); if (v != py_val_not_found) return v; else エラー; }

  19. その他のケース 要素部を評価してデータを作る関数を呼ぶ (mk_py_tuple, etc.) sub-Pythonでは不要 • expr_kind_display_tuple:/* [ a, b, c,...] */ • expr_kind_display_list: /* [ a, b, c,...] */ • expr_kind_display_dict: /* { a : x, b : y } */ • expr_kind_paren: /* ( e ) */ • expr_kind_operator:/* e + e, etc. */ • expr_kind_subscript: /* e[e] */ • expr_kind_attref: /* e.f */ • case expr_kind_call: /* e(e:e,..) */ カッコ内の式を評価する ほとんどの場合関数呼び出しの一種とみなせる(後述) 単独で現れたらエラー(後述)

  20. 関数呼び出し式の評価 • E0(E1, …, En)の評価 (後でひとつだけ例外説明) • E0を評価  py_val_t : f • E1, …, Enを評価  py_val_vec_t : A • 場合1: fが native関数の場合対応するC関数を呼び出す • 場合2: fが Python関数の場合後述 • 場合3: どちらでもない場合エラー

  21. Python関数の呼び出し • 新しい環境を作る(e’ = mk_env()) • その環境に「パラメータ名 : 渡された引数」を登録する(env_set(e’, …)) • その新しい局所環境の下で関数の本体(文の列)を評価する(eval_stmt_vec(…, e’, …)

  22. E0がattref式の場合の例外 • 例: L.append(x) • mini-Python固有の約束: • L.append(x) = append(L, x) • L.appendは構文としては,expr_kind_attrefという種類の式として構文解析されるが,関数呼び出しの関数の位置以外に現れることを許さない • 関数呼び出しを評価する際にこの場合を特別扱いする(レジュメ4.6節)

  23. 演算子,添え字式,などを関数呼び出しとみなす演算子,添え字式,などを関数呼び出しとみなす • 例: E0 + E1 • 実際評価の方法は似ている • E0を評価  v0 • E1を評価  v1 • v0 + v1を計算する(それほど簡単ではない) • そこでこれを add(E0 , E1)という関数呼び出しだとみなして評価する • addはどこかに(native関数,Python関数として)定義する

  24. 文の評価 • py_val_t eval_stmt(stmt_t s, env_t lenv, env_t genv, stack_trace_t bt) • 返り値の意味 • py_val_continue  continueで実行が終了した • py_val_break  breakで実行が終了した • Pythonデータの表現  returnで実行が終了した • py_val_next それ以外で(普通に)実行が終了した

  25. 文の種類 • stmt_kind_expression • stmt_kind_assignment • stmt_kind_pass • stmt_kind_return • stmt_kind_break: • stmt_kind_continue: • stmt_kind_del: • stmt_kind_print: • stmt_kind_global: • stmt_kind_if: • stmt_kind_while: • stmt_kind_for: • stmt_kind_fundef:

  26. 自明な3つ • pass, break, continue • py_val_next, py_val_break, py_val_continueを返すだけ

  27. 次に簡単な2つ • expression • 式をeval_exprを用いて評価する • py_val_nextを返す • return E • Eをeval_exprを用いて評価する • それを返す

  28. 「関数呼び出しとみなせる」文たち • print E • del E0[E1] • E0[E1] = E

  29. 環境を書き換える文(1) • global x • 局所環境でxが大域変数であるとマーク(env_set_global) • x = E • Eを評価  v • 局所環境でxをvにセット • ただし,局所環境でxが大域変数であるとマークされていれば(env_is_global)大域環境でxをvにセット

  30. 環境を書き換える文(2) • def f(x, y, …): S • Python関数(mk_py_ifun)を作って,環境に登録 • 変数fへの代入と同じ効果

  31. 制御構造 • if, while, for

  32. エラーメッセージの表示 • エラー発生ソース位置 • 簡単なエラーメッセージ • スタックトレース

  33. スタックトレースのインタフェース • stack_trace_t mk_stack_trace() • void stack_trace_push(stack_trace_tbt, char*name, src_pos_tcall_site) • btに,「nameとい関数がソース位置call_siteで呼ばれた」と記録(push) • void stack_trace_pop(stack_trace_tbt, char*name, src_pos_tcall_site) • btから頂上のエントリをひとつ除去(pop)する.それは,「nameとい関数がソース位置call_siteで呼ばれた」というエントリでなくてはならない • void print_stack_trace(stack_trace_tbt)

  34. まとめ:作る部品の全体像 各種演算子,組み込み関数 native関数群 eval_expr 環境(env_t) 関数呼び出し Pythonで書かれた組み込み関数,演算子,添え字式,del, printに対応した関数群 式文, return文 スタックトレース 実行時エラー表示 eval_stmt del, print, E[E] = E

  35. まとめ:概念として重要だったもの • 環境 • これがないと変数を含む式・文は評価できない • Python関数呼び出しの評価方法 • 新しい局所環境が作られる • 引数のあたいが局所環境に登録されて渡される • 様々な種類の式・文が「関数呼び出しの一種」とみなせる(要領よく実装) • 演算子,添え字,添え字に代入,del, print • 文を評価した結果の返り値 • py_val_continue, break, next

More Related