diff --git a/my_json_tutorial01/leptjson.cpp b/my_json_tutorial01/leptjson.cpp new file mode 100644 index 00000000..43fd88c1 --- /dev/null +++ b/my_json_tutorial01/leptjson.cpp @@ -0,0 +1,67 @@ +#include +#include"leptjson.h" +#include +struct lept_context{ + const char*json; +}; +#define EXPECT(c,ch) do{assert(*c.json == (ch));c.json++;}while(0) +static void lept_parse_whitespace(lept_context& c){ + const char *p = c.json; + while(*p ==' ' || *p == '\t' || *p == '\n' || *p == '\r') + p++; + c.json = p; +} + +static int lept_parse_null(lept_context &c, lept_value& v){ + EXPECT(c, 'n'); + if(c.json[0] != 'u' || c.json[1] != 'l' || c.json[2] != 'l') + return LEPT_PARSE_INVALID_VALUE; + c.json += 3; + v.type = lept_type::LNULL; + return LEPT_PARSE_OK; + +} +static int lept_parse_true(lept_context &c, lept_value &v){ + EXPECT(c,'t'); + if(c.json[0] != 'r' || c.json[1]!= 'u' || c.json[2] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c.json+=3; + v.type = lept_type::TRUE; + return LEPT_PARSE_OK; +} +static int lept_parse_false(lept_context&c, lept_value &v){ + EXPECT(c,'f'); + if(c.json[0] != 'a' || c.json[1] != 'l' || c.json[2] != 's' || c.json[3] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c.json += 4; + v.type = lept_type::FALSE; + return LEPT_PARSE_OK; +} +static int lept_parse_value(lept_context&c, lept_value &v){ + switch(*c.json){ + case 'n': return lept_parse_null(c,v); + case 't': return lept_parse_true(c,v); + case 'f': return lept_parse_false(c, v); + case '\0': return LEPT_PARSE_EXPECT_VALUE; + default: return LEPT_PARSE_INVALID_VALUE; + } +} +int lept_parse(lept_value &v, const char* json){ + lept_context c; + + assert( &v !=NULL); + int ret; + c.json = json; + v.type = lept_type::LNULL; + lept_parse_whitespace(c); + if((ret = lept_parse_value(c, v)) == LEPT_PARSE_OK){ + lept_parse_whitespace(c); + if(*c.json != '\0') + ret = LEPT_PARSE_ROOT_NOT_SINGULAR; + } + return ret; +} +lept_type lept_get_type(const lept_value& v){ + assert(& v!= NULL); + return v.type; +} diff --git a/my_json_tutorial01/leptjson.h b/my_json_tutorial01/leptjson.h new file mode 100644 index 00000000..3dc51b9f --- /dev/null +++ b/my_json_tutorial01/leptjson.h @@ -0,0 +1,29 @@ +#ifndef leptjson_h__ +#define leptjson_h__ + +//namespace lept_json { + enum class lept_type{ + LNULL, + FALSE,TRUE, + NUMBER, + STRING, + ARRAY, + OBJECT + }; +//using namespace lept_json; +enum{ + LEPT_PARSE_OK, + LEPT_PARSE_EXPECT_VALUE, + LEPT_PARSE_INVALID_VALUE, + LEPT_PARSE_ROOT_NOT_SINGULAR +}; + +struct lept_value{ + lept_type type; + +}; + +int lept_parse(lept_value &v, const char* json); +lept_type lept_get_type(const lept_value& v); + +#endif /* leptjson_h__ */ diff --git a/my_json_tutorial01/test.cpp b/my_json_tutorial01/test.cpp new file mode 100644 index 00000000..a2c54265 --- /dev/null +++ b/my_json_tutorial01/test.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include "leptjson.h" + +static int main_ret = 0; +static int test_count = 0; +static int test_pass = 0; + +#define EXPECT_EQ_BASE(equality, expect, actual, format)\ + do{\ + test_count++;\ + if(equality)\ + test_pass++;\ + else{\ + fprintf(stderr, "%s:%d: expect: " format "actual: " format"\n", __FILE__, __LINE__, expect,actual);\ + main_ret = 1;\ + }\ + }while(0) + +#define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d"); + +static void test_parse_null(){ + lept_value v; + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,"null")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); +} + +static void test_parse_true(){ + lept_value v; + v.type = lept_type::LNULL; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,"true")); + EXPECT_EQ_INT(lept_type::TRUE, lept_get_type(v)); +} + +static void test_parse_false(){ + lept_value v; + v.type = lept_type::LNULL; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,"false")); + EXPECT_EQ_INT(lept_type::FALSE, lept_get_type(v)); +} + +static void test_parse_expect_value(){ + lept_value v; + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_EXPECT_VALUE, lept_parse(v,"")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); + + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_EXPECT_VALUE, lept_parse(v, " ")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); + +} + +static void test_parse_invalid_value(){ + lept_value v; + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_INVALID_VALUE, lept_parse(v, "nul")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); + + v.type =lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_INVALID_VALUE, lept_parse(v, "?")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); +} +static void test_parse_root_not_singular(){ + lept_value v; + v.type =lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_ROOT_NOT_SINGULAR, lept_parse(v," null x")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); + +} + + + +static void test_parse(){ + test_parse_null(); + test_parse_true(); + test_parse_false(); + test_parse_expect_value(); + test_parse_invalid_value(); + test_parse_root_not_singular(); +} +int main(){ + + test_parse(); + printf("%d/%d (%3.2f%%) passed\n",test_pass, test_count,test_pass*100.0 / test_count); + return main_ret; +}