Add whitespace nonterminal

This commit is contained in:
2025-05-15 20:33:56 -04:00
parent d8a8bcbd19
commit 3cedd66d74

View File

@@ -157,6 +157,7 @@ enum Symbol : int8_t {
N_OBJECT_VALUE_OR_END, N_OBJECT_VALUE_OR_END,
N_ARRAY_MAYBE_CONTINUE, N_ARRAY_MAYBE_CONTINUE,
N_OBJECT_MAYBE_CONTINUE, N_OBJECT_MAYBE_CONTINUE,
N_WHITESPACE,
N_PAST_END, // Must be last nonterminal N_PAST_END, // Must be last nonterminal
}; };
@@ -178,6 +179,7 @@ static const char *symbolNames[N_PAST_END] = {
"N_OBJECT_VALUE_OR_END", "N_OBJECT_VALUE_OR_END",
"N_ARRAY_MAYBE_CONTINUE", "N_ARRAY_MAYBE_CONTINUE",
"N_OBJECT_MAYBE_CONTINUE", "N_OBJECT_MAYBE_CONTINUE",
"N_WHITESPACE",
}; };
constexpr static struct Tables { constexpr static struct Tables {
@@ -437,7 +439,7 @@ private:
struct Parser2 { struct Parser2 {
Parser2(const Callbacks *callbacks, void *data) Parser2(const Callbacks *callbacks, void *data)
: callbacks(callbacks), data(data) { : callbacks(callbacks), data(data) {
std::ignore = push({N_VALUE}); std::ignore = push({N_WHITESPACE, N_VALUE});
} }
void prime(char *buf, int len) { void prime(char *buf, int len) {
@@ -481,7 +483,9 @@ private:
break; break;
} }
} }
if (buf != bufBefore) {
callbacks->on_number_data(data, bufBefore, buf - bufBefore); callbacks->on_number_data(data, bufBefore, buf - bufBefore);
}
if (len() == 0) { if (len() == 0) {
return S_AGAIN; return S_AGAIN;
} }
@@ -517,7 +521,6 @@ private:
if (self->empty()) { if (self->empty()) {
return S_OK; return S_OK;
} }
self->maybeSkipWs();
if (self->len() == 0) { if (self->len() == 0) {
return S_AGAIN; return S_AGAIN;
} }
@@ -545,7 +548,7 @@ private:
++self->buf; ++self->buf;
self->callbacks->on_begin_object(self->data); self->callbacks->on_begin_object(self->data);
self->pop(); self->pop();
if (Status s = self->push({N_OBJECT_VALUE_OR_END})) { if (Status s = self->push({N_WHITESPACE, N_OBJECT_VALUE_OR_END})) {
return s; return s;
} }
break; break;
@@ -553,7 +556,7 @@ private:
++self->buf; ++self->buf;
self->callbacks->on_begin_array(self->data); self->callbacks->on_begin_array(self->data);
self->pop(); self->pop();
if (Status s = self->push({N_ARRAY_VALUE_OR_END})) { if (Status s = self->push({N_WHITESPACE, N_ARRAY_VALUE_OR_END})) {
return s; return s;
} }
break; break;
@@ -604,7 +607,8 @@ private:
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
} else { } else {
self->pop(); self->pop();
if (Status s = self->push({N_VALUE, N_ARRAY_MAYBE_CONTINUE})) { if (Status s =
self->push({N_VALUE, N_WHITESPACE, N_ARRAY_MAYBE_CONTINUE})) {
return s; return s;
} }
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
@@ -617,10 +621,12 @@ private:
self->callbacks->on_end_object(self->data); self->callbacks->on_end_object(self->data);
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
} else if (*self->buf == '"') { } else if (*self->buf == '"') {
self->callbacks->on_begin_string(self->data);
++self->buf; ++self->buf;
self->pop(); self->pop();
if (Status s = self->push( if (Status s =
{N_STRING, T_COLON, N_VALUE, N_OBJECT_MAYBE_CONTINUE})) { self->push({N_STRING, N_WHITESPACE, T_COLON, N_WHITESPACE,
N_VALUE, N_WHITESPACE, N_OBJECT_MAYBE_CONTINUE})) {
return s; return s;
} }
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
@@ -631,7 +637,8 @@ private:
if (*self->buf == ',') { if (*self->buf == ',') {
++self->buf; ++self->buf;
self->pop(); self->pop();
if (Status s = self->push({N_VALUE, N_ARRAY_MAYBE_CONTINUE})) { if (Status s = self->push(
{N_WHITESPACE, N_VALUE, N_WHITESPACE, N_ARRAY_MAYBE_CONTINUE})) {
return s; return s;
} }
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
@@ -647,8 +654,9 @@ private:
if (*self->buf == ',') { if (*self->buf == ',') {
++self->buf; ++self->buf;
self->pop(); self->pop();
if (Status s = self->push({T_DUBQUOTE, N_STRING, T_COLON, N_VALUE, if (Status s = self->push({N_WHITESPACE, T_DUBQUOTE, N_STRING,
N_OBJECT_MAYBE_CONTINUE})) { N_WHITESPACE, T_COLON, N_WHITESPACE, N_VALUE,
N_WHITESPACE, N_OBJECT_MAYBE_CONTINUE})) {
return s; return s;
} }
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
@@ -691,8 +699,24 @@ private:
} }
return S_REJECT; return S_REJECT;
} }
static Status dubquote(Parser2 *self) {
if (*self->buf++ == '"') {
self->callbacks->on_begin_string(self->data);
self->pop();
MUSTTAIL return keepGoing(self);
}
return S_REJECT;
}
static Status whitespace(Parser2 *self) {
self->maybeSkipWs();
if (self->len() == 0) {
return S_AGAIN;
}
self->pop();
MUSTTAIL return keepGoing(self);
}
static constexpr continuation table[N_PAST_END] = { static constexpr continuation table[] = {
/*T_COLON*/ singleChar<':'>, /*T_COLON*/ singleChar<':'>,
/*T_TRUE*/ finishTrue, /*T_TRUE*/ finishTrue,
/*T_FALSE*/ finishFalse, /*T_FALSE*/ finishFalse,
@@ -702,7 +726,7 @@ private:
/*T_A*/ singleChar<'a'>, /*T_A*/ singleChar<'a'>,
/*T_L*/ singleChar<'l'>, /*T_L*/ singleChar<'l'>,
/*T_S*/ singleChar<'s'>, /*T_S*/ singleChar<'s'>,
/*T_DUBQUOTE*/ singleChar<'"'>, /*T_DUBQUOTE*/ dubquote,
/*N_STRING*/ string, /*N_STRING*/ string,
/*N_NUMBER*/ number, /*N_NUMBER*/ number,
/*N_VALUE*/ value, /*N_VALUE*/ value,
@@ -710,8 +734,11 @@ private:
/*N_OBJECT_VALUE_OR_END*/ objectOrEnd, /*N_OBJECT_VALUE_OR_END*/ objectOrEnd,
/*N_ARRAY_MAYBE_CONTINUE*/ arrayContinue, /*N_ARRAY_MAYBE_CONTINUE*/ arrayContinue,
/*N_OBJECT_MAYBE_CONTINUE*/ objectContinue, /*N_OBJECT_MAYBE_CONTINUE*/ objectContinue,
/*N_WHITESPACE*/ whitespace,
}; };
static_assert(sizeof(table) / sizeof(table[0]) == N_PAST_END);
char *buf = nullptr; char *buf = nullptr;
char *bufEnd = nullptr; char *bufEnd = nullptr;
int len() const { return bufEnd - buf; } int len() const { return bufEnd - buf; }