Add PRESERVE_NONE to continuations
This commit is contained in:
@@ -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
11
src/preserve_none.h
Normal 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
|
||||||
Reference in New Issue
Block a user