找回密码
 立即注册
首页 业界区 业界 如何手写实现 JSON Parser

如何手写实现 JSON Parser

归筠溪 5 天前
JSON.parse 是我们在前端开发中经常会用到API,如果我们要自己实现一个JSON.parse,我们应该怎么实现呢?今天我们就试着手写一个JSON Parser,了解下其内部实现原理。
JSON语法

JSON 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 null 。语法规则如下:

  • 数据使用名/值对表示。
  • 使用大括号({})保存对象,每个名称后面跟着一个 '冒号),名/值对使用 ,(逗号)分割。
1.png


  • 使用方括号([])保存数组,数组值使用 ,(逗号)分割。
2.png


  • JSON值可以是:数字(整数或浮点数)/字符串(在双引号中)/逻辑值(true 或 false)/数组(在方括号中)/对象(在花括号中)/null
3.png

实现Parser

Parser 一般会经过下面几个过程,分为词法分析 、语法分析、转换、代码生成过程。
词法分析

4.png

通过对 JSON 语法的了解,我们可以看到 JSON 中会有一下类型及其特征如下表:
类型基本特征Object"{"  ":" "," "}"Array"[" "," "]"String'"'Number"0" "1" "2" "3" "4" "5" "6" "7" "8" "9"Boolean"true" "false"Null"null"所以根据这些特征,对 JSON 字符串进行遍历操作并与上述特征进行对比可以得到相应的 token。词法分析实现代码如下:
[code]// 词法分析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[this._index]    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[result.keyword])    }  }  isNumber(key) {    return key >= '0' && key
您需要登录后才可以回帖 登录 | 立即注册