]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Remove jsonapi.c's lex_accept().
authorRobert Haas <rhaas@postgresql.org>
Fri, 17 Jan 2020 19:06:41 +0000 (14:06 -0500)
committerRobert Haas <rhaas@postgresql.org>
Fri, 24 Jan 2020 18:29:52 +0000 (10:29 -0800)
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

src/backend/utils/adt/jsonapi.c

index fc8af9f861ebe3e9e67141596fb07186d776269b..9e14306b6f6202b25b4acf147f62ae6622be4984 100644 (file)
@@ -69,44 +69,7 @@ lex_peek(JsonLexContext *lex)
 }
 
 /*
- * lex_accept
- *
- * 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
+ * lex_expect
  *
  * move the lexer to the next token if the current look_ahead token matches
  * the parameter token. Otherwise, report an error.
@@ -114,7 +77,9 @@ lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
 static inline void
 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);
 }
 
@@ -260,12 +225,14 @@ json_count_array_elements(JsonLexContext *lex)
        lex_expect(JSON_PARSE_ARRAY_START, &copylex, JSON_TOKEN_ARRAY_START);
        if (lex_peek(&copylex) != JSON_TOKEN_ARRAY_END)
        {
-               do
+               while (1)
                {
                        count++;
                        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);
 
@@ -286,35 +253,41 @@ parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
 {
        char       *val = NULL;
        json_scalar_action sfunc = sem->scalar;
-       char      **valaddr;
        JsonTokenType tok = lex_peek(lex);
 
-       valaddr = sfunc == NULL ? NULL : &val;
-
        /* 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 &&
+               tok != JSON_TOKEN_NULL)
+               report_parse_error(JSON_PARSE_VALUE, lex);
+
+       /* if no semantic function, just consume the token */
+       if (sfunc == NULL)
        {
-               case JSON_TOKEN_TRUE:
-                       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);
+               json_lex(lex);
+               return;
+       }
+
+       /* 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';
        }
 
-       if (sfunc != NULL)
-               (*sfunc) (sem->semstate, val, tok);
+       /* consume the token */
+       json_lex(lex);
+
+       /* invoke the callback */
+       (*sfunc) (sem->semstate, val, tok);
 }
 
 static void
@@ -330,14 +303,13 @@ parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
        json_ofield_action ostart = sem->object_field_start;
        json_ofield_action oend = sem->object_field_end;
        bool            isnull;
-       char      **fnameaddr = NULL;
        JsonTokenType tok;
 
-       if (ostart != NULL || oend != NULL)
-               fnameaddr = &fname;
-
-       if (!lex_accept(lex, JSON_TOKEN_STRING, fnameaddr))
+       if (lex_peek(lex) != JSON_TOKEN_STRING)
                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);
 
@@ -387,16 +359,19 @@ parse_object(JsonLexContext *lex, JsonSemAction *sem)
         */
        lex->lex_level++;
 
-       /* we know this will succeed, just clearing the token */
-       lex_expect(JSON_PARSE_OBJECT_START, lex, JSON_TOKEN_OBJECT_START);
+       Assert(lex_peek(lex) == JSON_TOKEN_OBJECT_START);
+       json_lex(lex);
 
        tok = lex_peek(lex);
        switch (tok)
        {
                case JSON_TOKEN_STRING:
                        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);
+                       }
                        break;
                case JSON_TOKEN_OBJECT_END:
                        break;
@@ -473,8 +448,11 @@ parse_array(JsonLexContext *lex, JsonSemAction *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);
+               }
        }
 
        lex_expect(JSON_PARSE_ARRAY_NEXT, lex, JSON_TOKEN_ARRAY_END);