/* tree inserter * inserts element into the tree * if replace set to true - substitues previous element with * the same key value. Otherwise - appends new element. * * returns 0 in case of success, non-zero value otherwise. * */ int _node_insert(Tree* t, Node** r, void* element, int replace) { Node* n = *r; if ( ! n ) { n = *r = (Node*)malloc(sizeof(Node)); if (! n ) return -2; n->data = t->cl(element); n->left = NULL; n->right = NULL; return 0; } /* node exists */ if ( t->lf(element, n->data) ) { return _node_insert(t, &n->left, element, replace); } else if ( t->lf(n->data, element) || !replace ) { return _node_insert(t, &n->right, element, replace); } else { t->dt(n->data); n->data = t->cl(element); return 0; } }
/* nfa state map: rule a? |------------------ε-------------------| | ∨ <start> --ε--> <s1> --a--> <s2> --ε--> <end> */ static size_t _gen_op_rpq(struct reg_pattern* pattern, struct reg_ast_node* root, size_t start_state_pos){ size_t s1_pos = _node_new(pattern); _node_insert(pattern, start_state_pos, NULL, s1_pos); size_t s2_pos = _gen_op(pattern, root->childs[0], s1_pos); size_t end_pos = _node_new(pattern); _node_insert(pattern, start_state_pos, NULL, end_pos); _node_insert(pattern, s2_pos, NULL, end_pos); return end_pos; }
/* nfa state map: rule: ab --ε--> <start> --a--> <s1> --ε--> <s2> --b--> <end> */ static size_t _gen_op_and(struct reg_pattern* pattern, struct reg_ast_node* root, size_t start_state_pos){ assert(root->op == op_and); size_t s1_pos = _gen_op(pattern, root->childs[0], start_state_pos); size_t s2_pos = _node_new(pattern); _node_insert(pattern, s1_pos, NULL, s2_pos); size_t end = _gen_op(pattern, root->childs[1], s2_pos); return end; }
/* nfa state map: rule: [a-b] <start> --[a-b]--> <end> */ static size_t _gen_op_range(struct reg_pattern* pattern, struct reg_ast_node* root, size_t start_state_pos){ assert(root->op == op_range); struct reg_range* range = &(root->value.range); size_t end_pos = _node_new(pattern); int is_insert = 0; is_insert = _node_insert(pattern, start_state_pos, range, end_pos); assert(is_insert); return end_pos; }
int tree_insert(Tree* t, void* element, int replace) { return _node_insert(t, &t->root, element, replace); }