diff --git a/src/parser3.h b/src/parser3.h index 30c1a99..41a5ac2 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -160,9 +160,6 @@ inline Status n_json(Parser3 *self) { } inline Status n_value(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case '{': self->pop(); @@ -226,9 +223,6 @@ inline Status n_value(Parser3 *self) { } inline Status n_object(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (*self->buf != '{') { return S_REJECT; } @@ -242,9 +236,6 @@ inline Status n_object(Parser3 *self) { } inline Status n_object2(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case '}': ++self->buf; @@ -264,9 +255,6 @@ inline Status n_object2(Parser3 *self) { } inline Status n_object3(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case '}': ++self->buf; @@ -287,9 +275,6 @@ inline Status n_object3(Parser3 *self) { } inline Status n_array(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (*self->buf != '[') { return S_REJECT; } @@ -303,9 +288,6 @@ inline Status n_array(Parser3 *self) { } inline Status n_array2(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case ']': ++self->buf; @@ -322,9 +304,6 @@ inline Status n_array2(Parser3 *self) { } inline Status n_array3(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case ']': ++self->buf; @@ -352,9 +331,6 @@ inline Status n_element(Parser3 *self) { } inline Status n_string(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (*self->buf != '"') { return S_REJECT; } @@ -369,9 +345,6 @@ inline Status n_string(Parser3 *self) { } inline Status n_string2(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (tables.invalidStringByte[uint8_t(*self->buf)]) { return S_REJECT; } @@ -433,9 +406,6 @@ inline Status n_string2(Parser3 *self) { } inline Status n_string_following_escape(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case '"': case '\\': @@ -465,9 +435,6 @@ inline Status n_string_following_escape(Parser3 *self) { } inline Status t_utf8_continuation_byte(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (tables.invalidStringByte[uint8_t(*self->buf)]) { return S_REJECT; } @@ -482,9 +449,6 @@ inline Status t_utf8_continuation_byte(Parser3 *self) { } inline Status t_utf8_last_continuation_byte(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (tables.invalidStringByte[uint8_t(*self->buf)]) { return S_REJECT; } @@ -505,9 +469,6 @@ inline Status t_utf8_last_continuation_byte(Parser3 *self) { } inline Status t_digit(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if ('0' <= *self->buf && *self->buf <= '9') { ++self->buf; self->pop(); @@ -517,9 +478,6 @@ inline Status t_digit(Parser3 *self) { } inline Status t_onenine(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if ('1' <= *self->buf && *self->buf <= '9') { ++self->buf; self->pop(); @@ -529,9 +487,6 @@ inline Status t_onenine(Parser3 *self) { } inline Status t_hex(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -548,9 +503,6 @@ inline Status t_hex(Parser3 *self) { } inline Status t_hex2(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -618,9 +570,6 @@ inline Status t_hex2(Parser3 *self) { } inline Status t_hex3(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } self->utf8Codepoint <<= 4; if (('0' <= *self->buf && *self->buf <= '9')) { self->utf8Codepoint |= *self->buf - '0'; @@ -679,9 +628,6 @@ inline Status n_number(Parser3 *self) { } inline Status n_integer(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } self->callbacks->on_begin_number(self->data); self->dataBegin = self->buf; switch (*self->buf) { @@ -717,9 +663,6 @@ inline Status n_integer(Parser3 *self) { } inline Status n_integer2(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case '0': ++self->buf; @@ -746,9 +689,6 @@ inline Status n_integer2(Parser3 *self) { } inline Status n_digits(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } switch (*self->buf) { case '0': case '1': @@ -867,9 +807,6 @@ inline Status n_whitespace(Parser3 *self) { } inline Status n_true(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (*self->buf == 'e') { ++self->buf; self->pop(); @@ -880,9 +817,6 @@ inline Status n_true(Parser3 *self) { } inline Status n_false(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (*self->buf == 'e') { ++self->buf; self->pop(); @@ -893,9 +827,6 @@ inline Status n_false(Parser3 *self) { } inline Status n_null(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (*self->buf == 'l') { ++self->buf; self->pop(); @@ -906,9 +837,6 @@ inline Status n_null(Parser3 *self) { } template inline Status singleChar(Parser3 *self) { - if (self->len() == 0) { - return S_REJECT; - } if (*self->buf == kChar) { ++self->buf; self->pop(); @@ -982,6 +910,7 @@ constexpr inline struct ContinuationTable { continuations[T_EOF] = t_eof; continuations[T_END_NUMBER] = t_end_number; continuations[T_BACKSLASH] = singleChar<'\\'>; + symbolNames[N_JSON] = "n_json"; symbolNames[N_VALUE] = "n_value"; symbolNames[N_OBJECT] = "n_object"; @@ -1022,65 +951,80 @@ constexpr inline struct ContinuationTable { symbolNames[T_EOF] = "t_eof"; symbolNames[T_BACKSLASH] = "singleChar<'\\'>"; symbolNames[T_END_NUMBER] = "t_end_number"; + + // All others can assume that there's at least one byte when they're called + acceptsEmptyString[N_DIGITS2] = true; + acceptsEmptyString[N_FRACTION] = true; + acceptsEmptyString[N_EXPONENT] = true; + acceptsEmptyString[N_SIGN] = true; + acceptsEmptyString[N_WHITESPACE] = true; + acceptsEmptyString[T_EOF] = true; + acceptsEmptyString[T_END_NUMBER] = true; } Continuation continuations[N_SYMBOL_COUNT]{}; const char *symbolNames[N_SYMBOL_COUNT]{}; + bool acceptsEmptyString[N_SYMBOL_COUNT]{}; } symbolTables; inline Status Parser3::keepGoing(Parser3 *self) { - 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_STRING: - case N_STRING2: - case N_STRING_FOLLOWING_ESCAPE: - case T_UTF8_CONTINUATION_BYTE: - case T_UTF8_LAST_CONTINUATION_BYTE: - case T_HEX: - case T_HEX2: - case T_HEX3: - case T_BACKSLASH: - case T_U2: - self->flushString(); - 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_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_EOF: - case N_SYMBOL_COUNT: - break; - } - return S_AGAIN; - } // self->debugPrint(); + if (self->len() == 0) { + if (!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_STRING: + case N_STRING2: + case N_STRING_FOLLOWING_ESCAPE: + case T_UTF8_CONTINUATION_BYTE: + case T_UTF8_LAST_CONTINUATION_BYTE: + case T_HEX: + case T_HEX2: + case T_HEX3: + case T_BACKSLASH: + case T_U2: + self->flushString(); + 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_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_EOF: + case N_SYMBOL_COUNT: + break; + } + return S_AGAIN; + } + if (!symbolTables.acceptsEmptyString[self->top()]) { + return S_REJECT; + } + } MUSTTAIL return symbolTables.continuations[self->top()](self); }