Add PRESERVE_NONE to continuations

This commit is contained in:
2025-05-22 16:46:29 -04:00
parent ab23eda489
commit b2735330f9
2 changed files with 46 additions and 33 deletions

View File

@@ -19,12 +19,13 @@
#endif #endif
#include "musttail.h" #include "musttail.h"
#include "preserve_none.h"
#include "tables.h" #include "tables.h"
#include "weaseljson.h" #include "weaseljson.h"
namespace parser3 { namespace parser3 {
typedef WeaselJsonStatus (*Continuation)(struct Parser3 *); typedef PRESERVE_NONE WeaselJsonStatus (*Continuation)(struct Parser3 *);
// These appear in the stack of the pushdown // These appear in the stack of the pushdown
// automata // automata
@@ -119,7 +120,7 @@ struct Parser3 {
return *(stackPtr - 1); return *(stackPtr - 1);
} }
static WeaselJsonStatus keepGoing(Parser3 *self); static PRESERVE_NONE WeaselJsonStatus keepGoing(Parser3 *self);
constexpr static int kMaxStackSize = 1024; constexpr static int kMaxStackSize = 1024;
@@ -142,7 +143,7 @@ struct Parser3 {
uint32_t minCodepoint; uint32_t minCodepoint;
}; };
inline WeaselJsonStatus n_whitespace(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_whitespace(Parser3 *self) {
if (self->len() == 0) { if (self->len() == 0) {
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -157,7 +158,7 @@ inline WeaselJsonStatus n_whitespace(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus n_value(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self) {
assert(self->len() != 0); assert(self->len() != 0);
while (tables.whitespace[uint8_t(*self->buf)]) { while (tables.whitespace[uint8_t(*self->buf)]) {
++self->buf; ++self->buf;
@@ -280,7 +281,7 @@ inline WeaselJsonStatus n_value(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus n_object2(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self) {
assert(self->len() != 0); assert(self->len() != 0);
while (tables.whitespace[uint8_t(*self->buf)]) { while (tables.whitespace[uint8_t(*self->buf)]) {
++self->buf; ++self->buf;
@@ -308,7 +309,7 @@ inline WeaselJsonStatus n_object2(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_object3(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self) {
assert(self->len() != 0); assert(self->len() != 0);
while (tables.whitespace[uint8_t(*self->buf)]) { while (tables.whitespace[uint8_t(*self->buf)]) {
++self->buf; ++self->buf;
@@ -334,7 +335,7 @@ inline WeaselJsonStatus n_object3(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_array2(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_array2(Parser3 *self) {
assert(self->len() != 0); assert(self->len() != 0);
while (tables.whitespace[uint8_t(*self->buf)]) { while (tables.whitespace[uint8_t(*self->buf)]) {
++self->buf; ++self->buf;
@@ -357,7 +358,7 @@ inline WeaselJsonStatus n_array2(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_array3(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self) {
assert(self->len() != 0); assert(self->len() != 0);
while (tables.whitespace[uint8_t(*self->buf)]) { while (tables.whitespace[uint8_t(*self->buf)]) {
++self->buf; ++self->buf;
@@ -383,7 +384,7 @@ inline WeaselJsonStatus n_array3(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_string(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_string(Parser3 *self) {
assert(self->len() != 0); assert(self->len() != 0);
while (tables.whitespace[uint8_t(*self->buf)]) { while (tables.whitespace[uint8_t(*self->buf)]) {
++self->buf; ++self->buf;
@@ -404,7 +405,7 @@ inline WeaselJsonStatus n_string(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus n_string2(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self) {
const auto before = self->buf; const auto before = self->buf;
// Advance self->buf to the first "non-normal" character // Advance self->buf to the first "non-normal" character
@@ -531,7 +532,7 @@ inline WeaselJsonStatus n_string2(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_string_following_escape(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_string_following_escape(Parser3 *self) {
switch (*self->buf) { switch (*self->buf) {
case '"': case '"':
case '\\': case '\\':
@@ -560,7 +561,7 @@ inline WeaselJsonStatus n_string_following_escape(Parser3 *self) {
} }
} }
inline WeaselJsonStatus t_utf8_continuation_byte(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_utf8_continuation_byte(Parser3 *self) {
if (tables.stringByteMeaning[uint8_t(*self->buf)] != if (tables.stringByteMeaning[uint8_t(*self->buf)] !=
Tables::CONTINUATION_BYTE) [[unlikely]] { Tables::CONTINUATION_BYTE) [[unlikely]] {
return WeaselJson_REJECT; return WeaselJson_REJECT;
@@ -572,7 +573,8 @@ inline WeaselJsonStatus t_utf8_continuation_byte(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus t_utf8_last_continuation_byte(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus
t_utf8_last_continuation_byte(Parser3 *self) {
if (tables.stringByteMeaning[uint8_t(*self->buf)] != if (tables.stringByteMeaning[uint8_t(*self->buf)] !=
Tables::CONTINUATION_BYTE) [[unlikely]] { Tables::CONTINUATION_BYTE) [[unlikely]] {
return WeaselJson_REJECT; return WeaselJson_REJECT;
@@ -591,7 +593,7 @@ inline WeaselJsonStatus t_utf8_last_continuation_byte(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus t_digit(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_digit(Parser3 *self) {
if ('0' <= *self->buf && *self->buf <= '9') { if ('0' <= *self->buf && *self->buf <= '9') {
++self->buf; ++self->buf;
self->pop(); self->pop();
@@ -601,7 +603,7 @@ inline WeaselJsonStatus t_digit(Parser3 *self) {
} }
} }
inline WeaselJsonStatus t_onenine(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_onenine(Parser3 *self) {
if ('1' <= *self->buf && *self->buf <= '9') { if ('1' <= *self->buf && *self->buf <= '9') {
++self->buf; ++self->buf;
self->pop(); self->pop();
@@ -611,7 +613,7 @@ inline WeaselJsonStatus t_onenine(Parser3 *self) {
} }
} }
inline WeaselJsonStatus t_hex(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_hex(Parser3 *self) {
self->utf8Codepoint <<= 4; self->utf8Codepoint <<= 4;
if (('0' <= *self->buf && *self->buf <= '9')) { if (('0' <= *self->buf && *self->buf <= '9')) {
self->utf8Codepoint |= *self->buf - '0'; self->utf8Codepoint |= *self->buf - '0';
@@ -627,7 +629,7 @@ inline WeaselJsonStatus t_hex(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus t_hex2(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_hex2(Parser3 *self) {
self->utf8Codepoint <<= 4; self->utf8Codepoint <<= 4;
if (('0' <= *self->buf && *self->buf <= '9')) { if (('0' <= *self->buf && *self->buf <= '9')) {
self->utf8Codepoint |= *self->buf - '0'; self->utf8Codepoint |= *self->buf - '0';
@@ -694,7 +696,7 @@ inline WeaselJsonStatus t_hex2(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus t_hex3(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_hex3(Parser3 *self) {
self->utf8Codepoint <<= 4; self->utf8Codepoint <<= 4;
if (('0' <= *self->buf && *self->buf <= '9')) { if (('0' <= *self->buf && *self->buf <= '9')) {
self->utf8Codepoint |= *self->buf - '0'; self->utf8Codepoint |= *self->buf - '0';
@@ -745,7 +747,7 @@ inline WeaselJsonStatus t_hex3(Parser3 *self) {
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
} }
inline WeaselJsonStatus n_integer(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_integer(Parser3 *self) {
self->callbacks->on_begin_number(self->data); self->callbacks->on_begin_number(self->data);
self->dataBegin = self->buf; self->dataBegin = self->buf;
switch (*self->buf) { switch (*self->buf) {
@@ -780,7 +782,7 @@ inline WeaselJsonStatus n_integer(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_integer2(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_integer2(Parser3 *self) {
switch (*self->buf) { switch (*self->buf) {
case '0': case '0':
++self->buf; ++self->buf;
@@ -806,7 +808,7 @@ inline WeaselJsonStatus n_integer2(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_digits(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_digits(Parser3 *self) {
switch (*self->buf) { switch (*self->buf) {
case '0': case '0':
case '1': case '1':
@@ -829,7 +831,7 @@ inline WeaselJsonStatus n_digits(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_digits2(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_digits2(Parser3 *self) {
if (self->len() == 0) { if (self->len() == 0) {
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -853,7 +855,7 @@ inline WeaselJsonStatus n_digits2(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_fraction(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_fraction(Parser3 *self) {
if (self->len() == 0) { if (self->len() == 0) {
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -873,7 +875,7 @@ inline WeaselJsonStatus n_fraction(Parser3 *self) {
} }
// Responsible for ensuring that on_end_number gets called // Responsible for ensuring that on_end_number gets called
inline WeaselJsonStatus n_exponent(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_exponent(Parser3 *self) {
if (self->len() == 0) { if (self->len() == 0) {
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -895,7 +897,7 @@ inline WeaselJsonStatus n_exponent(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_sign(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_sign(Parser3 *self) {
if (self->len() == 0) { if (self->len() == 0) {
self->pop(); self->pop();
MUSTTAIL return Parser3::keepGoing(self); MUSTTAIL return Parser3::keepGoing(self);
@@ -912,7 +914,7 @@ inline WeaselJsonStatus n_sign(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_true(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_true(Parser3 *self) {
if (*self->buf == 'e') { if (*self->buf == 'e') {
++self->buf; ++self->buf;
self->pop(); self->pop();
@@ -923,7 +925,7 @@ inline WeaselJsonStatus n_true(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_false(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_false(Parser3 *self) {
if (*self->buf == 'e') { if (*self->buf == 'e') {
++self->buf; ++self->buf;
self->pop(); self->pop();
@@ -934,7 +936,7 @@ inline WeaselJsonStatus n_false(Parser3 *self) {
} }
} }
inline WeaselJsonStatus n_null(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus n_null(Parser3 *self) {
if (*self->buf == 'l') { if (*self->buf == 'l') {
++self->buf; ++self->buf;
self->pop(); self->pop();
@@ -946,7 +948,7 @@ inline WeaselJsonStatus n_null(Parser3 *self) {
} }
template <char kChar, bool kSkipWhitespace = false> template <char kChar, bool kSkipWhitespace = false>
inline WeaselJsonStatus singleChar(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus singleChar(Parser3 *self) {
if constexpr (kSkipWhitespace) { if constexpr (kSkipWhitespace) {
assert(self->len() != 0); assert(self->len() != 0);
while (tables.whitespace[uint8_t(*self->buf)]) { while (tables.whitespace[uint8_t(*self->buf)]) {
@@ -965,14 +967,14 @@ inline WeaselJsonStatus singleChar(Parser3 *self) {
} }
} }
inline WeaselJsonStatus t_eof(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_eof(Parser3 *self) {
if (self->len() > 0) [[unlikely]] { if (self->len() > 0) [[unlikely]] {
return WeaselJson_REJECT; return WeaselJson_REJECT;
} }
return self->complete ? WeaselJson_OK : WeaselJson_AGAIN; return self->complete ? WeaselJson_OK : WeaselJson_AGAIN;
} }
inline WeaselJsonStatus t_end_number(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus t_end_number(Parser3 *self) {
self->pop(); self->pop();
self->flushNumber(); self->flushNumber();
self->callbacks->on_end_number(self->data); self->callbacks->on_end_number(self->data);
@@ -983,7 +985,7 @@ constexpr inline struct ContinuationTable {
constexpr ContinuationTable() { constexpr ContinuationTable() {
// Defaults // Defaults
for (int i = 0; i < N_SYMBOL_COUNT; ++i) { for (int i = 0; i < N_SYMBOL_COUNT; ++i) {
continuations[i] = +[](struct Parser3 *) { continuations[i] = +[](struct Parser3 *) PRESERVE_NONE {
printf("unimplemented\n"); printf("unimplemented\n");
return WeaselJson_REJECT; return WeaselJson_REJECT;
}; };
@@ -1074,7 +1076,7 @@ constexpr inline struct ContinuationTable {
bool acceptsEmptyString[N_SYMBOL_COUNT]{}; bool acceptsEmptyString[N_SYMBOL_COUNT]{};
} symbolTables; } symbolTables;
inline WeaselJsonStatus Parser3::keepGoing(Parser3 *self) { inline PRESERVE_NONE WeaselJsonStatus Parser3::keepGoing(Parser3 *self) {
// self->debugPrint(); // self->debugPrint();
if (self->len() == 0) { if (self->len() == 0) {
if (!self->complete) { if (!self->complete) {

11
src/preserve_none.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if __has_attribute(preserve_none)
#define PRESERVE_NONE __attribute__((preserve_none))
#else
#define PRESERVE_NONE
#endif