62 using number_integer_t =
typename BasicJsonType::number_integer_t;
63 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
64 using number_float_t =
typename BasicJsonType::number_float_t;
65 using string_t =
typename BasicJsonType::string_t;
67 using token_type =
typename lexer_t::token_type;
71 explicit parser(InputAdapterType&& adapter,
72 parser_callback_t<BasicJsonType> cb =
nullptr,
73 const bool allow_exceptions_ =
true,
74 const bool ignore_comments =
false,
75 const bool ignore_trailing_commas_ =
false)
76 : callback(std::move(cb))
77 , m_lexer(std::move(adapter), ignore_comments)
78 , allow_exceptions(allow_exceptions_)
79 , ignore_trailing_commas(ignore_trailing_commas_)
100 sax_parse_internal(&sdp);
103 if (
strict && (get_token() != token_type::end_of_input))
105 sdp.parse_error(m_lexer.get_position(),
106 m_lexer.get_token_string(),
108 exception_message(token_type::end_of_input,
"value"),
nullptr));
112 if (sdp.is_errored())
120 if (result.is_discarded())
128 sax_parse_internal(&sdp);
131 if (
strict && (get_token() != token_type::end_of_input))
133 sdp.parse_error(m_lexer.get_position(),
134 m_lexer.get_token_string(),
135 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input,
"value"),
nullptr));
139 if (sdp.is_errored())
146 result.assert_invariant();
158 return sax_parse(&sax_acceptor,
strict);
161 template<
typename SAX>
162 JSON_HEDLEY_NON_NULL(2)
163 bool sax_parse(SAX* sax, const
bool strict = true)
166 const bool result = sax_parse_internal(sax);
169 if (result &&
strict && (get_token() != token_type::end_of_input))
180 template<
typename SAX>
181 JSON_HEDLEY_NON_NULL(2)
182 bool sax_parse_internal(SAX* sax)
186 std::vector<bool> states;
188 bool skip_to_state_evaluation =
false;
192 if (!skip_to_state_evaluation)
197 case token_type::begin_object:
199 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
205 if (get_token() == token_type::end_object)
207 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
215 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
217 return sax->parse_error(m_lexer.get_position(),
218 m_lexer.get_token_string(),
219 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string,
"object key"),
nullptr));
221 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
227 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
229 return sax->parse_error(m_lexer.get_position(),
230 m_lexer.get_token_string(),
231 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator,
"object separator"),
nullptr));
235 states.push_back(
false);
242 case token_type::begin_array:
244 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
250 if (get_token() == token_type::end_array)
252 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
260 states.push_back(
true);
266 case token_type::value_float:
268 const auto res = m_lexer.get_number_float();
270 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
272 return sax->parse_error(m_lexer.get_position(),
273 m_lexer.get_token_string(),
274 out_of_range::create(406, concat(
"number overflow parsing '", m_lexer.get_token_string(),
'\''),
nullptr));
277 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
285 case token_type::literal_false:
287 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(
false)))
294 case token_type::literal_null:
296 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
303 case token_type::literal_true:
305 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(
true)))
312 case token_type::value_integer:
314 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
321 case token_type::value_string:
323 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
330 case token_type::value_unsigned:
332 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
339 case token_type::parse_error:
342 return sax->parse_error(m_lexer.get_position(),
343 m_lexer.get_token_string(),
344 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized,
"value"),
nullptr));
346 case token_type::end_of_input:
348 if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
350 return sax->parse_error(m_lexer.get_position(),
351 m_lexer.get_token_string(),
353 "attempting to parse an empty input; check that your input string or stream contains the expected JSON",
nullptr));
356 return sax->parse_error(m_lexer.get_position(),
357 m_lexer.get_token_string(),
358 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value,
"value"),
nullptr));
360 case token_type::uninitialized:
361 case token_type::end_array:
362 case token_type::end_object:
363 case token_type::name_separator:
364 case token_type::value_separator:
365 case token_type::literal_or_value:
368 return sax->parse_error(m_lexer.get_position(),
369 m_lexer.get_token_string(),
370 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value,
"value"),
nullptr));
376 skip_to_state_evaluation =
false;
390 if (get_token() == token_type::value_separator)
396 if (!(ignore_trailing_commas && last_token == token_type::end_array))
403 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
405 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
414 JSON_ASSERT(!states.empty());
416 skip_to_state_evaluation =
true;
420 return sax->parse_error(m_lexer.get_position(),
421 m_lexer.get_token_string(),
422 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array,
"array"),
nullptr));
429 if (get_token() == token_type::value_separator)
434 if (!(ignore_trailing_commas && last_token == token_type::end_object))
437 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
439 return sax->parse_error(m_lexer.get_position(),
440 m_lexer.get_token_string(),
441 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string,
"object key"),
nullptr));
444 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
450 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
452 return sax->parse_error(m_lexer.get_position(),
453 m_lexer.get_token_string(),
454 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator,
"object separator"),
nullptr));
464 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
466 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
475 JSON_ASSERT(!states.empty());
477 skip_to_state_evaluation =
true;
481 return sax->parse_error(m_lexer.get_position(),
482 m_lexer.get_token_string(),
483 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object,
"object"),
nullptr));
488 token_type get_token()
490 return last_token = m_lexer.scan();
493 std::string exception_message(
const token_type expected,
const std::string& context)
495 std::string error_msg =
"syntax error ";
497 if (!context.empty())
499 error_msg += concat(
"while parsing ", context,
' ');
504 if (last_token == token_type::parse_error)
506 error_msg += concat(m_lexer.get_error_message(),
"; last read: '",
507 m_lexer.get_token_string(),
'\'');
514 if (expected != token_type::uninitialized)
524 const parser_callback_t<BasicJsonType> callback =
nullptr;
526 token_type last_token = token_type::uninitialized;
530 const bool allow_exceptions =
true;
532 const bool ignore_trailing_commas =
false;