]> git.kaiwu.me - njs.git/commitdiff
Added generic AST traverser.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 15 Jul 2021 14:51:57 +0000 (14:51 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 15 Jul 2021 14:51:57 +0000 (14:51 +0000)
src/njs_parser.c
src/njs_parser.h

index 2d3f18c2f2d17fa5d6ae57d58c91e47a0ded72cb..653e9081ca39ee60f49bd69030d748d0b6cf957d 100644 (file)
@@ -8688,6 +8688,75 @@ njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
 }
 
 
+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)
 {
index e237d1fc1664ed5cbdfc17e63ab1f5436a700266..97a274413229c6ad2ab4a9a1e01739ae888f8d2a 100644 (file)
@@ -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 *parser,
 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);