json_parse Douglas Crockford 簡易版

『JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス』のJSONパーサの簡易版 JavaScriptをやり始めた人が理解したほうが良いJSONパーサのコード

by s_hiroshi

JavaScript

// JSONをJavaScriptオブジェクトへ変換する
// JSONのデータは下記のように制限する
// プロパティ名は英小文字(a-z)の文字型のみを取る
// 値は英小文字(a-z)の文字型かオブジェクトリテラル{}のみを取る
// JSONの例 {"x": "abc"}'や{"x": {"y": "abc"}}
// reviver関数は省略
// エラー処理なし
var limit_json_parse = (function() {
    var at; // 現在の文字のインデックス
    var ch; // 現在の文字
    var text; // JSONデータを保管
    var next = function(c) { // インデックスを1文字進めて現在の文字を返す
        if (c && c !== ch) {
            return false;
        }
        ch = text.charAt(at);
        at += 1;
        return ch;
    };
 
    var white = function(c) {
        // ホワイトスペースを無視する関数
        // ' 'はUnicodeコードポイント0032(16進数)
        while (ch && ch <= ' ') {
            next();
        }
    };
 
    var string = function() {
        // 文字列の処理
        var string = '';
        if (ch === '"') {
            while (next()) {
                if (ch === '"') {
                    next();
                    return string;
                } else {
                    string += ch;
                }
            }
        }
        error("Bad string");
    };
 
    var object = function() {
        // オブジェクトを解析する関数
        var key, object = {};
 
        if (ch === '{') {
            next('{');
            white();
            if (ch === '}') {
                next('}');
                return object; // 空のオブジェクト
            }
            while (ch) { // オブジェクトを構築
                key = string(); // keyは文字列型のみなのでstring関数を直接実行
                white();
                next(':');
                object[key] = value(); // 値は文字型かオブジェクトなのでvalue関数を実行
                white();
                if (ch === '}') {
                    next('}');
                    return object;
                }
                next(',');
                white();
            }
        }
        return false;
    };
    var value = function() {
        // JSONの値を解析する関数
        // 型(オブジェクトか文字列のどちらか)に応じて対応する関数を実行
        // object関数から再帰。
        white();
        switch (ch) {
        case '{':
            return object();
        case '"':
...