/* retoor */ #include "ast.h" #include #include static ast_node_t *ast_create_node(ast_type_t type) { ast_node_t *node = malloc(sizeof(ast_node_t)); if (!node) return NULL; node->type = type; node->value = '\0'; node->left = NULL; node->right = NULL; node->group_id = -1; node->bracket = NULL; node->quant.min = 0; node->quant.max = -1; node->quant.greedy = true; return node; } ast_node_t *ast_create_char(char c) { ast_node_t *node = ast_create_node(AST_CHAR); if (node) node->value = c; return node; } ast_node_t *ast_create_dot(void) { return ast_create_node(AST_DOT); } ast_node_t *ast_create_concat(ast_node_t *left, ast_node_t *right) { ast_node_t *node = ast_create_node(AST_CONCAT); if (node) { node->left = left; node->right = right; } return node; } ast_node_t *ast_create_alter(ast_node_t *left, ast_node_t *right) { ast_node_t *node = ast_create_node(AST_ALTER); if (node) { node->left = left; node->right = right; } return node; } ast_node_t *ast_create_star(ast_node_t *child, bool greedy) { ast_node_t *node = ast_create_node(AST_STAR); if (node) { node->left = child; node->quant.greedy = greedy; } return node; } ast_node_t *ast_create_plus(ast_node_t *child, bool greedy) { ast_node_t *node = ast_create_node(AST_PLUS); if (node) { node->left = child; node->quant.greedy = greedy; } return node; } ast_node_t *ast_create_question(ast_node_t *child, bool greedy) { ast_node_t *node = ast_create_node(AST_QUESTION); if (node) { node->left = child; node->quant.greedy = greedy; } return node; } ast_node_t *ast_create_group(ast_node_t *child, int group_id) { ast_node_t *node = ast_create_node(AST_GROUP); if (node) { node->left = child; node->group_id = group_id; } return node; } ast_node_t *ast_create_anchor_start(void) { return ast_create_node(AST_ANCHOR_START); } ast_node_t *ast_create_anchor_end(void) { return ast_create_node(AST_ANCHOR_END); } ast_node_t *ast_create_bracket(bracket_class_t *bracket) { ast_node_t *node = ast_create_node(AST_BRACKET); if (node) node->bracket = bracket; return node; } ast_node_t *ast_create_quantifier(ast_node_t *child, int min, int max, bool greedy) { ast_node_t *node = ast_create_node(AST_QUANTIFIER); if (node) { node->left = child; node->quant.min = min; node->quant.max = max; node->quant.greedy = greedy; } return node; } ast_node_t *ast_create_class(ast_type_t type) { return ast_create_node(type); } void ast_free(ast_node_t *node) { if (!node) return; ast_free(node->left); ast_free(node->right); if (node->bracket) bracket_free(node->bracket); free(node); } bracket_class_t *bracket_create(void) { bracket_class_t *bracket = malloc(sizeof(bracket_class_t)); if (!bracket) return NULL; bracket->ranges = NULL; bracket->count = 0; bracket->capacity = 0; bracket->negated = false; return bracket; } static bool bracket_grow(bracket_class_t *bracket) { size_t new_cap = bracket->capacity == 0 ? 8 : bracket->capacity * 2; char_range_t *new_ranges = realloc(bracket->ranges, new_cap * sizeof(char_range_t)); if (!new_ranges) return false; bracket->ranges = new_ranges; bracket->capacity = new_cap; return true; } void bracket_add_char(bracket_class_t *bracket, char c) { bracket_add_range(bracket, c, c); } void bracket_add_range(bracket_class_t *bracket, char start, char end) { if (bracket->count >= bracket->capacity) { if (!bracket_grow(bracket)) return; } bracket->ranges[bracket->count].start = start; bracket->ranges[bracket->count].end = end; bracket->count++; } void bracket_free(bracket_class_t *bracket) { if (!bracket) return; free(bracket->ranges); free(bracket); } bool bracket_matches(bracket_class_t *bracket, char c) { bool found = false; for (size_t i = 0; i < bracket->count; i++) { if (c >= bracket->ranges[i].start && c <= bracket->ranges[i].end) { found = true; break; } } return bracket->negated ? !found : found; }