1 #ifndef STAN_IO_JSON_JSON_PARSER_HPP
2 #define STAN_IO_JSON_JSON_PARSER_HPP
4 #include <boost/lexical_cast.hpp>
21 const unsigned int MIN_HIGH_SURROGATE = 0xD800;
22 const unsigned int MAX_HIGH_SURROGATE = 0xDBFF;
23 const unsigned int MIN_LOW_SURROGATE = 0xDC00;
24 const unsigned int MAX_LOW_SURROGATE = 0xDFFF;
25 const unsigned int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
27 inline bool is_high_surrogate(
unsigned int cp) {
28 return (cp >= MIN_HIGH_SURROGATE && cp <= MAX_HIGH_SURROGATE);
31 inline bool is_low_surrogate(
unsigned int cp) {
32 return (cp >= MIN_LOW_SURROGATE && cp <= MAX_LOW_SURROGATE);
35 inline bool is_whitespace(
char c) {
36 return c ==
' ' || c ==
'\n' || c ==
'\t' || c ==
'\r';
45 template <
typename Handler,
bool Val
idate_UTF_8>
67 json_error json_exception(
const std::string& msg)
const {
69 ss <<
"Error in JSON parsing at"
74 return json_error(ss.str());
79 char c = get_non_ws_char();
82 parse_object_members_end_object();
84 }
else if (c ==
'[') {
87 parse_array_values_end_array();
90 throw json_exception(
"expecting start of object ({) or array ([)");
97 char c = get_non_ws_char();
100 parse_false_literal();
101 }
else if (c ==
'n') {
103 parse_null_literal();
104 }
else if (c ==
't') {
106 parse_true_literal();
107 }
else if (c ==
'"') {
109 h_.string(parse_string_chars_quotation_mark());
110 }
else if (c ==
'{' || c ==
'[') {
114 }
else if (c ==
'-' ||
115 (c >=
'0' && c <=
'9') ) {
119 throw json_exception(
"illegal value, expecting object, array, "
120 "number, string, or literal true/false/null");
124 void parse_number() {
125 bool is_positive =
true;
127 std::stringstream ss;
128 char c = get_non_ws_char();
138 if (c < '0' || c >
'9')
139 throw json_exception(
"expecting int part of number");
143 bool leading_zero = (c ==
'0');
145 if (leading_zero && (c ==
'0'))
146 throw json_exception(
"zero padded numbers not allowed");
147 while (c >=
'0' && c <=
'9') {
153 bool is_integer =
true;
158 if (c < '0' || c >
'9')
159 throw json_exception(
"expected digit after decimal");
162 while (c >=
'0' && c <=
'9') {
169 if (c ==
'e' || c ==
'E') {
174 if (c ==
'+' || c ==
'-') {
179 if (c < '0' || c >
'9')
180 throw json_exception(
"expected digit after e/E");
181 while (c >=
'0' && c <=
'9') {
193 n = boost::lexical_cast<
unsigned long>(ss.str());
194 }
catch (
const boost::bad_lexical_cast & ) {
195 throw json_exception(
"number exceeds integer range");
198 h_.number_unsigned_long(n);
203 n = boost::lexical_cast<
unsigned long>(ss.str());
204 }
catch (
const boost::bad_lexical_cast & ) {
205 throw json_exception(
"number exceeds integer range");
213 std::string ss_str = ss.str();
214 x = boost::lexical_cast<
double>(ss_str);
217 }
catch (
const boost::bad_lexical_cast & ) {
218 throw json_exception(
"number exceeds double range");
225 std::string parse_string_chars_quotation_mark() {
231 }
else if (c ==
'\\') {
233 if (c ==
'\\' || c ==
'/' || c ==
'"') {
235 }
else if (c ==
'b') {
237 }
else if (c ==
'f') {
239 }
else if (c ==
'n') {
241 }
else if (c ==
'r') {
243 }
else if (c ==
't') {
245 }
else if (c ==
'u') {
246 get_escaped_unicode(s);
248 throw json_exception(
"expecting legal escape");
251 }
else if (c > 0 && c < 0x20) {
252 throw json_exception(
"found control character, char values less "
253 "than U+0020 must be \\u escaped");
259 void parse_true_literal() {
264 void parse_false_literal() {
269 void parse_null_literal() {
274 void get_escaped_unicode(std::stringstream& s) {
275 unsigned int codepoint = get_int_as_hex_chars();
276 if (!(is_high_surrogate(codepoint) || is_low_surrogate(codepoint))) {
277 putCodepoint(s, codepoint);
278 }
else if (!is_high_surrogate(codepoint)) {
279 throw json_exception(
"illegal unicode values, found "
280 "low-surrogate, missing high-surrogate");
284 throw json_exception(
"illegal unicode values, found "
285 "high-surrogate, expecting low-surrogate");
288 throw json_exception(
"illegal unicode values, found "
289 "high-surrogate, expecting low-surrogate");
290 unsigned int codepoint2 = get_int_as_hex_chars();
291 unsigned int supplemental
292 = ((codepoint - MIN_HIGH_SURROGATE) << 10)
293 + (codepoint2 - MIN_LOW_SURROGATE)
294 + MIN_SUPPLEMENTARY_CODE_POINT;
295 putCodepoint(s, supplemental);
299 unsigned int get_int_as_hex_chars() {
302 for (
int i = 0; i < 4; i++) {
304 if (!((c >=
'a' && c<=
'f')
305 || (c >=
'A' && c<=
'F')
306 || (c >=
'0' && c<=
'9')))
307 throw json_exception(
"illegal unicode code point");
315 void putCodepoint(std::stringstream& s,
unsigned int codepoint) {
316 if (codepoint <= 0x7f) {
318 }
else if (codepoint <= 0x7ff) {
319 s.put(0xc0 | ((codepoint >> 6) & 0x1f));
320 s.put(0x80 | (codepoint & 0x3f));
321 }
else if (codepoint <= 0xffff) {
322 s.put(0xe0 | ((codepoint >> 12) & 0x0f));
323 s.put(0x80 | ((codepoint >> 6) & 0x3f));
324 s.put(0x80 | (codepoint & 0x3f));
326 s.put(0xf0 | ((codepoint >> 18) & 0x07));
327 s.put(0x80 | ((codepoint >> 12) & 0x3f));
328 s.put(0x80 | ((codepoint >> 6) & 0x3f));
329 s.put(0x80 | (codepoint & 0x3f));
333 void get_chars(
const std::string& s) {
334 for (
size_t i = 0; i < s.size(); ++i) {
337 throw json_exception(
"expecting rest of literal: "
342 void parse_array_values_end_array() {
343 char c = get_non_ws_char();
344 if (c ==
']')
return;
348 char c = get_non_ws_char();
349 if (c ==
']')
return;
351 throw json_exception(
"in array, expecting ] or ,");
353 c = get_non_ws_char();
355 throw json_exception(
"in array, expecting value");
360 void parse_object_members_end_object() {
361 char c = get_non_ws_char();
362 if (c ==
'}')
return;
366 throw json_exception(
"expecting member key"
367 " or end of object marker (})");
368 std::string key = parse_string_chars_quotation_mark();
371 c = get_non_ws_char();
373 throw json_exception(
"expecting key-value separator :");
378 c = get_non_ws_char();
382 throw json_exception(
"expecting end of object } or separator ,");
383 c = get_non_ws_char();
390 throw json_exception(
"unexpected end of stream");
400 char get_non_ws_char() {
403 if (is_whitespace(c))
continue;
432 template <
bool Val
idate_UTF_8,
typename Handler>
435 parser<Handler, Validate_UTF_8>(handler, in).
parse();
447 template <
typename Handler>
450 parse<false>(in, handler);
Probability, optimization and sampling library.
void validate_zero_buf(const B &buf)
Throw an bad-cast exception if the specified buffer contains a digit other than 0 before an e or E...
void parse(std::istream &in, Handler &handler)
Parse the JSON text represented by the specified input stream, sending events to the specified handle...