JLEX-01 | Reviewed: ⨯ | Score: 0.0#
The requirement regarding JSON Validation is fulfilled.
Supported Requests:
Item |
Summary |
Score |
Status |
|---|---|---|---|
Expected or required behaviours for the nlohmann/json library are identified, specified, verified and validated based on analysis. |
0.00 |
⨯ Item Reviewed |
Supporting Items:
Item |
Summary |
Score |
Status |
|---|---|---|---|
The service provided by the nlohmann/json library checks the well-formedness of the literal names. |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library checks the well-formedness of strings. |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library checks the well-formedness of numbers. |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library checks the well-formedness of array. |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library checks the well-formedness of objects. |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library checks that a JSON value must be an object, array, number, or string, or one of the lowercase literal names false, null, or true |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library checks that JSON is only serialized using UTF-8. |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library ignores byte order marks. |
0.00 |
⨯ Item Reviewed |
References:
function: [basic_json::accept] (include/nlohmann/json.hpp)Description: the public interface of the
accept-functionality of nlohmann/json for single inputs
static bool accept(InputType&& i, const bool ignore_comments = false) { return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true); }
function: [basic_json::accept] (include/nlohmann/json.hpp)Description: the public interface of the
accept-functionality of nlohmann/json for iterator inputs
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments = false) { return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true); }
function: [basic_json::accept] (include/nlohmann/json.hpp)Description: the public interface of the
accept-functionality of nlohmann/json for input buffer
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len)) static bool accept(detail::span_input_adapter&& i, const bool ignore_comments = false) { return parser(i.get(), nullptr, false, ignore_comments).accept(true); }
function: [parser::accept] (include/nlohmann/detail/input/parser.hpp)Description: the internal
accept-functionality called by basic_json::accept
bool accept(const bool strict = true) { json_sax_acceptor<BasicJsonType> sax_acceptor; return sax_parse(&sax_acceptor, strict); }
function: [parser::sax_parse] (include/nlohmann/detail/input/parser.hpp)Description: called by parser::accept
bool sax_parse(SAX* sax, const bool strict = true) { (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; const bool result = sax_parse_internal(sax); // strict mode: next byte must be EOF if (result && strict && (get_token() != token_type::end_of_input)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); } return result; }
function: [parser::sax_parse_internal] (include/nlohmann/detail/input/parser.hpp)Description: called by parser::sax_parse
bool sax_parse_internal(SAX* sax) { // stack to remember the hierarchy of structured values we are parsing // true = array; false = object std::vector<bool> states; // value to avoid a goto (see comment where set to true) bool skip_to_state_evaluation = false; while (true) { if (!skip_to_state_evaluation) { // invariant: get_token() was called before each iteration switch (last_token) { case token_type::begin_object: { if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size()))) { return false; } // closing } -> we are done if (get_token() == token_type::end_object) { if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) { return false; } break; } // parse key if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); } if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) { return false; } // parse separator (:) if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); } // remember we are now inside an object states.push_back(false); // parse values get_token(); continue; } case token_type::begin_array: { if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size()))) { return false; } // closing ] -> we are done if (get_token() == token_type::end_array) { if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) { return false; } break; } // remember we are now inside an array states.push_back(true); // parse values (no need to call get_token) continue; } case token_type::value_float: { const auto res = m_lexer.get_number_float(); if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr)); } if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) { return false; } break; } case token_type::literal_false: { if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) { return false; } break; } case token_type::literal_null: { if (JSON_HEDLEY_UNLIKELY(!sax->null())) { return false; } break; } case token_type::literal_true: { if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) { return false; } break; } case token_type::value_integer: { if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) { return false; } break; } case token_type::value_string: { if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) { return false; } break; } case token_type::value_unsigned: { if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) { return false; } break; } case token_type::parse_error: { // using "uninitialized" to avoid "expected" message return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr)); } case token_type::end_of_input: { if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr)); } return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); } case token_type::uninitialized: case token_type::end_array: case token_type::end_object: case token_type::name_separator: case token_type::value_separator: case token_type::literal_or_value: default: // the last token was unexpected { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); } } } else { skip_to_state_evaluation = false; } // we reached this line after we successfully parsed a value if (states.empty()) { // empty stack: we reached the end of the hierarchy: done return true; } if (states.back()) // array { // comma -> next value if (get_token() == token_type::value_separator) { // parse a new value get_token(); continue; } // closing ] if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) { if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) { return false; } // We are done with this array. Before we can parse a // new value, we need to evaluate the new state first. // By setting skip_to_state_evaluation to false, we // are effectively jumping to the beginning of this if. JSON_ASSERT(!states.empty()); states.pop_back(); skip_to_state_evaluation = true; continue; } return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr)); } // states.back() is false -> object // comma -> next value if (get_token() == token_type::value_separator) { // parse key if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); } if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) { return false; } // parse separator (:) if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); } // parse values get_token(); continue; } // closing } if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) { if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) { return false; } // We are done with this object. Before we can parse a // new value, we need to evaluate the new state first. // By setting skip_to_state_evaluation to false, we // are effectively jumping to the beginning of this if. JSON_ASSERT(!states.empty()); states.pop_back(); skip_to_state_evaluation = true; continue; } return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr)); } }
function: [lexer::scan] (include/nlohmann/detail/input/lexer.hpp)Description: scans input, called in parser::sax_parse_internal
token_type scan() { // initially, skip the BOM if (position.chars_read_total == 0 && !skip_bom()) { error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; return token_type::parse_error; } // read next character and ignore whitespace skip_whitespace(); // ignore comments while (ignore_comments && current == '/') { if (!scan_comment()) { return token_type::parse_error; } // skip following whitespace skip_whitespace(); } switch (current) { // structural characters case '[': return token_type::begin_array; case ']': return token_type::end_array; case '{': return token_type::begin_object; case '}': return token_type::end_object; case ':': return token_type::name_separator; case ',': return token_type::value_separator; // literals case 't': { std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}}; return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); } case 'f': { std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}}; return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); } case 'n': { std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}}; return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); } // string case '\"': return scan_string(); // number case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return scan_number(); // end of input (the null byte is needed when parsing from // string literals) case '\0': case char_traits<char_type>::eof(): return token_type::end_of_input; // error default: error_message = "invalid literal"; return token_type::parse_error; } }
Fallacies:
None
Graph:
date-time |
JLEX-01 |
WFJ-01 |
WFJ-02 |
WFJ-03 |
WFJ-04 |
WFJ-05 |
WFJ-06 |
WFJ-07 |
WFJ-08 |
|---|---|---|---|---|---|---|---|---|---|
2025-11-26 12:04:09 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
2025-11-26 12:52:19.093864 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
0.00 |
JLEX-02 | Reviewed: ⨯ | Score: 0.0#
The requirement regarding JSON Deserialization is fulfilled.
Supported Requests:
Item |
Summary |
Score |
Status |
|---|---|---|---|
Expected or required behaviours for the nlohmann/json library are identified, specified, verified and validated based on analysis. |
0.00 |
⨯ Item Reviewed |
Supporting Items:
Item |
Summary |
Score |
Status |
|---|---|---|---|
The service provided by the nlohmann/json library provides implementations that parses JSON texts, which ignores the presence of a byte order mark rather than treating it as an error. |
0.00 |
⨯ Item Reviewed |
|
The service provided by the nlohmann/json library parses all texts that conform to the JSON grammar. |
0.00 |
⨯ Item Reviewed |
References:
function: [basic_json::parse] (include/nlohmann/json.hpp)Description: the public interface of the
parse-functionality of nlohmann/json for single inputs
static basic_json parse(InputType&& i, parser_callback_t cb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false) { basic_json result; parser(detail::input_adapter(std::forward<InputType>(i)), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved,accessForwarded] return result; }
function: [basic_json::parse] (include/nlohmann/json.hpp)Description: the public interface of the
parse-functionality of nlohmann/json for iterator inputs
static basic_json parse(IteratorType first, IteratorType last, parser_callback_t cb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false) { basic_json result; parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved] return result; }
function: [basic_json::parse] (include/nlohmann/json.hpp)Description: the public interface of the
parse-functionality of nlohmann/json for input buffer
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len)) static basic_json parse(detail::span_input_adapter&& i, parser_callback_t cb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false) { basic_json result; parser(i.get(), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved] return result; }
function: [parser::parse] (include/nlohmann/detail/input/parser.hpp)Description: the internal
parse-functionality called by basic_json::parse
void parse(const bool strict, BasicJsonType& result) { if (callback) { json_sax_dom_callback_parser<BasicJsonType, InputAdapterType> sdp(result, callback, allow_exceptions, &m_lexer); sax_parse_internal(&sdp); // in strict mode, input must be completely read if (strict && (get_token() != token_type::end_of_input)) { sdp.parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); } // in case of an error, return discarded value if (sdp.is_errored()) { result = value_t::discarded; return; } // set top-level value to null if it was discarded by the callback // function if (result.is_discarded()) { result = nullptr; } } else { json_sax_dom_parser<BasicJsonType, InputAdapterType> sdp(result, allow_exceptions, &m_lexer); sax_parse_internal(&sdp); // in strict mode, input must be completely read if (strict && (get_token() != token_type::end_of_input)) { sdp.parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); } // in case of an error, return discarded value if (sdp.is_errored()) { result = value_t::discarded; return; } } result.assert_invariant(); }
function: [parser::sax_parse] (include/nlohmann/detail/input/parser.hpp)Description: called by parser::parse
bool sax_parse(SAX* sax, const bool strict = true) { (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; const bool result = sax_parse_internal(sax); // strict mode: next byte must be EOF if (result && strict && (get_token() != token_type::end_of_input)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); } return result; }
function: [parser::sax_parse_internal] (include/nlohmann/detail/input/parser.hpp)Description: called by parser::sax_parse
bool sax_parse_internal(SAX* sax) { // stack to remember the hierarchy of structured values we are parsing // true = array; false = object std::vector<bool> states; // value to avoid a goto (see comment where set to true) bool skip_to_state_evaluation = false; while (true) { if (!skip_to_state_evaluation) { // invariant: get_token() was called before each iteration switch (last_token) { case token_type::begin_object: { if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size()))) { return false; } // closing } -> we are done if (get_token() == token_type::end_object) { if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) { return false; } break; } // parse key if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); } if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) { return false; } // parse separator (:) if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); } // remember we are now inside an object states.push_back(false); // parse values get_token(); continue; } case token_type::begin_array: { if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size()))) { return false; } // closing ] -> we are done if (get_token() == token_type::end_array) { if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) { return false; } break; } // remember we are now inside an array states.push_back(true); // parse values (no need to call get_token) continue; } case token_type::value_float: { const auto res = m_lexer.get_number_float(); if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr)); } if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) { return false; } break; } case token_type::literal_false: { if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) { return false; } break; } case token_type::literal_null: { if (JSON_HEDLEY_UNLIKELY(!sax->null())) { return false; } break; } case token_type::literal_true: { if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) { return false; } break; } case token_type::value_integer: { if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) { return false; } break; } case token_type::value_string: { if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) { return false; } break; } case token_type::value_unsigned: { if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) { return false; } break; } case token_type::parse_error: { // using "uninitialized" to avoid "expected" message return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr)); } case token_type::end_of_input: { if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr)); } return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); } case token_type::uninitialized: case token_type::end_array: case token_type::end_object: case token_type::name_separator: case token_type::value_separator: case token_type::literal_or_value: default: // the last token was unexpected { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); } } } else { skip_to_state_evaluation = false; } // we reached this line after we successfully parsed a value if (states.empty()) { // empty stack: we reached the end of the hierarchy: done return true; } if (states.back()) // array { // comma -> next value if (get_token() == token_type::value_separator) { // parse a new value get_token(); continue; } // closing ] if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) { if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) { return false; } // We are done with this array. Before we can parse a // new value, we need to evaluate the new state first. // By setting skip_to_state_evaluation to false, we // are effectively jumping to the beginning of this if. JSON_ASSERT(!states.empty()); states.pop_back(); skip_to_state_evaluation = true; continue; } return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr)); } // states.back() is false -> object // comma -> next value if (get_token() == token_type::value_separator) { // parse key if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); } if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) { return false; } // parse separator (:) if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) { return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); } // parse values get_token(); continue; } // closing } if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) { if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) { return false; } // We are done with this object. Before we can parse a // new value, we need to evaluate the new state first. // By setting skip_to_state_evaluation to false, we // are effectively jumping to the beginning of this if. JSON_ASSERT(!states.empty()); states.pop_back(); skip_to_state_evaluation = true; continue; } return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string(), parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr)); } }
function: [lexer::scan] (include/nlohmann/detail/input/lexer.hpp)Description: scans input, called in parser::sax_parse_internal
token_type scan() { // initially, skip the BOM if (position.chars_read_total == 0 && !skip_bom()) { error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; return token_type::parse_error; } // read next character and ignore whitespace skip_whitespace(); // ignore comments while (ignore_comments && current == '/') { if (!scan_comment()) { return token_type::parse_error; } // skip following whitespace skip_whitespace(); } switch (current) { // structural characters case '[': return token_type::begin_array; case ']': return token_type::end_array; case '{': return token_type::begin_object; case '}': return token_type::end_object; case ':': return token_type::name_separator; case ',': return token_type::value_separator; // literals case 't': { std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}}; return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); } case 'f': { std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}}; return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); } case 'n': { std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}}; return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); } // string case '\"': return scan_string(); // number case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return scan_number(); // end of input (the null byte is needed when parsing from // string literals) case '\0': case char_traits<char_type>::eof(): return token_type::end_of_input; // error default: error_message = "invalid literal"; return token_type::parse_error; } }
Fallacies:
None
Graph:
date-time |
JLEX-02 |
PJD-01 |
PJD-03 |
|---|---|---|---|
2025-11-26 12:04:09 |
0.00 |
0.00 |
0.00 |
2025-11-26 12:52:19.093864 |
0.00 |
0.00 |
0.00 |