Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ラムダ計算に基づいた純粋関数型言語の実装 ~パーサーコンビネータを使ってみる~ #Te...

ラムダ計算に基づいた純粋関数型言語の実装 ~パーサーコンビネータを使ってみる~ #TechLunch

2011/05/18(水) @ Livesense TechLunch
発表者:塩足 拓也

Livesense Inc.

April 23, 2014
Tweet

More Decks by Livesense Inc.

Other Decks in Technology

Transcript

  1. AGENDA ¢  Abstrac,on   ¢  Design  policy   ¢  Programming

     Language  &  Compiler   ¢  Func,onal  Language   ¢  What’s  Lambda  calculus?   ¢  Parser  Combinator   ¢  rparsec
  2. DESIGN  POLICY ¢  実装言語はRuby   ¢  インタプリタとして実装   ¢  実装を単純化するためにIO等は実装しない

      ¢  パフォーマンスは一切考えない   ¢  文法はLisp-­‐Like   ¢  Scanner/ParserはParser  Combinatorで実装する
  3. FUNCTIONAL  LANGUAGE —  純粋関数型言語   ¢  Haskell、Concurrent  Clean、Miranda   — 

    非純粋関数型言語   ¢  ML、Lisp、Scheme、OCaml、F#   ラムダ計算の概念に基づいたプログラミング言語   特徴 —  第一級関数(First  class  func,on)   —  副作用(side  effects)なし —  カリー化(carrying)   —  遅延評価(lazy  evalua,on)   代表的な言語
  4. 関数の定義と実行を抽象化した計算モデル   WHAT’S  LAMBDA  CALCULUS? <expr>  ::=  <iden,fier>    

                                 |  (“λ”  <iden,fier>  “.”  <expr>)                                  |  (<expr>  <expr>)   例 f(x)  =  x  +  1 λ.x  x+1 変数 ラムダ抽象 関数適用 ラムダ抽象 f(2) (λ.x  x+1)  2 関数適用
  5. PARSER  COMBINATOR ¢  最近流行のトップダウン構文解析   ¢  基本的なアイデアはパーサを結合子で合成して複雑な パーサを生成   ¢ 

    BNFからコードに落とし込むのが簡単   ¢  実装と文法定義で言語にギャップレス   ¢  ScannerとParserでギャップレス  
  6. RPARSEC require  'rubygems'   require  'rparsec'     include  RParsec::Parsers

        eol                                    =  string  ?\n   quoted_char  =  not_char(?")  |  string('""')  >>  value(?")   quoted_cell      =  char(?")  >>  quoted_char.many.bind  {  |s|  value(s.join(''))  }  <<  char(?")   cell                                    =  quoted_cell  |  regexp(/[^,"\n]*/)   line                                    =  cell.separated(char(?,))   csv_file                      =  (line  <<  eol).many   csvパーサ
  7. RPARSEC require  'rubygems'   require  'rparsec'     include  RParsec::Parsers

      include  RParsec::Functors   ops  =  RParsec::OperatorTable.new  do  |tbl|              tbl.infixl(string(?+)  >>  Plus,    10)              tbl.infixl(string(?-­‐)  >>  Minus,  10)              tbl.infixl(string(?*)  >>  Mul,      20)              tbl.infixl(string(?/)  >>  Div,      20)              tbl.prefix(string(?-­‐)  >>  Neg,      50)   end   expr    =  nil   term    =  integer.map(&To_i)  |  string(?()  >>  lazy  {  expr  }  <<  string(?))   delim  =  whitespace.many_   expr    =  delim  >>  RParsec::Expressions.build(term,  ops,  delim)   calc
  8. 次回予告 ¢  ラムダ計算の実装   ¢  ラムダ式を用いて自然数を定義(チャーチ数) 0  :=  λf  x.

     x   1  :=  λf  x.  f  x   2  :=  λf  x.  f  (f  x)   3  :=  λf  x.  f  (f  (f  x))