Commit 530609aa authored by Robert Haas's avatar Robert Haas

Remove jsonapi.c's lex_accept().

At first glance, this function seems useful, but it actually increases
the amount of code required rather than decreasing it. Inline the
logic into the callers instead; most callers don't use the 'lexeme'
argument for anything and as a result considerable simplification is
possible.

Along the way, fix the header comment for the nearby function
lex_expect(), which mislabeled it as lex_accept().

Patch by me, reviewed by David Steele, Mark Dilger, and Andrew
Dunstan.

Discussion: http://postgr.es/m/CA+TgmoYfOXhd27MUDGioVh6QtpD0C1K-f6ObSA10AWiHBAL5bA@mail.gmail.com
parent 11b5e3e3
...@@ -69,44 +69,7 @@ lex_peek(JsonLexContext *lex) ...@@ -69,44 +69,7 @@ lex_peek(JsonLexContext *lex)
} }
/* /*
* lex_accept * lex_expect
*
* accept the look_ahead token and move the lexer to the next token if the
* look_ahead token matches the token parameter. In that case, and if required,
* also hand back the de-escaped lexeme.
*
* returns true if the token matched, false otherwise.
*/
static inline bool
lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
{
if (lex->token_type == token)
{
if (lexeme != NULL)
{
if (lex->token_type == JSON_TOKEN_STRING)
{
if (lex->strval != NULL)
*lexeme = pstrdup(lex->strval->data);
}
else
{
int len = (lex->token_terminator - lex->token_start);
char *tokstr = palloc(len + 1);
memcpy(tokstr, lex->token_start, len);
tokstr[len] = '\0';
*lexeme = tokstr;
}
}
json_lex(lex);
return true;
}
return false;
}
/*
* lex_accept
* *
* move the lexer to the next token if the current look_ahead token matches * move the lexer to the next token if the current look_ahead token matches
* the parameter token. Otherwise, report an error. * the parameter token. Otherwise, report an error.
...@@ -114,7 +77,9 @@ lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme) ...@@ -114,7 +77,9 @@ lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
static inline void static inline void
lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token) lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
{ {
if (!lex_accept(lex, token, NULL)) if (lex_peek(lex) == token)
json_lex(lex);
else
report_parse_error(ctx, lex); report_parse_error(ctx, lex);
} }
...@@ -260,12 +225,14 @@ json_count_array_elements(JsonLexContext *lex) ...@@ -260,12 +225,14 @@ json_count_array_elements(JsonLexContext *lex)
lex_expect(JSON_PARSE_ARRAY_START, &copylex, JSON_TOKEN_ARRAY_START); lex_expect(JSON_PARSE_ARRAY_START, &copylex, JSON_TOKEN_ARRAY_START);
if (lex_peek(&copylex) != JSON_TOKEN_ARRAY_END) if (lex_peek(&copylex) != JSON_TOKEN_ARRAY_END)
{ {
do while (1)
{ {
count++; count++;
parse_array_element(&copylex, &nullSemAction); parse_array_element(&copylex, &nullSemAction);
if (copylex.token_type != JSON_TOKEN_COMMA)
break;
json_lex(&copylex);
} }
while (lex_accept(&copylex, JSON_TOKEN_COMMA, NULL));
} }
lex_expect(JSON_PARSE_ARRAY_NEXT, &copylex, JSON_TOKEN_ARRAY_END); lex_expect(JSON_PARSE_ARRAY_NEXT, &copylex, JSON_TOKEN_ARRAY_END);
...@@ -286,34 +253,40 @@ parse_scalar(JsonLexContext *lex, JsonSemAction *sem) ...@@ -286,34 +253,40 @@ parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
{ {
char *val = NULL; char *val = NULL;
json_scalar_action sfunc = sem->scalar; json_scalar_action sfunc = sem->scalar;
char **valaddr;
JsonTokenType tok = lex_peek(lex); JsonTokenType tok = lex_peek(lex);
valaddr = sfunc == NULL ? NULL : &val;
/* a scalar must be a string, a number, true, false, or null */ /* a scalar must be a string, a number, true, false, or null */
switch (tok) if (tok != JSON_TOKEN_STRING && tok != JSON_TOKEN_NUMBER &&
{ tok != JSON_TOKEN_TRUE && tok != JSON_TOKEN_FALSE &&
case JSON_TOKEN_TRUE: tok != JSON_TOKEN_NULL)
lex_accept(lex, JSON_TOKEN_TRUE, valaddr);
break;
case JSON_TOKEN_FALSE:
lex_accept(lex, JSON_TOKEN_FALSE, valaddr);
break;
case JSON_TOKEN_NULL:
lex_accept(lex, JSON_TOKEN_NULL, valaddr);
break;
case JSON_TOKEN_NUMBER:
lex_accept(lex, JSON_TOKEN_NUMBER, valaddr);
break;
case JSON_TOKEN_STRING:
lex_accept(lex, JSON_TOKEN_STRING, valaddr);
break;
default:
report_parse_error(JSON_PARSE_VALUE, lex); report_parse_error(JSON_PARSE_VALUE, lex);
/* if no semantic function, just consume the token */
if (sfunc == NULL)
{
json_lex(lex);
return;
} }
if (sfunc != NULL) /* extract the de-escaped string value, or the raw lexeme */
if (lex_peek(lex) == JSON_TOKEN_STRING)
{
if (lex->strval != NULL)
val = pstrdup(lex->strval->data);
}
else
{
int len = (lex->token_terminator - lex->token_start);
val = palloc(len + 1);
memcpy(val, lex->token_start, len);
val[len] = '\0';
}
/* consume the token */
json_lex(lex);
/* invoke the callback */
(*sfunc) (sem->semstate, val, tok); (*sfunc) (sem->semstate, val, tok);
} }
...@@ -330,14 +303,13 @@ parse_object_field(JsonLexContext *lex, JsonSemAction *sem) ...@@ -330,14 +303,13 @@ parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
json_ofield_action ostart = sem->object_field_start; json_ofield_action ostart = sem->object_field_start;
json_ofield_action oend = sem->object_field_end; json_ofield_action oend = sem->object_field_end;
bool isnull; bool isnull;
char **fnameaddr = NULL;
JsonTokenType tok; JsonTokenType tok;
if (ostart != NULL || oend != NULL) if (lex_peek(lex) != JSON_TOKEN_STRING)
fnameaddr = &fname;
if (!lex_accept(lex, JSON_TOKEN_STRING, fnameaddr))
report_parse_error(JSON_PARSE_STRING, lex); report_parse_error(JSON_PARSE_STRING, lex);
if ((ostart != NULL || oend != NULL) && lex->strval != NULL)
fname = pstrdup(lex->strval->data);
json_lex(lex);
lex_expect(JSON_PARSE_OBJECT_LABEL, lex, JSON_TOKEN_COLON); lex_expect(JSON_PARSE_OBJECT_LABEL, lex, JSON_TOKEN_COLON);
...@@ -387,16 +359,19 @@ parse_object(JsonLexContext *lex, JsonSemAction *sem) ...@@ -387,16 +359,19 @@ parse_object(JsonLexContext *lex, JsonSemAction *sem)
*/ */
lex->lex_level++; lex->lex_level++;
/* we know this will succeed, just clearing the token */ Assert(lex_peek(lex) == JSON_TOKEN_OBJECT_START);
lex_expect(JSON_PARSE_OBJECT_START, lex, JSON_TOKEN_OBJECT_START); json_lex(lex);
tok = lex_peek(lex); tok = lex_peek(lex);
switch (tok) switch (tok)
{ {
case JSON_TOKEN_STRING: case JSON_TOKEN_STRING:
parse_object_field(lex, sem); parse_object_field(lex, sem);
while (lex_accept(lex, JSON_TOKEN_COMMA, NULL)) while (lex_peek(lex) == JSON_TOKEN_COMMA)
{
json_lex(lex);
parse_object_field(lex, sem); parse_object_field(lex, sem);
}
break; break;
case JSON_TOKEN_OBJECT_END: case JSON_TOKEN_OBJECT_END:
break; break;
...@@ -473,9 +448,12 @@ parse_array(JsonLexContext *lex, JsonSemAction *sem) ...@@ -473,9 +448,12 @@ parse_array(JsonLexContext *lex, JsonSemAction *sem)
parse_array_element(lex, sem); parse_array_element(lex, sem);
while (lex_accept(lex, JSON_TOKEN_COMMA, NULL)) while (lex_peek(lex) == JSON_TOKEN_COMMA)
{
json_lex(lex);
parse_array_element(lex, sem); parse_array_element(lex, sem);
} }
}
lex_expect(JSON_PARSE_ARRAY_NEXT, lex, JSON_TOKEN_ARRAY_END); lex_expect(JSON_PARSE_ARRAY_NEXT, lex, JSON_TOKEN_ARRAY_END);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment