JSON解析器实现
这篇文章从零搭建了一个 C++ JSON 解析器,并进一步扩展到通用对象序列化/反序列化框架。类型模型与核心对象设计先梳理 JSON 的基础类型与复合类型,并映射到 C++ 的 bool/int/double/string/vector/map。通过 JObject + TYPE 标签 + std::variant 统…
代码开源仓库:cpp造轮子项目--实现json解析器JSON格式介绍 JSON(JavaScript Object Notation),是一种序列化的格式,最大的优点在于可读性极强,以及可直接嵌入到js代码中,所以广泛运用于web数据的收发。 JSON格式有以下基本类型: null类型:值为null,表示为空 bool类型:值为true和false number类型:值为int、double(即整数或小数 string类型:形如 "abc" 以及以下复合类型:list类型(也称array类型)["abc",3.2,323,"sdaf"] dict类型(也称object类型){ "id":32, "name":"hhh" } 解析json字符串 整套解析流程如下: 绘图1.png创建JObject类 我们需要把json的类型对应到计算机语言的类型。 由于json的数据在我们看来都是字符串,那么有如下对应关系:"null"对应我们构造的null类型“true","false"对应内部的bool类型即可number类型数据对应int、double类型string类型数据对应string即可list类型对应C++中的vectordict类型对应C++中的map或unordered_map 我们在计算机语言中,需要构造一个对象类型,用于将以上类型全部涵盖。 在C++中我们通过std::variant来进行,还需要一个枚举tag来表示当前对象内存储的数据类型。 当然如果做的更绝的话,可以通过一个void* + 申请堆内存来解决,然后再强转为对应类型来操作。 对应的代码如下:(中间的类方法就暂时省略了 enum TYPE { T_NULL, T_BOOL, T_INT, T_DOUBLE, T_STR, T_LIST, T_DICT }; using null_t = string; using int_t = int32_t; using bool_t = bool; using double_t = double; using str_t = string; using list_t = vector<JObject>; using dict_t = map<string, JObject>; class JObject { public: using value_t = variant<bool_t, int_t, double_t, str_t, list_t, dict_t>; ... private: TYPE m_type; value_t m_value; }; 创建Parser类 我们有了JObject,可以把所有的JSON数据接收起来,现在要做的就是扫描JSON字符串,对其中的数据进行读取处理,然后转化为JObject。 关键代码如下:JObject Parser::parse() { char token = get_next_token(); if (token == 'n') { return parse_null(); } if (token == 't' || token == 'f') { return parse_bool(); } if (token == '-' || std::isdigit(token)) { return parse_number(); } if (token == '\"') { return parse_string(); } if (token == '[') { return parse_list(); } if (token == '{') { return parse_dict(); } throw std::logic_error("unexpected character in parse json"); } 以上就是整个字符串的解析过程,每次通过get_next_token这个方法得到整个字符串的下一个token,根据token决定解析对应的数据类型。get_next_token方法 跳过空白符号,以及跳过注释(标准的JSON格式不支持注释,我这里硬加的,为了vscode的JSON格式配置文件解析char Parser::get_next_token() { while (std::isspace(m_str[m_idx])) m_idx++; if (m_idx >= m_str.size()) throw std::logic_error("unexpected character in parse json"); //如果是注释,记得跳过 skip_comment(); return m_str[m_idx]; } parse_null和parse_bool…
正在初始化 WebAssembly 引擎…
首次编译原生模块可能需要数秒
就绪后,页面交互将以接近原生的速度运行