如何手写实现 JSON Parser
JSON.parse 是我们在前端开发中经常会用到API,如果我们要自己实现一个JSON.parse,我们应该怎么实现呢?今天我们就试着手写一个JSON Parser,了解下其内部实现原理。JSON语法
JSON 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 null 。语法规则如下:
[*]数据使用名/值对表示。
[*]使用大括号({})保存对象,每个名称后面跟着一个 ':'(冒号),名/值对使用 ,(逗号)分割。
[*]使用方括号([])保存数组,数组值使用 ,(逗号)分割。
[*]JSON值可以是:数字(整数或浮点数)/字符串(在双引号中)/逻辑值(true 或 false)/数组(在方括号中)/对象(在花括号中)/null
实现Parser
Parser 一般会经过下面几个过程,分为词法分析 、语法分析、转换、代码生成过程。
词法分析
通过对 JSON 语法的了解,我们可以看到 JSON 中会有一下类型及其特征如下表:
类型基本特征Object"{"":" "," "}"Array"[" "," "]"String'"'Number"0" "1" "2" "3" "4" "5" "6" "7" "8" "9"Boolean"true" "false"Null"null"所以根据这些特征,对 JSON 字符串进行遍历操作并与上述特征进行对比可以得到相应的 token。词法分析实现代码如下:
// 词法分析const TokenTypes = {OPEN_OBJECT: '{',CLOSE_OBJECT: '}',OPEN_ARRAY: '[',CLOSE_ARRAY: ']',STRING: 'string',NUMBER: 'number',TRUE: 'true',FALSE: 'false',NULL: 'null',COLON: ':',COMMA: ',',}class Lexer {constructor(json) { this._json = json this._index = 0 this._tokenList = []}createToken(type, value) { return { type, value: value || type }}getToken() { while (this._index < this._json.length) { const token = this.bigbang() this._tokenList.push(token) } return this._tokenList}bigbang() { const key = this._json switch (key) { case ' ': this._index++ return this.bigbang() case '{': this._index++ return this.createToken(TokenTypes.OPEN_OBJECT) case '}': this._index++ return this.createToken(TokenTypes.CLOSE_OBJECT) case '[': this._index++ return this.createToken(TokenTypes.OPEN_ARRAY) case ']': this._index++ return this.createToken(TokenTypes.CLOSE_ARRAY) case ':': this._index++ return this.createToken(TokenTypes.COLON) case ',': this._index++ return this.createToken(TokenTypes.COMMA) case '"': return this.parseString() } // number if (this.isNumber(key)) { return this.parseNumber() } // true false null const result = this.parseKeyword(key) if (result.isKeyword) { return this.createToken(TokenTypes) }}isNumber(key) { return key >= '0' && key
页:
[1]