This commit is contained in:
Douglas Crockford 2016-05-03 12:41:50 -07:00
parent bdeb882f4e
commit a48e0c7944

View file

@ -48,8 +48,8 @@
/*jslint for */
/*property
at, b, call, charAt, f, fromCharCode, hasOwnProperty, message, n, name,
/*property
at, b, call, charAt, f, fromCharCode, hasOwnProperty, message, n, name,
prototype, push, r, t, text
*/
@ -64,230 +64,230 @@ var json_parse = (function () {
// We are defining the function inside of another function to avoid creating
// global variables.
var at, // The index of the current character
ch, // The current character
escapee = {
'"': '"',
'\\': '\\',
'/': '/',
b: '\b',
f: '\f',
n: '\n',
r: '\r',
t: '\t'
},
text,
var at; // The index of the current character
var ch; // The current character
var escapee = {
'"': '"',
'\\': '\\',
'/': '/',
b: '\b',
f: '\f',
n: '\n',
r: '\r',
t: '\t'
};
var text;
error = function (m) {
var error = function (m) {
// Call error when something is wrong.
throw {
name: 'SyntaxError',
message: m,
at: at,
text: text
};
},
throw {
name: 'SyntaxError',
message: m,
at: at,
text: text
};
};
next = function (c) {
var next = function (c) {
// If a c parameter is provided, verify that it matches the current character.
if (c && c !== ch) {
error("Expected '" + c + "' instead of '" + ch + "'");
}
if (c && c !== ch) {
error("Expected '" + c + "' instead of '" + ch + "'");
}
// Get the next character. When there are no more characters,
// return the empty string.
ch = text.charAt(at);
at += 1;
return ch;
},
ch = text.charAt(at);
at += 1;
return ch;
};
number = function () {
var number = function () {
// Parse a number value.
var number,
string = '';
var number;
var string = '';
if (ch === '-') {
string = '-';
next('-');
if (ch === '-') {
string = '-';
next('-');
}
while (ch >= '0' && ch <= '9') {
string += ch;
next();
}
if (ch === '.') {
string += '.';
while (next() && ch >= '0' && ch <= '9') {
string += ch;
}
}
if (ch === 'e' || ch === 'E') {
string += ch;
next();
if (ch === '-' || ch === '+') {
string += ch;
next();
}
while (ch >= '0' && ch <= '9') {
string += ch;
next();
}
if (ch === '.') {
string += '.';
while (next() && ch >= '0' && ch <= '9') {
string += ch;
}
}
if (ch === 'e' || ch === 'E') {
string += ch;
next();
if (ch === '-' || ch === '+') {
string += ch;
next();
}
while (ch >= '0' && ch <= '9') {
string += ch;
next();
}
}
number = +string;
if (!isFinite(number)) {
error("Bad number");
} else {
return number;
}
},
}
number = +string;
if (!isFinite(number)) {
error("Bad number");
} else {
return number;
}
};
string = function () {
var string = function () {
// Parse a string value.
var hex,
i,
string = '',
uffff;
var hex;
var i;
var string = '';
var uffff;
// When parsing for string values, we must look for " and \ characters.
if (ch === '"') {
while (next()) {
if (ch === '"') {
next();
return string;
}
if (ch === '\\') {
next();
if (ch === 'u') {
uffff = 0;
for (i = 0; i < 4; i += 1) {
hex = parseInt(next(), 16);
if (!isFinite(hex)) {
break;
}
uffff = uffff * 16 + hex;
if (ch === '"') {
while (next()) {
if (ch === '"') {
next();
return string;
}
if (ch === '\\') {
next();
if (ch === 'u') {
uffff = 0;
for (i = 0; i < 4; i += 1) {
hex = parseInt(next(), 16);
if (!isFinite(hex)) {
break;
}
string += String.fromCharCode(uffff);
} else if (typeof escapee[ch] === 'string') {
string += escapee[ch];
} else {
break;
uffff = uffff * 16 + hex;
}
string += String.fromCharCode(uffff);
} else if (typeof escapee[ch] === 'string') {
string += escapee[ch];
} else {
string += ch;
break;
}
} else {
string += ch;
}
}
error("Bad string");
},
}
error("Bad string");
};
white = function () {
var white = function () {
// Skip whitespace.
while (ch && ch <= ' ') {
next();
}
},
while (ch && ch <= ' ') {
next();
}
};
word = function () {
var word = function () {
// true, false, or null.
switch (ch) {
case 't':
next('t');
next('r');
next('u');
next('e');
return true;
case 'f':
next('f');
next('a');
next('l');
next('s');
next('e');
return false;
case 'n':
next('n');
next('u');
next('l');
next('l');
return null;
}
error("Unexpected '" + ch + "'");
},
switch (ch) {
case 't':
next('t');
next('r');
next('u');
next('e');
return true;
case 'f':
next('f');
next('a');
next('l');
next('s');
next('e');
return false;
case 'n':
next('n');
next('u');
next('l');
next('l');
return null;
}
error("Unexpected '" + ch + "'");
};
value, // Place holder for the value function.
var value; // Place holder for the value function.
array = function () {
var array = function () {
// Parse an array value.
var array = [];
var array = [];
if (ch === '[') {
next('[');
if (ch === '[') {
next('[');
white();
if (ch === ']') {
next(']');
return array; // empty array
}
while (ch) {
array.push(value());
white();
if (ch === ']') {
next(']');
return array; // empty array
}
while (ch) {
array.push(value());
white();
if (ch === ']') {
next(']');
return array;
}
next(',');
white();
return array;
}
next(',');
white();
}
error("Bad array");
},
}
error("Bad array");
};
object = function () {
var object = function () {
// Parse an object value.
var key,
object = {};
var key;
var object = {};
if (ch === '{') {
next('{');
if (ch === '{') {
next('{');
white();
if (ch === '}') {
next('}');
return object; // empty object
}
while (ch) {
key = string();
white();
next(':');
if (Object.hasOwnProperty.call(object, key)) {
error('Duplicate key "' + key + '"');
}
object[key] = value();
white();
if (ch === '}') {
next('}');
return object; // empty object
}
while (ch) {
key = string();
white();
next(':');
if (Object.hasOwnProperty.call(object, key)) {
error('Duplicate key "' + key + '"');
}
object[key] = value();
white();
if (ch === '}') {
next('}');
return object;
}
next(',');
white();
return object;
}
next(',');
white();
}
error("Bad object");
};
}
error("Bad object");
};
value = function () {
@ -305,8 +305,8 @@ var json_parse = (function () {
case '-':
return number();
default:
return ch >= '0' && ch <= '9'
? number()
return (ch >= '0' && ch <= '9')
? number()
: word();
}
};
@ -332,9 +332,11 @@ var json_parse = (function () {
// in an empty key. If there is not a reviver function, we simply return the
// result.
return typeof reviver === 'function'
return (typeof reviver === 'function')
? (function walk(holder, key) {
var k, v, value = holder[key];
var k;
var v;
var value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {