10 #include <nlohmann/detail/exceptions.hpp>
11 #include <nlohmann/detail/input/input_adapters.hpp>
12 #include <nlohmann/detail/input/json_sax.hpp>
13 #include <nlohmann/detail/input/lexer.hpp>
14 #include <nlohmann/detail/macro_scope.hpp>
15 #include <nlohmann/detail/meta/is_sax.hpp>
16 #include <nlohmann/detail/value_t.hpp>
42 template<
typename BasicJsonType>
43 using parser_callback_t =
44 std::function<bool(
int depth,
parse_event_t event, BasicJsonType& parsed)>;
51 template<
typename BasicJsonType,
typename InputAdapterType>
54 using number_integer_t =
typename BasicJsonType::number_integer_t;
55 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
56 using number_float_t =
typename BasicJsonType::number_float_t;
57 using string_t =
typename BasicJsonType::string_t;
59 using token_type =
typename lexer_t::token_type;
63 explicit parser(InputAdapterType&& adapter,
64 const parser_callback_t<BasicJsonType> cb =
nullptr,
65 const bool allow_exceptions_ =
true,
66 const bool skip_comments =
false)
68 , m_lexer(std::move(adapter), skip_comments)
69 , allow_exceptions(allow_exceptions_)
85 void parse(
const bool strict, BasicJsonType& result)
90 sax_parse_internal(&sdp);
91 result.assert_invariant();
94 if (
strict && (get_token() != token_type::end_of_input))
99 exception_message(token_type::end_of_input,
"value")));
103 if (sdp.is_errored())
111 if (result.is_discarded())
119 sax_parse_internal(&sdp);
120 result.assert_invariant();
123 if (
strict && (get_token() != token_type::end_of_input))
128 exception_message(token_type::end_of_input,
"value")));
132 if (sdp.is_errored())
149 return sax_parse(&sax_acceptor,
strict);
152 template<
typename SAX>
153 JSON_HEDLEY_NON_NULL(2)
154 bool sax_parse(SAX* sax, const
bool strict = true)
157 const bool result = sax_parse_internal(sax);
160 if (result && strict && (get_token() != token_type::end_of_input))
165 exception_message(token_type::end_of_input,
"value")));
172 template<
typename SAX>
173 JSON_HEDLEY_NON_NULL(2)
174 bool sax_parse_internal(SAX* sax)
178 std::vector<bool> states;
180 bool skip_to_state_evaluation =
false;
184 if (!skip_to_state_evaluation)
189 case token_type::begin_object:
191 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
197 if (get_token() == token_type::end_object)
199 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
207 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
212 exception_message(token_type::value_string,
"object key")));
214 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.
get_string())))
220 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
225 exception_message(token_type::name_separator,
"object separator")));
229 states.push_back(
false);
236 case token_type::begin_array:
238 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
244 if (get_token() == token_type::end_array)
246 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
254 states.push_back(
true);
260 case token_type::value_float:
264 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
268 out_of_range::create(406,
"number overflow parsing '" + m_lexer.
get_token_string() +
"'"));
271 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.
get_string())))
279 case token_type::literal_false:
281 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(
false)))
288 case token_type::literal_null:
290 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
297 case token_type::literal_true:
299 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(
true)))
306 case token_type::value_integer:
315 case token_type::value_string:
317 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.
get_string())))
324 case token_type::value_unsigned:
333 case token_type::parse_error:
339 exception_message(token_type::uninitialized,
"value")));
347 exception_message(token_type::literal_or_value,
"value")));
353 skip_to_state_evaluation =
false;
366 if (get_token() == token_type::value_separator)
374 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
376 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
385 JSON_ASSERT(!states.empty());
387 skip_to_state_evaluation =
true;
394 exception_message(token_type::end_array,
"array")));
399 if (get_token() == token_type::value_separator)
402 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
407 exception_message(token_type::value_string,
"object key")));
410 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.
get_string())))
416 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
421 exception_message(token_type::name_separator,
"object separator")));
430 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
432 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
441 JSON_ASSERT(!states.empty());
443 skip_to_state_evaluation =
true;
450 exception_message(token_type::end_object,
"object")));
456 token_type get_token()
458 return last_token = m_lexer.scan();
461 std::string exception_message(
const token_type expected,
const std::string& context)
463 std::string error_msg =
"syntax error ";
465 if (!context.empty())
467 error_msg +=
"while parsing " + context +
" ";
472 if (last_token == token_type::parse_error)
482 if (expected != token_type::uninitialized)
492 const parser_callback_t<BasicJsonType> callback =
nullptr;
494 token_type last_token = token_type::uninitialized;
498 const bool allow_exceptions =
true;
Definition: json_sax.hpp:620
Definition: json_sax.hpp:324
SAX implementation to create a JSON value from SAX events.
Definition: json_sax.hpp:150
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST 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:54
lexical analysis
Definition: lexer.hpp:104
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: lexer.hpp:1422
constexpr position_t get_position() const noexcept
return position of last read token
Definition: lexer.hpp:1432
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: lexer.hpp:1404
constexpr JSON_HEDLEY_RETURNS_NON_NULL const char * get_error_message() const noexcept
return syntax error message
Definition: lexer.hpp:1465
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: lexer.hpp:1410
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: lexer.hpp:1416
std::string get_token_string() const
return the last read token (for errors only).
Definition: lexer.hpp:1440
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: exceptions.hpp:130
syntax analysis
Definition: parser.hpp:53
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: parser.hpp:63
bool accept(const bool strict=true)
public accept interface
Definition: parser.hpp:146
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: parser.hpp:85
zip_uint8_t uint8_t
zip_uint8_t typedef.
Definition: zip.hpp:78
@ discarded
discarded by the parser callback function
parse_event_t
Definition: parser.hpp:27
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
@ strict
throw a type_error exception in case of invalid UTF-8
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9
Definition: is_sax.hpp:97