diff --git a/src/test.cpp b/src/test.cpp index ab16594..5d4141e 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -516,12 +516,7 @@ private: self->nextToken(); MUSTTAIL return keepGoing(self); } - // If the top of the stack is a terminal that doesn't match, reject - if (self->stack.back() < T_PAST_END) { - return false; - } - MUSTTAIL return table[self->stack.back() - T_PAST_END][self->currentToken]( - self); + MUSTTAIL return table[self->stack.back()][self->currentToken](self); } PRESERVE_NONE static bool reject(Parser2 *) { return false; } @@ -602,7 +597,137 @@ private: } // table[nonterminal][terminal] - static constexpr continuation table[N_PAST_END - T_PAST_END][T_PAST_END] = { + static constexpr continuation table[N_PAST_END][T_PAST_END] = { + /*T_INVALID*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_EOF*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_LBRACE*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_RBRACE*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_COMMA*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_ATOM*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_STRING*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_LBRACKET*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_RBRACKET*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, + /*T_COLON*/ + { + /*T_INVALID*/ reject, + /*T_EOF*/ reject, + /*T_LBRACE*/ reject, + /*T_RBRACE*/ reject, + /*T_COMMA*/ reject, + /*T_ATOM*/ reject, + /*T_STRING*/ reject, + /*T_LBRACKET*/ reject, + /*T_RBRACKET*/ reject, + /*T_COLON*/ reject, + }, /*N_VALUE*/ { /*T_INVALID*/ reject, @@ -659,54 +784,69 @@ private: Symbol currentToken; const char *bufBefore; - Symbol nextToken() { + void nextToken() { maybeSkipWs(); bufBefore = buf; if (len == 0) { - return currentToken = T_EOF; + currentToken = T_EOF; + return; } if (*buf == '{') { parseLiteral("{"); - return currentToken = T_LBRACE; + currentToken = T_LBRACE; + return; } else if (*buf == '[') { parseLiteral("["); - return currentToken = T_LBRACKET; + currentToken = T_LBRACKET; + return; } else if (*buf == '}') { parseLiteral("}"); - return currentToken = T_RBRACE; + currentToken = T_RBRACE; + return; } else if (*buf == ']') { parseLiteral("]"); - return currentToken = T_RBRACKET; + currentToken = T_RBRACKET; + return; } else if (*buf == ':') { parseLiteral(":"); - return currentToken = T_COLON; + currentToken = T_COLON; + return; } else if (*buf == ',') { parseLiteral(","); - return currentToken = T_COMMA; + currentToken = T_COMMA; + return; } else if (*buf == '"') { if (!parse_string()) { - return currentToken = T_INVALID; + currentToken = T_INVALID; + return; } - return currentToken = T_STRING; + currentToken = T_STRING; + return; } else if (*buf == 't') { if (!parseLiteral("true")) { - return currentToken = T_INVALID; + currentToken = T_INVALID; + return; } - return currentToken = T_ATOM; + currentToken = T_ATOM; + return; } else if (*buf == 'f') { if (!parseLiteral("false")) { - return currentToken = T_INVALID; + currentToken = T_INVALID; + return; } } else if (*buf == 'n') { if (!parseLiteral("null")) { - return currentToken = T_INVALID; + currentToken = T_INVALID; + return; } } else { if (!parse_number()) { - return currentToken = T_INVALID; + currentToken = T_INVALID; + return; } } - return currentToken = T_ATOM; + currentToken = T_ATOM; + return; } char *buf; @@ -798,3 +938,15 @@ TEST_CASE("bench") { bench.doNotOptimizeAway(parser.parse()); }); } + +TEST_CASE("bench2") { + auto c = Callbacks{}; + ankerl::nanobench::Bench bench; + bench.batch(json.size()); + bench.unit("byte"); + bench.run("parser2", [&]() { + auto copy = json; + Parser2 parser(copy.data(), copy.length(), &c, nullptr); + bench.doNotOptimizeAway(parser.parse()); + }); +}