From: Dmitry Volyntsev Date: Thu, 15 Jul 2021 14:51:57 +0000 (+0000) Subject: Added generic AST traverser. X-Git-Tag: 0.6.2~16 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=caeca9160819d3e8363ac2058816723fcee32006;p=njs.git Added generic AST traverser. --- diff --git a/src/njs_parser.c b/src/njs_parser.c index 2d3f18c2..653e9081 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -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) { diff --git a/src/njs_parser.h b/src/njs_parser.h index e237d1fc..97a27441 100644 --- a/src/njs_parser.h +++ b/src/njs_parser.h @@ -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);