1 #include <msp/stringcodec/utf8.h>
4 #include "jsonparser.h"
11 JsonParser::JsonParser(Input &i, const string &s):
15 Statement JsonParser::parse()
17 if(toplevel_state==STATE_END)
20 bool was_init = (toplevel_state==STATE_INIT);
21 Token token = parse_token();
22 if(toplevel_state==STATE_INIT)
25 toplevel_state = STATE_ARRAY;
26 else if(token.str=="{")
27 toplevel_state = STATE_OBJECT;
30 // TODO Standalone simple values; does anyone use them?
31 toplevel_state = STATE_END;
32 throw syntax_error(token.str);
35 token = parse_token();
38 if((toplevel_state==STATE_ARRAY && token.str=="]") || (toplevel_state==STATE_OBJECT && token.str=="}"))
40 toplevel_state = STATE_END;
46 throw syntax_error(token.str);
48 token = parse_token();
51 return parse_statement(&token, toplevel_state, string());
54 Statement JsonParser::parse_statement(const Token *t, State outer_state, const string &outer_kw)
70 ParseState state = INIT;
72 if(outer_state==STATE_ARRAY)
74 result.keyword = outer_kw+"[]";
87 token = parse_token();
93 result.line = in.get_line_number();
98 if(token.type!=Token::STRING)
99 throw syntax_error(token.str);
101 result.keyword = token.str;
104 else if((state==ARRAY_INIT || state==ARRAY_ELEMENT) && token.str=="]")
106 else if((state==ARRAY_INIT || state==ARRAY))
108 Statement ss = parse_statement(&token, STATE_ARRAY, result.keyword);
109 result.sub.push_back(ss);
110 state = ARRAY_ELEMENT;
112 else if(state==ARRAY_ELEMENT && token.str==",")
114 else if((state==OBJECT_INIT || state==OBJECT_MEMBER) && token.str=="}")
116 else if((state==OBJECT_INIT || state==OBJECT))
118 Statement ss = parse_statement(&token, STATE_OBJECT, result.keyword);
119 result.sub.push_back(ss);
120 state = OBJECT_MEMBER;
122 else if(state==OBJECT_MEMBER && token.str==",")
124 else if(state==NAME && token.str==":")
126 else if(state==VALUE)
130 else if(token.str=="{")
132 else if(token.type!=Token::SPECIAL)
134 result.append_from_token(token);
138 throw syntax_error(token.str);
141 throw syntax_error(token.str);
147 Token JsonParser::parse_token()
159 return Token(Token::SPECIAL, "");
177 static Token::Type token_type[]=
193 ParseState state = INIT;
200 int next = in.peek();
213 else if(c=='{' || c=='}' || c=='[' || c==']' || c==':' || c==',')
214 return Token(Token::SPECIAL, string(1, c));
220 throw parse_error(buf);
229 throw parse_error(buf);
235 else if(c=='e' || c=='E')
236 state = FLOATEXPINIT;
238 throw parse_error(buf);
243 state = FLOATEXPINIT;
245 throw parse_error(buf);
250 state = FLOATEXPSIGN;
254 throw parse_error(buf);
261 throw parse_error(buf);
266 throw parse_error(buf);
271 state = STRING_ESCAPE;
282 throw parse_error(buf);
286 throw parse_error(buf);
289 throw logic_error("bad parser state");
292 if(is_delimiter(next) && state>=ACCEPT)
294 if(state==STRING_END)
295 return Token(Token::STRING, unescape(buf.substr(1, buf.size()-2)));
297 return Token(token_type[state], buf);
302 bool JsonParser::is_delimiter(int c)
304 return (isspace(c) || c=='{' || c=='}' || c=='[' || c==']' || c==':' || c==',');
307 string JsonParser::unescape(const string &str)
310 StringCodec::Utf8::Decoder dec;
311 StringCodec::Utf8::Encoder enc;
314 for(auto i=str.begin(); i!=str.end(); )
316 StringCodec::unichar c = dec.decode_char(str, i);
321 enc.encode_char('\"', result);
323 enc.encode_char('\\', result);
325 enc.encode_char('/', result);
327 enc.encode_char('\b', result);
329 enc.encode_char('\f', result);
331 enc.encode_char('\n', result);
333 enc.encode_char('\r', result);
335 enc.encode_char('\t', result);
339 for(unsigned n=0; n<4; ++n)
342 throw invalid_argument("JsonParser::unescape");
344 c = dec.decode_char(str, i);
349 else if(c>='a' && c<='f')
351 else if(c>='A' && c<='F')
354 throw invalid_argument("JsonParser::unescape");
356 code = (code<<4)+digit;
359 enc.encode_char(code, result);
362 throw invalid_argument("JsonParser::unescape");
369 enc.encode_char(c, result);
375 } // namespace DataFile