Fix parsing empty arrays/objects

This commit is contained in:
2025-05-14 19:41:57 -04:00
parent 555b388509
commit c30e3e6713

View File

@@ -143,6 +143,8 @@ enum Symbol : int8_t {
T_COLON, T_COLON,
// Nonterminals // Nonterminals
N_VALUE, N_VALUE,
N_ARRAY_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_PAST_END, // Must be last nonterminal N_PAST_END, // Must be last nonterminal
@@ -152,6 +154,8 @@ const char *symbolNames[] = {
"T_STRING", "T_STRING",
"T_COLON", "T_COLON",
"N_VALUE", "N_VALUE",
"N_ARRAY_VALUE_OR_END",
"N_OBJECT_VALUE_OR_END",
"N_ARRAY_MAYBE_CONTINUE", "N_ARRAY_MAYBE_CONTINUE",
"N_OBJECT_MAYBE_CONTINUE", "N_OBJECT_MAYBE_CONTINUE",
}; };
@@ -531,14 +535,14 @@ private:
} else if (self->parseLiteral("{")) { } else if (self->parseLiteral("{")) {
self->pop(); self->pop();
self->callbacks->on_begin_object(self->data); self->callbacks->on_begin_object(self->data);
if (!self->push({T_STRING, T_COLON, N_VALUE, N_OBJECT_MAYBE_CONTINUE})) { if (!self->push({N_OBJECT_VALUE_OR_END})) {
return false; return false;
} }
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
} else if (self->parseLiteral("[")) { } else if (self->parseLiteral("[")) {
self->pop(); self->pop();
self->callbacks->on_begin_array(self->data); self->callbacks->on_begin_array(self->data);
if (!self->push({N_VALUE, N_ARRAY_MAYBE_CONTINUE})) { if (!self->push({N_ARRAY_VALUE_OR_END})) {
return false; return false;
} }
MUSTTAIL return keepGoing(self); MUSTTAIL return keepGoing(self);
@@ -557,6 +561,33 @@ private:
} }
return false; return false;
} }
static bool arrayOrEnd(Parser2 *self) {
if (self->parseLiteral("]")) {
self->pop();
self->callbacks->on_end_array(self->data);
MUSTTAIL return keepGoing(self);
} else {
self->pop();
if (!self->push({N_VALUE, N_ARRAY_MAYBE_CONTINUE})) {
return false;
}
MUSTTAIL return keepGoing(self);
}
}
static bool objectOrEnd(Parser2 *self) {
if (self->parseLiteral("}")) {
self->pop();
self->callbacks->on_end_object(self->data);
MUSTTAIL return keepGoing(self);
} else {
self->pop();
if (!self->push({T_STRING, T_COLON, N_VALUE, N_OBJECT_MAYBE_CONTINUE})) {
return false;
}
MUSTTAIL return keepGoing(self);
}
return false;
}
static bool arrayContinue(Parser2 *self) { static bool arrayContinue(Parser2 *self) {
if (self->parseLiteral(",")) { if (self->parseLiteral(",")) {
self->pop(); self->pop();
@@ -590,6 +621,8 @@ private:
/*T_STRING*/ string, /*T_STRING*/ string,
/*T_COLON*/ colon, /*T_COLON*/ colon,
/*N_VALUE*/ value, /*N_VALUE*/ value,
/*N_ARRAY_VALUE_OR_END*/ arrayOrEnd,
/*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,
}; };