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, }
がパースエラーにならない。やったね。