状态机学习(三)解析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.
请按任意键继续. . .

原文地址:https://www.cnblogs.com/itdef/p/6097982.html