语法子集及解析思路:
当中 %xhh 表示以 16 进制表示的字符,/ 是多选一,* 是零或多个,( ) 用于分组。
上面的子集意思是 json文本是由空白 值 空白组成,空白是空格符/制表符/换行符/回车符的一种,值是null/false/true的一种,每一种有对应的字面值。
解析思路
由于 JSON 语法特别简单,只需检测下一个字符,便可以知道它是哪种类型的值,然后调用相关的分析函数。对于完整的 JSON 语法,跳过空白后,只需检测当前字符:
n ➔ null
t ➔ true
f ➔ false
这三个类型思路都是将json文本和字面值相比较,相同就设置类型并返回成功标识,不相同返回错误消息。
实现过程中遇到的问题;
test_parse_xx函数前两行设置了v.type值,再去解析不是一定会返回错误吗?
lept_parse()函数会根据输入的json文本重新设置v的类型。
这个解析器完成什么工作?
把读入的json文本解析成数据结构(包括类型,值,文本…),供程序调用
lept_context 作用?
为了减少解析函数之间传递多个参数,我们把这些数据都放进一个 lept_context 结构体。刚开始不理解,写到解析数组的时候就知道了,解析过程中除了json文本,还要传递栈,栈容量和栈顶位置。
练习:
修正关于 LEPT_PARSE_ROOT_NOT_SINGULAR 的单元测试,若 json 在一个值之后,空白之后还有其它字符,则要返回 LEPT_PARSE_ROOT_NOT_SINGULAR。
在处理完json一个关键字以后还要继续去掉空格,检查后面是否还有元素,这个操作应该加在哪里?
刚开始我是想加在lept_parse_value的switch语句里,因为case语句会按顺序执行,在检测完n,f,t以后检查空字符时去除空字符看后面还有没有元素,如果有,就返回 LEPT_PARSE_ROOT_NOT_SINGULAR,没有就返LEPT_PARSE_INVALID_VALUE,但是忘记了switch语句如果有return,break等显示打断流的语句,后面的case是不会执行的,也就是说去掉空格函数也许不会执行。后面想到在lept_parse中得到返回结果后再去空格检测是否还有其他字符。
总结
封装是真的强,头文件是写供外部调用的接口,如果这个接口要调用的函数外部不需要知道,就不在头文件中声明,而是定义成了static函数,放在cpp文件中
学习了TDD开发,先写测试,运行测试失败,再写实现代码,再运行测试,失败就修改实现代码,成功就可以想想重构。 方便新添加代码的时候保证原代码的正确性。