Make use of "expected symbol" info
This commit is contained in:
140
src/test.cpp
140
src/test.cpp
@@ -448,16 +448,20 @@ private:
|
|||||||
if (len < litLen) {
|
if (len < litLen) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
len -= litLen;
|
if (memcmp(buf, literal, litLen) == 0) {
|
||||||
return memcmp(std::exchange(buf, buf + litLen), literal, litLen) == 0;
|
len -= litLen;
|
||||||
|
buf += litLen;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
bool parse_number() {
|
bool parse_number() {
|
||||||
callbacks->on_begin_number(data);
|
|
||||||
char *const bufBefore = buf;
|
char *const bufBefore = buf;
|
||||||
|
if (len == 0 || !('0' <= *buf && *buf <= '9')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
callbacks->on_begin_number(data);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (len == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ('0' <= *buf && *buf <= '9') {
|
if ('0' <= *buf && *buf <= '9') {
|
||||||
++buf;
|
++buf;
|
||||||
--len;
|
--len;
|
||||||
@@ -473,10 +477,10 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool parse_string() {
|
bool parse_string() {
|
||||||
callbacks->on_begin_string(data);
|
|
||||||
if (!parseLiteral("\"")) {
|
if (!parseLiteral("\"")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
callbacks->on_begin_string(data);
|
||||||
auto *result = (char *)memchr(buf, '"', len);
|
auto *result = (char *)memchr(buf, '"', len);
|
||||||
if (result == nullptr) {
|
if (result == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
@@ -526,26 +530,6 @@ private:
|
|||||||
}
|
}
|
||||||
MUSTTAIL return keepGoing(self);
|
MUSTTAIL return keepGoing(self);
|
||||||
}
|
}
|
||||||
static bool atom(Parser2 *self) {
|
|
||||||
self->pop();
|
|
||||||
if (*self->bufBefore == 't') {
|
|
||||||
self->callbacks->on_true_literal(self->data);
|
|
||||||
} else if (*self->bufBefore == 'f') {
|
|
||||||
self->callbacks->on_false_literal(self->data);
|
|
||||||
} else if (*self->bufBefore == 'n') {
|
|
||||||
self->callbacks->on_null_literal(self->data);
|
|
||||||
} else {
|
|
||||||
self->callbacks->on_begin_number(self->data);
|
|
||||||
self->callbacks->on_number_data(self->data, self->bufBefore + 1,
|
|
||||||
self->buf - self->bufBefore - 2);
|
|
||||||
self->callbacks->on_end_number(self->data);
|
|
||||||
}
|
|
||||||
MUSTTAIL return keepGoing(self);
|
|
||||||
}
|
|
||||||
static bool string(Parser2 *self) {
|
|
||||||
self->pop();
|
|
||||||
MUSTTAIL return keepGoing(self);
|
|
||||||
}
|
|
||||||
static bool array(Parser2 *self) {
|
static bool array(Parser2 *self) {
|
||||||
self->pop();
|
self->pop();
|
||||||
self->callbacks->on_begin_array(self->data);
|
self->callbacks->on_begin_array(self->data);
|
||||||
@@ -718,8 +702,8 @@ private:
|
|||||||
/*T_LBRACE*/ object,
|
/*T_LBRACE*/ object,
|
||||||
/*T_RBRACE*/ reject,
|
/*T_RBRACE*/ reject,
|
||||||
/*T_COMMA*/ reject,
|
/*T_COMMA*/ reject,
|
||||||
/*T_ATOM*/ atom,
|
/*T_ATOM*/ tokenMatch,
|
||||||
/*T_STRING*/ string,
|
/*T_STRING*/ tokenMatch,
|
||||||
/*T_LBRACKET*/ array,
|
/*T_LBRACKET*/ array,
|
||||||
/*T_RBRACKET*/ reject,
|
/*T_RBRACKET*/ reject,
|
||||||
/*T_COLON*/ reject,
|
/*T_COLON*/ reject,
|
||||||
@@ -765,55 +749,71 @@ private:
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *bufBefore;
|
|
||||||
Symbol nextToken(Symbol expected) {
|
Symbol nextToken(Symbol expected) {
|
||||||
maybeSkipWs();
|
|
||||||
bufBefore = buf;
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return T_EOF;
|
return expected == T_EOF ? T_EOF : T_INVALID;
|
||||||
}
|
}
|
||||||
if (*buf == '{') {
|
maybeSkipWs();
|
||||||
parseLiteral("{");
|
switch (expected) {
|
||||||
|
case N_OBJECT:
|
||||||
|
case T_LBRACE:
|
||||||
|
return parseLiteral("{") ? T_LBRACE : T_INVALID;
|
||||||
|
case T_RBRACE:
|
||||||
|
return parseLiteral("}") ? T_RBRACE : T_INVALID;
|
||||||
|
case T_COMMA:
|
||||||
|
return parseLiteral(",") ? T_COMMA : T_INVALID;
|
||||||
|
case T_STRING:
|
||||||
|
return parse_string() ? T_STRING : T_INVALID;
|
||||||
|
case T_LBRACKET:
|
||||||
|
return parseLiteral("[") ? T_LBRACKET : T_INVALID;
|
||||||
|
case T_RBRACKET:
|
||||||
|
return parseLiteral("]") ? T_RBRACKET : T_INVALID;
|
||||||
|
case T_COLON:
|
||||||
|
return parseLiteral(":") ? T_COLON : T_INVALID;
|
||||||
|
case T_ATOM:
|
||||||
|
case N_VALUE:
|
||||||
|
break;
|
||||||
|
case N_ARRAY_MAYBE_CONTINUE:
|
||||||
|
return parseLiteral(",") ? T_COMMA
|
||||||
|
: parseLiteral("]") ? T_RBRACKET
|
||||||
|
: T_INVALID;
|
||||||
|
case N_OBJECT_MAYBE_CONTINUE:
|
||||||
|
return parseLiteral(",") ? T_COMMA
|
||||||
|
: parseLiteral("}") ? T_RBRACE
|
||||||
|
: T_INVALID;
|
||||||
|
case T_INVALID:
|
||||||
|
case T_EOF:
|
||||||
|
case N_PAST_END:
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
if (parseLiteral("{")) {
|
||||||
return T_LBRACE;
|
return T_LBRACE;
|
||||||
} else if (*buf == '[') {
|
} else if (parseLiteral("[")) {
|
||||||
parseLiteral("[");
|
|
||||||
return T_LBRACKET;
|
return T_LBRACKET;
|
||||||
} else if (*buf == '}') {
|
} else if (parse_string()) {
|
||||||
parseLiteral("}");
|
|
||||||
return T_RBRACE;
|
|
||||||
} else if (*buf == ']') {
|
|
||||||
parseLiteral("]");
|
|
||||||
return T_RBRACKET;
|
|
||||||
} else if (*buf == ':') {
|
|
||||||
parseLiteral(":");
|
|
||||||
return T_COLON;
|
|
||||||
} else if (*buf == ',') {
|
|
||||||
parseLiteral(",");
|
|
||||||
return T_COMMA;
|
|
||||||
} else if (*buf == '"') {
|
|
||||||
if (!parse_string()) {
|
|
||||||
return T_INVALID;
|
|
||||||
}
|
|
||||||
return T_STRING;
|
return T_STRING;
|
||||||
} else if (*buf == 't') {
|
} else if (parse_number()) {
|
||||||
if (!parseLiteral("true")) {
|
|
||||||
return T_INVALID;
|
|
||||||
}
|
|
||||||
return T_ATOM;
|
return T_ATOM;
|
||||||
} else if (*buf == 'f') {
|
} else if (parseLiteral("true")) {
|
||||||
if (!parseLiteral("false")) {
|
callbacks->on_true_literal(data);
|
||||||
return T_INVALID;
|
return T_ATOM;
|
||||||
}
|
} else if (parseLiteral("false")) {
|
||||||
} else if (*buf == 'n') {
|
callbacks->on_false_literal(data);
|
||||||
if (!parseLiteral("null")) {
|
return T_ATOM;
|
||||||
return T_INVALID;
|
} else if (parseLiteral("null")) {
|
||||||
}
|
callbacks->on_null_literal(data);
|
||||||
} else {
|
return T_ATOM;
|
||||||
if (!parse_number()) {
|
} else if (parseLiteral("}")) {
|
||||||
return T_INVALID;
|
return T_RBRACE;
|
||||||
}
|
} else if (parseLiteral("]")) {
|
||||||
|
return T_RBRACKET;
|
||||||
|
} else if (parseLiteral(":")) {
|
||||||
|
return T_COLON;
|
||||||
|
} else if (parseLiteral(",")) {
|
||||||
|
return T_COMMA;
|
||||||
}
|
}
|
||||||
return T_ATOM;
|
return T_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|||||||
Reference in New Issue
Block a user