SlideShare une entreprise Scribd logo
1  sur  21
言語処理系入門
第 8 回:コンパイラ I : CPS 変換
2009 年 12 月 18 日(金)
【改 :2009/12/21 】
服部 健太
コンパイルの流れ
 関数型言語における典型的なコンパイルパス
ソース
プログラム 字句・構文解析 型検査 CPS 変換
Cps.convTyping.checkparse
クロージャ変換コード生成
目的
コード
実行時
ライブラリ
中間言語
抽象構文木
GC など実行時に必要な処理
実行時にロード・リンクされる
C 言語で実装されることが多い
C 言語,アセンブリコード,
VM の中間言語(バイトコード) etc
2009/12/18 2言語処理系入門 8
中間言語(中間表現とも呼ぶ)
 利点
 最適化をしやすくする
 複数の目的言語をサポートするため
 複数の段階に分けることでコンパイルの処理を簡
潔にする
 どのような形式の中間言語を採用するかは言
語のデザインによって異なる
 命令型言語では, SSA や RTL ,
 関数型言語では, CPS や A 正規形, K 正規形
 複数の中間言語を採用するコンパイラも
我々の言語で
は CPS を採
用
2009/12/18 3言語処理系入門 8
復習:継続( continuation )とは
 残りの計算を表す概念
 プログラムの実行のある時点から最終的な答えを
得るまでの計算
 例:
let x = 2 in
let y = 3 + x * (f x) in
y * y;
 部分式 (f x) に注目したとき,このときの継続
let y = 3 + x * [<(f x) の値 >] in y * y
2009/12/4 4言語処理系入門 62009/12/18 4言語処理系入門 8
復習:継続渡しスタイル
( CPS )
 継続を明示的に渡す関数のスタイル
 ダイレクトスタイル(通常の形式)
let rec fact n =
if n == 0 then 1
else n * (fact (n – 1));
 継続渡しスタイル
let rec fact n k =
if n == 0 then k 1
else fact (n-1) (fn v -> k (v * n));
fact(n-1) を計算し
た後にする計算
(継続)
2009/12/4 5言語処理系入門 62009/12/18 5言語処理系入門 8
中間言語としての CPS
 制御の流れ , データの流れがコードに明示的に現れる
 最適化がしやすい(末尾呼び出し最適化,不要コードの除去
etc )
 shift/reset, callcc, letcc などの一級継続も CPS に変換することで
簡単に実装できる
 例:
let rec prod_primes n =
if n == 1 then
1
else
if is_prime n then
n * prod_primes(n-1)
else
prod_primes(n-1)
2009/12/18 6言語処理系入門 8
中間言語としての CPS ( 2 )
let rec prod_primes c n =
if n == 1 then c 1
else let k =   fn b ->
if b == true then
let j = fn p ->
let a = n * p in c a
and m = n – 1
in prod_primes j m
else
let h = fn q -> c q
and i = n – 1
in prod_primes h i
in is_prime k n
k: 継続 1
j: 継続
2
h: 継続
3
2009/12/18 7言語処理系入門 8
ソース言語の抽象構文
 E ::= F | V
 | let x1 = E1 and … and xn = En in E
 | let rec x1 = E1 and … and xn = En in E
 | if E1 then E2 else E3
 | handle E1 with x in E2
 | raise E
 | E.l
 | E1 E2
 | op(E1,…,En )
 | { l1=E1; …; ln=En }
 | fn x -> E
 V ::= c | x
op は +,-,*,/,strlen など
のプリミティブ演算子
2009/12/18 8言語処理系入門 8
CPS 式の構文
 K ::= E
 | let x1 = D1 and … and xn = Dn in K
 | let rec x1 = D1 and … and xn = Dn in K
 | if E then K1 else K2
 | V k E | k E
 D ::= E
 |{ l1=V1;…; ln = Vn }
 | fn k x -> K | fn x -> K
 E ::= V
    | let x1 = D1 and … and xn = Dn in E
    | let rec x1 = D1 and … and xn = Dn in E
 | E.l
 | op(E1, … ,En)
 V ::= c | x | k --- ただし, k, x∈Variable
関数呼び出しや分岐を
伴わない単純な式
レコードと関数は let/let rec で束縛
されてから使用される
2009/12/18 9言語処理系入門 8
CPS 変換
 変換関数を [[E]]к⇒K のように記述する
 E は,変換元の構文木, K は変換後の CPS 式, к
は単純な CPS 式 (E) を受け取り,完全な CPS 式
を出力する関数
 [[ ・ ]] : Esource→(Ecps→Kcps) → Kcps
 к : Ecps→Kcps
 Vsource の変換
 単に к に渡して, CPS 式の穴を埋める
[[csource]]к к⇒ ccps
[[xsource]]к к⇒ xcps
以降,あきらかな場合
には subscript を省略
2009/12/18 10言語処理系入門 8
if 式
 素朴な変換
[[if E1 then E2 else E3]]к⇒
[[E1]](λv.if v then [[E2]]к else [[E3]]к)
 к が複製されるため,コードが爆発する可能性あ
り
 正しい変換
[[if E1 then E2 else E3]]к⇒
[[E1]](λv.let j = fn x ->кx
in if v then [[E2]](λv.j v)
else [[E3]](λv.j v))2009/12/18 11言語処理系入門 8
let/let rec 式
 x=E の右辺式 E を単純な式に変換
 let 式
[[let x1 = E1 … and xn = En in E]]к⇒
[[Es]](λvs. к (let xs=vs in [[E]]кinit))  
  [[Es]](λvs.let xs=vs in [[E]]к)
 let rec 式
[[let rec x1 = E1 … and xn = En in E]]к⇒
[[Es]](λvs.к(let rec xs=vs in [[E]]кinit))
[[Es]](λvs.let rec xs=vs in [[E]]к)
2009/12/18 12言語処理系入門 8
E is simple
E is not simple
E is simple
E is not simple
関数・プリミティブ演算子の変換
 無名関数
[[fn x -> E]]к⇒
   let f = fn k x -> [[E]](λv.k v) in кf
 f や k はフレッシュな変数
 後のフェーズで便利なように無名の関数に名前を付けてお
く
 関数適用
[[E1 E2]]к⇒
   [[E1]](λf.[[E2]](λv.let k = fn r ->кr in f k v))
 プリミティブ演算子
[[op(E1,…,En)]]к⇒
   [[Es]](λvs.кop(vs))
呼び出し元に戻ってくるための継続
継続を受け取るた
めの引数を1つ増
やす
2009/12/18 13言語処理系入門 8
レコード式の変換
 レコード生成
 各フィールドの右辺式を単純な式に変換
[[{ l1=E1; …; ln=En }]]к⇒
[[Es]](λvs.к(let xs=vsin let r ={ls=xs} in r))
 フィールド参照
 参照元の式を変換し,そのフィールド値を x に束
縛
[[E.l]]к⇒
[[E]](λv.к(v.l))
2009/12/18 14言語処理系入門 8
例外捕捉・発生
 例外捕捉
 新しいハンドラをセットし,式を評価
 例外を捕捉したら元のハンドラをセットし直して, E2 を
評価
[[handle E1 with x in E2]]к⇒
   let h = gethdlr()
and k = fn x ->кx in
let h’ = fn x -> let _ = sethdlr h in
[[E2]](λv.k v)
in let _ = sethdlr h’ in
[[E1]](λv.let _ = sethdlr h in k v)
 例外発生
 ハンドラを取得して,呼び出すだけ
[[raise E]]к ⇒
     [[E]] (λv.let h = gethdlr() in h v)
2009/12/18 15言語処理系入門 8
変換例
 [[+(x,(f 0).l)]]к
⇒[[<x;(f 0).l>]](λvs.let x1 = +(vs) in кx1)
⇒[[ (f 0).l]](λv.let x1 = +(x,v) in кx1)
⇒[[(f 0)]](λv.let x2=v.l in (λv.let x1 = +(x,v) in кx1)x2)
⇒[[(f 0)]](λv.let x2=v.l in let x1 = +(x, x2) in кx1)
⇒[[f]](λf.[[0]] (λv.let k=fn r->
(λv.let x2=v.l in let x1 = +(x,x2) in к x1)r
in f k v))
⇒[[f]](λf.[[0]](λv.let k=fn r->
let x2=r.l in let x1 = +(x,x2) in кx1
in f k v))
⇒let k=fn r->let x2=r.l in
let x1 = +(x,x2)
in кx1
in f k 0
 演習問題
 [[let rec fact = fn n -> if ==(n,0) then 1 else *(n,fact(-(n,1))) in fact 5]]к
⇒?
2009/12/18 16言語処理系入門 8
Ocaml での実装( cps.ml )
let rec conv_expr k e = match e with
| Syntax.ValExpr v -> k (conv_value v)
| Syntax.IfExpr(e1,e2,e3) ->
let j = Symbol.fresh() in
let x = Symbol.fresh() in
let k' = fun v -> AppExpr(VarVal j,[v]) in
conv_expr (
fun v ->
LetExpr([j,FunExpr([x],k (VarVal x))],
IfExpr(v,conv_expr k' e2,conv_expr k' e3))
) e1
| Syntax.FunExpr((x,_),_,e1) ->
let k’ = Symbol.fresh() in
let f = FunExpr([k’;x],
conv_expr (fun v -> AppExpr(VarVal k’,[v])) e1)
in
k (VarVal f)
…
2009/12/18 17言語処理系入門 8
末尾呼び出しの最適化
 以下の式を CPS 変換すると
 let f x = g (x + 1)
 こうなるが こう最適化でき
る
let f k x = let f k x =
let k’ a = k a in let b = x + 1 in
let b = x + 1 in      g k b
g k’ b
 λ 計算において λx.M(x) を M に簡約化することを η
簡約と呼ぶ
 「 C 言語的に考えると, int foo(int x) { return bar(x); } とい
う関数定義がある場合,すべての foo の呼び出しを bar に
置き換えることができる」のと同じことである
2009/12/18 18言語処理系入門 8
参考文献
 A.W.Appel, “Compiling with Continuations”,
Cambridge Univ.Press, 1992.
 田浦さんの資料
 http://www.is.s.u-tokyo.ac.jp/vu/97/jugyo/processor/com
2009/12/18 19言語処理系入門 8
演習問題
 今週のサンプルプログラムを動かしてみよ
 無駄な変数のコピー伝播を削除する最適化を
実装せよ
 let x = y in …x… … y …⇒
 末尾呼び出しの最適化を実装せよ
2009/12/18 20言語処理系入門 8
次回予定
 日時:
 2009 年 12 月 25 日(金) 10 : 30 - 12 : 00
 場所:
 LB2 3F/A
 内容:
 コンパイル II :クロージャ変換
2009/12/10 21言語処理系入門 72009/12/18 21言語処理系入門 8

Contenu connexe

En vedette

Cadoul unui cosmonaut nasa
Cadoul unui cosmonaut nasaCadoul unui cosmonaut nasa
Cadoul unui cosmonaut nasaIonut Vasilescu
 
LinkedIn Analysis of Digital Leaders in CPG
LinkedIn Analysis of Digital Leaders in CPGLinkedIn Analysis of Digital Leaders in CPG
LinkedIn Analysis of Digital Leaders in CPGRob Walker
 
Corona del Mar Homes for Sale
Corona del Mar Homes for SaleCorona del Mar Homes for Sale
Corona del Mar Homes for SaleArbor Real Estate
 
خطة عمل مشروع منظومة السلامة الكهربائية 15002
خطة عمل مشروع منظومة السلامة الكهربائية 15002خطة عمل مشروع منظومة السلامة الكهربائية 15002
خطة عمل مشروع منظومة السلامة الكهربائية 15002emad12345
 
What social marketers can learn from brimfield police
What social marketers can learn from brimfield policeWhat social marketers can learn from brimfield police
What social marketers can learn from brimfield policeRob Walker
 
Homicid, suicid i decije shvatanje smrti
Homicid, suicid i decije shvatanje smrti Homicid, suicid i decije shvatanje smrti
Homicid, suicid i decije shvatanje smrti Novi Prostori
 
2010 1215-건국대인문학연구원발표-이정모5-2
2010 1215-건국대인문학연구원발표-이정모5-22010 1215-건국대인문학연구원발표-이정모5-2
2010 1215-건국대인문학연구원발표-이정모5-2Sungkyunkwan University
 
Tips to Get Top Dollar for your Newport Beach Home!
Tips to Get Top Dollar for your Newport Beach Home!Tips to Get Top Dollar for your Newport Beach Home!
Tips to Get Top Dollar for your Newport Beach Home!Arbor Real Estate
 
Ecnew 090926143211-phpapp01 (autosaved)
Ecnew 090926143211-phpapp01 (autosaved)Ecnew 090926143211-phpapp01 (autosaved)
Ecnew 090926143211-phpapp01 (autosaved)Vatzac King's
 
分散システム第7章(後半)
分散システム第7章(後半)分散システム第7章(後半)
分散システム第7章(後半)Kenta Hattori
 

En vedette (20)

Cadoul unui cosmonaut nasa
Cadoul unui cosmonaut nasaCadoul unui cosmonaut nasa
Cadoul unui cosmonaut nasa
 
Rollup GSO1
Rollup GSO1Rollup GSO1
Rollup GSO1
 
Strategialuonnos 27052013
Strategialuonnos 27052013Strategialuonnos 27052013
Strategialuonnos 27052013
 
The Value Proposition - August 2013
The Value Proposition - August 2013The Value Proposition - August 2013
The Value Proposition - August 2013
 
LinkedIn Analysis of Digital Leaders in CPG
LinkedIn Analysis of Digital Leaders in CPGLinkedIn Analysis of Digital Leaders in CPG
LinkedIn Analysis of Digital Leaders in CPG
 
Corona del Mar Homes for Sale
Corona del Mar Homes for SaleCorona del Mar Homes for Sale
Corona del Mar Homes for Sale
 
Miset oy kärjet
Miset oy kärjetMiset oy kärjet
Miset oy kärjet
 
Mind powerscrolls 22
Mind powerscrolls 22Mind powerscrolls 22
Mind powerscrolls 22
 
خطة عمل مشروع منظومة السلامة الكهربائية 15002
خطة عمل مشروع منظومة السلامة الكهربائية 15002خطة عمل مشروع منظومة السلامة الكهربائية 15002
خطة عمل مشروع منظومة السلامة الكهربائية 15002
 
Aliso Viejo Homes For Sale
Aliso Viejo Homes For Sale Aliso Viejo Homes For Sale
Aliso Viejo Homes For Sale
 
Fotos
FotosFotos
Fotos
 
Workshop
WorkshopWorkshop
Workshop
 
What social marketers can learn from brimfield police
What social marketers can learn from brimfield policeWhat social marketers can learn from brimfield police
What social marketers can learn from brimfield police
 
Presentation2
Presentation2Presentation2
Presentation2
 
Homicid, suicid i decije shvatanje smrti
Homicid, suicid i decije shvatanje smrti Homicid, suicid i decije shvatanje smrti
Homicid, suicid i decije shvatanje smrti
 
2010 1215-건국대인문학연구원발표-이정모5-2
2010 1215-건국대인문학연구원발표-이정모5-22010 1215-건국대인문학연구원발표-이정모5-2
2010 1215-건국대인문학연구원발표-이정모5-2
 
Tips to Get Top Dollar for your Newport Beach Home!
Tips to Get Top Dollar for your Newport Beach Home!Tips to Get Top Dollar for your Newport Beach Home!
Tips to Get Top Dollar for your Newport Beach Home!
 
Rollup GSO2
Rollup GSO2Rollup GSO2
Rollup GSO2
 
Ecnew 090926143211-phpapp01 (autosaved)
Ecnew 090926143211-phpapp01 (autosaved)Ecnew 090926143211-phpapp01 (autosaved)
Ecnew 090926143211-phpapp01 (autosaved)
 
分散システム第7章(後半)
分散システム第7章(後半)分散システム第7章(後半)
分散システム第7章(後半)
 

Similaire à 言語処理系入門€8

言語処理系入門3
言語処理系入門3言語処理系入門3
言語処理系入門3Kenta Hattori
 
言語処理系入門€10
言語処理系入門€10言語処理系入門€10
言語処理系入門€10Kenta Hattori
 
言語処理系入門€6
言語処理系入門€6言語処理系入門€6
言語処理系入門€6Kenta Hattori
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話bleis tift
 
言語処理系入門€7
言語処理系入門€7言語処理系入門€7
言語処理系入門€7Kenta Hattori
 
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)Shin-ya Koga
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介fukuoka.ex
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Ransui Iso
 
Emacs上のターミナルを最強に
Emacs上のターミナルを最強にEmacs上のターミナルを最強に
Emacs上のターミナルを最強にLintaro Ina
 
Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1NISHIMOTO Keisuke
 
Lisper はじめました (再)
Lisper はじめました (再)Lisper はじめました (再)
Lisper はじめました (再)Nobutada Matsubara
 
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』Kenta USAMI
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーmganeko
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜Takeshi Arabiki
 
Programming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選びProgramming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選びdekosuke
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミングOuka Yuka
 
普通のプログラミング言語R
普通のプログラミング言語R普通のプログラミング言語R
普通のプログラミング言語RShuyo Nakatani
 

Similaire à 言語処理系入門€8 (20)

言語処理系入門3
言語処理系入門3言語処理系入門3
言語処理系入門3
 
言語処理系入門€10
言語処理系入門€10言語処理系入門€10
言語処理系入門€10
 
言語処理系入門€6
言語処理系入門€6言語処理系入門€6
言語処理系入門€6
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話
 
言語処理系入門€7
言語処理系入門€7言語処理系入門€7
言語処理系入門€7
 
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介
 
PRML 第14章
PRML 第14章PRML 第14章
PRML 第14章
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
 
Emacs上のターミナルを最強に
Emacs上のターミナルを最強にEmacs上のターミナルを最強に
Emacs上のターミナルを最強に
 
Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1Siphone coffeemaker okayama-js-1
Siphone coffeemaker okayama-js-1
 
Lisper はじめました (再)
Lisper はじめました (再)Lisper はじめました (再)
Lisper はじめました (再)
 
Lisperはじめました
LisperはじめましたLisperはじめました
Lisperはじめました
 
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
Programming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選びProgramming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選び
 
講座C入門
講座C入門講座C入門
講座C入門
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
 
普通のプログラミング言語R
普通のプログラミング言語R普通のプログラミング言語R
普通のプログラミング言語R
 

Plus de Kenta Hattori

オブジェクト指向入門2
オブジェクト指向入門2オブジェクト指向入門2
オブジェクト指向入門2Kenta Hattori
 
オブジェクト指向入門1
オブジェクト指向入門1オブジェクト指向入門1
オブジェクト指向入門1Kenta Hattori
 
オブジェクト指向入門10
オブジェクト指向入門10オブジェクト指向入門10
オブジェクト指向入門10Kenta Hattori
 
オブジェクト指向入門9
オブジェクト指向入門9オブジェクト指向入門9
オブジェクト指向入門9Kenta Hattori
 
オブジェクト指向入門8
オブジェクト指向入門8オブジェクト指向入門8
オブジェクト指向入門8Kenta Hattori
 
オブジェクト指向入門7
オブジェクト指向入門7オブジェクト指向入門7
オブジェクト指向入門7Kenta Hattori
 
オブジェクト指向入門6
オブジェクト指向入門6オブジェクト指向入門6
オブジェクト指向入門6Kenta Hattori
 
オブジェクト指向入門5
オブジェクト指向入門5オブジェクト指向入門5
オブジェクト指向入門5Kenta Hattori
 
オブジェクト指向入門4
オブジェクト指向入門4オブジェクト指向入門4
オブジェクト指向入門4Kenta Hattori
 
オブジェクト指向入門3
オブジェクト指向入門3オブジェクト指向入門3
オブジェクト指向入門3Kenta Hattori
 
ソフトウェア・テスト入門2
ソフトウェア・テスト入門2ソフトウェア・テスト入門2
ソフトウェア・テスト入門2Kenta Hattori
 
ソフトウェア・テスト入門1
ソフトウェア・テスト入門1ソフトウェア・テスト入門1
ソフトウェア・テスト入門1Kenta Hattori
 
ソフトウェア・テスト入門8
ソフトウェア・テスト入門8ソフトウェア・テスト入門8
ソフトウェア・テスト入門8Kenta Hattori
 
ソフトウェア・テスト入門7
ソフトウェア・テスト入門7ソフトウェア・テスト入門7
ソフトウェア・テスト入門7Kenta Hattori
 
ソフトウェア・テスト入門6
ソフトウェア・テスト入門6ソフトウェア・テスト入門6
ソフトウェア・テスト入門6Kenta Hattori
 
ソフトウェア・テスト入門5
ソフトウェア・テスト入門5ソフトウェア・テスト入門5
ソフトウェア・テスト入門5Kenta Hattori
 
ソフトウェア・テスト入門4
ソフトウェア・テスト入門4ソフトウェア・テスト入門4
ソフトウェア・テスト入門4Kenta Hattori
 
ソフトウェア・テスト入門3
ソフトウェア・テスト入門3ソフトウェア・テスト入門3
ソフトウェア・テスト入門3Kenta Hattori
 
アルゴリズムとデータ構造15
アルゴリズムとデータ構造15アルゴリズムとデータ構造15
アルゴリズムとデータ構造15Kenta Hattori
 
アルゴリズムとデータ構造14
アルゴリズムとデータ構造14アルゴリズムとデータ構造14
アルゴリズムとデータ構造14Kenta Hattori
 

Plus de Kenta Hattori (20)

オブジェクト指向入門2
オブジェクト指向入門2オブジェクト指向入門2
オブジェクト指向入門2
 
オブジェクト指向入門1
オブジェクト指向入門1オブジェクト指向入門1
オブジェクト指向入門1
 
オブジェクト指向入門10
オブジェクト指向入門10オブジェクト指向入門10
オブジェクト指向入門10
 
オブジェクト指向入門9
オブジェクト指向入門9オブジェクト指向入門9
オブジェクト指向入門9
 
オブジェクト指向入門8
オブジェクト指向入門8オブジェクト指向入門8
オブジェクト指向入門8
 
オブジェクト指向入門7
オブジェクト指向入門7オブジェクト指向入門7
オブジェクト指向入門7
 
オブジェクト指向入門6
オブジェクト指向入門6オブジェクト指向入門6
オブジェクト指向入門6
 
オブジェクト指向入門5
オブジェクト指向入門5オブジェクト指向入門5
オブジェクト指向入門5
 
オブジェクト指向入門4
オブジェクト指向入門4オブジェクト指向入門4
オブジェクト指向入門4
 
オブジェクト指向入門3
オブジェクト指向入門3オブジェクト指向入門3
オブジェクト指向入門3
 
ソフトウェア・テスト入門2
ソフトウェア・テスト入門2ソフトウェア・テスト入門2
ソフトウェア・テスト入門2
 
ソフトウェア・テスト入門1
ソフトウェア・テスト入門1ソフトウェア・テスト入門1
ソフトウェア・テスト入門1
 
ソフトウェア・テスト入門8
ソフトウェア・テスト入門8ソフトウェア・テスト入門8
ソフトウェア・テスト入門8
 
ソフトウェア・テスト入門7
ソフトウェア・テスト入門7ソフトウェア・テスト入門7
ソフトウェア・テスト入門7
 
ソフトウェア・テスト入門6
ソフトウェア・テスト入門6ソフトウェア・テスト入門6
ソフトウェア・テスト入門6
 
ソフトウェア・テスト入門5
ソフトウェア・テスト入門5ソフトウェア・テスト入門5
ソフトウェア・テスト入門5
 
ソフトウェア・テスト入門4
ソフトウェア・テスト入門4ソフトウェア・テスト入門4
ソフトウェア・テスト入門4
 
ソフトウェア・テスト入門3
ソフトウェア・テスト入門3ソフトウェア・テスト入門3
ソフトウェア・テスト入門3
 
アルゴリズムとデータ構造15
アルゴリズムとデータ構造15アルゴリズムとデータ構造15
アルゴリズムとデータ構造15
 
アルゴリズムとデータ構造14
アルゴリズムとデータ構造14アルゴリズムとデータ構造14
アルゴリズムとデータ構造14
 

言語処理系入門€8

  • 1. 言語処理系入門 第 8 回:コンパイラ I : CPS 変換 2009 年 12 月 18 日(金) 【改 :2009/12/21 】 服部 健太
  • 2. コンパイルの流れ  関数型言語における典型的なコンパイルパス ソース プログラム 字句・構文解析 型検査 CPS 変換 Cps.convTyping.checkparse クロージャ変換コード生成 目的 コード 実行時 ライブラリ 中間言語 抽象構文木 GC など実行時に必要な処理 実行時にロード・リンクされる C 言語で実装されることが多い C 言語,アセンブリコード, VM の中間言語(バイトコード) etc 2009/12/18 2言語処理系入門 8
  • 3. 中間言語(中間表現とも呼ぶ)  利点  最適化をしやすくする  複数の目的言語をサポートするため  複数の段階に分けることでコンパイルの処理を簡 潔にする  どのような形式の中間言語を採用するかは言 語のデザインによって異なる  命令型言語では, SSA や RTL ,  関数型言語では, CPS や A 正規形, K 正規形  複数の中間言語を採用するコンパイラも 我々の言語で は CPS を採 用 2009/12/18 3言語処理系入門 8
  • 4. 復習:継続( continuation )とは  残りの計算を表す概念  プログラムの実行のある時点から最終的な答えを 得るまでの計算  例: let x = 2 in let y = 3 + x * (f x) in y * y;  部分式 (f x) に注目したとき,このときの継続 let y = 3 + x * [<(f x) の値 >] in y * y 2009/12/4 4言語処理系入門 62009/12/18 4言語処理系入門 8
  • 5. 復習:継続渡しスタイル ( CPS )  継続を明示的に渡す関数のスタイル  ダイレクトスタイル(通常の形式) let rec fact n = if n == 0 then 1 else n * (fact (n – 1));  継続渡しスタイル let rec fact n k = if n == 0 then k 1 else fact (n-1) (fn v -> k (v * n)); fact(n-1) を計算し た後にする計算 (継続) 2009/12/4 5言語処理系入門 62009/12/18 5言語処理系入門 8
  • 6. 中間言語としての CPS  制御の流れ , データの流れがコードに明示的に現れる  最適化がしやすい(末尾呼び出し最適化,不要コードの除去 etc )  shift/reset, callcc, letcc などの一級継続も CPS に変換することで 簡単に実装できる  例: let rec prod_primes n = if n == 1 then 1 else if is_prime n then n * prod_primes(n-1) else prod_primes(n-1) 2009/12/18 6言語処理系入門 8
  • 7. 中間言語としての CPS ( 2 ) let rec prod_primes c n = if n == 1 then c 1 else let k =   fn b -> if b == true then let j = fn p -> let a = n * p in c a and m = n – 1 in prod_primes j m else let h = fn q -> c q and i = n – 1 in prod_primes h i in is_prime k n k: 継続 1 j: 継続 2 h: 継続 3 2009/12/18 7言語処理系入門 8
  • 8. ソース言語の抽象構文  E ::= F | V  | let x1 = E1 and … and xn = En in E  | let rec x1 = E1 and … and xn = En in E  | if E1 then E2 else E3  | handle E1 with x in E2  | raise E  | E.l  | E1 E2  | op(E1,…,En )  | { l1=E1; …; ln=En }  | fn x -> E  V ::= c | x op は +,-,*,/,strlen など のプリミティブ演算子 2009/12/18 8言語処理系入門 8
  • 9. CPS 式の構文  K ::= E  | let x1 = D1 and … and xn = Dn in K  | let rec x1 = D1 and … and xn = Dn in K  | if E then K1 else K2  | V k E | k E  D ::= E  |{ l1=V1;…; ln = Vn }  | fn k x -> K | fn x -> K  E ::= V     | let x1 = D1 and … and xn = Dn in E     | let rec x1 = D1 and … and xn = Dn in E  | E.l  | op(E1, … ,En)  V ::= c | x | k --- ただし, k, x∈Variable 関数呼び出しや分岐を 伴わない単純な式 レコードと関数は let/let rec で束縛 されてから使用される 2009/12/18 9言語処理系入門 8
  • 10. CPS 変換  変換関数を [[E]]к⇒K のように記述する  E は,変換元の構文木, K は変換後の CPS 式, к は単純な CPS 式 (E) を受け取り,完全な CPS 式 を出力する関数  [[ ・ ]] : Esource→(Ecps→Kcps) → Kcps  к : Ecps→Kcps  Vsource の変換  単に к に渡して, CPS 式の穴を埋める [[csource]]к к⇒ ccps [[xsource]]к к⇒ xcps 以降,あきらかな場合 には subscript を省略 2009/12/18 10言語処理系入門 8
  • 11. if 式  素朴な変換 [[if E1 then E2 else E3]]к⇒ [[E1]](λv.if v then [[E2]]к else [[E3]]к)  к が複製されるため,コードが爆発する可能性あ り  正しい変換 [[if E1 then E2 else E3]]к⇒ [[E1]](λv.let j = fn x ->кx in if v then [[E2]](λv.j v) else [[E3]](λv.j v))2009/12/18 11言語処理系入門 8
  • 12. let/let rec 式  x=E の右辺式 E を単純な式に変換  let 式 [[let x1 = E1 … and xn = En in E]]к⇒ [[Es]](λvs. к (let xs=vs in [[E]]кinit))     [[Es]](λvs.let xs=vs in [[E]]к)  let rec 式 [[let rec x1 = E1 … and xn = En in E]]к⇒ [[Es]](λvs.к(let rec xs=vs in [[E]]кinit)) [[Es]](λvs.let rec xs=vs in [[E]]к) 2009/12/18 12言語処理系入門 8 E is simple E is not simple E is simple E is not simple
  • 13. 関数・プリミティブ演算子の変換  無名関数 [[fn x -> E]]к⇒    let f = fn k x -> [[E]](λv.k v) in кf  f や k はフレッシュな変数  後のフェーズで便利なように無名の関数に名前を付けてお く  関数適用 [[E1 E2]]к⇒    [[E1]](λf.[[E2]](λv.let k = fn r ->кr in f k v))  プリミティブ演算子 [[op(E1,…,En)]]к⇒    [[Es]](λvs.кop(vs)) 呼び出し元に戻ってくるための継続 継続を受け取るた めの引数を1つ増 やす 2009/12/18 13言語処理系入門 8
  • 14. レコード式の変換  レコード生成  各フィールドの右辺式を単純な式に変換 [[{ l1=E1; …; ln=En }]]к⇒ [[Es]](λvs.к(let xs=vsin let r ={ls=xs} in r))  フィールド参照  参照元の式を変換し,そのフィールド値を x に束 縛 [[E.l]]к⇒ [[E]](λv.к(v.l)) 2009/12/18 14言語処理系入門 8
  • 15. 例外捕捉・発生  例外捕捉  新しいハンドラをセットし,式を評価  例外を捕捉したら元のハンドラをセットし直して, E2 を 評価 [[handle E1 with x in E2]]к⇒    let h = gethdlr() and k = fn x ->кx in let h’ = fn x -> let _ = sethdlr h in [[E2]](λv.k v) in let _ = sethdlr h’ in [[E1]](λv.let _ = sethdlr h in k v)  例外発生  ハンドラを取得して,呼び出すだけ [[raise E]]к ⇒      [[E]] (λv.let h = gethdlr() in h v) 2009/12/18 15言語処理系入門 8
  • 16. 変換例  [[+(x,(f 0).l)]]к ⇒[[<x;(f 0).l>]](λvs.let x1 = +(vs) in кx1) ⇒[[ (f 0).l]](λv.let x1 = +(x,v) in кx1) ⇒[[(f 0)]](λv.let x2=v.l in (λv.let x1 = +(x,v) in кx1)x2) ⇒[[(f 0)]](λv.let x2=v.l in let x1 = +(x, x2) in кx1) ⇒[[f]](λf.[[0]] (λv.let k=fn r-> (λv.let x2=v.l in let x1 = +(x,x2) in к x1)r in f k v)) ⇒[[f]](λf.[[0]](λv.let k=fn r-> let x2=r.l in let x1 = +(x,x2) in кx1 in f k v)) ⇒let k=fn r->let x2=r.l in let x1 = +(x,x2) in кx1 in f k 0  演習問題  [[let rec fact = fn n -> if ==(n,0) then 1 else *(n,fact(-(n,1))) in fact 5]]к ⇒? 2009/12/18 16言語処理系入門 8
  • 17. Ocaml での実装( cps.ml ) let rec conv_expr k e = match e with | Syntax.ValExpr v -> k (conv_value v) | Syntax.IfExpr(e1,e2,e3) -> let j = Symbol.fresh() in let x = Symbol.fresh() in let k' = fun v -> AppExpr(VarVal j,[v]) in conv_expr ( fun v -> LetExpr([j,FunExpr([x],k (VarVal x))], IfExpr(v,conv_expr k' e2,conv_expr k' e3)) ) e1 | Syntax.FunExpr((x,_),_,e1) -> let k’ = Symbol.fresh() in let f = FunExpr([k’;x], conv_expr (fun v -> AppExpr(VarVal k’,[v])) e1) in k (VarVal f) … 2009/12/18 17言語処理系入門 8
  • 18. 末尾呼び出しの最適化  以下の式を CPS 変換すると  let f x = g (x + 1)  こうなるが こう最適化でき る let f k x = let f k x = let k’ a = k a in let b = x + 1 in let b = x + 1 in      g k b g k’ b  λ 計算において λx.M(x) を M に簡約化することを η 簡約と呼ぶ  「 C 言語的に考えると, int foo(int x) { return bar(x); } とい う関数定義がある場合,すべての foo の呼び出しを bar に 置き換えることができる」のと同じことである 2009/12/18 18言語処理系入門 8
  • 19. 参考文献  A.W.Appel, “Compiling with Continuations”, Cambridge Univ.Press, 1992.  田浦さんの資料  http://www.is.s.u-tokyo.ac.jp/vu/97/jugyo/processor/com 2009/12/18 19言語処理系入門 8
  • 20. 演習問題  今週のサンプルプログラムを動かしてみよ  無駄な変数のコピー伝播を削除する最適化を 実装せよ  let x = y in …x… … y …⇒  末尾呼び出しの最適化を実装せよ 2009/12/18 20言語処理系入門 8
  • 21. 次回予定  日時:  2009 年 12 月 25 日(金) 10 : 30 - 12 : 00  場所:  LB2 3F/A  内容:  コンパイル II :クロージャ変換 2009/12/10 21言語処理系入門 72009/12/18 21言語処理系入門 8