2009年12月28日
as3corelib の JSON.decode() をいい加減な JSON に対応させる
JSON は手軽に書けていいのですが、仕様がちょっと厳密すぎるところもあるので緩い JSON で書きたくなる。
JSON の仕様で個人的に面倒だと思うのは次の3つ。
- object や array の最後に
,があるとエラーになる - object のキーは文字列じゃないといけない
0.3を.3と書くとエラーになる
たとえば、次のような JSON はパースエラーとなる。
{
a: .3,
b: .4,
c: .9,
}
本当はこうすべき。
{
// a → "a"
"a": 0.3, // .3 → 0.3
"b": 0.4,
"c": 0.9 // カンマを削った
}
オレオレなプロジェクトで JSON を手書きするときには、この3つの制限を緩和してあげたくなる。json.org の仕様には違反しちゃうけど、書きやすさを優先で GO!!!
そこで、ActionScript の定番 JSON パーサーである as3corelib の .92.1 に手を入れてみた。
たとえば、配列末尾のカンマを許容するには com/adobe/serialization/json/JSONDecoder.as の parseArray() 関数に次のように手を入れた。
} else if ( token.type == JSONTokenType.COMMA ) {
// move past the comma and read another value
nextToken();
+
+ // allow trailing comma.
+ if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
+ return a;
+ }
} else {
カンマだったときに次が ] だったら、配列を返すようにする。
こんな感じで、ごにょごにょといじっていく。
「2. object のキーは文字列じゃないといけない」については、そもそも JSON の仕様に identifier がないので、ECMAScript の仕様を参考にしつつ、JSONTokenizer.as に手を入れていった。本当はキー名として日本語などの Unicode 文字も許可しなきゃいけないんだけど、めんどくさいので
/^[a-z_$][a-z_$0-9]*$/
を許可するキー名の条件とした。
完成品のソースはここにおいてる:
ここに置いてるやつを使えば
{
a: .3,
b: .4,
c: .9,
}
がパースエラーにならない。やったね。