From 9ac854ad5a3b75e35554b769b0b3514a6fa8d9f4 Mon Sep 17 00:00:00 2001 From: petermlm Date: Tue, 19 Apr 2016 22:27:32 +0100 Subject: [PATCH 1/5] Made post order tree traversal --- mpc.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mpc.h | 17 ++++++++++++ 2 files changed, 104 insertions(+) diff --git a/mpc.c b/mpc.c index a305b12..9304f24 100644 --- a/mpc.c +++ b/mpc.c @@ -2808,6 +2808,93 @@ mpc_ast_t *mpc_ast_get_child_lb(mpc_ast_t *ast, const char *tag, int lb) { return NULL; } +mpc_ast_trav_t *mpc_ast_traverse_start(mpc_ast_t *ast, + mpc_ast_trav_order_t order) +{ + mpc_ast_trav_t *trav, *n_trav; + mpc_ast_t *cnode = ast; + + /* Create the traversal structure */ + trav = malloc(sizeof(mpc_ast_trav_t)); + trav->curr_node = cnode; + trav->parent = NULL; + trav->curr_child = 0; + trav->order = order; + + /* Get start node */ + switch(order) { + case mpc_ast_trav_order_pre: + break; + + case mpc_ast_trav_order_post: + while(cnode->children_num > 0) { + cnode = cnode->children[0]; + + n_trav = malloc(sizeof(mpc_ast_trav_t)); + n_trav->curr_node = cnode; + n_trav->parent = trav; + n_trav->curr_child = 0; + n_trav->order = order; + + trav = n_trav; + } + + break; + } + + return trav; +} + +mpc_ast_t *mpc_ast_traverse_next(mpc_ast_trav_t **trav) { + mpc_ast_trav_t *n_trav, *to_free; + mpc_ast_t *ret = NULL; + int cchild; + + if(*trav == NULL) return NULL; + + switch((*trav)->order) { + case mpc_ast_trav_order_pre: + break; + + case mpc_ast_trav_order_post: + ret = (*trav)->curr_node; + + /* Move up tree to the parent If the parent doesn't have any more + * nodes, then this is the current node. If it does, move down to + * its left most child. Also, free the previous traversal node */ + to_free = *trav; + *trav = (*trav)->parent; + free(to_free); + + if(*trav == NULL) + break; + + /* Next child */ + (*trav)->curr_child++; + + /* If there aren't any more children, this is the next node */ + if((*trav)->curr_child >= (*trav)->curr_node->children_num) { + break; + } + + /* If there are still more children, find the leftmost child from + * this node */ + while((*trav)->curr_node->children_num > 0) { + n_trav = malloc(sizeof(mpc_ast_trav_t)); + + cchild = (*trav)->curr_child; + n_trav->curr_node = (*trav)->curr_node->children[cchild]; + n_trav->parent = *trav; + n_trav->curr_child = 0; + n_trav->order = (*trav)->order; + + *trav = n_trav; + } + } + + return ret; +} + mpc_val_t *mpcf_fold_ast(int n, mpc_val_t **xs) { int i, j; diff --git a/mpc.h b/mpc.h index 82ee6ba..bb6d72a 100644 --- a/mpc.h +++ b/mpc.h @@ -281,6 +281,23 @@ int mpc_ast_get_index_lb(mpc_ast_t *ast, const char *tag, int lb); mpc_ast_t *mpc_ast_get_child(mpc_ast_t *ast, const char *tag); mpc_ast_t *mpc_ast_get_child_lb(mpc_ast_t *ast, const char *tag, int lb); +typedef enum { + mpc_ast_trav_order_pre, + mpc_ast_trav_order_post +} mpc_ast_trav_order_t; + +typedef struct mpc_ast_trav_t { + mpc_ast_t *curr_node; + struct mpc_ast_trav_t *parent; + int curr_child; + mpc_ast_trav_order_t order; +} mpc_ast_trav_t; + +mpc_ast_trav_t *mpc_ast_traverse_start(mpc_ast_t *ast, + mpc_ast_trav_order_t order); + +mpc_ast_t *mpc_ast_traverse_next(mpc_ast_trav_t **trav); + /* ** Warning: This function currently doesn't test for equality of the `state` member! */ From 719ca68b6c3fddf75e6a5399d2e188715b6fb499 Mon Sep 17 00:00:00 2001 From: petermlm Date: Tue, 19 Apr 2016 23:14:00 +0100 Subject: [PATCH 2/5] Implemented pre order ast traversal --- mpc.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/mpc.c b/mpc.c index 9304f24..4da4cd8 100644 --- a/mpc.c +++ b/mpc.c @@ -2824,6 +2824,7 @@ mpc_ast_trav_t *mpc_ast_traverse_start(mpc_ast_t *ast, /* Get start node */ switch(order) { case mpc_ast_trav_order_pre: + /* Nothing else is needed for pre order start */ break; case mpc_ast_trav_order_post: @@ -2850,10 +2851,39 @@ mpc_ast_t *mpc_ast_traverse_next(mpc_ast_trav_t **trav) { mpc_ast_t *ret = NULL; int cchild; + /* The end of traversal was reached */ if(*trav == NULL) return NULL; switch((*trav)->order) { case mpc_ast_trav_order_pre: + ret = (*trav)->curr_node; + + /* If there aren't any more children, go up */ + while(*trav != NULL && + (*trav)->curr_child >= (*trav)->curr_node->children_num) + { + to_free = *trav; + *trav = (*trav)->parent; + free(to_free); + } + + /* If trav is NULL, the end was reached */ + if(*trav == NULL) { + break; + } + + /* Go to next child */ + n_trav = malloc(sizeof(mpc_ast_trav_t)); + + cchild = (*trav)->curr_child; + n_trav->curr_node = (*trav)->curr_node->children[cchild]; + n_trav->parent = *trav; + n_trav->curr_child = 0; + n_trav->order = (*trav)->order; + + (*trav)->curr_child++; + *trav = n_trav; + break; case mpc_ast_trav_order_post: From e99b35796c4bced28019751e6a473c31f04811f7 Mon Sep 17 00:00:00 2001 From: petermlm Date: Tue, 19 Apr 2016 23:21:39 +0100 Subject: [PATCH 3/5] Made example for tree traversal --- examples/tree_traversal.c | 29 ++++++++++++++++++++++++++++- mpc.c | 8 ++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/examples/tree_traversal.c b/examples/tree_traversal.c index b31f660..7553cdd 100644 --- a/examples/tree_traversal.c +++ b/examples/tree_traversal.c @@ -5,7 +5,8 @@ int main(int argc, char *argv[]) { mpc_parser_t *Input = mpc_new("input"); mpc_parser_t *Node = mpc_new("node"); mpc_parser_t *Leaf = mpc_new("leaf"); - mpc_ast_t *ast, *tree, *child, *child_sub; + mpc_ast_t *ast, *tree, *child, *child_sub, *ast_next; + mpc_ast_trav_t *trav; mpc_result_t r; int index, lb; @@ -65,6 +66,32 @@ int main(int argc, char *argv[]) { child_sub = mpc_ast_get_child_lb(child, "node|leaf|regex", lb); } + /* Traversal */ + printf("Pre order tree traversal.\n"); + trav = mpc_ast_traverse_start(ast, mpc_ast_trav_order_pre); + + ast_next = mpc_ast_traverse_next(&trav); + + while(ast_next != NULL) { + printf("Tag: %s; Contents: %s\n", + ast_next->tag, + ast_next->contents); + ast_next = mpc_ast_traverse_next(&trav); + } + + printf("Post order tree traversal.\n"); + + trav = mpc_ast_traverse_start(ast, mpc_ast_trav_order_post); + + ast_next = mpc_ast_traverse_next(&trav); + + while(ast_next != NULL) { + printf("Tag: %s; Contents: %s\n", + ast_next->tag, + ast_next->contents); + ast_next = mpc_ast_traverse_next(&trav); + } + /* Clean up and return */ mpc_cleanup(3, Node, Leaf, Input); mpc_ast_delete(ast); diff --git a/mpc.c b/mpc.c index 4da4cd8..cbfbcf7 100644 --- a/mpc.c +++ b/mpc.c @@ -2841,6 +2841,10 @@ mpc_ast_trav_t *mpc_ast_traverse_start(mpc_ast_t *ast, } break; + + default: + /* Unreachable, but compiler complaints */ + break; } return trav; @@ -2920,6 +2924,10 @@ mpc_ast_t *mpc_ast_traverse_next(mpc_ast_trav_t **trav) { *trav = n_trav; } + + default: + /* Unreachable, but compiler complaints */ + break; } return ret; From 0037648c49dddffec7cf86f3624486fd577c85a1 Mon Sep 17 00:00:00 2001 From: petermlm Date: Tue, 19 Apr 2016 23:26:20 +0100 Subject: [PATCH 4/5] Identation --- mpc.c | 182 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/mpc.c b/mpc.c index cbfbcf7..29e78c4 100644 --- a/mpc.c +++ b/mpc.c @@ -2811,126 +2811,126 @@ mpc_ast_t *mpc_ast_get_child_lb(mpc_ast_t *ast, const char *tag, int lb) { mpc_ast_trav_t *mpc_ast_traverse_start(mpc_ast_t *ast, mpc_ast_trav_order_t order) { - mpc_ast_trav_t *trav, *n_trav; - mpc_ast_t *cnode = ast; + mpc_ast_trav_t *trav, *n_trav; + mpc_ast_t *cnode = ast; - /* Create the traversal structure */ - trav = malloc(sizeof(mpc_ast_trav_t)); - trav->curr_node = cnode; - trav->parent = NULL; - trav->curr_child = 0; - trav->order = order; + /* Create the traversal structure */ + trav = malloc(sizeof(mpc_ast_trav_t)); + trav->curr_node = cnode; + trav->parent = NULL; + trav->curr_child = 0; + trav->order = order; - /* Get start node */ - switch(order) { - case mpc_ast_trav_order_pre: - /* Nothing else is needed for pre order start */ - break; + /* Get start node */ + switch(order) { + case mpc_ast_trav_order_pre: + /* Nothing else is needed for pre order start */ + break; - case mpc_ast_trav_order_post: - while(cnode->children_num > 0) { - cnode = cnode->children[0]; + case mpc_ast_trav_order_post: + while(cnode->children_num > 0) { + cnode = cnode->children[0]; - n_trav = malloc(sizeof(mpc_ast_trav_t)); - n_trav->curr_node = cnode; - n_trav->parent = trav; - n_trav->curr_child = 0; - n_trav->order = order; + n_trav = malloc(sizeof(mpc_ast_trav_t)); + n_trav->curr_node = cnode; + n_trav->parent = trav; + n_trav->curr_child = 0; + n_trav->order = order; - trav = n_trav; - } + trav = n_trav; + } - break; + break; - default: - /* Unreachable, but compiler complaints */ - break; - } + default: + /* Unreachable, but compiler complaints */ + break; + } - return trav; + return trav; } mpc_ast_t *mpc_ast_traverse_next(mpc_ast_trav_t **trav) { - mpc_ast_trav_t *n_trav, *to_free; - mpc_ast_t *ret = NULL; - int cchild; + mpc_ast_trav_t *n_trav, *to_free; + mpc_ast_t *ret = NULL; + int cchild; - /* The end of traversal was reached */ - if(*trav == NULL) return NULL; + /* The end of traversal was reached */ + if(*trav == NULL) return NULL; - switch((*trav)->order) { - case mpc_ast_trav_order_pre: - ret = (*trav)->curr_node; + switch((*trav)->order) { + case mpc_ast_trav_order_pre: + ret = (*trav)->curr_node; - /* If there aren't any more children, go up */ - while(*trav != NULL && - (*trav)->curr_child >= (*trav)->curr_node->children_num) - { - to_free = *trav; - *trav = (*trav)->parent; - free(to_free); - } + /* If there aren't any more children, go up */ + while(*trav != NULL && + (*trav)->curr_child >= (*trav)->curr_node->children_num) + { + to_free = *trav; + *trav = (*trav)->parent; + free(to_free); + } - /* If trav is NULL, the end was reached */ - if(*trav == NULL) { - break; - } + /* If trav is NULL, the end was reached */ + if(*trav == NULL) { + break; + } - /* Go to next child */ - n_trav = malloc(sizeof(mpc_ast_trav_t)); + /* Go to next child */ + n_trav = malloc(sizeof(mpc_ast_trav_t)); - cchild = (*trav)->curr_child; - n_trav->curr_node = (*trav)->curr_node->children[cchild]; - n_trav->parent = *trav; - n_trav->curr_child = 0; - n_trav->order = (*trav)->order; + cchild = (*trav)->curr_child; + n_trav->curr_node = (*trav)->curr_node->children[cchild]; + n_trav->parent = *trav; + n_trav->curr_child = 0; + n_trav->order = (*trav)->order; - (*trav)->curr_child++; - *trav = n_trav; + (*trav)->curr_child++; + *trav = n_trav; - break; + break; - case mpc_ast_trav_order_post: - ret = (*trav)->curr_node; + case mpc_ast_trav_order_post: + ret = (*trav)->curr_node; - /* Move up tree to the parent If the parent doesn't have any more - * nodes, then this is the current node. If it does, move down to - * its left most child. Also, free the previous traversal node */ - to_free = *trav; - *trav = (*trav)->parent; - free(to_free); + /* Move up tree to the parent If the parent doesn't have any more nodes, + * then this is the current node. If it does, move down to its left most + * child. Also, free the previous traversal node */ + to_free = *trav; + *trav = (*trav)->parent; + free(to_free); - if(*trav == NULL) - break; + if(*trav == NULL) + break; - /* Next child */ - (*trav)->curr_child++; + /* Next child */ + (*trav)->curr_child++; - /* If there aren't any more children, this is the next node */ - if((*trav)->curr_child >= (*trav)->curr_node->children_num) { - break; - } + /* If there aren't any more children, this is the next node */ + if((*trav)->curr_child >= (*trav)->curr_node->children_num) { + break; + } - /* If there are still more children, find the leftmost child from - * this node */ - while((*trav)->curr_node->children_num > 0) { - n_trav = malloc(sizeof(mpc_ast_trav_t)); + /* If there are still more children, find the leftmost child from this + * node */ + while((*trav)->curr_node->children_num > 0) { + n_trav = malloc(sizeof(mpc_ast_trav_t)); - cchild = (*trav)->curr_child; - n_trav->curr_node = (*trav)->curr_node->children[cchild]; - n_trav->parent = *trav; - n_trav->curr_child = 0; - n_trav->order = (*trav)->order; + cchild = (*trav)->curr_child; + n_trav->curr_node = (*trav)->curr_node->children[cchild]; + n_trav->parent = *trav; + n_trav->curr_child = 0; + n_trav->order = (*trav)->order; - *trav = n_trav; - } + *trav = n_trav; + } - default: - /* Unreachable, but compiler complaints */ - break; - } + default: + /* Unreachable, but compiler complaints */ + break; + } - return ret; + return ret; } mpc_val_t *mpcf_fold_ast(int n, mpc_val_t **xs) { From 0b287e6252cddbe317185c898fba219c43fa01de Mon Sep 17 00:00:00 2001 From: petermlm Date: Tue, 19 Apr 2016 23:26:52 +0100 Subject: [PATCH 5/5] Indentation --- mpc.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mpc.h b/mpc.h index bb6d72a..1ac123a 100644 --- a/mpc.h +++ b/mpc.h @@ -282,15 +282,15 @@ mpc_ast_t *mpc_ast_get_child(mpc_ast_t *ast, const char *tag); mpc_ast_t *mpc_ast_get_child_lb(mpc_ast_t *ast, const char *tag, int lb); typedef enum { - mpc_ast_trav_order_pre, - mpc_ast_trav_order_post + mpc_ast_trav_order_pre, + mpc_ast_trav_order_post } mpc_ast_trav_order_t; typedef struct mpc_ast_trav_t { - mpc_ast_t *curr_node; - struct mpc_ast_trav_t *parent; - int curr_child; - mpc_ast_trav_order_t order; + mpc_ast_t *curr_node; + struct mpc_ast_trav_t *parent; + int curr_child; + mpc_ast_trav_order_t order; } mpc_ast_trav_t; mpc_ast_trav_t *mpc_ast_traverse_start(mpc_ast_t *ast,