added optional parent token pointer support. Increases parsing speed

master
Serge A. Zaitsev 12 years ago
parent cfbb5b5091
commit 37964b40ee

@ -14,6 +14,9 @@ static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
tok = &tokens[parser->toknext++]; tok = &tokens[parser->toknext++];
tok->start = tok->end = -1; tok->start = tok->end = -1;
tok->size = 0; tok->size = 0;
#ifdef JSMN_PARENT_LINKS
tok->parent = -1;
#endif
return tok; return tok;
} }
@ -65,6 +68,9 @@ found:
return JSMN_ERROR_NOMEM; return JSMN_ERROR_NOMEM;
} }
jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
#ifdef JSMN_PARENT_LINKS
token->parent = parser->toksuper;
#endif
parser->pos--; parser->pos--;
return JSMN_SUCCESS; return JSMN_SUCCESS;
} }
@ -92,6 +98,9 @@ static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
return JSMN_ERROR_NOMEM; return JSMN_ERROR_NOMEM;
} }
jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
#ifdef JSMN_PARENT_LINKS
token->parent = parser->toksuper;
#endif
return JSMN_SUCCESS; return JSMN_SUCCESS;
} }
@ -137,14 +146,35 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
token = jsmn_alloc_token(parser, tokens, num_tokens); token = jsmn_alloc_token(parser, tokens, num_tokens);
if (token == NULL) if (token == NULL)
return JSMN_ERROR_NOMEM; return JSMN_ERROR_NOMEM;
if (parser->toksuper != -1) if (parser->toksuper != -1) {
tokens[parser->toksuper].size++; tokens[parser->toksuper].size++;
#ifdef JSMN_PARENT_LINKS
token->parent = parser->toksuper;
#endif
}
token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
token->start = parser->pos; token->start = parser->pos;
parser->toksuper = parser->toknext - 1; parser->toksuper = parser->toknext - 1;
break; break;
case '}': case ']': case '}': case ']':
type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
#ifdef JSMN_PARENT_LINKS
if (parser->toknext < 1) {
return JSMN_ERROR_INVAL;
}
token = &tokens[parser->toknext - 1];
for (;;) {
if (token->start != -1 && token->end == -1) {
token->end = parser->pos + 1;
parser->toksuper = token->parent;
break;
}
if (token->parent == -1) {
break;
}
token = &tokens[token->parent];
}
#else
for (i = parser->toknext - 1; i >= 0; i--) { for (i = parser->toknext - 1; i >= 0; i--) {
token = &tokens[i]; token = &tokens[i];
if (token->start != -1 && token->end == -1) { if (token->start != -1 && token->end == -1) {
@ -165,6 +195,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
break; break;
} }
} }
#endif
break; break;
case '\"': case '\"':
r = jsmn_parse_string(parser, js, tokens, num_tokens); r = jsmn_parse_string(parser, js, tokens, num_tokens);

@ -37,6 +37,9 @@ typedef struct {
int start; int start;
int end; int end;
int size; int size;
#ifdef JSMN_PARENT_LINKS
int parent;
#endif
} jsmntok_t; } jsmntok_t;
/** /**

Loading…
Cancel
Save