状态机学习(六)解析JSON2

来自 

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

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

 

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

这里写的有点随便 怎么方便怎么来

浮点的判断也是使用的函数 判断范围比json的要宽松些 仅作为练手练习使用

 1 #ifndef LEPTJSON_H
 2 #define LEPTJSON_H
 3 #include <string>
 4 
 5 
 6 
 7 
 8 enum DefParseResult{
 9     DEF_PARSE_OK = 0,
10     DEF_PARSE_EXPECT_VALUE,
11     DEF_PARSE_INVALID_VALUE,
12     DEF_PARSE_ROOT_NOT_SINGULAR
13 };
14 
15 enum DefType {
16     DEF_NONE = 0,
17     DEF_NULL,
18     DEF_FALSE,
19     DEF_TRUE,
20     DEF_NUMBER,
21     DEF_STRING,
22     DEF_ARRAY,
23     DEF_OBJECT
24 };
25 
26 struct MyJsonStruct {
27     double d;
28     std::string jsonStr;
29     size_t index;
30     DefType type;
31 };
32 
33 
34 DefParseResult DefParse(MyJsonStruct& jstruct);
35 MyJsonStruct InitJsonStruct(char* str);
36 DefType GetJsonStructType( MyJsonStruct& jstruct);
37 double GetJsonStructNumber( MyJsonStruct& jstruct);
38 
39 #endif // LEPTJSON_H
View Code
  1 #include "leptjson.h"
  2 #include <string>
  3 #include <exception>
  4 
  5 void DefParseWhiteSpace(MyJsonStruct& jstruct)
  6 {
  7     if(jstruct.index == jstruct.jsonStr.size()-1){
  8         jstruct.index++;
  9         return;
 10     }
 11     while( isspace(jstruct.jsonStr[jstruct.index])){
 12         jstruct.index++;
 13     }
 14 }
 15 
 16 DefParseResult DefParseType(MyJsonStruct& jstruct){
 17     if( jstruct.jsonStr[jstruct.index] == 'n'){
 18         if(jstruct.jsonStr[jstruct.index+1] == 'u'  &&
 19             jstruct.jsonStr[jstruct.index+2] == 'l' &&
 20             jstruct.jsonStr[jstruct.index+3] == 'l')
 21         {
 22             jstruct.index += 4;
 23             jstruct.type = DEF_NULL;
 24             return DEF_PARSE_OK;
 25         }
 26 
 27     }else if(jstruct.jsonStr[jstruct.index] == 't'){
 28         if(jstruct.jsonStr[jstruct.index+1] == 'r'  &&
 29             jstruct.jsonStr[jstruct.index+2] == 'u' &&
 30             jstruct.jsonStr[jstruct.index+3] == 'e')
 31         {
 32             jstruct.index += 4;
 33             jstruct.type = DEF_TRUE;
 34             return DEF_PARSE_OK;
 35         }
 36     }else if(jstruct.jsonStr[jstruct.index] == 'f'){
 37         if(jstruct.jsonStr[jstruct.index+1] == 'a'  &&
 38             jstruct.jsonStr[jstruct.index+2] == 'l' &&
 39             jstruct.jsonStr[jstruct.index+3] == 's' &&
 40             jstruct.jsonStr[jstruct.index+4] == 'e')
 41         {
 42             jstruct.index += 5;
 43             jstruct.type = DEF_FALSE;
 44             return DEF_PARSE_OK;
 45         }
 46     }
 47 
 48     return DEF_PARSE_INVALID_VALUE;
 49 }
 50 
 51 #define ISDIGIT(ch)         ((ch) >= '0' && (ch) <= '9')
 52 #define ISDIGIT1TO9(ch)     ((ch) >= '1' && (ch) <= '9')
 53 DefParseResult DefParseNumber(MyJsonStruct& jstruct)
 54 {
 55     try{
 56         jstruct.d = std::stod(jstruct.jsonStr);
 57         jstruct.index = jstruct.jsonStr.find_first_of("\t\r\n ");
 58     }catch(std::exception& e){
 59         return DEF_PARSE_INVALID_VALUE;
 60     }
 61 
 62     jstruct.type = DEF_NUMBER;
 63 
 64     return DEF_PARSE_OK;
 65 }
 66 
 67 DefParseResult DefParseValue(MyJsonStruct& jstruct)
 68 {
 69     if(jstruct.index > jstruct.jsonStr.size())
 70         return DEF_PARSE_INVALID_VALUE;
 71     switch(jstruct.jsonStr[jstruct.index]){
 72     case 'n':
 73     case 'f':
 74     case 't':
 75         return DefParseType(jstruct);
 76     default:
 77         return DefParseNumber(jstruct);
 78     }
 79 }
 80 
 81 MyJsonStruct InitJsonStruct(char* str){
 82     if(str == nullptr){
 83         return MyJsonStruct{0.0,NULL,NULL,DEF_NONE};
 84     }
 85 
 86     return MyJsonStruct{0.0,str,0,DEF_NONE};
 87 }
 88 
 89 DefType GetJsonStructType( MyJsonStruct& jstruct){
 90    return  jstruct.type;
 91 }
 92 
 93 double GetJsonStructNumber( MyJsonStruct& jstruct)
 94 {
 95     return  jstruct.d;
 96 }
 97 
 98 DefParseResult DefParse(MyJsonStruct& jstruct)
 99 {
100     DefParseResult ret = DEF_PARSE_INVALID_VALUE;
101     DefParseWhiteSpace(jstruct);
102 
103     ret = DefParseValue(jstruct);
104     if(ret != DEF_PARSE_OK){
105         return ret;
106     }
107 
108     DefParseWhiteSpace(jstruct);
109     if(jstruct.index < jstruct.jsonStr.size()){
110         ret = DEF_PARSE_ROOT_NOT_SINGULAR;
111         jstruct.type = DEF_NONE;
112     }
113 
114     return ret;
115 }
View Code
  1 #include <iostream>
  2 #include "leptjson.h"
  3 
  4 class MyTestClass {
  5     static size_t testCount_;
  6     static size_t testPass_;
  7 public:
  8     template<typename E,typename A>
  9     bool ExceptEqual(E e, A a)
 10     {
 11         testCount_++;
 12         if (e == a){
 13             testPass_++;
 14             return true;
 15         }
 16         return false;
 17     }
 18 
 19     void PrintResult(){
 20         std::cout << testPass_ << "/" << testCount_ << "\t" << "("<<(testPass_ * 100.0 / testCount_) << "%)" << " passed." << std::endl;
 21     }
 22 };
 23 size_t MyTestClass::testCount_ = 0;
 24 size_t MyTestClass::testPass_ = 0;
 25 
 26 #define ERROR_PRINT(expect,actual)                  \
 27  std::cerr << __FILE__ <<":"<< __LINE__ << "\r\nexpect: " << expect << "  actual: " << actual << std::endl;
 28 
 29 #define EXPECT_EQ(expect, actual)           \
 30 do{                                         \
 31     MyTestClass TEST;                       \
 32     if(!TEST.ExceptEqual(expect, actual)){  \
 33         ERROR_PRINT(expect,actual)          \
 34     }                                       \
 35 }while(0)
 36 
 37 #define PRINT_TEST_RESULT()                 \
 38 do{                                         \
 39     MyTestClass TEST;                       \
 40     TEST.PrintResult();                     \
 41 }while(0)
 42 //=======================================================================
 43 using namespace std;
 44 
 45 static void TestParseNULL(){
 46     MyJsonStruct jsonStruct = InitJsonStruct("null");
 47     EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct));
 48     EXPECT_EQ(DEF_NULL, GetJsonStructType(jsonStruct));
 49 }
 50 
 51 static void TestParseTRUE(){
 52     MyJsonStruct jsonStruct = InitJsonStruct("true");
 53     EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct));
 54     EXPECT_EQ(DEF_TRUE, GetJsonStructType(jsonStruct));
 55 }
 56 
 57 static void TestParseFALSE(){
 58     MyJsonStruct jsonStruct = InitJsonStruct("false");
 59     EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct));
 60     EXPECT_EQ(DEF_FALSE, GetJsonStructType(jsonStruct));
 61 }
 62 
 63 #define TEST_ERROR(error, json)\
 64     do {\
 65         MyJsonStruct jsonStruct = InitJsonStruct(json);\
 66         EXPECT_EQ(error, DefParse(jsonStruct));\
 67         EXPECT_EQ(DEF_NONE, GetJsonStructType(jsonStruct));\
 68     } while(0)
 69 
 70 static void TestParseInvaliValue(){
 71     TEST_ERROR(DEF_PARSE_INVALID_VALUE,"nul");
 72     TEST_ERROR(DEF_PARSE_INVALID_VALUE,"?");
 73 
 74     TEST_ERROR(DEF_PARSE_INVALID_VALUE,"nul");
 75     TEST_ERROR(DEF_PARSE_INVALID_VALUE,"?");
 76 
 77 }
 78 
 79 static void TestParseRootNotSingular(){
 80     MyJsonStruct jsonStruct = InitJsonStruct("null x");
 81     EXPECT_EQ(DEF_PARSE_ROOT_NOT_SINGULAR, DefParse(jsonStruct));
 82     EXPECT_EQ(DEF_NONE, GetJsonStructType(jsonStruct));
 83 }
 84 
 85 
 86 
 87 
 88 #define TEST_NUMBER(expect, json)\
 89     do {\
 90         MyJsonStruct jsonStruct = InitJsonStruct(json);  \
 91         EXPECT_EQ(DEF_PARSE_OK, DefParse(jsonStruct));\
 92         EXPECT_EQ(DEF_NUMBER, GetJsonStructType(jsonStruct));\
 93         EXPECT_EQ(expect, GetJsonStructNumber(jsonStruct));\
 94     } while(0)
 95 
 96 
 97 static void TestParseNumber(){
 98     TEST_NUMBER(0.0, "0");
 99     TEST_NUMBER(0.0, "-0");
100     TEST_NUMBER(0.0, "-0.0");
101     TEST_NUMBER(1.0, "1");
102     TEST_NUMBER(-1.0, "-1");
103     TEST_NUMBER(1.5, "1.5");
104     TEST_NUMBER(-1.5, "-1.5");
105     TEST_NUMBER(3.1416, "3.1416");
106     TEST_NUMBER(1E10, "1E10");
107     TEST_NUMBER(1e10, "1e10");
108     TEST_NUMBER(1E+10, "1E+10");
109     TEST_NUMBER(1E-10, "1E-10");
110     TEST_NUMBER(-1E10, "-1E10");
111     TEST_NUMBER(-1e10, "-1e10");
112     TEST_NUMBER(-1E+10, "-1E+10");
113     TEST_NUMBER(-1E-10, "-1E-10");
114     TEST_NUMBER(1.234E+10, "1.234E+10");
115     TEST_NUMBER(1.234E-10, "1.234E-10");
116 
117 
118     TEST_NUMBER(1.0000000000000002, "1.0000000000000002"); /* the smallest number > 1 */
119     TEST_NUMBER( 2.2250738585072014e-308, "2.2250738585072014e-308");  /* Min normal positive double */
120     TEST_NUMBER(-2.2250738585072014e-308, "-2.2250738585072014e-308");
121     TEST_NUMBER( 1.7976931348623157e+308, "1.7976931348623157e+308");  /* Max double */
122     TEST_NUMBER(-1.7976931348623157e+308, "-1.7976931348623157e+308");
123 }
124 
125 
126 void TestParse()
127 {
128     TestParseNULL();
129     TestParseTRUE();
130     TestParseFALSE();
131     TestParseInvaliValue();
132     TestParseRootNotSingular();
133     TestParseNumber();
134 }
135 
136 
137 
138 
139 int main(int argc, char *argv[])
140 {
141     TestParse();
142     PRINT_TEST_RESULT();
143     return 0;
144 }
View Code

显示结果

 

posted on 2017-07-05 14:58  itdef  阅读(962)  评论(0编辑  收藏  举报

导航