json_parse Douglas Crockford
JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス avaScriptをやり始めた人が理解したほうが良いJSONパーサのコード
by s_hiroshi
JavaScript
// JavaScriptをやり始めた人が理解したほうが良いJSONパーサのコード
// http://d.hatena.ne.jp/sifue/20120218/1329588477
// JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
// 作者: Douglas Crockford,水野貴明
// 出版社/メーカー: オライリージャパン
var json_parse = function () {
// JSONをパースして、JavaScriptのデータ構造を生成する関数
// シンプルな再帰下降パーサで実装されています
//
// 実行例:
// var obj = json_parse("{\"first\": \"Jerome\"}");
//
// 実行例(全ての値に操作を行うreviver関数ありの場合):
// var obj = json_parse("{\"first\": \"Jerome\"}",
// function(key, value){if(key==='first') return 'hoge'; return value;});
//
// Chromeの方は、ツール > JavaScriptコンソールに、このソースを全て貼り付けて、
// 実行例を実行して、すぐに動作確認できます。
// グローバル変数を生成することを避けるため、以下の変数及び関数は、
// 関数の中で定義されます
var at, // 現在の文字のインデックス値
ch, // 現在の文字
escapee = {
'"': '"',
'\\': '\\',
'/': '/',
b: 'b',
f: '\f',
n: '\n',
r: '\r',
t: '\t'
},
text,
error = function (m) {
// 何か問題が発生した場合に、errorが呼び出す関数
throw {
name: 'SyntaxError',
message: m,
at: at,
text: text
};
},
next = function (c) {
// 一文字次に進める関数
// もしパラメーターcが指定されていたら、
// それが現在の文字にマッチするのかを調べ、矛盾がありそうならエラーで終わらせます
if (c && c !== ch) {
error("Expected '" + c + "' instead of '" + ch + "'");
}
// 次の文字を取得します。もしそれ以上がなかったら、
// 空文字を返します
ch = text.charAt(at);
at += 1;
return ch;
},
number = function () {
// 数値を解析する関数
var number,
string = '';
// もしマイナスが来たら、マイナスをstringに取りおいて次へ
if (ch === '-') {
string = '-';
next('-');
}
// 0~9までの間の文字コードならば、stringに連結させては次へ
while...