来源

《JavaScript语言精粹(修订版)》

代码

 <!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script>
var json_parse = function () {
var
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) {
if (c && c !== ch) {
error(`Expected ${c} instead of ${ch}`);
}
ch = text.charAt(at);
at += 1;
return ch;
},
// 解析一个数字值
number = function () {
var 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();
// unicode码
if (ch === 'u') {
uffff = 0;
for (i = 0; i < 4; i++) {
hex = parseInt(next(), 16);
if (!isFinite(hex)) {
break;
}
ufff = ufff * 16 + hex;
}
string += String.fromCharCode(ufff)
}
else if (typeof escapee[ch] === 'string') { // 转义字符
string += escapee[ch]
} else {
break;
}
} else {
string += ch;
}
}
}
error('Bac string');
},
// 跳过空白
white = function () {
while (ch && ch <= ' ') {
next();
}
},
// 解析 true、false、null
word = function () {
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 true;
case 'n':
next('n');
next('u');
next('l');
next('l');
return true;
}
error(`Unexpected ${ch}`)
},
// 解析一个数组值
array = function () {
var 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 () {
var 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');
},
// 解析一个JSON值。它可以是对象、数组、字符串、数字、一个词。
value = function () {
white();
switch (ch) {
case '{':
return object();
case '[':
return array();
case '"':
return string();
case '-':
return number;
default:
return ch >= '0' && ch <= '9' ? number() : word();
}
};
// 返回json_parse函数
return function (source, reviver) {
var result;
text = source;
at = 0;
ch = ' ';
result = value();
white();
if (ch) { // 多余的非空白字符
error('Syntax error');
}
return typeof reviver === 'function' ? function walk(holder, key) {
var k, v, value = holder[key];
if (value && typeof value === 'object') {
// 递归处理对象的属性
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k]
}
}
}
}
// 处理对象
return reviver.call(holder, key, value);
}({ '': result }, '') : result;
}
}();
// \n是一个字符,\\n是两个字符
const str = '{"name":"饮料","price":2.5,"cool":true,"description":["雪碧","可乐"],"escapseSlash":"\\/","escapeN":"\\n"}';
console.log(json_parse(str, (key, val) => val))
</script>
</body> </html>

运行结果

一个JSON解析器的更多相关文章

  1. 一起写一个JSON解析器

    [本篇博文会介绍JSON解析的原理与实现,并一步一步写出来一个简单但实用的JSON解析器,项目地址:SimpleJSON.希望通过这篇博文,能让我们以后与JSON打交道时更加得心应手.由于个人水平有限 ...

  2. 如何编写一个JSON解析器

    编写一个JSON解析器实际上就是一个函数,它的输入是一个表示JSON的字符串,输出是结构化的对应到语言本身的数据结构. 和XML相比,JSON本身结构非常简单,并且仅有几种数据类型,以Java为例,对 ...

  3. 几百行代码实现一个 JSON 解析器

    前言 之前在写 gscript时我就在想有没有利用编译原理实现一个更实际工具?毕竟真写一个语言的难度不低,并且也很难真的应用起来. 一次无意间看到有人提起 JSON 解析器,这类工具充斥着我们的日常开 ...

  4. 自己动手实现一个简单的JSON解析器

    1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 ...

  5. 用c#自己实现一个简单的JSON解析器

    一.JSON格式介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着很多优点.例如易读性更好,占用空间更 ...

  6. 面试题|手写JSON解析器

    这周的 Cassidoo 的每周简讯有这么一个面试题:: 写一个函数,这个函数接收一个正确的 JSON 字符串并将其转化为一个对象(或字典,映射等,这取决于你选择的语言).示例输入: fakePars ...

  7. 手写Json解析器学习心得

    一. 介绍 一周前,老同学阿立给我转了一篇知乎回答,答主说检验一门语言是否掌握的标准是实现一个Json解析器,网易游戏过去的Python入门培训作业之一就是五天时间实现一个Json解析器. 知乎回答- ...

  8. 一个简单的json解析器

    实现一个简单地json解析器. 两部分组成,词法分析.语法分析 词法分析 package com.mahuan.json; import java.util.LinkedList; import ja ...

  9. 这个东西,写C++插件的可以用到。 RapidJSON —— C++ 快速 JSON 解析器和生成器

    点这里 原文: RapidJSON —— C++ 快速 JSON 解析器和生成器 时间 2015-04-05 07:33:33  开源中国新闻原文  http://www.oschina.net/p/ ...

随机推荐

  1. 生成不带版本的jar包 不影响deploy

    1 How to build maven project without version? 工程pom中增加 <project> ... <build> ... <fin ...

  2. 遗传算法的C语言实现(二)

    上一次我们使用遗传算法求解了一个较为复杂的多元非线性函数的极值问题,也基本了解了遗传算法的实现基本步骤.这一次,我再以经典的TSP问题为例,更加深入地说明遗传算法中选择.交叉.变异等核心步骤的实现.而 ...

  3. Struts 2 实现Action的几种方式_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 Action用于处理用户的请求,因此也被称为业务控制器.每个Action类就是一个工作单元,Struts 2框架负责将用 ...

  4. 对vue虚拟dom的研究

    Vue.js通过编译将template 模板转换成渲染函数(render ) ,执行渲染函数就可以得到一个虚拟节点树 在对 Model 进行操作的时候,会触发对应 Dep 中的 Watcher 对象. ...

  5. LeetCode - LRU怎么将书架上的旧书完美淘汰呢

    你有一排书架,有空时会拿些书来看,经常性会买些新书.无奈书架容量有限,当新买的书放不下时,需要一个策略将旧书淘汰. LRU(最近最少使用)缓存淘汰机制正合适. 1)新买的书放在最左侧. 2)最近常看的 ...

  6. .NET面试题系列(二十)XX

    遍历树.实现造成锁的代码.在线音乐网站 抽象工厂和工厂的区别 简单工厂 : 用来生产同一等级结构中的任意产品.(对于增加新的产品,无能为力) 工厂方法 :用来生产同一等级结构中的固定产品.(支持增加任 ...

  7. ASP.NET实现文件断点续传

    IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...

  8. win7如何设置以管理员身份运行

    一.对所有程序以管理员身份运行 1.右键单击桌面“计算机”,选择“管理” 2.在页面左侧,依此打开“计算机管理(本地)→ 系统工具→本地用户和组→用户”,在右侧找到“Administrator”,双击 ...

  9. Debian Buster升级后找不到声卡

    昨天将Debian从Stretch升级到了新版巴斯光年(Buster).仍旧是先将source.list中的stretch替换为buster,再执行apt-get的update.upgrade.dis ...

  10. Scrapy终端(Scrapy shell)

    1.介绍文档:http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/shell.html# 2.终端的启用方式:scrapy shell url u ...