All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
nlohmann::detail::parser< BasicJsonType > Class Template Reference

syntax analysis More...

#include <json.hpp>

Public Types

enum  parse_event_t : uint8_t {
  parse_event_t::object_start, parse_event_t::object_end, parse_event_t::array_start, parse_event_t::array_end,
  parse_event_t::key, parse_event_t::value
}
 
using parser_callback_t = std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)>
 

Public Member Functions

 parser (detail::input_adapter_t &&adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
 a parser reading from an input adapter More...
 
void parse (const bool strict, BasicJsonType &result)
 public parser interface More...
 
bool accept (const bool strict=true)
 public accept interface More...
 
template<typename SAX >
bool sax_parse (SAX *sax, const bool strict=true)
 

Private Types

using number_integer_t = typename BasicJsonType::number_integer_t
 
using number_unsigned_t = typename BasicJsonType::number_unsigned_t
 
using number_float_t = typename BasicJsonType::number_float_t
 
using string_t = typename BasicJsonType::string_t
 
using lexer_t = lexer< BasicJsonType >
 
using token_type = typename lexer_t::token_type
 

Private Member Functions

template<typename SAX >
bool sax_parse_internal (SAX *sax)
 
token_type get_token ()
 get next token from lexer More...
 
std::string exception_message (const token_type expected, const std::string &context)
 

Private Attributes

const parser_callback_t callback = nullptr
 callback function More...
 
token_type last_token = token_type::uninitialized
 the type of the last read token More...
 
lexer_t m_lexer
 the lexer More...
 
const bool allow_exceptions = true
 whether to throw exceptions in case of errors More...
 

Detailed Description

template<typename BasicJsonType>
class nlohmann::detail::parser< BasicJsonType >

syntax analysis

This class implements a recursive decent parser.

Definition at line 8684 of file json.hpp.

Member Typedef Documentation

template<typename BasicJsonType >
using nlohmann::detail::parser< BasicJsonType >::lexer_t = lexer<BasicJsonType>
private

Definition at line 8690 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::parser< BasicJsonType >::number_float_t = typename BasicJsonType::number_float_t
private

Definition at line 8688 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::parser< BasicJsonType >::number_integer_t = typename BasicJsonType::number_integer_t
private

Definition at line 8686 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::parser< BasicJsonType >::number_unsigned_t = typename BasicJsonType::number_unsigned_t
private

Definition at line 8687 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::parser< BasicJsonType >::parser_callback_t = std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>

Definition at line 8711 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::parser< BasicJsonType >::string_t = typename BasicJsonType::string_t
private

Definition at line 8689 of file json.hpp.

template<typename BasicJsonType >
using nlohmann::detail::parser< BasicJsonType >::token_type = typename lexer_t::token_type
private

Definition at line 8691 of file json.hpp.

Member Enumeration Documentation

template<typename BasicJsonType >
enum nlohmann::detail::parser::parse_event_t : uint8_t
strong
Enumerator
object_start 

the parser read { and started to process a JSON object

object_end 

the parser read } and finished processing a JSON object

array_start 

the parser read [ and started to process a JSON array

array_end 

the parser read ] and finished processing a JSON array

key 

the parser read a key of a value in an object

value 

the parser finished reading a JSON value

Definition at line 8694 of file json.hpp.

8694  : uint8_t
8695  {
8696  /// the parser read `{` and started to process a JSON object
8697  object_start,
8698  /// the parser read `}` and finished processing a JSON object
8699  object_end,
8700  /// the parser read `[` and started to process a JSON array
8701  array_start,
8702  /// the parser read `]` and finished processing a JSON array
8703  array_end,
8704  /// the parser read a key of a value in an object
8705  key,
8706  /// the parser finished reading a JSON value
8707  value
8708  };
temporary value

Constructor & Destructor Documentation

template<typename BasicJsonType >
nlohmann::detail::parser< BasicJsonType >::parser ( detail::input_adapter_t &&  adapter,
const parser_callback_t  cb = nullptr,
const bool  allow_exceptions_ = true 
)
inlineexplicit

a parser reading from an input adapter

Definition at line 8714 of file json.hpp.

8717  : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
8718  {
8719  // read first token
8720  get_token();
8721  }
const parser_callback_t callback
callback function
Definition: json.hpp:9140
lexer_t m_lexer
the lexer
Definition: json.hpp:9144
token_type get_token()
get next token from lexer
Definition: json.hpp:9104
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition: json.hpp:9146

Member Function Documentation

template<typename BasicJsonType >
bool nlohmann::detail::parser< BasicJsonType >::accept ( const bool  strict = true)
inline

public accept interface

Parameters
[in]strictwhether to expect the last token to be EOF
Returns
whether the input is a proper JSON text

Definition at line 8794 of file json.hpp.

8795  {
8796  json_sax_acceptor<BasicJsonType> sax_acceptor;
8797  return sax_parse(&sax_acceptor, strict);
8798  }
throw a type_error exception in case of invalid UTF-8
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:8802
template<typename BasicJsonType >
std::string nlohmann::detail::parser< BasicJsonType >::exception_message ( const token_type  expected,
const std::string context 
)
inlineprivate

Definition at line 9109 of file json.hpp.

9110  {
9111  std::string error_msg = "syntax error ";
9112 
9113  if (not context.empty())
9114  {
9115  error_msg += "while parsing " + context + " ";
9116  }
9117 
9118  error_msg += "- ";
9119 
9120  if (last_token == token_type::parse_error)
9121  {
9122  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
9123  m_lexer.get_token_string() + "'";
9124  }
9125  else
9126  {
9127  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
9128  }
9129 
9130  if (expected != token_type::uninitialized)
9131  {
9132  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
9133  }
9134 
9135  return error_msg;
9136  }
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: json.hpp:7194
lexer_t m_lexer
the lexer
Definition: json.hpp:9144
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8513
token_type last_token
the type of the last read token
Definition: json.hpp:9142
std::string get_token_string() const
Definition: json.hpp:8488
template<typename BasicJsonType >
token_type nlohmann::detail::parser< BasicJsonType >::get_token ( )
inlineprivate

get next token from lexer

Definition at line 9104 of file json.hpp.

9105  {
9106  return last_token = m_lexer.scan();
9107  }
lexer_t m_lexer
the lexer
Definition: json.hpp:9144
token_type scan()
Definition: json.hpp:8540
token_type last_token
the type of the last read token
Definition: json.hpp:9142
template<typename BasicJsonType >
void nlohmann::detail::parser< BasicJsonType >::parse ( const bool  strict,
BasicJsonType &  result 
)
inline

public parser interface

Parameters
[in]strictwhether to expect the last token to be EOF
[in,out]resultparsed JSON value
Exceptions
parse_error.101in case of an unexpected token
parse_error.102if to_unicode fails or surrogate error
parse_error.103if to_unicode fails

Definition at line 8733 of file json.hpp.

8734  {
8735  if (callback)
8736  {
8737  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
8738  sax_parse_internal(&sdp);
8739  result.assert_invariant();
8740 
8741  // in strict mode, input must be completely read
8742  if (strict and (get_token() != token_type::end_of_input))
8743  {
8744  sdp.parse_error(m_lexer.get_position(),
8747  exception_message(token_type::end_of_input, "value")));
8748  }
8749 
8750  // in case of an error, return discarded value
8751  if (sdp.is_errored())
8752  {
8753  result = value_t::discarded;
8754  return;
8755  }
8756 
8757  // set top-level value to null if it was discarded by the callback
8758  // function
8759  if (result.is_discarded())
8760  {
8761  result = nullptr;
8762  }
8763  }
8764  else
8765  {
8766  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
8767  sax_parse_internal(&sdp);
8768  result.assert_invariant();
8769 
8770  // in strict mode, input must be completely read
8771  if (strict and (get_token() != token_type::end_of_input))
8772  {
8773  sdp.parse_error(m_lexer.get_position(),
8776  exception_message(token_type::end_of_input, "value")));
8777  }
8778 
8779  // in case of an error, return discarded value
8780  if (sdp.is_errored())
8781  {
8782  result = value_t::discarded;
8783  return;
8784  }
8785  }
8786  }
const parser_callback_t callback
callback function
Definition: json.hpp:9140
lexer_t m_lexer
the lexer
Definition: json.hpp:9144
token_type get_token()
get next token from lexer
Definition: json.hpp:9104
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition: json.hpp:9146
throw a type_error exception in case of invalid UTF-8
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8480
bool sax_parse_internal(SAX *sax)
Definition: json.hpp:8822
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:9109
std::string get_token_string() const
Definition: json.hpp:8488
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:1947
discarded by the the parser callback function
template<typename BasicJsonType >
template<typename SAX >
bool nlohmann::detail::parser< BasicJsonType >::sax_parse ( SAX *  sax,
const bool  strict = true 
)
inline

Definition at line 8802 of file json.hpp.

8803  {
8804  (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8805  const bool result = sax_parse_internal(sax);
8806 
8807  // strict mode: next byte must be EOF
8808  if (result and strict and (get_token() != token_type::end_of_input))
8809  {
8810  return sax->parse_error(m_lexer.get_position(),
8813  exception_message(token_type::end_of_input, "value")));
8814  }
8815 
8816  return result;
8817  }
lexer_t m_lexer
the lexer
Definition: json.hpp:9144
token_type get_token()
get next token from lexer
Definition: json.hpp:9104
throw a type_error exception in case of invalid UTF-8
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8480
bool sax_parse_internal(SAX *sax)
Definition: json.hpp:8822
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
j template void())
Definition: json.hpp:3108
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:9109
std::string get_token_string() const
Definition: json.hpp:8488
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:1947
template<typename BasicJsonType >
template<typename SAX >
bool nlohmann::detail::parser< BasicJsonType >::sax_parse_internal ( SAX *  sax)
inlineprivate

Definition at line 8822 of file json.hpp.

8823  {
8824  // stack to remember the hierarchy of structured values we are parsing
8825  // true = array; false = object
8826  std::vector<bool> states;
8827  // value to avoid a goto (see comment where set to true)
8828  bool skip_to_state_evaluation = false;
8829 
8830  while (true)
8831  {
8832  if (not skip_to_state_evaluation)
8833  {
8834  // invariant: get_token() was called before each iteration
8835  switch (last_token)
8836  {
8837  case token_type::begin_object:
8838  {
8839  if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
8840  {
8841  return false;
8842  }
8843 
8844  // closing } -> we are done
8845  if (get_token() == token_type::end_object)
8846  {
8847  if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
8848  {
8849  return false;
8850  }
8851  break;
8852  }
8853 
8854  // parse key
8855  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
8856  {
8857  return sax->parse_error(m_lexer.get_position(),
8860  exception_message(token_type::value_string, "object key")));
8861  }
8862  if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
8863  {
8864  return false;
8865  }
8866 
8867  // parse separator (:)
8868  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
8869  {
8870  return sax->parse_error(m_lexer.get_position(),
8873  exception_message(token_type::name_separator, "object separator")));
8874  }
8875 
8876  // remember we are now inside an object
8877  states.push_back(false);
8878 
8879  // parse values
8880  get_token();
8881  continue;
8882  }
8883 
8884  case token_type::begin_array:
8885  {
8886  if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
8887  {
8888  return false;
8889  }
8890 
8891  // closing ] -> we are done
8892  if (get_token() == token_type::end_array)
8893  {
8894  if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
8895  {
8896  return false;
8897  }
8898  break;
8899  }
8900 
8901  // remember we are now inside an array
8902  states.push_back(true);
8903 
8904  // parse values (no need to call get_token)
8905  continue;
8906  }
8907 
8908  case token_type::value_float:
8909  {
8910  const auto res = m_lexer.get_number_float();
8911 
8912  if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
8913  {
8914  return sax->parse_error(m_lexer.get_position(),
8916  out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
8917  }
8918 
8919  if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
8920  {
8921  return false;
8922  }
8923 
8924  break;
8925  }
8926 
8927  case token_type::literal_false:
8928  {
8929  if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false)))
8930  {
8931  return false;
8932  }
8933  break;
8934  }
8935 
8936  case token_type::literal_null:
8937  {
8938  if (JSON_HEDLEY_UNLIKELY(not sax->null()))
8939  {
8940  return false;
8941  }
8942  break;
8943  }
8944 
8945  case token_type::literal_true:
8946  {
8947  if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true)))
8948  {
8949  return false;
8950  }
8951  break;
8952  }
8953 
8954  case token_type::value_integer:
8955  {
8956  if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
8957  {
8958  return false;
8959  }
8960  break;
8961  }
8962 
8963  case token_type::value_string:
8964  {
8965  if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
8966  {
8967  return false;
8968  }
8969  break;
8970  }
8971 
8972  case token_type::value_unsigned:
8973  {
8974  if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
8975  {
8976  return false;
8977  }
8978  break;
8979  }
8980 
8981  case token_type::parse_error:
8982  {
8983  // using "uninitialized" to avoid "expected" message
8984  return sax->parse_error(m_lexer.get_position(),
8987  exception_message(token_type::uninitialized, "value")));
8988  }
8989 
8990  default: // the last token was unexpected
8991  {
8992  return sax->parse_error(m_lexer.get_position(),
8995  exception_message(token_type::literal_or_value, "value")));
8996  }
8997  }
8998  }
8999  else
9000  {
9001  skip_to_state_evaluation = false;
9002  }
9003 
9004  // we reached this line after we successfully parsed a value
9005  if (states.empty())
9006  {
9007  // empty stack: we reached the end of the hierarchy: done
9008  return true;
9009  }
9010 
9011  if (states.back()) // array
9012  {
9013  // comma -> next value
9014  if (get_token() == token_type::value_separator)
9015  {
9016  // parse a new value
9017  get_token();
9018  continue;
9019  }
9020 
9021  // closing ]
9022  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
9023  {
9024  if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9025  {
9026  return false;
9027  }
9028 
9029  // We are done with this array. Before we can parse a
9030  // new value, we need to evaluate the new state first.
9031  // By setting skip_to_state_evaluation to false, we
9032  // are effectively jumping to the beginning of this if.
9033  assert(not states.empty());
9034  states.pop_back();
9035  skip_to_state_evaluation = true;
9036  continue;
9037  }
9038 
9039  return sax->parse_error(m_lexer.get_position(),
9042  exception_message(token_type::end_array, "array")));
9043  }
9044  else // object
9045  {
9046  // comma -> next value
9047  if (get_token() == token_type::value_separator)
9048  {
9049  // parse key
9050  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
9051  {
9052  return sax->parse_error(m_lexer.get_position(),
9055  exception_message(token_type::value_string, "object key")));
9056  }
9057 
9058  if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
9059  {
9060  return false;
9061  }
9062 
9063  // parse separator (:)
9064  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
9065  {
9066  return sax->parse_error(m_lexer.get_position(),
9069  exception_message(token_type::name_separator, "object separator")));
9070  }
9071 
9072  // parse values
9073  get_token();
9074  continue;
9075  }
9076 
9077  // closing }
9078  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
9079  {
9080  if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
9081  {
9082  return false;
9083  }
9084 
9085  // We are done with this object. Before we can parse a
9086  // new value, we need to evaluate the new state first.
9087  // By setting skip_to_state_evaluation to false, we
9088  // are effectively jumping to the beginning of this if.
9089  assert(not states.empty());
9090  states.pop_back();
9091  skip_to_state_evaluation = true;
9092  continue;
9093  }
9094 
9095  return sax->parse_error(m_lexer.get_position(),
9098  exception_message(token_type::end_object, "object")));
9099  }
9100  }
9101  }
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8458
lexer_t m_lexer
the lexer
Definition: json.hpp:9144
token_type get_token()
get next token from lexer
Definition: json.hpp:9104
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8470
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8480
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8452
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8464
bool isfinite(Vector const &v)
Returns whether all components of the vector are finite.
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1123
token_type last_token
the type of the last read token
Definition: json.hpp:9142
static out_of_range create(int id_, const std::string &what_arg)
Definition: json.hpp:2125
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1124
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:9109
std::string get_token_string() const
Definition: json.hpp:8488
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:1947

Member Data Documentation

template<typename BasicJsonType >
const bool nlohmann::detail::parser< BasicJsonType >::allow_exceptions = true
private

whether to throw exceptions in case of errors

Definition at line 9146 of file json.hpp.

template<typename BasicJsonType >
const parser_callback_t nlohmann::detail::parser< BasicJsonType >::callback = nullptr
private

callback function

Definition at line 9140 of file json.hpp.

template<typename BasicJsonType >
token_type nlohmann::detail::parser< BasicJsonType >::last_token = token_type::uninitialized
private

the type of the last read token

Definition at line 9142 of file json.hpp.

template<typename BasicJsonType >
lexer_t nlohmann::detail::parser< BasicJsonType >::m_lexer
private

the lexer

Definition at line 9144 of file json.hpp.


The documentation for this class was generated from the following file: