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

Slides:



Advertisements
Similar presentations
C 言語講座第 5 回 構造体. 構造体とは ... 異なる型の値をまとめて新しい型とする 機能がある . つまり , 複数の変数を 1 つのまとまりにできる . 配列と違って同じ型でデータをまとめるのではな く違った型のデータをまとめられる .
Advertisements

2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
コンパイラ 2011年10月17日
プログラミング言語としてのR 情報知能学科 白井 英俊.
スレッドの同期と、スレッドの使用例 スレッドの同期 Lockオブジェクト: lockオブジェクトの生成
12.3,E,-15, 12.3,E5,+,=, >,<,…,
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
Lightweight Language Weekend ls-lRシェル
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
プログラミング基礎I(再) 山元進.
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
プログラミング言語論 第4回 手続きの引数機構 変数の有効範囲
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
構造体.
プログラミング 田浦健次朗.
プログラミング論 II 電卓,逆ポーランド記法電卓
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
コンパイラ 2012年10月15日
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
関数 関数とスタック.
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラムの制御構造 選択・繰り返し.
プログラミング2 関数
プログラミング言語論 第9回 Hoare論理の練習問題 手続きの引数機構 変数の有効範囲
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
B演習(言語処理系演習)第3回 字句解析 田浦.
関数の定義.
Cプログラミング演習 第7回 メモリ内でのデータの配置.
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング演習I 2003年5月7日(第4回) 木村巌.
B演習(言語処理系演習)第4回 田浦.
ソフトウェア制作論 平成30年10月3日.
04: 式・条件分岐 (if) C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
Java8について 2014/03/07.
コードクローンの動作を比較するためのコードクローン周辺コードの解析
PHP 概要 担当 岡村耕二 月曜日 2限 平成22年度 情報科学III (理系コア科目・2年生)
プログラミング言語論 第四回 理工学部 情報システム工学科 新田直也.
プログラミング言語論 第5回 手続きの引数機構 変数の有効範囲
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コンパイラ 2011年10月20日
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
B演習(言語処理系演習)第2回 田浦.
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
C言語ファミリー C# 高級言語(抽象的) Java オブジェクト指向 C++ C 機械語(原始的)
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
情報処理Ⅱ 第7回 2004年11月16日(火).
情報処理Ⅱ 2005年10月28日(金).
Nakano School of Business 経営情報ビジネス科 【 Java概論(Test4)】
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
コンパイラ 2012年10月11日
プログラミング 4 文字列.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
演算子のオーバーロード.
プログラミング演習I 2003年6月11日(第9回) 木村巌.
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
プログラミング基礎a 第5回 C言語によるプログラミング入門 配列と文字列
君ならどうする – ls-lRシェル Python編
復習 いろいろな変数型(2) char 1バイト → 英数字1文字を入れるのにぴったり アスキーコード → 付録 int
情報処理Ⅱ 第3回 2004年10月19日(火).
計算技術研究会 C言語講座 第二回 制御構文 if , switch.
分岐(If-Else, Else if, Switch) ループ(While, For, Do-while)
プログラミング 3 ポインタ(1).
Presentation transcript:

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

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

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

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

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

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

全体像 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: … … } }

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

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

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

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

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

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

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

変数への代入, global global x x = v 局所環境で「xは大域変数である」とマーク 局所環境のxをvにセット

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

環境のインタフェース 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)

変数参照の評価(まとめ) 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 エラー; }

ほとんどの場合関数呼び出しの一種とみなせる(後述) その他のケース 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,..) */ 要素部を評価してデータを作る関数を呼ぶ (mk_py_tuple, etc.) sub-Pythonでは不要 カッコ内の式を評価する ほとんどの場合関数呼び出しの一種とみなせる(後述) 単独で現れたらエラー(後述)

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

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

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

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

文の評価 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 それ以外で(普通に)実行が終了した

文の種類 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:

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

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

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

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

環境を書き換える文(2) def f(x, y, …): S Python関数(mk_py_ifun)を作って,環境に登録

制御構造 if, while, for

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

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

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

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