|
1 | 1 | #include "leptjson.h" |
2 | 2 | #include <cassert> /* assert() */ |
3 | | -#include <stdexcept> /* NULL */ |
4 | | -#include <string> |
| 3 | +#include <cctype> /* NULL */ |
| 4 | +#include <bitset> |
5 | 5 |
|
6 | 6 | namespace lept{ |
| 7 | + struct Context{ |
| 8 | + const char* json; |
| 9 | + }; |
7 | 10 |
|
8 | | - // 解析上下文 |
9 | | - class Context{ |
10 | | - public: |
11 | | - explicit Context(const std::string& json):json_(json),pos_(0){} |
| 11 | +#define EXPECT(c,ch) do {assert(*c.json==(ch));c.json++;}while(0) |
12 | 12 |
|
13 | | - //获取当前字符 |
14 | | - char current()const{ |
15 | | - return pos_<json_.size()?json_[pos_]:'\0'; |
16 | | - } |
| 13 | + static void parse_whitespace(Context& c){ |
| 14 | + const char* p = c.json; |
| 15 | + while(*p ==' '||*p=='\t'||*p=='\n'||*p=='\r') |
| 16 | + ++p; |
| 17 | + c.json=p; |
| 18 | + } |
17 | 19 |
|
18 | | - //移动到下一个字符 |
19 | | - void advance(){ |
20 | | - if(pos_<json_.size())++pos_; |
| 20 | + static ParseResult parse_true(Context& c, Value& v){ |
| 21 | + EXPECT(c,'t'); |
| 22 | + if(c.json[0]!='r'||c.json[1]!='u'||c.json[2]!='e'){ |
| 23 | + return ParseResult::PARSE_INVALID_VALUE; |
21 | 24 | } |
| 25 | + c.json+=3; |
| 26 | + v.type=Type::TRUE; |
| 27 | + return ParseResult::PARSE_OK; |
| 28 | + } |
22 | 29 |
|
23 | | - //验证当前字符是否符合预期 |
24 | | - void expect(char ch){ |
25 | | - if(current()!=ch){ |
26 | | - throw std::runtime_error("unexpected character"); |
27 | | - } |
28 | | - advance(); |
| 30 | + static ParseResult parse_false(Context& c, Value& v){ |
| 31 | + EXPECT(c, 'f'); |
| 32 | + if(c.json[0]!='a'||c.json[1]!='l'||c.json[2]!='s'||c.json[3]!='e'){ |
| 33 | + return ParseResult::PARSE_INVALID_VALUE; |
29 | 34 | } |
| 35 | + c.json+=4; |
| 36 | + v.type=Type::FALSE; |
| 37 | + return ParseResult::PARSE_OK; |
| 38 | + } |
30 | 39 |
|
31 | | - //跳过空白字符 |
32 | | - void skip_whitespace(){ |
33 | | - while(current()!=' '||current()!='\t'||current()!='\n'||current()!='\r'){ |
34 | | - advance(); |
35 | | - } |
| 40 | + static ParseResult parse_null(Context& c, Value& v){ |
| 41 | + EXPECT(c,'n'); |
| 42 | + if(c.json[0]!='u'||c.json[1]!='l'||c.json[2]!='l'){ |
| 43 | + return ParseResult::PARSE_INVALID_VALUE; |
36 | 44 | } |
| 45 | + c.json+=3; |
| 46 | + v.type=Type::NULL_; |
| 47 | + return ParseResult::PARSE_OK; |
| 48 | + } |
37 | 49 |
|
38 | | - //查看当前解析位置之后的字符 |
39 | | - char peek(size_t offset=0)const{ |
40 | | - size_t index = pos_ + offset; |
41 | | - return index<json_.size()?json_[index]:'\0'; |
| 50 | + static ParseResult parse_value(Context& c, Value& v){ |
| 51 | + switch (*c.json) { |
| 52 | + case 't': return parse_true(c,v); |
| 53 | + case 'f': return parse_false(c,v); |
| 54 | + case 'n': return parse_null(c,v); |
| 55 | + case '\0': return ParseResult::PARSE_EXPECT_VALUE; |
| 56 | + default: return ParseResult::PARSE_INVALID_VALUE; |
42 | 57 | } |
43 | | - private: |
44 | | - std::string json_; //JSON字符串 |
45 | | - size_t pos_;//当前解析位置 |
| 58 | + } |
46 | 59 |
|
47 | | - }; |
48 | 60 |
|
49 | | - //解析null值 |
50 | | - int parse_null(Context& c,Value* v){ |
51 | | - c.expect('n'); |
52 | | - if(c.peek(0)!='u'||c.peek(1)!='l'||c.peek(2)!='l'){ |
53 | | - return ParseError::ParseInvalidValue; |
54 | | - } |
55 | | - c.advance();c.advance();c.advance(); |
56 | | - v->type=Type::Null; |
57 | | - return ParseError::ParseOk; |
| 61 | + static int lept_parse_number(lept_context* c, lept_value* v) { |
| 62 | + char* end; |
| 63 | + /* \TODO validate number */ |
| 64 | + v->n = strtod(c->json, &end); |
| 65 | + if (c->json == end) |
| 66 | + return LEPT_PARSE_INVALID_VALUE; |
| 67 | + c->json = end; |
| 68 | + v->type = LEPT_NUMBER; |
| 69 | + return LEPT_PARSE_OK; |
| 70 | + } |
| 71 | + static ParseResult parse_number(Context& c,Value& v){ |
| 72 | + std::bitset<8> binary() |
58 | 73 | } |
59 | 74 |
|
60 | | - //解析值 |
61 | | - int parse_value(Context& c,Value *v){ |
62 | | - switch(c.current()){ |
63 | | - case 'n':return parse_null(c,v);//如果当前字符为'n',尝试解析为null |
64 | | - case '\0':return ParseError::ParseExpectValue; |
65 | | - default: return ParseError::ParseInvalidValue; |
| 75 | + ParseResult parse(Value& v, const std::string& json){ |
| 76 | + Context c; |
| 77 | + c.json=json.c_str(); |
| 78 | + v.type = Type::NULL_; |
| 79 | + parse_whitespace(c); |
| 80 | + auto result = parse_value(c,v); |
| 81 | + if(result==ParseResult::PARSE_OK){ |
| 82 | + parse_whitespace(c); |
| 83 | + if(*c.json!='\0'){ |
| 84 | + result = ParseResult::PARSE_ROOT_NOT_SINGULAR; |
| 85 | + } |
66 | 86 | } |
| 87 | + return result; |
67 | 88 | } |
68 | 89 |
|
69 | | - //主解析函数 |
70 | | - int type_parse(Value* v,const std::string& json){ |
71 | | - assert(v!= nullptr); |
72 | | - Context c(json); |
73 | | - v->type=Type::Null; |
74 | | - c.skip_whitespace(); |
75 | | - return parse_value(c,v); |
| 90 | + Type get_type(const Value& v){ |
| 91 | + return v.type; |
76 | 92 | } |
77 | | - |
78 | | - //获取类型 |
79 | | - Type get_type(const Value* v){ |
80 | | - assert(v!= nullptr); |
81 | | - return v->type; |
| 93 | + double get_number(const Value& v){ |
| 94 | + return v.n; |
82 | 95 | } |
83 | 96 | } |
84 | 97 |
|
85 | 98 |
|
86 | | - |
87 | | - |
88 | | - |
|
0 commit comments