/* JSON parser based on the grammar described at http://json.org/. */ /* ===== Syntactical Elements ===== */ start = _ object { return $2; } object = "{" _ "}" _ { return {}; } / "{" _ members "}" _ { return $3; } members = pair ("," _ pair)* { var result = {}; result[$1[0]] = $1[1]; for (var i = 0; i < $2.length; i++) { result[$2[i][2][0]] = $2[i][2][1]; } return result; } pair = string ":" _ value { return [$1, $4]; } array = "[" _ "]" _ { return []; } / "[" _ elements "]" _ { return $3; } elements = value ("," _ value)* { var result = [$1]; for (var i = 0; i < $2.length; i++) { result.push($2[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 '"' _ { return $2; } chars = char+ { return $1.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" hexDigit hexDigit hexDigit hexDigit { return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); } number "number" = int frac exp _ { return parseFloat($1 + $2 + $3); } / int frac _ { return parseFloat($1 + $2); } / int exp _ { return parseFloat($1 + $2); } / int _ { return parseFloat($1); } int = digit19 digits { return $1 + $2; } / digit / "-" digit19 digits { return $1 + $2 + $3; } / "-" digit { return $1 + $2; } frac = "." digits { return $1 + $2; } exp = e digits { return $1 + $2; } digits = digit+ { return $1.join(""); } e = [eE] [+-]? { return $1 + $2; } /* * 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]