refactor: split the strict and non-strict paths in parser

Folding the release_lookahead() call into the existing strict check left
the "in strict mode" comment on an else-if branch, and made the strict
condition in sax_parse() redundant with the branch it followed.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-08-19 22:50:21 +02:00
1 parent 7fc3a7d87e
commit e5f84e1ebf
2 files changed
+58 -34

No files matched your search

+29 -17
View File
@@ -99,20 +99,23 @@ class parser
json_sax_dom_callback_parser<BasicJsonType, InputAdapterType> sdp(result, callback, allow_exceptions, &m_lexer); json_sax_dom_callback_parser<BasicJsonType, InputAdapterType> sdp(result, callback, allow_exceptions, &m_lexer);
sax_parse_internal(&sdp); sax_parse_internal(&sdp);
if (!strict) if (strict)
{ {
// the caller keeps using the input: position it right after
// the value by leaving the character that terminated it
m_lexer.release_lookahead();
}
// in strict mode, input must be completely read // in strict mode, input must be completely read
else if (get_token() != token_type::end_of_input) if (get_token() != token_type::end_of_input)
{ {
sdp.parse_error(m_lexer.get_position(), sdp.parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_of_input, "value"), nullptr)); exception_message(token_type::end_of_input, "value"), nullptr));
} }
}
else
{
// the caller keeps using the input: position it right after
// the value by leaving the character that terminated it
m_lexer.release_lookahead();
}
// in case of an error, return a discarded value // in case of an error, return a discarded value
if (sdp.is_errored()) if (sdp.is_errored())
@@ -133,18 +136,21 @@ class parser
json_sax_dom_parser<BasicJsonType, InputAdapterType> sdp(result, allow_exceptions, &m_lexer); json_sax_dom_parser<BasicJsonType, InputAdapterType> sdp(result, allow_exceptions, &m_lexer);
sax_parse_internal(&sdp); sax_parse_internal(&sdp);
if (!strict) if (strict)
{ {
// see above
m_lexer.release_lookahead();
}
// in strict mode, input must be completely read // in strict mode, input must be completely read
else if (get_token() != token_type::end_of_input) if (get_token() != token_type::end_of_input)
{ {
sdp.parse_error(m_lexer.get_position(), sdp.parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
} }
}
else
{
// see above
m_lexer.release_lookahead();
}
// in case of an error, return a discarded value // in case of an error, return a discarded value
if (sdp.is_errored()) if (sdp.is_errored())
@@ -176,19 +182,25 @@ class parser
(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
const bool result = sax_parse_internal(sax); const bool result = sax_parse_internal(sax);
if (result && !strict) if (result)
{
if (strict)
{ {
// the caller keeps using the input: position it right after the
// value by leaving the character that terminated it
m_lexer.release_lookahead();
}
// strict mode: next byte must be EOF // strict mode: next byte must be EOF
else if (result && strict && (get_token() != token_type::end_of_input)) if (get_token() != token_type::end_of_input)
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
} }
}
else
{
// the caller keeps using the input: position it right after
// the value by leaving the character that terminated it
m_lexer.release_lookahead();
}
}
return result; return result;
} }
+29 -17
View File
@@ -14115,20 +14115,23 @@ class parser
json_sax_dom_callback_parser<BasicJsonType, InputAdapterType> sdp(result, callback, allow_exceptions, &m_lexer); json_sax_dom_callback_parser<BasicJsonType, InputAdapterType> sdp(result, callback, allow_exceptions, &m_lexer);
sax_parse_internal(&sdp); sax_parse_internal(&sdp);
if (!strict) if (strict)
{ {
// the caller keeps using the input: position it right after
// the value by leaving the character that terminated it
m_lexer.release_lookahead();
}
// in strict mode, input must be completely read // in strict mode, input must be completely read
else if (get_token() != token_type::end_of_input) if (get_token() != token_type::end_of_input)
{ {
sdp.parse_error(m_lexer.get_position(), sdp.parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_of_input, "value"), nullptr)); exception_message(token_type::end_of_input, "value"), nullptr));
} }
}
else
{
// the caller keeps using the input: position it right after
// the value by leaving the character that terminated it
m_lexer.release_lookahead();
}
// in case of an error, return a discarded value // in case of an error, return a discarded value
if (sdp.is_errored()) if (sdp.is_errored())
@@ -14149,18 +14152,21 @@ class parser
json_sax_dom_parser<BasicJsonType, InputAdapterType> sdp(result, allow_exceptions, &m_lexer); json_sax_dom_parser<BasicJsonType, InputAdapterType> sdp(result, allow_exceptions, &m_lexer);
sax_parse_internal(&sdp); sax_parse_internal(&sdp);
if (!strict) if (strict)
{ {
// see above
m_lexer.release_lookahead();
}
// in strict mode, input must be completely read // in strict mode, input must be completely read
else if (get_token() != token_type::end_of_input) if (get_token() != token_type::end_of_input)
{ {
sdp.parse_error(m_lexer.get_position(), sdp.parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
} }
}
else
{
// see above
m_lexer.release_lookahead();
}
// in case of an error, return a discarded value // in case of an error, return a discarded value
if (sdp.is_errored()) if (sdp.is_errored())
@@ -14192,19 +14198,25 @@ class parser
(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
const bool result = sax_parse_internal(sax); const bool result = sax_parse_internal(sax);
if (result && !strict) if (result)
{
if (strict)
{ {
// the caller keeps using the input: position it right after the
// value by leaving the character that terminated it
m_lexer.release_lookahead();
}
// strict mode: next byte must be EOF // strict mode: next byte must be EOF
else if (result && strict && (get_token() != token_type::end_of_input)) if (get_token() != token_type::end_of_input)
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
} }
}
else
{
// the caller keeps using the input: position it right after
// the value by leaving the character that terminated it
m_lexer.release_lookahead();
}
}
return result; return result;
} }