11 #include <nlohmann/detail/exceptions.hpp>
12 #include <nlohmann/detail/input/input_adapters.hpp>
13 #include <nlohmann/detail/input/json_sax.hpp>
14 #include <nlohmann/detail/input/lexer.hpp>
15 #include <nlohmann/detail/macro_scope.hpp>
16 #include <nlohmann/detail/meta/is_sax.hpp>
17 #include <nlohmann/detail/value_t.hpp>
32 template<
typename BasicJsonType>
35 using number_integer_t =
typename BasicJsonType::number_integer_t;
36 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
37 using number_float_t =
typename BasicJsonType::number_float_t;
38 using string_t =
typename BasicJsonType::string_t;
39 using lexer_t = lexer<BasicJsonType>;
59 using parser_callback_t =
60 std::function<bool(
int depth,
parse_event_t event, BasicJsonType& parsed)>;
64 const parser_callback_t cb =
nullptr,
65 const bool allow_exceptions_ =
true)
66 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
82 void parse(
const bool strict, BasicJsonType& result)
87 sax_parse_internal(&sdp);
88 result.assert_invariant();
91 if (strict and (get_token() != token_type::end_of_input))
96 exception_message(token_type::end_of_input,
"value")));
100 if (sdp.is_errored())
108 if (result.is_discarded())
116 sax_parse_internal(&sdp);
117 result.assert_invariant();
120 if (strict and (get_token() != token_type::end_of_input))
125 exception_message(token_type::end_of_input,
"value")));
129 if (sdp.is_errored())
146 return sax_parse(&sax_acceptor, strict);
149 template <
typename SAX>
150 JSON_HEDLEY_NON_NULL(2)
151 bool sax_parse(SAX* sax, const
bool strict = true)
154 const bool result = sax_parse_internal(sax);
157 if (result and strict and (get_token() != token_type::end_of_input))
162 exception_message(token_type::end_of_input,
"value")));
169 template <
typename SAX>
170 JSON_HEDLEY_NON_NULL(2)
171 bool sax_parse_internal(SAX* sax)
175 std::vector<bool> states;
177 bool skip_to_state_evaluation =
false;
181 if (not skip_to_state_evaluation)
186 case token_type::begin_object:
188 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
194 if (get_token() == token_type::end_object)
196 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
204 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
209 exception_message(token_type::value_string,
"object key")));
211 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.
get_string())))
217 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
222 exception_message(token_type::name_separator,
"object separator")));
226 states.push_back(
false);
233 case token_type::begin_array:
235 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
241 if (get_token() == token_type::end_array)
243 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
251 states.push_back(
true);
257 case token_type::value_float:
261 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
265 out_of_range::create(406,
"number overflow parsing '" + m_lexer.
get_token_string() +
"'"));
268 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.
get_string())))
276 case token_type::literal_false:
278 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(
false)))
285 case token_type::literal_null:
287 if (JSON_HEDLEY_UNLIKELY(not sax->null()))
294 case token_type::literal_true:
296 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(
true)))
303 case token_type::value_integer:
312 case token_type::value_string:
314 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.
get_string())))
321 case token_type::value_unsigned:
330 case token_type::parse_error:
336 exception_message(token_type::uninitialized,
"value")));
344 exception_message(token_type::literal_or_value,
"value")));
350 skip_to_state_evaluation =
false;
363 if (get_token() == token_type::value_separator)
371 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
373 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
382 assert(not states.empty());
384 skip_to_state_evaluation =
true;
391 exception_message(token_type::end_array,
"array")));
396 if (get_token() == token_type::value_separator)
399 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
404 exception_message(token_type::value_string,
"object key")));
407 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.
get_string())))
413 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
418 exception_message(token_type::name_separator,
"object separator")));
427 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
429 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
438 assert(not states.empty());
440 skip_to_state_evaluation =
true;
447 exception_message(token_type::end_object,
"object")));
453 token_type get_token()
455 return last_token = m_lexer.scan();
458 std::string exception_message(
const token_type expected,
const std::string& context)
460 std::string error_msg =
"syntax error ";
462 if (not context.empty())
464 error_msg +=
"while parsing " + context +
" ";
469 if (last_token == token_type::parse_error)
479 if (expected != token_type::uninitialized)
489 const parser_callback_t callback =
nullptr;
491 token_type last_token = token_type::uninitialized;
495 const bool allow_exceptions =
true;