Handle more "number" digits

This commit is contained in:
2025-05-16 12:54:13 -04:00
parent 545836f6d2
commit dbf20328d1

View File

@@ -192,14 +192,21 @@ constexpr static struct Tables {
whitespace['\n'] = true; whitespace['\n'] = true;
whitespace['\r'] = true; whitespace['\r'] = true;
whitespace['\t'] = true; whitespace['\t'] = true;
for (int i = 0; i < 10; ++i) {
number['0' + i] = true;
}
number['.'] = true;
number['+'] = true;
number['-'] = true;
} }
alignas(16) bool whitespace[256]{}; alignas(16) bool whitespace[256]{};
alignas(16) bool number[256]{};
} tables; } tables;
namespace { namespace {
// Straightforward recursive descent that doesn't handle string escaping and // Straightforward recursive descent that doesn't handle string escaping and
// treats numbers as [0-9.]+. May stack overflow on deeply nested json documents // all numbers. May stack overflow on deeply nested json documents
struct Parser1 { struct Parser1 {
Parser1(char *buf, int len, const Callbacks *callbacks, void *data) Parser1(char *buf, int len, const Callbacks *callbacks, void *data)
: buf(buf), bufEnd(buf + len), callbacks(callbacks), data(data) {} : buf(buf), bufEnd(buf + len), callbacks(callbacks), data(data) {}
@@ -396,7 +403,7 @@ private:
if (len() == 0) { if (len() == 0) {
return false; return false;
} }
if ('0' <= *buf && *buf <= '9' || (*buf == '.')) { if (tables.number[*buf]) {
++buf; ++buf;
} else { } else {
break; break;
@@ -445,8 +452,8 @@ private:
#define MUSTTAIL #define MUSTTAIL
#endif #endif
// Table-based ll(1) parser that doesn't handle escaping and treats numbers as // Table-based ll(1) parser that doesn't handle escaping and all numbers, with a
// [0-9.]+. Could be adapted to have a streaming interface. Uses O(1) memory. // streaming interface. Uses O(1) memory.
struct Parser2 { struct Parser2 {
Parser2(const Callbacks *callbacks, void *data) Parser2(const Callbacks *callbacks, void *data)
: callbacks(callbacks), data(data) { : callbacks(callbacks), data(data) {
@@ -488,7 +495,7 @@ private:
Status parse_number() { Status parse_number() {
char *const bufBefore = buf; char *const bufBefore = buf;
while (len() > 0) { while (len() > 0) {
if ('0' <= *buf && *buf <= '9' || (*buf == '.')) { if (tables.number[*buf]) {
++buf; ++buf;
} else { } else {
break; break;