10 #include <nlohmann/detail/exceptions.hpp> 11 #include <nlohmann/detail/macro_scope.hpp> 12 #include <nlohmann/detail/input/input_adapters.hpp> 13 #include <nlohmann/detail/input/lexer.hpp> 14 #include <nlohmann/detail/value_t.hpp> 29 template<
typename BasicJsonType>
32 using number_integer_t =
typename BasicJsonType::number_integer_t;
33 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
34 using number_float_t =
typename BasicJsonType::number_float_t;
55 using parser_callback_t =
56 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
60 const parser_callback_t cb =
nullptr,
61 const bool allow_exceptions_ =
true)
62 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
75 void parse(
const bool strict, BasicJsonType& result)
80 parse_internal(
true, result);
81 result.assert_invariant();
87 expect(token_type::end_of_input);
99 if (result.is_discarded())
116 if (not accept_internal())
122 return not strict or (get_token() == token_type::end_of_input);
132 void parse_internal(
bool keep, BasicJsonType& result)
138 if (not result.is_discarded())
140 result.m_value.destroy(result.m_type);
146 case token_type::begin_object:
155 if (not callback or keep)
167 if (last_token == token_type::end_object)
171 result.m_value.destroy(result.m_type);
183 if (not expect(token_type::value_string))
187 key = m_lexer.move_string();
189 bool keep_tag =
false;
194 BasicJsonType k(key);
205 if (not expect(token_type::name_separator))
212 value.m_value.destroy(value.m_type);
214 parse_internal(keep, value);
216 if (JSON_UNLIKELY(errored))
221 if (keep and keep_tag and not value.is_discarded())
223 result.m_value.object->emplace(std::move(key), std::move(value));
228 if (last_token == token_type::value_separator)
235 if (not expect(token_type::end_object))
244 result.m_value.destroy(result.m_type);
250 case token_type::begin_array:
259 if (not callback or keep)
271 if (last_token == token_type::end_array)
275 result.m_value.destroy(result.m_type);
286 value.m_value.destroy(value.m_type);
288 parse_internal(keep, value);
290 if (JSON_UNLIKELY(errored))
295 if (keep and not value.is_discarded())
297 result.m_value.array->push_back(std::move(value));
302 if (last_token == token_type::value_separator)
309 if (not expect(token_type::end_array))
318 result.m_value.destroy(result.m_type);
324 case token_type::literal_null:
330 case token_type::value_string:
333 result.m_value = m_lexer.move_string();
337 case token_type::literal_true:
340 result.m_value =
true;
344 case token_type::literal_false:
347 result.m_value =
false;
351 case token_type::value_unsigned:
354 result.m_value = m_lexer.get_number_unsigned();
358 case token_type::value_integer:
361 result.m_value = m_lexer.get_number_integer();
365 case token_type::value_float:
368 result.m_value = m_lexer.get_number_float();
371 if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
373 if (allow_exceptions)
375 JSON_THROW(out_of_range::create(406,
"number overflow parsing '" +
376 m_lexer.get_token_string() +
"'"));
378 expect(token_type::uninitialized);
383 case token_type::parse_error:
386 if (not expect(token_type::uninitialized))
396 if (not expect(token_type::literal_or_value))
420 bool accept_internal()
424 case token_type::begin_object:
430 if (last_token == token_type::end_object)
439 if (last_token != token_type::value_string)
446 if (last_token != token_type::name_separator)
453 if (not accept_internal())
460 if (last_token == token_type::value_separator)
467 return (last_token == token_type::end_object);
471 case token_type::begin_array:
477 if (last_token == token_type::end_array)
486 if (not accept_internal())
493 if (last_token == token_type::value_separator)
500 return (last_token == token_type::end_array);
504 case token_type::value_float:
507 return std::isfinite(m_lexer.get_number_float());
510 case token_type::literal_false:
511 case token_type::literal_null:
512 case token_type::literal_true:
513 case token_type::value_integer:
514 case token_type::value_string:
515 case token_type::value_unsigned:
524 token_type get_token()
526 return (last_token = m_lexer.scan());
532 bool expect(token_type t)
534 if (JSON_UNLIKELY(t != last_token))
538 if (allow_exceptions)
551 [[noreturn]]
void throw_exception()
const 554 if (last_token == token_type::parse_error)
556 error_msg +=
std::string(m_lexer.get_error_message()) +
"; last read: '" +
557 m_lexer.get_token_string() +
"'";
564 if (expected != token_type::uninitialized)
576 const parser_callback_t callback =
nullptr;
578 token_type last_token = token_type::uninitialized;
582 bool errored =
false;
584 token_type expected = token_type::uninitialized;
586 const bool allow_exceptions =
true;
token_type
token types for the parser
Definition: lexer.hpp:38
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
Definition: input_adapters.hpp:48
array (ordered collection of values)
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: parser.hpp:75
number value (signed integer)
lexical analysis
Definition: lexer.hpp:30
syntax analysis
Definition: parser.hpp:30
parse_event_t
Definition: parser.hpp:39
the parser finished reading a JSON value
namespace for Niels Lohmann
Definition: adl_serializer.hpp:8
the parser read [ and started to process a JSON array
object (unordered set of name/value pairs)
the parser read a key of a value in an object
parser(detail::input_adapter_t adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
a parser reading from an input adapter
Definition: parser.hpp:59
bool accept(const bool strict=true)
public accept interface
Definition: parser.hpp:111
the parser read } and finished processing a JSON object
static const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: lexer.hpp:60
the parser read { and started to process a JSON object
number value (unsigned integer)
number value (floating-point)
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
create a parse error exception
Definition: exceptions.hpp:122
the parser read ] and finished processing a JSON array
discarded by the the parser callback function