/* JSON parser based on the grammar described at http://json.org/. */ /* ===== Syntactical Elements ===== */ start = _ object:object { return object; } object = "{" _ "}" _ { return {}; } / "{" _ members:members "}" _ { return members; } members = head:pair tail:("," _ pair)* { var result = {}; result[head[0]] = head[1]; for (var i = 0; i < tail.length; i++) { result[tail[i][2][0]] = tail[i][2][1]; } return result; } pair = name:string ":" _ value:value { return [name, value]; } array = "[" _ "]" _ { return []; } / "[" _ elements:elements "]" _ { return elements; } elements = head:value tail:("," _ value)* { var result = [head]; for (var i = 0; i < tail.length; i++) { result.push(tail[i][2]); } return result; } value = string / number / object / array / "true" _ { return true; } / "false" _ { return false; } // FIXME: We can't return null here because that would mean parse failure. / "null" _ { return "null"; } /* ===== Lexical Elements ===== */ string "string" = '"' '"' _ { return ""; } / '"' chars:chars '"' _ { return chars; } chars = chars:char+ { return chars.join(""); } char // In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character" = [^"\\\0-\x1F\x7f] / '\\"' { return '"'; } / "\\\\" { return "\\"; } / "\\/" { return "/"; } / "\\b" { return "\b"; } / "\\f" { return "\f"; } / "\\n" { return "\n"; } / "\\r" { return "\r"; } / "\\t" { return "\t"; } / "\\u" digits:$(hexDigit hexDigit hexDigit hexDigit) { return String.fromCharCode(parseInt("0x" + digits)); } number "number" = parts:$(int frac exp) _ { return parseFloat(parts); } / parts:$(int frac) _ { return parseFloat(parts); } / parts:$(int exp) _ { return parseFloat(parts); } / parts:$(int) _ { return parseFloat(parts); } int = digit19 digits / digit / "-" digit19 digits / "-" digit frac = "." digits exp = e digits digits = digit+ e = [eE] [+-]? /* * The following rules are not present in the original JSON gramar, but they are * assumed to exist implicitly. * * FIXME: Define them according to ECMA-262, 5th ed. */ digit = [0-9] digit19 = [1-9] hexDigit = [0-9a-fA-F] /* ===== Whitespace ===== */ _ "whitespace" = whitespace* // Whitespace is undefined in the original JSON grammar, so I assume a simple // conventional definition consistent with ECMA-262, 5th ed. whitespace = [ \t\n\r]