来源

《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. django笔记二之数据库

    django笔记二之数据库 [同步数据库之前的操作] yum install MySQL-python.x86_64 -y 2)开启数据库服务并创建表 创建数据库设置 为utf8: create da ...

  2. java基本类型和包装类型的区别

    Java的类型分为两部分,一个是基本类型(primitive),如int.double等八种基本数据类型: 另一个是引用类型(reference type),如String.List等.而每一个基本类 ...

  3. zabbix 内存溢出

    tail -f /var/log/zabbix/zabbix_server_log ::165110.914 ================================ ::165110.914 ...

  4. centos7部署nagios(二)

    一.Nagios简介 分类: 监控 undefined Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系 ...

  5. mysql5.7.26做主从复制配置

    一.首先两台服务器安装好mysql数据库环境 参照linux rpm方式安装mysql5.1 https://www.cnblogs.com/sky-cheng/p/10564604.html 二.主 ...

  6. Codeforces1238F. The Maximum Subtree(树形dp)

    题目链接:传送门 思路: 题意说用线段的相交作为边,来构造树,所以不存在大于等于3个的线段两两相交,否则会构成环.因而构造出的树中,每个点最多只会与2个度大于1的节点相邻. 不妨把1设为树根,用deg ...

  7. SQLServer Transaction Isolation Level

    基本用法 -- Syntax for SQL Server and Azure SQL Database SET TRANSACTION ISOLATION LEVEL { READ UNCOMMIT ...

  8. 如何连接虚拟的OneNote打印机

    include <Windows.h> #include <iostream> int main() { HANDLE handle = CreateFile(L"O ...

  9. @ResponseStatus注解作用

    @ResponseStatus注解有两种用法,一种是加载自定义异常类上,一种是加在目标方法中 这里我们说一下加在目标方法上的这种情况,注解中有两个参数,value属性设置异常的状态码,reaseon是 ...

  10. mysql 8.0.16 单主 mgr搭建

    mysql 8.0.16 单主 mgr搭建 环境介绍: 192.168.142.142 db142192.168.142.143 db143192.168.142.145 db145 1.安装依赖包 ...