zoukankan      html  css  js  c++  java
  • 状态机学习(三)解析JSON1

    来自 

    从零开始的 JSON 库教程
    从零开始教授如何写一个符合标准的 C 语言 JSON 库
    作者 Milo Yip

    https://zhuanlan.zhihu.com/json-tutorial

    根据第一课教程 自己重新编写 做了一点修改 加深学习印象

    //JsonParse.h
    #pragma once
    #include "JsonStruct.h"
    #include <assert.h>
    
    void DEFParseWhitespace(MyJsonStruct& js)
    {
    	while (js.jsonStr[js.index] == ' ' ||
    		js.jsonStr[js.index] == '\r' ||
    		js.jsonStr[js.index] == '\n') {
    		js.index++;
    	}
    }
    
    DefParseResult DEFParseNull(MyJsonStruct& js)
    {
    	assert(js.jsonStr[js.index] = 'n');
    	if (js.jsonStr[js.index + 1] != 'u' ||
    		js.jsonStr[js.index+2] != 'l' ||
    		js.jsonStr[js.index+3] != 'l') {
    		return DEF_PARSE_INVALID_VALUE;
    	}
    	js.index += 4;
    	js.type = DEF_NULL;
    	return DEF_PARSE_OK;
    }
    
    DefParseResult DEFParseValue(MyJsonStruct& js)
    {
    	switch (js.jsonStr[js.index]){
    	case 'n':return DEFParseNull(js);
    	case '\0':return DEF_PARSE_EXPECT_VALUE;
    	default:return DEF_PARSE_INVALID_VALUE;
    	}
    }
    
    
    DefParseType GetParseType(MyJsonStruct& js)
    {
    	return js.type;
    }
    
    
    void ResetJsonStruct(const char* jsonBuf, MyJsonStruct& js)
    {
    	js.jsonStr = jsonBuf;
    	js.index = 0;
    	js.type = DEF_NONE;
    }
    
    
    MyJsonStruct InitJsonStruct(char* jsonBuf)
    {
    	MyJsonStruct jsonStruct;
    	ResetJsonStruct(jsonBuf, jsonStruct);
    	return jsonStruct;
    }
    
    
    DefParseResult DEFParse(MyJsonStruct& jsonStruct)
    {
    	DefParseResult ret;
    
    	DEFParseWhitespace(jsonStruct);
    
    	if ((ret = DEFParseValue(jsonStruct)) == DEF_PARSE_OK) {
    		DEFParseWhitespace(jsonStruct);
    		if (jsonStruct.index < jsonStruct.jsonStr.size()) {
    			ret = DEF_PARSE_ROOT_NOT_SINGULAR;
    			jsonStruct.type = DEF_NONE;
    		}
    			
    	}
    	return ret;
    }
    

      

    //JsonStruct.h
    #pragma once
    #include <string>
    
    enum DefParseType {
    	DEF_NONE,
    	DEF_NULL,
    	DEF_FALSE,
    	DEF_TRUE,
    	DEF_NUMBER,
    	DEF_STRING,
    	DEF_ARRAY,
    	DEF_OBJECT
    };
    
    struct MyJsonStruct {
    	std::string jsonStr;
    	size_t index;
    	DefParseType type;
    };
    
    enum DefParseResult{
    	DEF_PARSE_OK = 0,
    	DEF_PARSE_EXPECT_VALUE,
    	DEF_PARSE_INVALID_VALUE,
    	DEF_PARSE_ROOT_NOT_SINGULAR
    };
    

      

    //MyTestUnit.h
    #pragma once
    #include <iostream>
    
    
    class MyTestClass {
    	static size_t testCount_;
    	static size_t testPass_;
    public:
    	template<typename E,typename A>
    	bool ExceptEqual(E e, A a)
    	{
    		testCount_++;
    		if (e == a){
    			testPass_++;
    			return true;
    		}
    		return false;
    	}
    
    	void PrintResult(){
    		std::cout << testPass_ << "/" << testCount_ << "\t" << "("<<(testPass_ * 100.0 / testCount_) << "%)" << " passed." << std::endl;
    	}
    };
    size_t MyTestClass::testCount_ = 0;
    size_t MyTestClass::testPass_ = 0;
    
    #define ERROR_PRINT(expect,actual)					\
     std::cerr << __FILE__ <<":"<< __LINE__ << "\r\nexpect: " << expect << "  actual: " << actual << std::endl; 
    
    #define EXCEPT_EQ(expect, actual)			\
    do{											\
    	MyTestClass TEST;						\
    	if(!TEST.ExceptEqual(expect, actual)){	\
    		ERROR_PRINT(expect,actual)			\
    	}										\
    }while(0)
    
    #define PRINT_TEST_RESULT()					\
    do{											\
    	MyTestClass TEST;						\
    	TEST.PrintResult();						\
    }while(0)
    

      

    // MyJson.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "JsonParse.h"
    #include <iostream>
    #include "MyTestUnit.h"    
    
    int main()
    {
    	MyJsonStruct js =InitJsonStruct("null");
    	EXCEPT_EQ(DEF_PARSE_OK, DEFParse(js));
    	EXCEPT_EQ(DEF_NULL, GetParseType(js));
    
    	ResetJsonStruct("", js);
    	EXCEPT_EQ(DEF_PARSE_EXPECT_VALUE, DEFParse(js));
    	EXCEPT_EQ(DEF_NONE, GetParseType(js));
    
    	ResetJsonStruct(" ", js);
    	EXCEPT_EQ(DEF_PARSE_EXPECT_VALUE, DEFParse(js));
    	EXCEPT_EQ(DEF_NONE, GetParseType(js));
    
    
    	ResetJsonStruct("nul", js);
    	EXCEPT_EQ(DEF_PARSE_INVALID_VALUE, DEFParse(js));
    	EXCEPT_EQ(DEF_NONE, GetParseType(js));
    
    	ResetJsonStruct("?", js);
    	EXCEPT_EQ(DEF_PARSE_INVALID_VALUE, DEFParse(js));
    	EXCEPT_EQ(DEF_NONE, GetParseType(js));
    
    	ResetJsonStruct("null x", js);
    	EXCEPT_EQ(DEF_PARSE_ROOT_NOT_SINGULAR, DEFParse(js));
    	EXCEPT_EQ(DEF_NONE, GetParseType(js));
    
    	PRINT_TEST_RESULT();
        return 0;
    }
    

      测试效果

    12/12 (100%) passed.
    请按任意键继续. . .

  • 相关阅读:
    Google Chrome 默认非安全端口列表
    js判断类型的方法
    博客园样式排版自定义
    easyloader.js源代码分析
    JQuery操作cookies
    js获取iframe里面的dom
    封装GetQueryString()方法来获取URL的value值
    js 获取系统时间:年月日 星期 时分秒(动态)
    vue 滚动加载数据
    props 父组件给子组件传递参数
  • 原文地址:https://www.cnblogs.com/itdef/p/6097982.html
Copyright © 2011-2022 走看看