🔨 simplified error handling in parser

This commit is contained in:
Niels Lohmann 2017-06-20 20:14:18 +02:00
parent f2cdb3d594
commit 82b95ca664
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
2 changed files with 87 additions and 85 deletions

View file

@ -12902,7 +12902,7 @@ scan_number_done:
default: default:
{ {
// the last token was unexpected // the last token was unexpected
unexpect(last_token); unexpect();
} }
} }
@ -13040,16 +13040,32 @@ scan_number_done:
/// get next token from lexer /// get next token from lexer
typename lexer::token_type get_token() typename lexer::token_type get_token()
{ {
last_token = m_lexer.scan(); return (last_token = m_lexer.scan());
return last_token;
} }
/*! /*!
@throw parse_error.101 if expected token did not occur @throw parse_error.101 if expected token did not occur
*/ */
void expect(typename lexer::token_type t) const void expect(typename lexer::token_type t)
{ {
if (JSON_UNLIKELY(t != last_token)) if (JSON_UNLIKELY(t != last_token))
{
errored = true;
expected = t;
throw_exception();
}
}
/*!
@throw parse_error.101 if unexpected token occurred
*/
void unexpect()
{
errored = true;
throw_exception();
}
[[noreturn]] void throw_exception() const
{ {
std::string error_msg = "syntax error - "; std::string error_msg = "syntax error - ";
if (last_token == lexer::token_type::parse_error) if (last_token == lexer::token_type::parse_error)
@ -13061,31 +13077,13 @@ scan_number_done:
error_msg += "unexpected " + std::string(lexer::token_type_name(last_token)); error_msg += "unexpected " + std::string(lexer::token_type_name(last_token));
} }
error_msg += "; expected " + std::string(lexer::token_type_name(t)); if (expected != lexer::token_type::uninitialized)
JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
}
}
/*!
@throw parse_error.101 if unexpected token occurred
*/
void unexpect(typename lexer::token_type t) const
{ {
if (JSON_UNLIKELY(t == last_token)) error_msg += "; expected " + std::string(lexer::token_type_name(expected));
{
std::string error_msg = "syntax error - ";
if (last_token == lexer::token_type::parse_error)
{
error_msg += std::string(m_lexer.get_error_message()) + "; last read '" + m_lexer.get_token_string() + "'";
}
else
{
error_msg += "unexpected " + std::string(lexer::token_type_name(last_token));
} }
JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg)); JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
} }
}
private: private:
/// current level of recursion /// current level of recursion
@ -13096,6 +13094,10 @@ scan_number_done:
typename lexer::token_type last_token = lexer::token_type::uninitialized; typename lexer::token_type last_token = lexer::token_type::uninitialized;
/// the lexer /// the lexer
lexer m_lexer; lexer m_lexer;
/// whether a syntax error occurred
bool errored = false;
/// possible reason for the syntax error
typename lexer::token_type expected = lexer::token_type::uninitialized;
}; };
public: public:

View file

@ -98,18 +98,18 @@ TEST_CASE("parser class")
// error: tab in string // error: tab in string
CHECK_THROWS_AS(parse_string("\"\t\"").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\t\"").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("\"\t\"").parse(), CHECK_THROWS_WITH(parse_string("\"\t\"").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"<U+0009>'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0009>'");
// error: newline in string // error: newline in string
CHECK_THROWS_AS(parse_string("\"\n\"").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\n\"").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("\"\r\"").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\r\"").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("\"\n\"").parse(), CHECK_THROWS_WITH(parse_string("\"\n\"").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"<U+000A>'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000A>'");
CHECK_THROWS_WITH(parse_string("\"\r\"").parse(), CHECK_THROWS_WITH(parse_string("\"\r\"").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"<U+000D>'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+000D>'");
// error: backspace in string // error: backspace in string
CHECK_THROWS_AS(parse_string("\"\b\"").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\b\"").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("\"\b\"").parse(), CHECK_THROWS_WITH(parse_string("\"\b\"").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"<U+0008>'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"<U+0008>'");
// improve code coverage // improve code coverage
CHECK_THROWS_AS(parse_string("\uFF01").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\uFF01").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("[-4:1,]").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("[-4:1,]").parse(), json::parse_error);
@ -317,21 +317,21 @@ TEST_CASE("parser class")
CHECK_THROWS_WITH(parse_string("-01").parse(), CHECK_THROWS_WITH(parse_string("-01").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - unexpected number literal; expected end of input"); "[json.exception.parse_error.101] parse error at 3: syntax error - unexpected number literal; expected end of input");
CHECK_THROWS_WITH(parse_string("--1").parse(), CHECK_THROWS_WITH(parse_string("--1").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '--'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'");
CHECK_THROWS_WITH(parse_string("1.").parse(), CHECK_THROWS_WITH(parse_string("1.").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '1.'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.'");
CHECK_THROWS_WITH(parse_string("1E").parse(), CHECK_THROWS_WITH(parse_string("1E").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E'");
CHECK_THROWS_WITH(parse_string("1E-").parse(), CHECK_THROWS_WITH(parse_string("1E-").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after exponent sign; last read '1E-'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after exponent sign; last read: '1E-'");
CHECK_THROWS_WITH(parse_string("1.E1").parse(), CHECK_THROWS_WITH(parse_string("1.E1").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '1.E'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.E'");
CHECK_THROWS_WITH(parse_string("-1E").parse(), CHECK_THROWS_WITH(parse_string("-1E").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '-1E'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'");
CHECK_THROWS_WITH(parse_string("-0E#").parse(), CHECK_THROWS_WITH(parse_string("-0E#").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '-0E#'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'");
CHECK_THROWS_WITH(parse_string("-0E-#").parse(), CHECK_THROWS_WITH(parse_string("-0E-#").parse(),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read '-0E-#'"); "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0E-#'");
CHECK_THROWS_WITH(parse_string("-0#").parse(), CHECK_THROWS_WITH(parse_string("-0#").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: '-0#'; expected end of input"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: '-0#'; expected end of input");
CHECK_THROWS_WITH(parse_string("-0.0:").parse(), CHECK_THROWS_WITH(parse_string("-0.0:").parse(),
@ -343,7 +343,7 @@ TEST_CASE("parser class")
CHECK_THROWS_WITH(parse_string("-0e0-:").parse(), CHECK_THROWS_WITH(parse_string("-0e0-:").parse(),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid number; expected digit after '-'; last read: '-:'; expected end of input"); "[json.exception.parse_error.101] parse error at 6: syntax error - invalid number; expected digit after '-'; last read: '-:'; expected end of input");
CHECK_THROWS_WITH(parse_string("-0e-:").parse(), CHECK_THROWS_WITH(parse_string("-0e-:").parse(),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read '-0e-:'"); "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0e-:'");
CHECK_THROWS_WITH(parse_string("-0f").parse(), CHECK_THROWS_WITH(parse_string("-0f").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read: '-0f'; expected end of input"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read: '-0f'; expected end of input");
} }
@ -630,55 +630,55 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parse_string("1E/").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("1E/").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("1E:").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("1E:").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("0.").parse(), CHECK_THROWS_WITH(parse_string("0.").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '0.'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.'");
CHECK_THROWS_WITH(parse_string("-").parse(), CHECK_THROWS_WITH(parse_string("-").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '-'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-'");
CHECK_THROWS_WITH(parse_string("--").parse(), CHECK_THROWS_WITH(parse_string("--").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '--'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'");
CHECK_THROWS_WITH(parse_string("-0.").parse(), CHECK_THROWS_WITH(parse_string("-0.").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after '.'; last read '-0.'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after '.'; last read: '-0.'");
CHECK_THROWS_WITH(parse_string("-.").parse(), CHECK_THROWS_WITH(parse_string("-.").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '-.'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-.'");
CHECK_THROWS_WITH(parse_string("-:").parse(), CHECK_THROWS_WITH(parse_string("-:").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '-:'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-:'");
CHECK_THROWS_WITH(parse_string("0.:").parse(), CHECK_THROWS_WITH(parse_string("0.:").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '0.:'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.:'");
CHECK_THROWS_WITH(parse_string("e.").parse(), CHECK_THROWS_WITH(parse_string("e.").parse(),
"[json.exception.parse_error.101] parse error at 1: syntax error - invalid literal; last read 'e'"); "[json.exception.parse_error.101] parse error at 1: syntax error - invalid literal; last read: 'e'");
CHECK_THROWS_WITH(parse_string("1e.").parse(), CHECK_THROWS_WITH(parse_string("1e.").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1e.'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'");
CHECK_THROWS_WITH(parse_string("1e/").parse(), CHECK_THROWS_WITH(parse_string("1e/").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1e/'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'");
CHECK_THROWS_WITH(parse_string("1e:").parse(), CHECK_THROWS_WITH(parse_string("1e:").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1e:'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'");
CHECK_THROWS_WITH(parse_string("1E.").parse(), CHECK_THROWS_WITH(parse_string("1E.").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E.'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'");
CHECK_THROWS_WITH(parse_string("1E/").parse(), CHECK_THROWS_WITH(parse_string("1E/").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E/'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'");
CHECK_THROWS_WITH(parse_string("1E:").parse(), CHECK_THROWS_WITH(parse_string("1E:").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E:'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'");
// unexpected end of null // unexpected end of null
CHECK_THROWS_AS(parse_string("n").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("n").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("nu").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("nu").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("nul").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("nul").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("n").parse(), CHECK_THROWS_WITH(parse_string("n").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'null'; last read 'n'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'null'; last read: 'n'");
CHECK_THROWS_WITH(parse_string("nu").parse(), CHECK_THROWS_WITH(parse_string("nu").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'null'; last read 'nu'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'null'; last read: 'nu'");
CHECK_THROWS_WITH(parse_string("nul").parse(), CHECK_THROWS_WITH(parse_string("nul").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'null'; last read 'nul'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'null'; last read: 'nul'");
// unexpected end of true // unexpected end of true
CHECK_THROWS_AS(parse_string("t").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("t").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("tr").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("tr").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("tru").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("tru").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("t").parse(), CHECK_THROWS_WITH(parse_string("t").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'true'; last read 't'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'true'; last read: 't'");
CHECK_THROWS_WITH(parse_string("tr").parse(), CHECK_THROWS_WITH(parse_string("tr").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'true'; last read 'tr'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'true'; last read: 'tr'");
CHECK_THROWS_WITH(parse_string("tru").parse(), CHECK_THROWS_WITH(parse_string("tru").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'true'; last read 'tru'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'true'; last read: 'tru'");
// unexpected end of false // unexpected end of false
CHECK_THROWS_AS(parse_string("f").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("f").parse(), json::parse_error);
@ -686,13 +686,13 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parse_string("fal").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("fal").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("fals").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("fals").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("f").parse(), CHECK_THROWS_WITH(parse_string("f").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'false'; last read 'f'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'false'; last read: 'f'");
CHECK_THROWS_WITH(parse_string("fa").parse(), CHECK_THROWS_WITH(parse_string("fa").parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'false'; last read 'fa'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'false'; last read: 'fa'");
CHECK_THROWS_WITH(parse_string("fal").parse(), CHECK_THROWS_WITH(parse_string("fal").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read 'fal'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read: 'fal'");
CHECK_THROWS_WITH(parse_string("fals").parse(), CHECK_THROWS_WITH(parse_string("fals").parse(),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; expected 'false'; last read 'fals'"); "[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; expected 'false'; last read: 'fals'");
// missing/unexpected end of array // missing/unexpected end of array
CHECK_THROWS_AS(parse_string("[").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("[").parse(), json::parse_error);
@ -743,25 +743,25 @@ TEST_CASE("parser class")
CHECK_THROWS_AS(parse_string("\"\\u01").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\\u01").parse(), json::parse_error);
CHECK_THROWS_AS(parse_string("\"\\u012").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\\u012").parse(), json::parse_error);
CHECK_THROWS_WITH(parse_string("\"").parse(), CHECK_THROWS_WITH(parse_string("\"").parse(),
"[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: missing closing quote; last read '\"'"); "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: missing closing quote; last read: '\"'");
CHECK_THROWS_WITH(parse_string("\"\\\"").parse(), CHECK_THROWS_WITH(parse_string("\"\\\"").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: missing closing quote; last read '\"\\\"'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: missing closing quote; last read: '\"\\\"'");
CHECK_THROWS_WITH(parse_string("\"\\u\"").parse(), CHECK_THROWS_WITH(parse_string("\"\\u\"").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u\"'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u\"'");
CHECK_THROWS_WITH(parse_string("\"\\u0\"").parse(), CHECK_THROWS_WITH(parse_string("\"\\u0\"").parse(),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u0\"'"); "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0\"'");
CHECK_THROWS_WITH(parse_string("\"\\u01\"").parse(), CHECK_THROWS_WITH(parse_string("\"\\u01\"").parse(),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u01\"'"); "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'");
CHECK_THROWS_WITH(parse_string("\"\\u012\"").parse(), CHECK_THROWS_WITH(parse_string("\"\\u012\"").parse(),
"[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u012\"'"); "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012\"'");
CHECK_THROWS_WITH(parse_string("\"\\u").parse(), CHECK_THROWS_WITH(parse_string("\"\\u").parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u'");
CHECK_THROWS_WITH(parse_string("\"\\u0").parse(), CHECK_THROWS_WITH(parse_string("\"\\u0").parse(),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u0'"); "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0'");
CHECK_THROWS_WITH(parse_string("\"\\u01").parse(), CHECK_THROWS_WITH(parse_string("\"\\u01").parse(),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u01'"); "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01'");
CHECK_THROWS_WITH(parse_string("\"\\u012").parse(), CHECK_THROWS_WITH(parse_string("\"\\u012").parse(),
"[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u012'"); "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012'");
// invalid escapes // invalid escapes
for (int c = 1; c < 128; ++c) for (int c = 1; c < 128; ++c)
@ -798,7 +798,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parse_string(s.c_str()).parse(), CHECK_THROWS_WITH(parse_string(s.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 3: syntax error - invalid string: forbidden character after backslash; last read '\"\\" + std::string(1, static_cast<char>(c)) + "'"); "[json.exception.parse_error.101] parse error at 3: syntax error - invalid string: forbidden character after backslash; last read: '\"\\" + std::string(1, static_cast<char>(c)) + "'");
} }
break; break;
} }
@ -874,7 +874,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parse_string(s1.c_str()).parse(), CHECK_THROWS_WITH(parse_string(s1.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s1.substr(0, 7) + "'"); "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s1.substr(0, 7) + "'");
} }
CAPTURE(s2); CAPTURE(s2);
@ -883,7 +883,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parse_string(s2.c_str()).parse(), CHECK_THROWS_WITH(parse_string(s2.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s2.substr(0, 6) + "'"); "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s2.substr(0, 6) + "'");
} }
CAPTURE(s3); CAPTURE(s3);
@ -892,7 +892,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parse_string(s3.c_str()).parse(), CHECK_THROWS_WITH(parse_string(s3.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s3.substr(0, 5) + "'"); "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s3.substr(0, 5) + "'");
} }
CAPTURE(s4); CAPTURE(s4);
@ -901,7 +901,7 @@ TEST_CASE("parser class")
if (c > 0x1f) if (c > 0x1f)
{ {
CHECK_THROWS_WITH(parse_string(s4.c_str()).parse(), CHECK_THROWS_WITH(parse_string(s4.c_str()).parse(),
"[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s4.substr(0, 4) + "'"); "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s4.substr(0, 4) + "'");
} }
} }
} }
@ -910,17 +910,17 @@ TEST_CASE("parser class")
// missing part of a surrogate pair // missing part of a surrogate pair
CHECK_THROWS_AS(json::parse("\"\\uD80C\""), json::parse_error); CHECK_THROWS_AS(json::parse("\"\\uD80C\""), json::parse_error);
CHECK_THROWS_WITH(json::parse("\"\\uD80C\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\""),
"[json.exception.parse_error.101] parse error at 8: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\"'"); "[json.exception.parse_error.101] parse error at 8: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\"'");
// invalid surrogate pair // invalid surrogate pair
CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), json::parse_error); CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), json::parse_error);
CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), json::parse_error); CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), json::parse_error);
CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), json::parse_error); CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), json::parse_error);
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""),
"[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\\uD80C'"); "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uD80C'");
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""),
"[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\\u0000'"); "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\u0000'");
CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""), CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""),
"[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\\uFFFF'"); "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uFFFF'");
} }
SECTION("parse errors (accept)") SECTION("parse errors (accept)")