[njs] Refactored njs_parser_terminal().

Dmitry Volyntsev xeioex at nginx.com
Mon Feb 11 15:16:22 UTC 2019


details:   https://hg.nginx.org/njs/rev/a091eaa9d8eb
branches:  
changeset: 773:a091eaa9d8eb
user:      hongzhidao <hongzhidao at gmail.com>
date:      Sat Feb 09 17:34:04 2019 +0800
description:
Refactored njs_parser_terminal().

1) Introduced njs_parser_reference().
2) njs_parser_builtin_object() and njs_parser_builtin_function()
    are refactored into njs_parser_builtin().
3) njs_parser_external() is simplified and renamed as
    njs_external_lookup().

diffstat:

 njs/njs_extern.c |    6 +-
 njs/njs_extern.h |    1 +
 njs/njs_parser.c |  267 ++++++++++++++++++++++++++++++------------------------
 njs/njs_parser.h |    2 -
 4 files changed, 153 insertions(+), 123 deletions(-)

diffs (442 lines):

diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_extern.c
--- a/njs/njs_extern.c	Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_extern.c	Sat Feb 09 17:34:04 2019 +0800
@@ -304,13 +304,13 @@ njs_extern_keys_array(njs_vm_t *vm, cons
 
 
 njs_value_t *
-njs_parser_external(njs_vm_t *vm, njs_parser_t *parser)
+njs_external_lookup(njs_vm_t *vm, nxt_str_t *name, uint32_t hash)
 {
     nxt_lvlhsh_query_t  lhq;
     njs_extern_value_t  *ev;
 
-    lhq.key_hash = parser->lexer->key_hash;
-    lhq.key = parser->lexer->text;
+    lhq.key_hash = hash;
+    lhq.key = *name;
     lhq.proto = &njs_extern_value_hash_proto;
 
     if (nxt_lvlhsh_find(&vm->externals_hash, &lhq) == NXT_OK) {
diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_extern.h
--- a/njs/njs_extern.h	Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_extern.h	Sat Feb 09 17:34:04 2019 +0800
@@ -42,6 +42,7 @@ typedef struct {
 
 
 njs_array_t *njs_extern_keys_array(njs_vm_t *vm, const njs_extern_t *external);
+njs_value_t *njs_external_lookup(njs_vm_t *vm, nxt_str_t *name, uint32_t hash);
 nxt_int_t njs_external_match_native_function(njs_vm_t *vm,
     njs_function_native_t func, nxt_str_t *name);
 
diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_parser.c
--- a/njs/njs_parser.c	Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_parser.c	Sat Feb 09 17:34:04 2019 +0800
@@ -52,10 +52,11 @@ static njs_token_t njs_parser_throw_stat
     njs_parser_t *parser);
 static njs_token_t njs_parser_grouping_expression(njs_vm_t *vm,
     njs_parser_t *parser);
-static njs_token_t njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser,
-    njs_parser_node_t *node);
-static njs_token_t njs_parser_builtin_function(njs_vm_t *vm,
-    njs_parser_t *parser, njs_parser_node_t *node);
+static njs_parser_node_t *njs_parser_reference(njs_vm_t *vm,
+    njs_parser_t *parser, njs_token_t token, nxt_str_t *name, uint32_t hash);
+static nxt_int_t njs_parser_builtin(njs_vm_t *vm, njs_parser_t *parser,
+    njs_parser_node_t *node, njs_value_type_t type, nxt_str_t *name,
+    uint32_t hash);
 static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_node_t *obj);
 static njs_token_t njs_parser_array(njs_vm_t *vm, njs_parser_t *parser,
@@ -1808,11 +1809,12 @@ njs_parser_token(njs_parser_t *parser)
 njs_token_t
 njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
 {
-    double              num;
-    njs_ret_t           ret;
-    njs_value_t         *ext;
-    njs_parser_node_t   *node;
-    njs_parser_scope_t  *scope;
+    double             num;
+    njs_ret_t          ret;
+    njs_lexer_t        *lexer;
+    njs_parser_node_t  *node;
+
+    lexer = parser->lexer;
 
     if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
 
@@ -1833,37 +1835,16 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
         return njs_parser_function_expression(vm, parser);
     }
 
-    node = njs_parser_node_new(vm, parser, token);
-    if (nxt_slow_path(node == NULL)) {
-        return NJS_TOKEN_ERROR;
-    }
-
     switch (token) {
 
-    case NJS_TOKEN_NAME:
-        nxt_thread_log_debug("JS: %V", &parser->lexer->text);
-
-        ext = njs_parser_external(vm, parser);
-
-        if (ext != NULL) {
-            node->token = NJS_TOKEN_EXTERNAL;
-            node->u.value = *ext;
-            node->index = (njs_index_t) ext;
-            break;
-        }
-
-        ret = njs_parser_variable_reference(vm, parser, node, NJS_REFERENCE);
-        if (nxt_slow_path(ret != NXT_OK)) {
+    case NJS_TOKEN_OPEN_BRACE:
+        nxt_thread_log_debug("JS: OBJECT");
+
+        node = njs_parser_node_new(vm, parser, NJS_TOKEN_OBJECT);
+        if (nxt_slow_path(node == NULL)) {
             return NJS_TOKEN_ERROR;
         }
 
-        break;
-
-    case NJS_TOKEN_OPEN_BRACE:
-        node->token = NJS_TOKEN_OBJECT;
-
-        nxt_thread_log_debug("JS: OBJECT");
-
         parser->node = node;
 
         token = njs_parser_object(vm, parser, node);
@@ -1877,10 +1858,13 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
         return token;
 
     case NJS_TOKEN_OPEN_BRACKET:
-        node->token = NJS_TOKEN_ARRAY;
-
         nxt_thread_log_debug("JS: ARRAY");
 
+        node = njs_parser_node_new(vm, parser, NJS_TOKEN_ARRAY);
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
+
         parser->node = node;
 
         token = njs_parser_array(vm, parser, node);
@@ -1894,19 +1878,27 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
         return token;
 
     case NJS_TOKEN_DIVISION:
+        node = njs_parser_node_new(vm, parser, NJS_TOKEN_REGEXP);
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
+
         token = njs_regexp_literal(vm, parser, &node->u.value);
         if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
             return token;
         }
 
-        nxt_thread_log_debug("REGEX: '%V'", &parser->lexer->text);
-
-        node->token = NJS_TOKEN_REGEXP;
+        nxt_thread_log_debug("REGEX: '%V'", &lexer->text);
 
         break;
 
     case NJS_TOKEN_STRING:
-        nxt_thread_log_debug("JS: '%V'", &parser->lexer->text);
+        nxt_thread_log_debug("JS: '%V'", &lexer->text);
+
+        node = njs_parser_node_new(vm, parser, NJS_TOKEN_STRING);
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
 
         ret = njs_parser_string_create(vm, &node->u.value);
         if (nxt_slow_path(ret != NXT_OK)) {
@@ -1916,9 +1908,12 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
         break;
 
     case NJS_TOKEN_ESCAPE_STRING:
-        node->token = NJS_TOKEN_STRING;
-
-        nxt_thread_log_debug("JS: '%V'", &parser->lexer->text);
+        nxt_thread_log_debug("JS: '%V'", &lexer->text);
+
+        node = njs_parser_node_new(vm, parser, NJS_TOKEN_STRING);
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
 
         ret = njs_parser_escape_string_create(vm, parser, &node->u.value);
         if (nxt_slow_path(ret != NJS_TOKEN_STRING)) {
@@ -1929,14 +1924,19 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
 
     case NJS_TOKEN_UNTERMINATED_STRING:
         njs_parser_syntax_error(vm, parser, "Unterminated string \"%V\"",
-                                &parser->lexer->text);
+                                &lexer->text);
 
         return NJS_TOKEN_ILLEGAL;
 
     case NJS_TOKEN_NUMBER:
-        nxt_thread_log_debug("JS: %f", parser->lexer->number);
-
-        num = parser->lexer->number;
+        num = lexer->number;
+        nxt_thread_log_debug("JS: %f", num);
+
+        node = njs_parser_node_new(vm, parser, NJS_TOKEN_NUMBER);
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
+
         node->u.value.data.u.number = num;
         node->u.value.type = NJS_NUMBER;
         node->u.value.data.truth = njs_is_number_true(num);
@@ -1944,9 +1944,14 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
         break;
 
     case NJS_TOKEN_BOOLEAN:
-        nxt_thread_log_debug("JS: boolean: %V", &parser->lexer->text);
-
-        if (parser->lexer->number == 0) {
+        nxt_thread_log_debug("JS: boolean: %V", &lexer->text);
+
+        node = njs_parser_node_new(vm, parser, NJS_TOKEN_BOOLEAN);
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
+
+        if (lexer->number == 0) {
             node->u.value = njs_value_false;
 
         } else {
@@ -1955,6 +1960,39 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
 
         break;
 
+    default:
+        node = njs_parser_reference(vm, parser, token, &lexer->text,
+                                    lexer->key_hash);
+
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
+
+        break;
+    }
+
+    parser->node = node;
+
+    return njs_parser_token(parser);
+}
+
+
+static njs_parser_node_t *
+njs_parser_reference(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token,
+    nxt_str_t *name, uint32_t hash)
+{
+    njs_ret_t           ret;
+    njs_value_t         *ext;
+    njs_parser_node_t   *node;
+    njs_parser_scope_t  *scope;
+
+    node = njs_parser_node_new(vm, parser, token);
+    if (nxt_slow_path(node == NULL)) {
+        return NULL;
+    }
+
+    switch (token) {
+
     case NJS_TOKEN_NULL:
         nxt_thread_log_debug("JS: null");
 
@@ -1992,16 +2030,21 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
     case NJS_TOKEN_NJS:
     case NJS_TOKEN_MATH:
     case NJS_TOKEN_JSON:
-        return njs_parser_builtin_object(vm, parser, node);
+        ret = njs_parser_builtin(vm, parser, node, NJS_OBJECT, name, hash);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            return NULL;
+        }
+
+        break;
 
     case NJS_TOKEN_ARGUMENTS:
         nxt_thread_log_debug("JS: arguments");
 
         if (parser->scope->type <= NJS_SCOPE_GLOBAL) {
             njs_parser_syntax_error(vm, parser, "\"%V\" object "
-                                    "in global scope", &parser->lexer->text);
-
-            return NJS_TOKEN_ILLEGAL;
+                                    "in global scope", name);
+
+            return NULL;
         }
 
         break;
@@ -2088,24 +2131,46 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
     case NJS_TOKEN_SET_TIMEOUT:
     case NJS_TOKEN_SET_IMMEDIATE:
     case NJS_TOKEN_CLEAR_TIMEOUT:
-        return njs_parser_builtin_function(vm, parser, node);
+        ret = njs_parser_builtin(vm, parser, node, NJS_FUNCTION, name, hash);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            return NULL;
+        }
+
+        break;
+
+    case NJS_TOKEN_NAME:
+        nxt_thread_log_debug("JS: %V", name);
+
+        ext = njs_external_lookup(vm, name, hash);
+
+        if (ext != NULL) {
+            node->token = NJS_TOKEN_EXTERNAL;
+            node->u.value = *ext;
+            node->index = (njs_index_t) ext;
+            break;
+        }
+
+        ret = njs_variable_reference(vm, parser->scope, node, name, hash,
+                                     NJS_REFERENCE);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            return NULL;
+        }
+
+        break;
 
     default:
-        return njs_parser_unexpected_token(vm, parser, token);
+        (void) njs_parser_unexpected_token(vm, parser, token);
+        return NULL;
     }
 
-    parser->node = node;
-
-    return njs_parser_token(parser);
+    return node;
 }
 
 
-static njs_token_t
-njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser,
-    njs_parser_node_t *node)
+static nxt_int_t
+njs_parser_builtin(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node,
+    njs_value_type_t type, nxt_str_t *name, uint32_t hash)
 {
-    uint32_t            hash;
-    nxt_str_t           *name;
     njs_ret_t           ret;
     nxt_uint_t          index;
     njs_variable_t      *var;
@@ -2117,70 +2182,36 @@ njs_parser_builtin_object(njs_vm_t *vm, 
         scope = scope->parent;
     }
 
-    hash = parser->lexer->key_hash;
-    name = &parser->lexer->text;
-
     var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR);
     if (nxt_slow_path(var == NULL)) {
-        return NJS_TOKEN_ERROR;
+        return NXT_ERROR;
     }
 
     /* TODO: once */
-    index = node->token - NJS_TOKEN_FIRST_OBJECT;
-    var->value.data.u.object = &vm->shared->objects[index];
-    var->value.type = NJS_OBJECT;
+    switch (type) {
+    case NJS_OBJECT:
+        index = node->token - NJS_TOKEN_FIRST_OBJECT;
+        var->value.data.u.object = &vm->shared->objects[index];
+        break;
+
+    case NJS_FUNCTION:
+        index = node->token - NJS_TOKEN_FIRST_FUNCTION;
+        var->value.data.u.function = &vm->shared->functions[index];
+        break;
+
+    default:
+        return NXT_ERROR;
+    }
+
+    var->value.type = type;
     var->value.data.truth = 1;
 
     ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE);
     if (nxt_slow_path(ret != NXT_OK)) {
-        return NJS_TOKEN_ERROR;
+        return NXT_ERROR;
     }
 
-    parser->node = node;
-
-    return njs_parser_token(parser);
-}
-
-
-static njs_token_t
-njs_parser_builtin_function(njs_vm_t *vm, njs_parser_t *parser,
-    njs_parser_node_t *node)
-{
-    uint32_t            hash;
-    nxt_str_t           *name;
-    njs_ret_t           ret;
-    nxt_uint_t          index;
-    njs_variable_t      *var;
-    njs_parser_scope_t  *scope;
-
-    scope = parser->scope;
-
-    while (scope->type != NJS_SCOPE_GLOBAL) {
-        scope = scope->parent;
-    }
-
-    hash = parser->lexer->key_hash;
-    name = &parser->lexer->text;
-
-    var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR);
-    if (nxt_slow_path(var == NULL)) {
-        return NJS_TOKEN_ERROR;
-    }
-
-    /* TODO: once */
-    index = node->token - NJS_TOKEN_FIRST_FUNCTION;
-    var->value.data.u.function = &vm->shared->functions[index];
-    var->value.type = NJS_FUNCTION;
-    var->value.data.truth = 1;
-
-    ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE);
-    if (nxt_slow_path(ret != NXT_OK)) {
-        return NJS_TOKEN_ERROR;
-    }
-
-    parser->node = node;
-
-    return njs_parser_token(parser);
+    return NXT_OK;
 }
 
 
diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_parser.h
--- a/njs/njs_parser.h	Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_parser.h	Sat Feb 09 17:34:04 2019 +0800
@@ -306,8 +306,6 @@ void njs_lexer_rollback(njs_lexer_t *lex
 nxt_int_t njs_lexer_keywords_init(nxt_mp_t *mcp, nxt_lvlhsh_t *hash);
 njs_token_t njs_lexer_keyword(njs_lexer_t *lexer);
 
-njs_value_t *njs_parser_external(njs_vm_t *vm, njs_parser_t *parser);
-
 nxt_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_t *prev);
 njs_token_t njs_parser_arguments(njs_vm_t *vm, njs_parser_t *parser,


More information about the nginx-devel mailing list