ScalaでJSONのパース(DSL)

コップ本の復習。

目的

・コップ本にあったJSONパースプログラムの実装。
・sbtを使用する。
・jarファイルにまとめる。

環境

IntelliJ(12.1.2)
Scala 2.10.1
・sbt 0.12.3
 http://www.scala-sbt.org/release/docs/Getting-Started/Setup.html
 から、今回はmsiをダウンロードした。

実装

・以下の内容でプロジェクト用に用意したディレクトリにbuild.sbtを作成。

import AssemblyKeys._ // put this at the top of the file

// for assembly
assemblySettings

//Main Class
mainClass in assembly := Some("ParseJSON")

name := "ParseJSON"
 
version := "0.0.1"
 
scalaVersion := "2.10.1"

libraryDependencies += "org.scalatest" % "scalatest_2.10" % "1.9.1" % "test"

・以下の内容でプロジェクト用に用意したディレクトリにproject/plugins.sbtを作成。

resolvers += "Sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
 
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.0-SNAPSHOT")

addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0")

// for assembly
resolvers += Resolver.url("artifactory", url("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.8")

・sbtからgen-ideaと打ってIntelliJ用のプロジェクトを作成してIDEから読み込む。

・src/main/scala/JSON.scala

import scala.util.parsing.combinator
import scala.util.parsing.combinator.JavaTokenParsers

class JSON extends JavaTokenParsers {
  def obj: Parser[Map[String, Any]] =
    "{"~> repsep(member, ",") <~"}" ^^ (Map() ++ _)
  def arr: Parser[List[Any]] =
    "["~> repsep(value, ",") <~"]"
  def member: Parser[(String, Any)] =
    stringLiteral~":"~value ^^ { case name~":"~value => (name, value) }
  def value: Parser[Any] = (
    obj
      | arr
      | stringLiteral
      | floatingPointNumber ^^ (_.toDouble)
      | "null" ^^ (x => null)
      | "true" ^^ (x => true)
      | "false" ^^ (x => false)
    )
}

・src/main/scala/ParseJSON.scala

import java.io.FileReader

object ParseJSON extends JSON {
  def main(args: Array[String]) {
    val reader = new FileReader(args(0))
    println(parseAll(value, reader))
  }
}

・sbtコンソールから以下のコマンドで target/scala-2.10/ParseJSON-assembly-0.0.1.jar が作成される。

assembly

・動作チェック。

java -jar ParseJSON-assembly-0.0.1.jar something.json

 以下のように出力できたのでOK。

[7.2] parsed: Map("employees" -> List(Map("firstName" -> "John", "lastName" -> "Doe"), Map("firstName" -> "Anna", "lastName" -> "Smith"), Map("firstName" -> "Peter", "lastName" -> "Jones")))

はてな記法を間違っていたようなので修正。