1 2 3 4 5 6 7
| typedef enum { LEPT_NULL, LEPT_FALSE, LEPT_TRUE, LEPT_NUMBER, LEPT_STRING, LEPT_ARRAY, LEPT_OBJECT } lept_type;
|
json数据分为 null,true,false,number,string,array,object这几个类型,用枚举存放
lept_value 存放解析好的json串 lept_type表示解析好的json类型
lept_member 代表json成员
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct lept_value { union { struct { lept_member* m; size_t size; }o; struct { lept_value* e; size_t size; }a; struct { char* s; size_t len; }s; double n; }u; lept_type type; }; struct lept_member { char* k; size_t klen; lept_value v; };
|
lept_context
json代表解析的串
stack代表栈
size 表示栈的大小
top 表示栈顶指针
1 2 3 4 5
| typedef struct { const char *json; char *stack; size_t size, top; } lept_context;
|
json语法
1 2
| JSON-text = ws value ws ws = *(%x20 / %x09 / %x0A / %x0D)
|
在value前后有一些空白字符,需要处理掉
1 2 3 4 5 6
| 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; }
|
lept_parse()
传入json串,将解析好的json数据存在v中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| int lept_parse(lept_value *v, const char *json) { lept_context c; int ret; assert(v != NULL); c.json = json; c.stack = NULL; c.size = c.top = 0; lept_init(v); lept_parse_whitespace(&c); if ((ret = lept_parse_value(&c, v)) == LEPT_PARSE_OK) { lept_parse_whitespace(&c); if (*c.json != '\0') { v->type = LEPT_NULL; ret = LEPT_PARSE_ROOT_NOT_SINGULAR; } } assert(c.top == 0); free(c.stack); return ret; }
|
lept_parse_value()
查看当前json解析位置,是否为以下字符,分别进入相应的解析函数
1 2 3 4 5 6 7 8 9 10 11 12
| static int lept_parse_value(lept_context *c, lept_value *v) { switch (*c->json) { case 't': return lept_parse_literal(c, v, "true", LEPT_TRUE); case 'f': return lept_parse_literal(c, v, "false", LEPT_FALSE); case 'n': return lept_parse_literal(c, v, "null", LEPT_NULL); default: return lept_parse_number(c, v); case '"': return lept_parse_string(c, v); case '[': return lept_parse_array(c, v); case '{': return lept_parse_object(c, v); case '\0': return LEPT_PARSE_EXPECT_VALUE; } }
|
lept_parse_literal() : 查看此时c->json位置是否与literal一样(检查null,true,false)
1 2 3 4 5 6 7 8 9 10
| static int lept_parse_literal(lept_context *c, lept_value *v, const char *literal, lept_type type) { size_t i; EXPECT(c, literal[0]); for (i = 0; literal[i + 1]; i++) if (c->json[i] != literal[i + 1]) return LEPT_PARSE_INVALID_VALUE; c->json += i; v->type = type; return LEPT_PARSE_OK; }
|
lept_parse_number() : 查看此时是否符合number标准
1 2 3 4
| number = [ "-" ] int [ frac ] [ exp ] int = "0" / digit1-9 *digit frac = "." 1*digit exp = ("e" / "E") ["-" / "+"] 1*digit
|

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| static int lept_parse_number(lept_context *c, lept_value *v) { const char *p = c->json; if (*p == '-') p++; if (*p == '0') p++; else { if (!ISDIGIT1TO9(*p)) return LEPT_PARSE_INVALID_VALUE; for (p++; ISDIGIT(*p); p++); } if (*p == '.') { p++; if (!ISDIGIT(*p)) return LEPT_PARSE_INVALID_VALUE; for (p++; ISDIGIT(*p); p++); } if (*p == 'e' || *p == 'E') { p++; if (*p == '+' || *p == '-') p++; if (!ISDIGIT(*p)) return LEPT_PARSE_INVALID_VALUE; for (p++; ISDIGIT(*p); p++); } errno = 0; v->u.n = strtod(c->json, NULL); if (errno == ERANGE && (v->u.n == HUGE_VAL || v->u.n == -HUGE_VAL)) return LEPT_PARSE_NUMBER_TOO_BIG; v->type = LEPT_NUMBER; c->json = p; return LEPT_PARSE_OK; }
|
lept_parse_string_raw() : 将c->json的字符串复制到*str指向的位置上,长度为len
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| static int lept_parse_string_raw(lept_context *c, char **str, size_t *len) { size_t head = c->top; unsigned u, u2; const char *p; EXPECT(c, '\"'); p = c->json; for (;;) { char ch = *p++; switch (ch) { case '\"': *len = c->top - head; *str = lept_context_pop(c, *len); c->json = p; return LEPT_PARSE_OK; case '\\': switch (*p++) { case '\"': PUTC(c, '\"'); break; case '\\': PUTC(c, '\\'); break; case '/': PUTC(c, '/'); break; case 'b': PUTC(c, '\b'); break; case 'f': PUTC(c, '\f'); break; case 'n': PUTC(c, '\n'); break; case 'r': PUTC(c, '\r'); break; case 't': PUTC(c, '\t'); break; case 'u': if (!(p = lept_parse_hex4(p, &u))) STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX); if (u >= 0xD800 && u <= 0xDBFF) { if (*p++ != '\\') STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE); if (*p++ != 'u') STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE); if (!(p = lept_parse_hex4(p, &u2))) STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX); if (u2 < 0xDC00 || u2 > 0xDFFF) STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE); u = (((u - 0xD800) << 10) | (u2 - 0xDC00)) + 0x10000; } lept_encode_utf8(c, u); break; default: STRING_ERROR(LEPT_PARSE_INVALID_STRING_ESCAPE); } break; case '\0': STRING_ERROR(LEPT_PARSE_MISS_QUOTATION_MARK); default: if ((unsigned char)ch < 0x20) STRING_ERROR(LEPT_PARSE_INVALID_STRING_CHAR); PUTC(c, ch); } } }
|