Skip to content

leptjson.cpp中,lept_shrink_object函数有问题 #241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b7e05fb
just a test
coderhare Sep 18, 2021
a63569c
just a test
coderhare Sep 18, 2021
84c9213
test
coderhare Nov 23, 2021
7f021fe
chapter1: finished
coderhare Nov 23, 2021
2b12e9f
chapter1: finished
coderhare Nov 23, 2021
f167da6
tutorial2 : (1) Refactor
coderhare Nov 23, 2021
f2ffbbb
tutorial2 : (1) Refactor
coderhare Nov 23, 2021
9d98ef2
tutorial2 : (1) Refactor
coderhare Nov 23, 2021
d06739d
tutorial2 : (1) Refactor
coderhare Nov 23, 2021
0a095df
tutorial2 : ALL finished
coderhare Nov 23, 2021
132133d
tutorial2 : ALL finished
coderhare Nov 24, 2021
c635f71
tutorial3 : ALL finished
coderhare Nov 24, 2021
9e2fe72
tutorial3 : ALL finished
coderhare Nov 24, 2021
ae0b741
tutorial3 : ALL finished.
coderhare Nov 24, 2021
b4ea2c4
tutorial4: I have my design, but considering the quality and I use th…
coderhare Nov 26, 2021
7e544bb
add tutorial4总结.md
coderhare Nov 26, 2021
97b8034
tutorial5 数组解析了一部分,需要转到Linux环境下继续实验
coderhare Nov 28, 2021
6a43f53
tutorial5 数组解析了一部分,需要转到Linux环境下继续实验
coderhare Nov 30, 2021
8cc2518
tutorial5 数组解析了一部分,需要转到Linux环境下继续实验
coderhare Nov 30, 2021
6b1027a
tutorial5 数组解析了一部分,需要转到Linux环境下继续实验
coderhare Nov 30, 2021
a32bc26
tutorial5 数组解析了一部分,需要转到Linux环境下继续实验
coderhare Nov 30, 2021
9ce8a74
tutorial5 数组解析了一部分,需要转到Linux环境下继续实验
coderhare Nov 30, 2021
1d85f99
update
coderhare Dec 7, 2021
2b36d87
update tutorial06总结.md
coderhare Dec 7, 2021
7221ff2
update tutorial06总结.md
coderhare Dec 7, 2021
0ab7efa
update tutorial08总结.md
coderhare Dec 9, 2021
fbeb1bf
update tutorial08总结.md
coderhare Dec 9, 2021
0eb9278
update tutorial08总结.md
coderhare Dec 9, 2021
25102a7
Update tutorial08总结.md
coderhare Dec 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 53 additions & 7 deletions tutorial01/leptjson.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <stdlib.h> /* NULL */

#define EXPECT(c, ch) do { assert(*c->json == (ch)); c->json++; } while(0)

typedef struct {
const char* json;
}lept_context;
Expand All @@ -15,23 +14,70 @@ static void lept_parse_whitespace(lept_context* c) {
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;
//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;
// lept_parse_whitespace(c); //跳过空格,然后看是否不为结束位置
// if(c->json[0] != '\0'){
// return LEPT_PARSE_ROOT_NOT_SINGULAR;
// }
// v->type = LEPT_NULL;
// 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_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_FALSE;
// return LEPT_PARSE_OK;
//}

static int lept_parse_literal(lept_context * c, lept_value * v, char prefix){
c->json++;
switch(prefix){
case 'f': if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e')
return LEPT_PARSE_INVALID_VALUE; break;
case 't': if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e')
return LEPT_PARSE_INVALID_VALUE; break;
case 'n': if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l')
return LEPT_PARSE_INVALID_VALUE;
break;
}
c->json += 3;
v->type = LEPT_NULL;
if(prefix == 'f') c->json++;
switch (prefix) {
case 'f': v->type = LEPT_FALSE; break;
case 't': v->type = LEPT_TRUE; break;
case 'n': v->type = LEPT_NULL; lept_parse_whitespace(c);
if(*c->json != '\0') return LEPT_PARSE_ROOT_NOT_SINGULAR;break;
}
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 'n': return lept_parse_literal(c, v, 'n');
case '\0': return LEPT_PARSE_EXPECT_VALUE;
case 't': return lept_parse_literal(c, v, 't');
case 'f': return lept_parse_literal(c, v, 'f');
default: return LEPT_PARSE_INVALID_VALUE;
}
}



int lept_parse(lept_value* v, const char* json) {
lept_context c;
assert(v != NULL);
Expand Down
19 changes: 18 additions & 1 deletion tutorial01/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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++;\
Expand All @@ -17,7 +18,7 @@ static int test_pass = 0;
main_ret = 1;\
}\
} while(0)

//测试函数宏
#define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d")

static void test_parse_null() {
Expand Down Expand Up @@ -57,11 +58,27 @@ static void test_parse_root_not_singular() {
EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v));
}

static void test_parse_false(){
lept_value v;
v.type = LEPT_TRUE;
EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "false"));
EXPECT_EQ_INT(LEPT_FALSE, lept_get_type(&v));
}

static void test_parse_true(){
lept_value v;
v.type = LEPT_FALSE;
EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "true"));
EXPECT_EQ_INT(LEPT_TRUE, lept_get_type(&v));
}

static void test_parse() {
test_parse_null();
test_parse_expect_value();
test_parse_invalid_value();
test_parse_root_not_singular();
test_parse_true();
test_parse_false();
}

int main() {
Expand Down
47 changes: 24 additions & 23 deletions tutorial01_answer/leptjson.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,41 @@ static void lept_parse_whitespace(lept_context* c) {
c->json = p;
}

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_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_FALSE;
static int lept_parse_literal(lept_context * c, lept_value * v, char prefix){
c->json++;
switch(prefix){
case 'f': if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e')
return LEPT_PARSE_INVALID_VALUE;
case 't': if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e')
return LEPT_PARSE_INVALID_VALUE;
case 'n': if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l')
return LEPT_PARSE_INVALID_VALUE;
}
c->json += 3;
if(prefix == 'f') c->json++;
switch (prefix) {
case 'f': v->type = LEPT_FALSE;
case 't': v->type = LEPT_TRUE;
case 'n': v->type = LEPT_NULL;
}
return LEPT_PARSE_OK;
}

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')
static int lept_parse_number(lept_context * c, lept_value * v){
if(*c->json == '+') {
return LEPT_PARSE_INVALID_VALUE;
c->json += 3;
v->type = LEPT_NULL;
}
return LEPT_PARSE_OK;
}

static int lept_parse_value(lept_context* c, lept_value* v) {
switch (*c->json) {
case 't': return lept_parse_true(c, v);
case 'f': return lept_parse_false(c, v);
case 'n': return lept_parse_null(c, v);
case 't': return lept_parse_literal(c, v, 't');
case 'f': return lept_parse_literal(c, v, 'f');
case 'n': return lept_parse_literal(c, v, 'n');
case '\0': return LEPT_PARSE_EXPECT_VALUE;
default: return LEPT_PARSE_INVALID_VALUE;
default: return lept_parse_number(c, v); //for numbers
}
}

Expand Down
72 changes: 45 additions & 27 deletions tutorial02/leptjson.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#include "leptjson.h"
#include <assert.h> /* assert() */
#include <stdlib.h> /* NULL, strtod() */
#include <errno.h>
#include <string.h>
#include <math.h>

#define EXPECT(c, ch) do { assert(*c->json == (ch)); c->json++; } while(0)
#define ISDIGIT0(ch) ((ch) >= '0' && (ch) <= '9')
#define ISDIGIT1(ch) ((ch) >= '1' && (ch) <= '9')

typedef struct {
const char* json;
Expand All @@ -15,51 +20,64 @@ static void lept_parse_whitespace(lept_context* c) {
c->json = p;
}

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_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_FALSE;
return LEPT_PARSE_OK;
}

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;
static int lept_parse_literal(lept_context * c, lept_value * v, char prefix){
c->json++;
switch(prefix){
case 'f': if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e')
return LEPT_PARSE_INVALID_VALUE; break;
case 't': if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e')
return LEPT_PARSE_INVALID_VALUE; break;
case 'n': if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l')
return LEPT_PARSE_INVALID_VALUE; break;
}
c->json += 3;
v->type = LEPT_NULL;
if(prefix == 'f') c->json++;
switch (prefix) {
case 'f': v->type = LEPT_FALSE; break;
case 't': v->type = LEPT_TRUE; break;
case 'n': v->type = LEPT_NULL; lept_parse_whitespace(c);
if(*c->json != '\0') return LEPT_PARSE_ROOT_NOT_SINGULAR;break;
}
return LEPT_PARSE_OK;
}

static int lept_parse_number(lept_context* c, lept_value* v) {
char* end;
/* \TODO validate number */
//errno是记录系统中存在错误的变量,只有当库函数出错的时候才会出现,设置为其他值代表不同的错误
errno = 0;
v->n = strtod(c->json, &end);
//范围过大并且INF, inf这些宏在C语言里头是合法的,但是在JSON里头是INVALID的,所以解析结果会不一样
if(errno == ERANGE && (v->n == HUGE_VAL || v->n == -HUGE_VAL)) return LEPT_PARSE_NUMBER_TOO_BIG;
if (c->json == end)
return LEPT_PARSE_INVALID_VALUE;
//开头的非法字符
//the grammer is number = [ "-" ] int [ frac ] [ exp ]
if(*c->json == '-') c->json++;
if(!ISDIGIT0(*c->json)) return LEPT_PARSE_INVALID_VALUE;
//0 end with other numbers
if(*c->json == '0' && (c->json[1] != '\0' && c->json[1] != 'e' && c->json[1]
!= 'E' && c->json[1] != '.')) return LEPT_PARSE_ROOT_NOT_SINGULAR;
while(ISDIGIT1(*c->json)) c->json++;
//1.234E+10 case
if(*c->json == '.') {
c->json++;
if(*c->json == '\0') return LEPT_PARSE_INVALID_VALUE;
}
while(ISDIGIT0(*c->json)) c->json++;
c->json = end;
v->type = LEPT_NUMBER;
return LEPT_PARSE_OK;
}

static int lept_parse_value(lept_context* c, lept_value* v) {
switch (*c->json) {
case 't': return lept_parse_true(c, v);
case 'f': return lept_parse_false(c, v);
case 'n': return lept_parse_null(c, v);
default: return lept_parse_number(c, v);
case 't': return lept_parse_literal(c, v, 't');
case 'f': return lept_parse_literal(c, v, 'f');
case 'n': return lept_parse_literal(c, v, 'n');
case '\0': return LEPT_PARSE_EXPECT_VALUE;
default: return lept_parse_number(c, v);

}
}

Expand Down
17 changes: 14 additions & 3 deletions tutorial02/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ 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++;\
Expand Down Expand Up @@ -70,6 +72,15 @@ static void test_parse_number() {
TEST_NUMBER(1.234E+10, "1.234E+10");
TEST_NUMBER(1.234E-10, "1.234E-10");
TEST_NUMBER(0.0, "1e-10000"); /* must underflow */
TEST_NUMBER(1.0000000000000002, "1.0000000000000002"); /* the smallest number > 1 */
TEST_NUMBER( 4.9406564584124654e-324, "4.9406564584124654e-324"); /* minimum denormal */
TEST_NUMBER(-4.9406564584124654e-324, "-4.9406564584124654e-324");
TEST_NUMBER( 2.2250738585072009e-308, "2.2250738585072009e-308"); /* Max subnormal double */
TEST_NUMBER(-2.2250738585072009e-308, "-2.2250738585072009e-308");
TEST_NUMBER( 2.2250738585072014e-308, "2.2250738585072014e-308"); /* Min normal positive double */
TEST_NUMBER(-2.2250738585072014e-308, "-2.2250738585072014e-308");
TEST_NUMBER( 1.7976931348623157e+308, "1.7976931348623157e+308"); /* Max double */
TEST_NUMBER(-1.7976931348623157e+308, "-1.7976931348623157e+308");
}

#define TEST_ERROR(error, json)\
Expand All @@ -89,7 +100,7 @@ static void test_parse_invalid_value() {
TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "nul");
TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "?");

#if 0
#if 1
/* invalid number */
TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+0");
TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+1");
Expand All @@ -105,7 +116,7 @@ static void test_parse_invalid_value() {
static void test_parse_root_not_singular() {
TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "null x");

#if 0
#if 1
/* invalid number */
TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0123"); /* after zero should be '.' , 'E' , 'e' or nothing */
TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0x0");
Expand All @@ -114,7 +125,7 @@ static void test_parse_root_not_singular() {
}

static void test_parse_number_too_big() {
#if 0
#if 1
TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "1e309");
TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "-1e309");
#endif
Expand Down
Loading