正月休みの最終日、JSONパーサを作りました

コピペで使おう! ライブラリ」とか始めたものの現在内容がしょぼいので、正月休みの最終日である今日、JSONパーサを作りました。
朝から(といっても11:00頃ですが)からかかって20:00頃まで、途中昼食を作って食べたりおやつを食べたりとかはしたものの、割とがっつりコード書きして、現状時間切れでテストが足りないところはちょっとあるものの、以下くらいのJSONは読み込めるようになりました。

{
  "array": [1, 2.0, 123, 123.456, -1, -2.0],
  "array2": [3e5, 3E5, 3.1e5, 3.1E5, 3.1e+5, 3.1e-5, true, false, null],
  "string": "abcあいうえお",
  "string2": "\"\\\/\t",
  "string3": "\u3042",
  "string4": "\u3042\u3044\u3046",
  "string5": "\uD867\uDE3D",
  "string6": "\uD867\uDE3D\r\n",
  "string7": "\uD867\uDE3D\u3042\u3044\u3046",
  "objSub": {
    "sub1": 1,
    "sub2": "abc"
  },
  "objInArray": [
    {
      "objInArray1": 1,
      "objInArray2": "abc"
    }
  ],
  "arrayInArray": [
    [
      1,
      true,
      {
        "arrayInArray1": 1,
        "arrayInArray2": "abc"
      }
    ]
  ]
}

コードは例によってGitHubに上げてあります。
github.com
もうちょっとちゃんとテストしたら、「コピペで使おう! ライブラリ」にも上げます。

以前、同じような休日コーディング(Twitter実況付き。ほんのちょっとですが)で、samplanというプログラミング言語を作ったのですが、
kmaebashi.hatenablog.com
プログラミング言語といえば当然パーサを含むので、今回作ったものもまあ似たようなプログラムではあります。ただ、ちゃんとJSONに対応しようとすると「1.2e3」のような指数表記やら「\uXXXX」のようなunicodeエンコードやらにも対応しなければいけなくて、その辺は結構面倒でした……

今回のJSONパーサは、JSONを読み込んでJsonElementというインタフェースを返します。これのサブインタフェースにJsonObject、JsonArray, JsonValueがあり、それぞれがJSONのオブジェクト、配列、値を表します。つまり、これは「任意のJSONを読み込むためのJSONパーサ」であり、「あらかじめ決められた形式のJSONを読み込むためのJSONパーサ」ではありません。もちろんあらかじめ決められた形式のJSONを読んでもよいのですが、どうせ形式が決まっているなら、クラスにマッピングするところまでやりたいですよね。その辺はまた後日。

今回、1日でテストコード除いて785行(空行込み、コメントなぞ書いてない)ばかり書いてなかなかに疲れましたが、やっぱりコードを書くのは楽しいです。コードを書き始める前に、ティーポット1杯(カップ3杯分)の紅茶を淹れたのに1杯だけ飲んで残りは忘れてしまったりとか、トイレに行く間も惜しんでコード書いてたのでトイレ行くのはいつもぎりぎりだったりとか、ひさびさに集中したコード書きができました。

しかし疲れた。明日も休みになんないかな。