Swiftの動向とアツさを追う try! Swift参加レポート

try! Swift 3日目 参加レポート

この記事を読むのに必要な時間:およそ 5 分

Yasuhiro Inami氏「Parser Combinator in Swift」

続いてはLINE株式会社所属で,ReactKitなどのライブラリの作者としても知られるYasuhiro Inami氏@inamiyによる,Parser Combinatorについてのトークを紹介します。

Parser Combinator

Inami氏はまずParser Combinatorとそれを構成するParser(構文解析器)について,どういったものなのかについて次のように解説しました。

Parser
  • テキスト等のデータ,特にLexer(字句解析器)の結果としてのトークンを入力として受け取り,AST(Abstract Syntax Tree)のようなデータ構造を生成
  • ボトムアップなアルゴリズムとトップダウンなアルゴリズムの2種類が存在
Parser Combinator
  • Combinatorによって複数の小さなParserを組み合わせ,より複雑なParserを構成
  • 結果として1つの大きいParserが動いているように見える

画像

SwiftでのシンプルなParser

以上を踏まえた上で,実際にシンプルなParserをSwiftで複数定義し,それらを組み合わせて複雑なParserを構成する例を示しました。Parserのモナドとして以下を定義します。

struct Parser<A> {
    let parse: String -> (A, String)?
}

これは次の状態の変換を行うコンテナと言えます。

  • 入力: String
  • 出力: 出力と入力の残りのタプルのオプショナル値(失敗することがあるため)

これを利用し,例えば常に成功するParserは以下のように書くことができます。

func pure<A>(a: A) -> Parser<A> {
    return Parser { (a, $0) }
}

こういったシンプルなParserを多数定義していき,さらにそれらを組み合わせたParser(Parser Combinator)の例を多数紹介しました。それぞれの具体的な中身全てを今回のレポートに載せるのは難しいため,ぜひ発表資料を確認してみてください。例を挙げると,あるシンボルのParserは次のようにskipSpacesに挟まれたハンバーガー状になると紹介しました(個々のParserの定義は省略します)。

func symbol(str: String) -> Parser<String> {
    return skipSpaces() *>  string(str) <* skipSpaces()
}

その後,BNFで表現した自然数で構成される計算機に基づいた,小さなParserを組み合わせたParser Combinatorを構築し,実際に"(12 + 3) * 4 + 5"という数式を解く例を示しました。しかしこれはまだ単純な例ということで,トークは次のTryParsecの紹介へと続きます。

TryParsec

TryParsecは今回のカンファレンス用にInami氏が実装したParserで,以下のレポジトリでその内容を確認できます。

以下のような特徴を持っています。

  • CSV,XML,JSONのパースをサポート
  • HaskellのAttoparsec/Aesonにインスパイアされたもので,Monadicである
  • 独自のParserも簡単に作成可能

実際にSwift標準の機能を利用せず,TryParsecによりJSONデータをパースする例をまず示しました。さらに,マッピングルールを記述したモデルに対してのJSON Decoding/Encodingが簡単に行えることと,その例を紹介しました。例えばあるモデルに対するJSON DecodingについてはFromJSONを採用し,以下のように書くことができます。

extension Model: FromJSON {  
   static func fromJSON(json: JSON) -> Result<Model, JSON.ParseError> {  
       return fromJSONObject(json) {  
           curry(self.init)  
               <^> $0 !! "string"  
               <*> $0 !! "num"  
               <*> $0 !! "bool"  
               <*> $0 !! "null"  
               <*> $0 !! "array"  
               <*> $0 !! "dict"  
               <*> $0 !! "object"  
               <*> $0 !? "dummy"  
       }  
   }  
}

SwiftでJSONを扱う際の有名なライブラリの1つであるthoughtbot/Argoと同じApplicative Styleでの記述が可能になっており,非常に興味深い内容でした。まだパフォーマンス面が課題とのことですが,改善は継続していくとのことです。

画像

著者プロフィール

後藤慎一(ごとうしんいち)

Wantedly, Inc.のソフトウェアエンジニア。

インフラエンジニアとしてサービスを支える仕事をしていたが、プログラマとしての能力を高めたくなり転職。現在はObjective-CでのiOSアプリ開発やRailsでのサーバサイド開発に従事。ヒマがあればSwiftと戯れて生きている。

Twitter:@_shingt