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から読み込む。
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")))
はてな記法を間違っていたようなので修正。