diff --git a/src/core/json/grammar.h b/src/core/json/grammar.h index 093df10cf..6b9338af6 100644 --- a/src/core/json/grammar.h +++ b/src/core/json/grammar.h @@ -72,14 +72,17 @@ static constexpr CharT token_object_delimiter{'\u002C'}; // https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf // Boolean +template static constexpr CharT token_true{'\u0074'}; template static constexpr std::basic_string_view constant_true{ "\u0074\u0072\u0075\u0065"}; +template static constexpr CharT token_false{'\u0066'}; template static constexpr std::basic_string_view constant_false{ "\u0066\u0061\u006C\u0073\u0065"}; // Null +template static constexpr CharT token_null{'\u006E'}; template static constexpr std::basic_string_view constant_null{ "\u006E\u0075\u006C\u006C"}; diff --git a/src/core/json/parser.h b/src/core/json/parser.h index d18efd001..5dae84137 100644 --- a/src/core/json/parser.h +++ b/src/core/json/parser.h @@ -229,9 +229,11 @@ inline auto scan_string_escape(const std::uint64_t line, std::uint64_t &column, template inline auto scan_string(const std::uint64_t line, std::uint64_t &column, const char *&cursor, const char *end) -> void { + using CharT = typename JSON::Char; while (cursor < end) { const char *scan{cursor}; - while (scan < end && *scan != '"' && *scan != '\\' && + while (scan < end && *scan != internal::token_string_quote && + *scan != internal::token_string_escape && static_cast(*scan) >= 0x20) { scan++; } @@ -276,8 +278,10 @@ template inline auto scan_digits(const std::uint64_t line, std::uint64_t &column, const char *&cursor, const char *end, const bool at_least_one) -> void { + using CharT = typename JSON::Char; bool found{false}; - while (cursor < end && *cursor >= '0' && *cursor <= '9') { + while (cursor < end && *cursor >= internal::token_number_zero && + *cursor <= internal::token_number_nine) { found = true; if constexpr (TrackPositions) { column += 1; @@ -296,8 +300,10 @@ template inline auto scan_number(const std::uint64_t line, std::uint64_t &column, const char *&cursor, const char *end, const char first) -> void { - if (first == '-') { - if (cursor >= end || *cursor < '0' || *cursor > '9') { + using CharT = typename JSON::Char; + if (first == internal::token_number_minus) { + if (cursor >= end || *cursor < internal::token_number_zero || + *cursor > internal::token_number_nine) { if constexpr (TrackPositions) { column += 1; } @@ -305,16 +311,18 @@ inline auto scan_number(const std::uint64_t line, std::uint64_t &column, } } - const char int_start{first == '-' ? *cursor : first}; - if (first == '-') { + const char int_start{first == internal::token_number_minus ? *cursor + : first}; + if (first == internal::token_number_minus) { if constexpr (TrackPositions) { column += 1; } cursor++; } - if (int_start == '0') { - if (cursor < end && *cursor >= '0' && *cursor <= '9') { + if (int_start == internal::token_number_zero) { + if (cursor < end && *cursor >= internal::token_number_zero && + *cursor <= internal::token_number_nine) { if constexpr (TrackPositions) { column += 1; } @@ -324,7 +332,7 @@ inline auto scan_number(const std::uint64_t line, std::uint64_t &column, scan_digits(line, column, cursor, end, false); } - if (cursor < end && *cursor == '.') { + if (cursor < end && *cursor == internal::token_number_decimal_point) { if constexpr (TrackPositions) { column += 1; } @@ -332,12 +340,15 @@ inline auto scan_number(const std::uint64_t line, std::uint64_t &column, scan_digits(line, column, cursor, end, true); } - if (cursor < end && (*cursor == 'e' || *cursor == 'E')) { + if (cursor < end && + (*cursor == internal::token_number_exponent_lowercase || + *cursor == internal::token_number_exponent_uppercase)) { if constexpr (TrackPositions) { column += 1; } cursor++; - if (cursor < end && (*cursor == '+' || *cursor == '-')) { + if (cursor < end && (*cursor == internal::token_number_plus || + *cursor == internal::token_number_minus)) { if constexpr (TrackPositions) { column += 1; } @@ -361,6 +372,7 @@ inline auto scan_json(const char *&cursor, const char *end, std::uint32_t child_count; }; + using CharT = typename JSON::Char; char character = 0; std::vector container_stack; container_stack.reserve(32); @@ -381,19 +393,19 @@ inline auto scan_json(const char *&cursor, const char *end, const auto value_line{line}; const auto value_column{column}; switch (character) { - case 't': + case internal::token_true: internal::scan_true(line, column, cursor, end); tape.push_back({TapeType::True, 0, 0, 0, value_line, value_column}); return; - case 'f': + case internal::token_false: internal::scan_false(line, column, cursor, end); tape.push_back({TapeType::False, 0, 0, 0, value_line, value_column}); return; - case 'n': + case internal::token_null: internal::scan_null(line, column, cursor, end); tape.push_back({TapeType::Null, 0, 0, 0, value_line, value_column}); return; - case '"': { + case internal::token_string_quote: { const auto string_start{ static_cast(cursor - buffer_start)}; internal::scan_string(line, column, cursor, end); @@ -403,21 +415,21 @@ inline auto scan_json(const char *&cursor, const char *end, value_line, value_column}); return; } - case '[': + case internal::token_array_begin: goto do_scan_array; - case '{': + case internal::token_object_begin: goto do_scan_object; - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { + case internal::token_number_minus: + case internal::token_number_zero: + case internal::token_number_one: + case internal::token_number_two: + case internal::token_number_three: + case internal::token_number_four: + case internal::token_number_five: + case internal::token_number_six: + case internal::token_number_seven: + case internal::token_number_eight: + case internal::token_number_nine: { const auto number_start{ static_cast(cursor - buffer_start - 1)}; internal::scan_number(line, column, cursor, end, @@ -450,7 +462,7 @@ do_scan_array: { throw JSONParseError(line, column); } - if (*cursor == ']') { + if (*cursor == internal::token_array_end) { if constexpr (TrackPositions) { column += 1; } @@ -484,23 +496,23 @@ do_scan_array: { const auto value_line{line}; const auto value_column{column}; switch (character) { - case '[': + case internal::token_array_begin: goto do_scan_array; - case '{': + case internal::token_object_begin: goto do_scan_object; - case 't': + case internal::token_true: internal::scan_true(line, column, cursor, end); tape.push_back({TapeType::True, 0, 0, 0, value_line, value_column}); goto do_scan_array_item_separator; - case 'f': + case internal::token_false: internal::scan_false(line, column, cursor, end); tape.push_back({TapeType::False, 0, 0, 0, value_line, value_column}); goto do_scan_array_item_separator; - case 'n': + case internal::token_null: internal::scan_null(line, column, cursor, end); tape.push_back({TapeType::Null, 0, 0, 0, value_line, value_column}); goto do_scan_array_item_separator; - case '"': { + case internal::token_string_quote: { const auto string_start{ static_cast(cursor - buffer_start)}; internal::scan_string(line, column, cursor, end); @@ -510,17 +522,17 @@ do_scan_array: { value_line, value_column}); goto do_scan_array_item_separator; } - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { + case internal::token_number_minus: + case internal::token_number_zero: + case internal::token_number_one: + case internal::token_number_two: + case internal::token_number_three: + case internal::token_number_four: + case internal::token_number_five: + case internal::token_number_six: + case internal::token_number_seven: + case internal::token_number_eight: + case internal::token_number_nine: { const auto number_start{ static_cast(cursor - buffer_start - 1)}; internal::scan_number(line, column, cursor, end, @@ -549,9 +561,9 @@ do_scan_array: { } character = *cursor++; switch (character) { - case ',': + case internal::token_array_delimiter: goto do_scan_array_item; - case ']': { + case internal::token_array_end: { assert(!container_stack.empty()); auto &frame{container_stack.back()}; tape[frame.tape_index].count = frame.child_count; @@ -580,7 +592,7 @@ do_scan_object: { throw JSONParseError(line, column); } - if (*cursor == '}') { + if (*cursor == internal::token_object_end) { if constexpr (TrackPositions) { column += 1; } @@ -610,7 +622,7 @@ do_scan_object: { } character = *cursor++; switch (character) { - case '"': { + case internal::token_string_quote: { const auto key_start{static_cast(cursor - buffer_start)}; const auto key_line{line}; const auto key_column{column}; @@ -638,7 +650,7 @@ do_scan_object: { } character = *cursor++; switch (character) { - case ':': + case internal::token_object_key_delimiter: goto do_scan_object_value; default: throw JSONParseError(line, column); @@ -661,23 +673,23 @@ do_scan_object: { const auto value_line{line}; const auto value_column{column}; switch (character) { - case '[': + case internal::token_array_begin: goto do_scan_array; - case '{': + case internal::token_object_begin: goto do_scan_object; - case 't': + case internal::token_true: internal::scan_true(line, column, cursor, end); tape.push_back({TapeType::True, 0, 0, 0, value_line, value_column}); goto do_scan_object_property_end; - case 'f': + case internal::token_false: internal::scan_false(line, column, cursor, end); tape.push_back({TapeType::False, 0, 0, 0, value_line, value_column}); goto do_scan_object_property_end; - case 'n': + case internal::token_null: internal::scan_null(line, column, cursor, end); tape.push_back({TapeType::Null, 0, 0, 0, value_line, value_column}); goto do_scan_object_property_end; - case '"': { + case internal::token_string_quote: { const auto string_start{ static_cast(cursor - buffer_start)}; internal::scan_string(line, column, cursor, end); @@ -687,17 +699,17 @@ do_scan_object: { value_line, value_column}); goto do_scan_object_property_end; } - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { + case internal::token_number_minus: + case internal::token_number_zero: + case internal::token_number_one: + case internal::token_number_two: + case internal::token_number_three: + case internal::token_number_four: + case internal::token_number_five: + case internal::token_number_six: + case internal::token_number_seven: + case internal::token_number_eight: + case internal::token_number_nine: { const auto number_start{ static_cast(cursor - buffer_start - 1)}; internal::scan_number(line, column, cursor, end, @@ -726,9 +738,9 @@ do_scan_object: { } character = *cursor++; switch (character) { - case ',': + case internal::token_object_delimiter: goto do_scan_object_key; - case '}': { + case internal::token_object_end: { assert(!container_stack.empty()); auto &frame{container_stack.back()}; tape[frame.tape_index].count = frame.child_count;