Skip to content

Commit 530609a

Browse files
committed
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
1 parent 11b5e3e commit 530609a

File tree

1 file changed

+51
-73
lines changed

1 file changed

+51
-73
lines changed

src/backend/utils/adt/jsonapi.c

Lines changed: 51 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -69,52 +69,17 @@ lex_peek(JsonLexContext *lex)
6969
}
7070

7171
/*
72-
* lex_accept
73-
*
74-
* accept the look_ahead token and move the lexer to the next token if the
75-
* look_ahead token matches the token parameter. In that case, and if required,
76-
* also hand back the de-escaped lexeme.
77-
*
78-
* returns true if the token matched, false otherwise.
79-
*/
80-
static inline bool
81-
lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
82-
{
83-
if (lex->token_type == token)
84-
{
85-
if (lexeme != NULL)
86-
{
87-
if (lex->token_type == JSON_TOKEN_STRING)
88-
{
89-
if (lex->strval != NULL)
90-
*lexeme = pstrdup(lex->strval->data);
91-
}
92-
else
93-
{
94-
int len = (lex->token_terminator - lex->token_start);
95-
char *tokstr = palloc(len + 1);
96-
97-
memcpy(tokstr, lex->token_start, len);
98-
tokstr[len] = '\0';
99-
*lexeme = tokstr;
100-
}
101-
}
102-
json_lex(lex);
103-
return true;
104-
}
105-
return false;
106-
}
107-
108-
/*
109-
* lex_accept
72+
* lex_expect
11073
*
11174
* move the lexer to the next token if the current look_ahead token matches
11275
* the parameter token. Otherwise, report an error.
11376
*/
11477
static inline void
11578
lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
11679
{
117-
if (!lex_accept(lex, token, NULL))
80+
if (lex_peek(lex) == token)
81+
json_lex(lex);
82+
else
11883
report_parse_error(ctx, lex);
11984
}
12085

@@ -260,12 +225,14 @@ json_count_array_elements(JsonLexContext *lex)
260225
lex_expect(JSON_PARSE_ARRAY_START, &copylex, JSON_TOKEN_ARRAY_START);
261226
if (lex_peek(&copylex) != JSON_TOKEN_ARRAY_END)
262227
{
263-
do
228+
while (1)
264229
{
265230
count++;
266231
parse_array_element(&copylex, &nullSemAction);
232+
if (copylex.token_type != JSON_TOKEN_COMMA)
233+
break;
234+
json_lex(&copylex);
267235
}
268-
while (lex_accept(&copylex, JSON_TOKEN_COMMA, NULL));
269236
}
270237
lex_expect(JSON_PARSE_ARRAY_NEXT, &copylex, JSON_TOKEN_ARRAY_END);
271238

@@ -286,35 +253,41 @@ parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
286253
{
287254
char *val = NULL;
288255
json_scalar_action sfunc = sem->scalar;
289-
char **valaddr;
290256
JsonTokenType tok = lex_peek(lex);
291257

292-
valaddr = sfunc == NULL ? NULL : &val;
293-
294258
/* a scalar must be a string, a number, true, false, or null */
295-
switch (tok)
259+
if (tok != JSON_TOKEN_STRING && tok != JSON_TOKEN_NUMBER &&
260+
tok != JSON_TOKEN_TRUE && tok != JSON_TOKEN_FALSE &&
261+
tok != JSON_TOKEN_NULL)
262+
report_parse_error(JSON_PARSE_VALUE, lex);
263+
264+
/* if no semantic function, just consume the token */
265+
if (sfunc == NULL)
296266
{
297-
case JSON_TOKEN_TRUE:
298-
lex_accept(lex, JSON_TOKEN_TRUE, valaddr);
299-
break;
300-
case JSON_TOKEN_FALSE:
301-
lex_accept(lex, JSON_TOKEN_FALSE, valaddr);
302-
break;
303-
case JSON_TOKEN_NULL:
304-
lex_accept(lex, JSON_TOKEN_NULL, valaddr);
305-
break;
306-
case JSON_TOKEN_NUMBER:
307-
lex_accept(lex, JSON_TOKEN_NUMBER, valaddr);
308-
break;
309-
case JSON_TOKEN_STRING:
310-
lex_accept(lex, JSON_TOKEN_STRING, valaddr);
311-
break;
312-
default:
313-
report_parse_error(JSON_PARSE_VALUE, lex);
267+
json_lex(lex);
268+
return;
269+
}
270+
271+
/* extract the de-escaped string value, or the raw lexeme */
272+
if (lex_peek(lex) == JSON_TOKEN_STRING)
273+
{
274+
if (lex->strval != NULL)
275+
val = pstrdup(lex->strval->data);
276+
}
277+
else
278+
{
279+
int len = (lex->token_terminator - lex->token_start);
280+
281+
val = palloc(len + 1);
282+
memcpy(val, lex->token_start, len);
283+
val[len] = '\0';
314284
}
315285

316-
if (sfunc != NULL)
317-
(*sfunc) (sem->semstate, val, tok);
286+
/* consume the token */
287+
json_lex(lex);
288+
289+
/* invoke the callback */
290+
(*sfunc) (sem->semstate, val, tok);
318291
}
319292

320293
static void
@@ -330,14 +303,13 @@ parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
330303
json_ofield_action ostart = sem->object_field_start;
331304
json_ofield_action oend = sem->object_field_end;
332305
bool isnull;
333-
char **fnameaddr = NULL;
334306
JsonTokenType tok;
335307

336-
if (ostart != NULL || oend != NULL)
337-
fnameaddr = &fname;
338-
339-
if (!lex_accept(lex, JSON_TOKEN_STRING, fnameaddr))
308+
if (lex_peek(lex) != JSON_TOKEN_STRING)
340309
report_parse_error(JSON_PARSE_STRING, lex);
310+
if ((ostart != NULL || oend != NULL) && lex->strval != NULL)
311+
fname = pstrdup(lex->strval->data);
312+
json_lex(lex);
341313

342314
lex_expect(JSON_PARSE_OBJECT_LABEL, lex, JSON_TOKEN_COLON);
343315

@@ -387,16 +359,19 @@ parse_object(JsonLexContext *lex, JsonSemAction *sem)
387359
*/
388360
lex->lex_level++;
389361

390-
/* we know this will succeed, just clearing the token */
391-
lex_expect(JSON_PARSE_OBJECT_START, lex, JSON_TOKEN_OBJECT_START);
362+
Assert(lex_peek(lex) == JSON_TOKEN_OBJECT_START);
363+
json_lex(lex);
392364

393365
tok = lex_peek(lex);
394366
switch (tok)
395367
{
396368
case JSON_TOKEN_STRING:
397369
parse_object_field(lex, sem);
398-
while (lex_accept(lex, JSON_TOKEN_COMMA, NULL))
370+
while (lex_peek(lex) == JSON_TOKEN_COMMA)
371+
{
372+
json_lex(lex);
399373
parse_object_field(lex, sem);
374+
}
400375
break;
401376
case JSON_TOKEN_OBJECT_END:
402377
break;
@@ -473,8 +448,11 @@ parse_array(JsonLexContext *lex, JsonSemAction *sem)
473448

474449
parse_array_element(lex, sem);
475450

476-
while (lex_accept(lex, JSON_TOKEN_COMMA, NULL))
451+
while (lex_peek(lex) == JSON_TOKEN_COMMA)
452+
{
453+
json_lex(lex);
477454
parse_array_element(lex, sem);
455+
}
478456
}
479457

480458
lex_expect(JSON_PARSE_ARRAY_NEXT, lex, JSON_TOKEN_ARRAY_END);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy