[njs] Making parser hoist more generic.
Dmitry Volyntsev
xeioex at nginx.com
Fri Apr 12 17:49:10 UTC 2019
details: https://hg.nginx.org/njs/rev/ace6f73dff8d
branches:
changeset: 891:ace6f73dff8d
user: hongzhidao <hongzhidao at gmail.com>
date: Sat Apr 13 01:11:49 2019 +0800
description:
Making parser hoist more generic.
diffstat:
njs/njs_parser.c | 121 ++++++++++++++++++++++--------------------------------
njs/njs_parser.h | 1 +
2 files changed, 51 insertions(+), 71 deletions(-)
diffs (207 lines):
diff -r de5127995b43 -r ace6f73dff8d njs/njs_parser.c
--- a/njs/njs_parser.c Sat Apr 13 01:07:34 2019 +0800
+++ b/njs/njs_parser.c Sat Apr 13 01:11:49 2019 +0800
@@ -13,7 +13,7 @@ static njs_ret_t njs_parser_scope_begin(
njs_scope_t type);
static void njs_parser_scope_end(njs_vm_t *vm, njs_parser_t *parser);
static njs_token_t njs_parser_statement_chain(njs_vm_t *vm,
- njs_parser_t *parser, njs_token_t token, njs_parser_node_t **dest);
+ njs_parser_t *parser, njs_token_t token, nxt_bool_t top);
static njs_token_t njs_parser_statement(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token);
static njs_token_t njs_parser_block_statement(njs_vm_t *vm,
@@ -61,8 +61,6 @@ static njs_token_t njs_parser_import_sta
njs_parser_t *parser);
static njs_token_t njs_parser_export_statement(njs_vm_t *vm,
njs_parser_t *parser);
-static nxt_int_t njs_parser_import_hoist(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *new_node);
static nxt_int_t njs_parser_export_sink(njs_vm_t *vm, njs_parser_t *parser);
static njs_token_t njs_parser_grouping_expression(njs_vm_t *vm,
njs_parser_t *parser);
@@ -130,8 +128,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p
while (token != NJS_TOKEN_END) {
- token = njs_parser_statement_chain(vm, parser, token,
- &njs_parser_chain_top(parser));
+ token = njs_parser_statement_chain(vm, parser, token, 1);
if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
return NXT_ERROR;
}
@@ -271,35 +268,58 @@ njs_parser_scope_end(njs_vm_t *vm, njs_p
static njs_token_t
njs_parser_statement_chain(njs_vm_t *vm, njs_parser_t *parser,
- njs_token_t token, njs_parser_node_t **dest)
+ njs_token_t token, nxt_bool_t top)
{
- njs_parser_node_t *node, *last;
-
- last = *dest;
+ njs_parser_node_t *stmt, *last, *node, *new_node, **child;
+
+ child = top ? &njs_parser_chain_top(parser)
+ : &njs_parser_chain_current(parser);
+
+ last = *child;
token = njs_parser_statement(vm, parser, token);
-
if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
return njs_parser_unexpected_token(vm, parser, token);
}
- if (parser->node != NULL) {
- /* The statement is not empty block or just semicolon. */
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- node->left = last;
- node->right = parser->node;
- *dest = node;
-
- while (token == NJS_TOKEN_SEMICOLON) {
- token = njs_parser_token(vm, parser);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
+ if (parser->node == NULL) {
+ /* The statement is empty block or just semicolon. */
+ return token;
+ }
+
+ new_node = parser->node;
+
+ if (new_node->hoist) {
+ child = &njs_parser_chain_top(parser);
+
+ while (*child != NULL) {
+ node = *child;
+
+ if (node->hoist) {
break;
}
+
+ child = &node->left;
+ }
+
+ last = *child;
+ }
+
+ stmt = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
+ if (nxt_slow_path(stmt == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
+ stmt->hoist = new_node->hoist;
+ stmt->left = last;
+ stmt->right = new_node;
+
+ *child = stmt;
+
+ while (token == NJS_TOKEN_SEMICOLON) {
+ token = njs_parser_token(vm, parser);
+ if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
+ break;
}
}
@@ -442,8 +462,7 @@ njs_parser_block_statement(njs_vm_t *vm,
parser->node = NULL;
while (token != NJS_TOKEN_CLOSE_BRACE) {
- token = njs_parser_statement_chain(vm, parser, token,
- &njs_parser_chain_current(parser));
+ token = njs_parser_statement_chain(vm, parser, token, 0);
if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
return token;
}
@@ -940,8 +959,7 @@ njs_parser_lambda_statements(njs_vm_t *v
parser->node = NULL;
while (token != NJS_TOKEN_CLOSE_BRACE) {
- token = njs_parser_statement_chain(vm, parser, token,
- &njs_parser_chain_top(parser));
+ token = njs_parser_statement_chain(vm, parser, token, 1);
if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
return token;
}
@@ -1253,8 +1271,7 @@ njs_parser_switch_statement(njs_vm_t *vm
return NJS_TOKEN_ILLEGAL;
}
- token = njs_parser_statement_chain(vm, parser, token,
- &njs_parser_chain_current(parser));
+ token = njs_parser_statement_chain(vm, parser, token, 0);
if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
return token;
}
@@ -1839,12 +1856,8 @@ njs_parser_import_statement(njs_vm_t *vm
import->left = name;
import->right = parser->node;
- ret = njs_parser_import_hoist(vm, parser, import);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NJS_TOKEN_ERROR;
- }
-
- parser->node = NULL;
+ parser->node = import;
+ parser->node->hoist = 1;
return njs_parser_token(vm, parser);
}
@@ -1961,40 +1974,6 @@ njs_parser_export_statement(njs_vm_t *vm
static nxt_int_t
-njs_parser_import_hoist(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *new_node)
-{
- njs_parser_node_t *node, *stmt, **child;
-
- child = &njs_parser_chain_top(parser);
-
- while (*child != NULL) {
- node = *child;
-
- if (node->right != NULL
- && node->right->token == NJS_TOKEN_IMPORT)
- {
- break;
- }
-
- child = &node->left;
- }
-
- stmt = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
- if (nxt_slow_path(stmt == NULL)) {
- return NXT_ERROR;
- }
-
- stmt->left = *child;
- stmt->right = new_node;
-
- *child = stmt;
-
- return NXT_OK;
-}
-
-
-static nxt_int_t
njs_parser_export_sink(njs_vm_t *vm, njs_parser_t *parser)
{
nxt_uint_t n;
diff -r de5127995b43 -r ace6f73dff8d njs/njs_parser.h
--- a/njs/njs_parser.h Sat Apr 13 01:07:34 2019 +0800
+++ b/njs/njs_parser.h Sat Apr 13 01:11:49 2019 +0800
@@ -40,6 +40,7 @@ struct njs_parser_node_s {
njs_token_t token:16;
uint8_t ctor:1;
uint8_t temporary; /* 1 bit */
+ uint8_t hoist; /* 1 bit */
uint32_t token_line;
union {
More information about the nginx-devel
mailing list