[njs] Added generic AST traverser.

Dmitry Volyntsev xeioex at nginx.com
Thu Jul 15 15:43:02 UTC 2021


details:   https://hg.nginx.org/njs/rev/1ed302b68909
branches:  
changeset: 1679:1ed302b68909
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Thu Jul 15 14:51:57 2021 +0000
description:
Added generic AST traverser.

diffstat:

 src/njs_parser.c |  69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/njs_parser.h |   6 ++++
 2 files changed, 75 insertions(+), 0 deletions(-)

diffs (102 lines):

diff -r 1cfcce81e4e9 -r 1ed302b68909 src/njs_parser.c
--- a/src/njs_parser.c	Wed Jul 14 13:18:56 2021 +0000
+++ b/src/njs_parser.c	Thu Jul 15 14:51:57 2021 +0000
@@ -8689,6 +8689,75 @@ njs_parser_node_error(njs_vm_t *vm, njs_
 
 
 njs_int_t
+njs_parser_traverse(njs_vm_t *vm, njs_parser_node_t *root, void *ctx,
+    njs_parser_traverse_cb_t cb)
+{
+    njs_int_t          ret;
+    njs_arr_t          *stack;
+    njs_parser_node_t  *node, **ref;
+
+    if (root == NULL) {
+        return NJS_OK;
+    }
+
+    stack = njs_arr_create(vm->mem_pool, 8, sizeof(njs_parser_node_t *));
+    if (njs_slow_path(stack == NULL)) {
+        return NJS_ERROR;
+
+    }
+
+    ref = njs_arr_add(stack);
+    if (njs_slow_path(ref == NULL)) {
+        goto failed;
+    }
+
+    *ref = root;
+
+    while (1) {
+        if (njs_arr_is_empty(stack)) {
+            break;
+        }
+
+        ref = njs_arr_remove_last(stack);
+        node = *ref;
+
+        ret = cb(vm, node, ctx);
+        if (njs_slow_path(ret != NJS_OK)) {
+            goto failed;
+        }
+
+        if (node->left != NULL) {
+            ref = njs_arr_add(stack);
+            if (njs_slow_path(ref == NULL)) {
+                goto failed;
+            }
+
+            *ref = node->left;
+        }
+
+        if (node->right != NULL) {
+            ref = njs_arr_add(stack);
+            if (njs_slow_path(ref == NULL)) {
+                goto failed;
+            }
+
+            *ref = node->right;
+        }
+    }
+
+    njs_arr_destroy(stack);
+
+    return NJS_OK;
+
+failed:
+
+    njs_arr_destroy(stack);
+
+    return NJS_ERROR;
+}
+
+
+njs_int_t
 njs_parser_serialize_ast(njs_parser_node_t *node, njs_chb_t *chain)
 {
     njs_int_t  ret;
diff -r 1cfcce81e4e9 -r 1ed302b68909 src/njs_parser.h
--- a/src/njs_parser.h	Wed Jul 14 13:18:56 2021 +0000
+++ b/src/njs_parser.h	Thu Jul 15 14:51:57 2021 +0000
@@ -102,6 +102,10 @@ typedef struct {
 } njs_parser_rbtree_node_t;
 
 
+typedef njs_int_t (*njs_parser_traverse_cb_t)(njs_vm_t *vm,
+    njs_parser_node_t *node, void *ctx);
+
+
 njs_int_t njs_parser_failed_state(njs_parser_t *parser,
     njs_lexer_token_t *token, njs_queue_link_t *current);
 
@@ -128,6 +132,8 @@ void njs_parser_lexer_error(njs_parser_t
 void njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
     njs_object_type_t type, const char *fmt, ...);
 
+njs_int_t njs_parser_traverse(njs_vm_t *vm, njs_parser_node_t *root,
+    void *ctx, njs_parser_traverse_cb_t cb);
 njs_int_t njs_parser_serialize_ast(njs_parser_node_t *node, njs_chb_t *chain);
 
 


More information about the nginx-devel mailing list