SMLでJSONをパースする

SML/njにはデフォルトでいろんなライブラリが同梱されていて,なにやら便利そうな雰囲気を出しているものもあるんですが,…ことごとくドキュメントが無いですorz
その中でも,ぱっと見でどうにか使えそうなJSONパーサライブラリを紹介.(jsonて2.0っぽいし)

場所

SMLNJ_HOME/smlnj-lib/JSON

機能

以下の二つの使い方が出来るようです. とりあえず前者を使ってみます.

  • 入力ストリーム(ファイル)を読み込んでパース結果を一度に返す
  • 入力ストリームをパースしながら,あらかじめ登録しておいたコールバックを呼ぶ

signature

それっぽいインターフェースが公開されています.

structure JSONParser :
sig
    val parse : TextIO.instream -> JSON.value
    val parseFile : string -> JSON.value
end

ストリームを読み込んでパースしてくれるようです.signatureからして直感的です.
(しかし JSON.value って…なんだかな. 普通?)

使用例

 $ cd $SMLNJ_HOME/smlnj-lib/JSON
 $ cat test.json
 {"foo":"one","bar":"two","bazz":"three"}
 $ sml
 - CM.make "json-lib.cm";
 - JSONParser.parseFile "test.json"; (* ファイルから読み込む *)
 val it =
   OBJECT [("foo",STRING "one"),("bar",STRING "two"),("bazz",STRING "three")]
   : JSON.value
 
 (* 文字列から直接読み込んでもいいけどエスケープ地獄 XD *)
 - JSONParser.parse (openString "{\"foo\":\"one\",\"bar\":\"two\",\"bazz\":\"three\"}");
 val it =
   OBJECT [("foo",STRING "one"),("bar",STRING "two"),("bazz",STRING "three")]
   : JSON.value

実装

lexer(の定義)にSML版lex(MLLex)を使っているのでSMLだけで完結してるわけではない.
MLLexはSMLのコード吐くんだけど.
その他のコードはかなりコンパクトなので(その気があれば)すぐに読めそうだけど,
短すぎて不安になる.
JSONパーサのテスト用入力とかどっかに無いのかな.