zoukankan      html  css  js  c++  java
  • 状态机学习(六)解析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("	
     ");
     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_ << "	" << "("<<(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__ << "
    expect: " << 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

    显示结果

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    (转).NET Compact Framework使用P/Invoke服务
    C#编码好习惯
    有些东西必须时刻放在心上!
    我是这样的人吗?是!!!!!!!!!
    经济学家张五常教大家四招读书的方法 (转)
    #在宏中的某些用法(转)
    牛人太强了,我该怎么努力呀?
    利用增强限制条件来求解问题
    努力呀!即将面临的deadline
    volume visualization reserach时刻记在心的要点
  • 原文地址:https://www.cnblogs.com/itdef/p/7121397.html
Copyright © 2011-2022 走看看