CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

用C++编写一个简易的JSON解析器(1)写一个动态类型-免费源码丞旭猿

JSON是由道格拉斯·克罗克福特构想和设计的一种轻量级资料交换格式。其内容由属性和值所组成,因此也有易于阅读和处理的优势。

JSON一般用于网络上传输数据,比如我这里有一个用户的信息,想要传输过去,我可以给他传这样的一个字符串。

另一段接收到字符串用进行解析即可。这里我展示先我们讲要写的解析器的效果。

可以看到JSON被我们成功的解析了。

JSON的语法很简单,支持以下类型

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在中括号中) []
  • 对象/字典(在大括号中) {} key 和 val 用 : 隔开
  • null

比如123是个数字,是个合理的JSON值,[123]是个数组,也是个合理的JSON值。

{“hello”:”world”} 是个对象/字典,key为”hello” ,val 为”world”。

为了方便我们的解析器的编写,我们先写一个动态类型的变量,可以储存上述的值。这里为了模仿python,我们把对象当成字典,同时去掉null值。

关于动态类型,简单的写法就是在一个类里面,塞几个相关类型的变量,根据记录的类型来判断。判断类型可以用枚举类型,但是我懒。

然后是我们的class,重写相应的构造函数即可。

classVal{public:intINT_VAL;doubleDOU_VAL;stringSTR_VAL;boolBOOL_VAL;inttype;voiddel(){//del用于在更换变量类型的时候清除原来的变量if(type==STR)STR_VAL.clear();}Val(){}~Val(){del();}Val(constint&x){del();INT_VAL=x;type=INT;}Val(constdouble&x){del();DOU_VAL=x;type=DOU;}Val(conststring&x){del();STR_VAL=x;type=STR;}Val(constchar*x){del();type=STR;STR_VAL=string(x);}Val(constbool&x){del();BOOL_VAL=x;type=BOOL;}};

为了我们的输出方便,记得重载输出运算符。

ostream&operator<<(ostream&out,constVal&v){if(v.type==INT)out<<v.INT_VAL;if(v.type==DOU)out<<v.DOU_VAL;if(v.type==STR)out<<"\""<<v.STR_VAL<<"\"";if(v.type==BOOL){if(v.BOOL_VAL)out<<"true";elseout<<"false";}returnout;}

我们来测试一下。

接下来我们添加 数组/列表 类型,众所周知C++11引入了列表初始化,所有我们可以用列表初始化来初始化我们的动态类型。

添加函数

Val(initializer_list<Val>l){del();type=LIST;for(Valx:l)List.push_back(x);}voidadd(Valx){if(type==LIST)List.push_back(x);}

顺便重载下输出。注意我们的格式要尽可能的符合JSON的语法。

if(v.type==LIST){out<<"[";for(inti=0;i<v.List.size();i++){if(i)out<<",";out<<v.List[i];}out<<"]";}

这里我们测试一下。

然后就是字典类型了,因为C++的符号不够,所以不能初始化化字典了qwq。

还有就是我们如果使用map的化,需要重载小于运算符号,比较好的一点是C++里的vector和map都已经重载了小于号。

booloperator<(constVal&a,constVal&b){if(a.type!=b.type)returna.type<b.type;else{if(a.type==INT)returna.INT_VAL<b.INT_VAL;if(a.type==DOU)returna.DOU_VAL<b.DOU_VAL;if(a.type==STR)returna.STR_VAL<b.STR_VAL;if(a.type==LIST)returna.List<b.List;if(a.type==DICT)returna.dict<b.dict;returntrue;}}

这样我们使用字典的时候需要告诉是个字典,这里放上我们的所有的代码。

define INT 0define DOU 1define STR 2define BOOL 3define LIST 4define DICT 5classVal{public:intINT_VAL;doubleDOU_VAL;stringSTR_VAL;boolBOOL_VAL;vector<Val>List;map<Val,Val>dict;inttype;voiddel(){if(type==STR)STR_VAL.clear();if(type==LIST)List.clear();if(type==DICT)dict.clear();}Val(){}~Val(){del();}Val(constint&x){del();INT_VAL=x;type=INT;}Val(constdouble&x){del();DOU_VAL=x;type=DOU;}Val(conststring&x){del();STR_VAL=x;type=STR;}Val(constchar*x){del();type=STR;STR_VAL=string(x);}Val(constbool&x){del();BOOL_VAL=x;type=BOOL;}Val(initializer_list<Val>l){del();type=LIST;for(Valx:l)List.push_back(x);}voidadd(Valx){if(type==LIST)List.push_back(x);}voidput(Valkey,Valval){if(type==DICT)dict[key]=val;}Val&operator[](Vali){if(type==LIST)returnList[i.INT_VAL];elsereturndict[i];}};ostream&operator<<(ostream&out,constVal&v){if(v.type==INT)out<<v.INT_VAL;if(v.type==DOU)out<<v.DOU_VAL;if(v.type==STR)out<<"\""<<v.STR_VAL<<"\"";if(v.type==BOOL){if(v.BOOL_VAL)out<<"true";elseout<<"false";}if(v.type==LIST){out<<"[";for(inti=0;i<v.List.size();i++){if(i)out<<",";out<<v.List[i];}out<<"]";}if(v.type==DICT){out<<"{";for(autoit=v.dict.begin();it!=v.dict.end();it++){if(it!=v.dict.begin())out<<",";out<<it->first<<":"<<it->second;}out<<"}";}returnout;}booloperator<(constVal&a,constVal&b){if(a.type!=b.type)returna.type<b.type;else{if(a.type==INT)returna.INT_VAL<b.INT_VAL;if(a.type==DOU)returna.DOU_VAL<b.DOU_VAL;if(a.type==STR)returna.STR_VAL<b.STR_VAL;if(a.type==LIST)returna.List<b.List;if(a.type==DICT)returna.dict<b.dict;returntrue;}}

再测试一下。

这样我们的动态类型就出来了。非常的简陋啊qwq。但是已经是初具人性了呢。

下一章就直接写出一个JSON的解析器了。带上这个动态类型,代码不超过200行。

用C++编写一个简易的JSON解析器(2)parser 完成

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容