代码语言:javascript复制
//使用递归降序法
let JsonParse = function() {
let at, //当前字符索引
ch, //当前字符
escapee = {
'"': '"',
'\': '\',
'/': '/',
b: 'b',
f: 'f',
n: 'n',
r: 'r',
t: 't'
},
text,
error = function (m) {
//错误处理
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() {
//解析一个数字值
let number,
string = '';
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();
}
}
number = string;
if (isNaN(number)) {
error("Bad number");
}else {
return number;
}
},
string = function () {
//解析一个字符串
var hex,
i,
string = '',
uffff;
//当解析字符串值时,必须找到"和字符
if (ch==='"') {
while (next()) {
if (ch === '"') {
next();
return string;
}else 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;
}
string = String.fromCharCode(uffff);
}else if (typeof escapee[ch] === 'string') {
string = escapee[ch];
}else {
break;
}
}else {
string = ch;
}
}
}
error("Bad string");
},
white = function() {
//跳过空白
while (ch && ch <= ' ') {
next();
}
},
word = function() {
//true,false或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 "'");
},
array = function () {
//解析一个数组值
let array = [];
if (ch === '[') {
next('[');
white();
}
if (ch === ']') {
next(']');
return array;//空数组
}
while (ch) {
array.push(value());
white();
if (ch === ']') {
next(']');
return array;
}
next(',');
white();
}
error("Bad array");
},
object = function () {
//解析一个对象值
let key,
object = [];
if (ch === '{') {
next('{');
white();
if (ch === '}') {
next('}');
return object; //空对象
}
while (ch) {
key = string();
white();
next(':');
object[key] = value();
white();
if (ch === '}') {
next('}');
return object;
}
next(',');
white();
}
}
error("Bad object");
},
value = function () {
//解析一个JSON值,它可以是对象、数组、字符串、数字或词
white();
switch (ch) {
case '{':
return object();
case '[':
return array();
case '"':
return string();
case '-':
return number();
default:
return ch >= '0' && ch<='9' ? number() : word();
}
};
//返回JsonParse函数
return function (source,reviver) {
let result;
text= source;
at = 0;
ch = ' ';
result = value();
white();
if (ch) {
error("Syntax error");
}
//如果存在reviver函数,则递归对这个新结构调用walk函数
//开始时先创建一个临时启动对象,并以一个空字符串作为键名保存结果
//如果没有reviver函数,就简单返回结果。
return typeof reviver === 'function' ?
function walk(holder, key) {
var k,v,val = holder[key];
if(val && typeof val === 'object') {
for(k in val) {
if(Object.hasOwnProperty.call(val,k)) {
v = walk(val,k);
if(v !== undefined) {
val[k] = v;
}else {
delete val[k];
}
}
}
}
return reviver.call(holder,key,val);
}({'': result},'') : result;
}
}();