Call on_number_data with all available bytes

This commit is contained in:
2025-05-19 12:37:06 -04:00
parent 5ae8d4343c
commit b7cacf13f4

View File

@@ -68,6 +68,7 @@ enum Symbol : uint8_t {
T_DIGIT, T_DIGIT,
T_ONENINE, T_ONENINE,
T_EOF, T_EOF,
T_END_NUMBER,
N_SYMBOL_COUNT, // Must be last N_SYMBOL_COUNT, // Must be last
}; };
struct Parser3 { struct Parser3 {
@@ -78,11 +79,16 @@ struct Parser3 {
[[nodiscard]] Status parse(char *buf, int len) { [[nodiscard]] Status parse(char *buf, int len) {
complete = len == 0; complete = len == 0;
this->buf = buf; this->buf = this->dataBegin = buf;
this->bufEnd = buf + len; this->bufEnd = buf + len;
return keepGoing(this); return keepGoing(this);
} }
void flushNumber() {
int len = buf - dataBegin;
callbacks->on_number_data(data, dataBegin, len);
}
[[nodiscard]] bool empty() const { return stackPtr == stack; } [[nodiscard]] bool empty() const { return stackPtr == stack; }
void pop() { void pop() {
assert(!empty()); assert(!empty());
@@ -114,6 +120,8 @@ struct Parser3 {
[[maybe_unused]] void debugPrint(); [[maybe_unused]] void debugPrint();
char *buf = nullptr; char *buf = nullptr;
char *bufEnd = nullptr; char *bufEnd = nullptr;
// Used for flushing pending data with on_*_data callbacks
char *dataBegin;
const Callbacks *const callbacks; const Callbacks *const callbacks;
void *const data; void *const data;
Symbol stack[kMaxStackSize]; Symbol stack[kMaxStackSize];
@@ -520,7 +528,7 @@ inline Status t_hex(Parser3 *self) {
inline Status n_number(Parser3 *self) { inline Status n_number(Parser3 *self) {
self->pop(); self->pop();
if (auto s = self->push({N_INTEGER, N_FRACTION, N_EXPONENT})) { if (auto s = self->push({N_INTEGER, N_FRACTION, N_EXPONENT, T_END_NUMBER})) {
return s; return s;
} }
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -531,9 +539,9 @@ inline Status n_integer(Parser3 *self) {
return S_REJECT; return S_REJECT;
} }
self->callbacks->on_begin_number(self->data); self->callbacks->on_begin_number(self->data);
self->dataBegin = self->buf;
switch (*self->buf) { switch (*self->buf) {
case '0': case '0':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -546,7 +554,6 @@ inline Status n_integer(Parser3 *self) {
case '7': case '7':
case '8': case '8':
case '9': case '9':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
if (auto s = self->push({N_DIGITS2})) { if (auto s = self->push({N_DIGITS2})) {
@@ -554,7 +561,6 @@ inline Status n_integer(Parser3 *self) {
} }
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
case '-': case '-':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
if (auto s = self->push({N_INTEGER2})) { if (auto s = self->push({N_INTEGER2})) {
@@ -572,7 +578,6 @@ inline Status n_integer2(Parser3 *self) {
} }
switch (*self->buf) { switch (*self->buf) {
case '0': case '0':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -585,7 +590,6 @@ inline Status n_integer2(Parser3 *self) {
case '7': case '7':
case '8': case '8':
case '9': case '9':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
if (auto s = self->push({N_DIGITS2})) { if (auto s = self->push({N_DIGITS2})) {
@@ -612,7 +616,6 @@ inline Status n_digits(Parser3 *self) {
case '7': case '7':
case '8': case '8':
case '9': case '9':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
if (auto s = self->push({N_DIGITS2})) { if (auto s = self->push({N_DIGITS2})) {
@@ -640,7 +643,6 @@ inline Status n_digits2(Parser3 *self) {
case '7': case '7':
case '8': case '8':
case '9': case '9':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
default: default:
@@ -656,7 +658,6 @@ inline Status n_fraction(Parser3 *self) {
} }
switch (*self->buf) { switch (*self->buf) {
case '.': case '.':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
if (auto s = self->push({N_DIGITS})) { if (auto s = self->push({N_DIGITS})) {
@@ -677,7 +678,6 @@ inline Status n_exponent(Parser3 *self) {
switch (*self->buf) { switch (*self->buf) {
case 'e': case 'e':
case 'E': case 'E':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
if (auto s = self->push({N_SIGN, N_DIGITS})) { if (auto s = self->push({N_SIGN, N_DIGITS})) {
@@ -698,7 +698,6 @@ inline Status n_sign(Parser3 *self) {
switch (*self->buf) { switch (*self->buf) {
case '+': case '+':
case '-': case '-':
self->callbacks->on_number_data(self->data, self->buf, 1);
++self->buf; ++self->buf;
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -779,6 +778,13 @@ inline Status t_eof(Parser3 *self) {
return self->complete ? S_OK : S_AGAIN; return self->complete ? S_OK : S_AGAIN;
} }
inline Status t_end_number(Parser3 *self) {
self->pop();
self->flushNumber();
self->callbacks->on_end_number(self->data);
MUSTTAIL return Parser3::keepGoing(self);
}
constexpr inline struct ContinuationTable { constexpr inline struct ContinuationTable {
constexpr ContinuationTable() { constexpr ContinuationTable() {
// Defaults // Defaults
@@ -825,6 +831,7 @@ constexpr inline struct ContinuationTable {
continuations[T_DIGIT] = t_digit; continuations[T_DIGIT] = t_digit;
continuations[T_ONENINE] = t_onenine; continuations[T_ONENINE] = t_onenine;
continuations[T_EOF] = t_eof; continuations[T_EOF] = t_eof;
continuations[T_END_NUMBER] = t_end_number;
symbolNames[N_JSON] = "n_json"; symbolNames[N_JSON] = "n_json";
symbolNames[N_VALUE] = "n_value"; symbolNames[N_VALUE] = "n_value";
symbolNames[N_OBJECT] = "n_object"; symbolNames[N_OBJECT] = "n_object";
@@ -860,6 +867,7 @@ constexpr inline struct ContinuationTable {
symbolNames[T_DIGIT] = "t_digit"; symbolNames[T_DIGIT] = "t_digit";
symbolNames[T_ONENINE] = "t_onenine"; symbolNames[T_ONENINE] = "t_onenine";
symbolNames[T_EOF] = "t_eof"; symbolNames[T_EOF] = "t_eof";
symbolNames[T_END_NUMBER] = "t_end_number";
} }
Continuation continuations[N_SYMBOL_COUNT]{}; Continuation continuations[N_SYMBOL_COUNT]{};
const char *symbolNames[N_SYMBOL_COUNT]{}; const char *symbolNames[N_SYMBOL_COUNT]{};
@@ -867,6 +875,49 @@ constexpr inline struct ContinuationTable {
inline Status Parser3::keepGoing(Parser3 *self) { inline Status Parser3::keepGoing(Parser3 *self) {
if (self->len() == 0 && !self->complete) { if (self->len() == 0 && !self->complete) {
switch (self->top()) {
case N_NUMBER:
case N_INTEGER:
case N_INTEGER2:
case N_DIGITS:
case N_DIGITS2:
case N_FRACTION:
case N_EXPONENT:
case N_SIGN:
case T_DIGIT:
case T_ONENINE:
case T_END_NUMBER:
self->flushNumber();
break;
case N_JSON:
case N_VALUE:
case N_OBJECT:
case N_OBJECT2:
case N_OBJECT3:
case N_ARRAY:
case N_ARRAY2:
case N_ARRAY3:
case N_ELEMENT:
case N_STRING:
case N_STRING2:
case N_STRING_FOLLOWING_ESCAPE:
case N_WHITESPACE:
case N_TRUE:
case N_FALSE:
case N_NULL:
case T_R:
case T_U:
case T_A:
case T_L:
case T_S:
case T_COLON:
case T_UTF8_CONTINUATION_BYTE:
case T_UTF8_LAST_CONTINUATION_BYTE:
case T_HEX:
case T_EOF:
case N_SYMBOL_COUNT:
break;
}
return S_AGAIN; return S_AGAIN;
} }
// self->debugPrint(); // self->debugPrint();