Made post order tree traversal

This commit is contained in:
petermlm
2016-04-19 22:27:32 +01:00
parent aa17e0723e
commit 9ac854ad5a
2 changed files with 104 additions and 0 deletions

87
mpc.c
View File

@@ -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;

17
mpc.h
View File

@@ -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!
*/