From: Lukas Jiriste Date: Fri, 21 Jun 2024 13:44:09 +0000 (+0200) Subject: Refactor ft_parse.c to comply with the Norm X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=849bac655e50af0af304e41325cb6068504089d1;p=Libft.git Refactor ft_parse.c to comply with the Norm --- diff --git a/Makefile b/Makefile index 00ad5e0..6ed432a 100644 --- a/Makefile +++ b/Makefile @@ -22,8 +22,12 @@ SRCparse:= ft_parse.c \ ft_parsing_table_print.c \ ft_parsing_table_free.c \ ft_parse_tree_print.c \ + ft_parse_tree_free.c \ load_rules.c \ add_line.c \ + actions.c \ + helpers.c \ + SRCgen := ft_swap.c \ diff --git a/ft_parse/actions.c b/ft_parse/actions.c new file mode 100644 index 0000000..a84b040 --- /dev/null +++ b/ft_parse/actions.c @@ -0,0 +1,87 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* actions.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/21 15:34:14 by ljiriste #+# #+# */ +/* Updated: 2024/06/21 15:36:12 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_parse_inner.h" +#include "ft_parse.h" +#include "libft.h" +#include + +int push_state(t_stack *stack, size_t state_num, t_token token) +{ + t_parser_stack_element element; + + element.node = malloc(sizeof(*element.node)); + if (!element.node) + return (1); + ft_vec_init(&element.node->children, sizeof(t_parse_tree_node)); + element.node->token = dup_token(token); + if (!element.node->token.type) + return (1); + element.state_num = state_num; + ft_stack_push(stack, &element); + return (0); +} + +static ssize_t goto_state(const t_parser_stack_element *el, + const t_parsing_table *table, t_token token) +{ + const t_parser_state *state; + ssize_t column; + + state = ft_vec_caccess(&table->states, el->state_num); + column = find_token_index(token, &table->tokens); + return (*(ssize_t *)ft_vec_caccess(&state->gotos, + column - (table->terminal_tokens_num + 1))); +} + +static int hang_top_from_tree(t_stack *stack, t_parse_tree_node *tree, + const t_token *constituent_token) +{ + t_parse_tree_node *node; + + node = ((t_parser_stack_element *)ft_stack_pop(stack, NULL))->node; + if (ft_strcmp(node->token.type, constituent_token->type) + || ft_vec_insert(&tree->children, node, 0) != success) + { + ft_parse_tree_free(node); + return (1); + } + free(node); + return (0); +} + +int follow_rule(t_stack *stack, size_t rule_num, const t_parsing_table *table) +{ + const t_grammar_rule *rule; + t_parser_stack_element element; + size_t i; + + element.node = malloc(sizeof(*element.node)); + if (!element.node) + return (1); + ft_vec_init(&element.node->children, sizeof(t_parse_tree_node)); + rule = ft_vec_caccess(&table->rules, rule_num); + element.node->token = dup_token(rule->result); + i = rule->constituents.size; + while (i > 0) + { + --i; + if (hang_top_from_tree(stack, element.node, + ft_vec_caccess(&rule->constituents, i))) + { + ft_parse_tree_free(element.node); + return (1); + } + } + element.state_num = goto_state(ft_stack_top(stack), table, rule->result); + return (ft_stack_push(stack, &element) != success || element.state_num < 0); +} diff --git a/ft_parse/ft_parse.c b/ft_parse/ft_parse.c index 7a47bd6..083f8c2 100644 --- a/ft_parse/ft_parse.c +++ b/ft_parse/ft_parse.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/20 20:51:36 by ljiriste #+# #+# */ -/* Updated: 2024/06/21 15:22:31 by ljiriste ### ########.fr */ +/* Updated: 2024/06/21 15:36:40 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,133 +15,7 @@ #include "libft.h" #include -static void parse_tree_free_children(void *v_node) -{ - t_parse_tree_node *node; - - node = v_node; - if (!node) - return ; - ft_vec_free(&node->children, parse_tree_free_children); - free_token(&node->token); -} - -void ft_parse_tree_free(void *node) -{ - parse_tree_free_children(node); - free(node); - return ; -} - -void ft_stack_element_free(void *v_el) -{ - t_parser_stack_element *el; - - el = v_el; - if (!el) - return ; - ft_parse_tree_free(el->node); - return ; -} - -t_token dup_token(t_token token) -{ - t_token res; - - res.type = ft_strdup(token.type); - res.str = ft_strdup(token.str); - return (res); -} - -int push_state(t_stack *stack, size_t state_num, t_token token) -{ - t_parser_stack_element element; - - element.node = malloc(sizeof(*element.node)); - if (!element.node) - return (1); - ft_vec_init(&element.node->children, sizeof(t_parse_tree_node)); - element.node->token = dup_token(token); - if (!element.node->token.type) - return (1); - element.state_num = state_num; - ft_stack_push(stack, &element); - return (0); -} - -ssize_t find_token_index(t_token token, const t_vec *tokens) -{ - size_t i; - - if (!token.type) - return (-1); - i = 0; - while (i < tokens->size) - { - if (!ft_strcmp(token.type, - ((t_token *)ft_vec_caccess(tokens, i))->type)) - return (i); - ++i; - } - return (-1); -} - -ssize_t goto_state(const t_parser_stack_element *el, - const t_parsing_table *table, t_token token) -{ - const t_parser_state *state; - ssize_t column; - - state = ft_vec_caccess(&table->states, el->state_num); - column = find_token_index(token, &table->tokens); - return (*(ssize_t *)ft_vec_caccess(&state->gotos, - column - (table->terminal_tokens_num + 1))); -} - -int hang_top_from_tree(t_stack *stack, t_parse_tree_node *tree, - const t_token *constituent_token) -{ - t_parse_tree_node *node; - - node = ((t_parser_stack_element *)ft_stack_pop(stack, NULL))->node; - if (ft_strcmp(node->token.type, constituent_token->type) - || ft_vec_insert(&tree->children, node, 0) != success) - { - ft_parse_tree_free(node); - return (1); - } - free(node); - return (0); -} - -int follow_rule(t_stack *stack, size_t rule_num, const t_parsing_table *table) -{ - const t_grammar_rule *rule; - t_parser_stack_element element; - size_t i; - - element.node = malloc(sizeof(*element.node)); - if (!element.node) - return (1); - ft_vec_init(&element.node->children, sizeof(t_parse_tree_node)); - rule = ft_vec_caccess(&table->rules, rule_num); - element.node->token = dup_token(rule->result); - i = rule->constituents.size; - while (i > 0) - { - --i; - if (hang_top_from_tree(stack, element.node, - ft_vec_caccess(&rule->constituents, i))) - { - ft_parse_tree_free(element.node); - return (1); - } - } - element.state_num = goto_state(ft_stack_top(stack), table, rule->result); - return (ft_stack_push(stack, &element) != success || element.state_num < 0); -} - -void initialize_parser_stack(t_stack *stack) +static void initialize_parser_stack(t_stack *stack) { t_parser_stack_element zero; @@ -152,7 +26,7 @@ void initialize_parser_stack(t_stack *stack) return ; } -const t_parser_action *get_action(t_stack *stack, t_token token, +static const t_parser_action *get_action(t_stack *stack, t_token token, const t_parsing_table *table) { const t_parser_state *state; @@ -163,13 +37,13 @@ const t_parser_action *get_action(t_stack *stack, t_token token, column = find_token_index(token, &table->tokens); if (column < 0 || (size_t)column > table->terminal_tokens_num) { - ft_stack_free(stack, ft_stack_element_free); + ft_stack_free(stack, free_stack_element); return (NULL); } return (ft_vec_caccess(&state->lookahead, column)); } -t_token get_token(const t_vec *tokens, size_t index) +static t_token get_token(const t_vec *tokens, size_t index) { static char end_token[] = "$"; @@ -179,7 +53,7 @@ t_token get_token(const t_vec *tokens, size_t index) return ((t_token){.type = end_token, .str = NULL}); } -t_parse_tree_node *handle_accept(t_stack *stack) +static t_parse_tree_node *handle_accept(t_stack *stack) { t_parse_tree_node *root; @@ -207,7 +81,7 @@ t_parse_tree_node *ft_parse(const t_vec *tokens, const t_parsing_table *table) || (action->type == parser_shift && push_state(&stack, action->number, token))) { - ft_stack_free(&stack, ft_stack_element_free); + ft_stack_free(&stack, free_stack_element); return (NULL); } else if (action->type == parser_accept) diff --git a/ft_parse/ft_parse_inner.h b/ft_parse/ft_parse_inner.h index 2b15263..8c70ea2 100644 --- a/ft_parse/ft_parse_inner.h +++ b/ft_parse/ft_parse_inner.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/20 13:23:20 by ljiriste #+# #+# */ -/* Updated: 2024/06/21 11:47:25 by ljiriste ### ########.fr */ +/* Updated: 2024/06/21 15:37:09 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,8 +18,15 @@ void free_token(void *v_token); void free_rule(void *v_rule); void free_state(void *v_state); +void free_stack_element(void *v_el); + +t_token dup_token(t_token token); +ssize_t find_token_index(t_token token, const t_vec *tokens); t_ft_stat load_rules(t_vec *rules, const char *rules_filename); int add_line(t_vec *states, const char *line, size_t lookahead_size); +int follow_rule(t_stack *stack, size_t rule_num, + const t_parsing_table *table); +int push_state(t_stack *stack, size_t state_num, t_token token); #endif //FT_PARSE_INNER_H diff --git a/ft_parse/ft_parse_tree_free.c b/ft_parse/ft_parse_tree_free.c new file mode 100644 index 0000000..287507a --- /dev/null +++ b/ft_parse/ft_parse_tree_free.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_parse_tree_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/21 15:26:34 by ljiriste #+# #+# */ +/* Updated: 2024/06/21 15:28:52 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_parse_inner.h" +#include "ft_parse.h" +#include + +static void parse_tree_free_children(void *v_node) +{ + t_parse_tree_node *node; + + node = v_node; + if (!node) + return ; + ft_vec_free(&node->children, parse_tree_free_children); + free_token(&node->token); +} + +void ft_parse_tree_free(void *node) +{ + parse_tree_free_children(node); + free(node); + return ; +} diff --git a/ft_parse/helpers.c b/ft_parse/helpers.c new file mode 100644 index 0000000..adb9867 --- /dev/null +++ b/ft_parse/helpers.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* helpers.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/21 15:30:29 by ljiriste #+# #+# */ +/* Updated: 2024/06/21 15:33:39 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_parse_inner.h" +#include "ft_parse.h" +#include "libft.h" + +void free_stack_element(void *v_el) +{ + t_parser_stack_element *el; + + el = v_el; + if (!el) + return ; + ft_parse_tree_free(el->node); + return ; +} + +t_token dup_token(t_token token) +{ + t_token res; + + res.type = ft_strdup(token.type); + res.str = ft_strdup(token.str); + return (res); +} + +ssize_t find_token_index(t_token token, const t_vec *tokens) +{ + size_t i; + + if (!token.type) + return (-1); + i = 0; + while (i < tokens->size) + { + if (!ft_strcmp(token.type, + ((t_token *)ft_vec_caccess(tokens, i))->type)) + return (i); + ++i; + } + return (-1); +} diff --git a/inc/ft_parse.h b/inc/ft_parse.h index d567af4..609390e 100644 --- a/inc/ft_parse.h +++ b/inc/ft_parse.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/27 21:21:54 by ljiriste #+# #+# */ -/* Updated: 2024/06/21 11:47:12 by ljiriste ### ########.fr */ +/* Updated: 2024/06/21 15:39:41 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -62,7 +62,7 @@ typedef struct s_parse_tree_node t_vec children; // t_vec of t_parse_tree_node } t_parse_tree_node; -typedef struct s_parser_stack_element +typedef struct s_parser_stack_element { ssize_t state_num; t_parse_tree_node *node; @@ -91,17 +91,18 @@ typedef struct s_parser_stack_element // // Tokens should not contain whitespace as it is used as separator -t_ft_stat ft_parsing_table_init(t_parsing_table *table); -t_ft_stat ft_parsing_table_load(t_parsing_table *table, - const char *filename, - const char *rules_filename); -t_parse_tree_node *ft_parse(const t_vec *tokens, const t_parsing_table *table); +t_ft_stat ft_parsing_table_init(t_parsing_table *table); +t_ft_stat ft_parsing_table_load(t_parsing_table *table, + const char *filename, + const char *rules_filename); +t_parse_tree_node *ft_parse(const t_vec *tokens, + const t_parsing_table *table); -void ft_parsing_table_print(t_parsing_table *table, - unsigned int column_width); -void ft_parse_tree_print(t_parse_tree_node *root); +void ft_parsing_table_print(t_parsing_table *table, + unsigned int column_width); +void ft_parse_tree_print(t_parse_tree_node *root); -void ft_parse_tree_free(void *v_node); -void ft_parsing_table_free(t_parsing_table *table); +void ft_parse_tree_free(void *node); +void ft_parsing_table_free(t_parsing_table *table); #endif // FT_PARSE_H