From: Lukas Jiriste Date: Thu, 4 Jul 2024 10:32:26 +0000 (+0200) Subject: Add first kernel construction and its support X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=7f13e68a114a2777ae66fdde4b3efe997c612263;p=Libft.git Add first kernel construction and its support The supporting changes consist of changing the ft_token_dup function to take pointer to token as input. Taking global static token caused some error but was solved by passing pointer. Function to free structs now handle NULL gracefully. This was encountered because not all used structures are initialized yet. The zeroth rule is added to generate a table, that returns the original first token as a root of the table. The type of NULL cannot be achieved any other way inside the table.rules. --- diff --git a/ft_parse/actions.c b/ft_parse/actions.c index accc57c..9dcc13f 100644 --- a/ft_parse/actions.c +++ b/ft_parse/actions.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/21 15:34:14 by ljiriste #+# #+# */ -/* Updated: 2024/06/21 16:46:28 by ljiriste ### ########.fr */ +/* Updated: 2024/07/04 12:22:27 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,7 +23,7 @@ int push_state(t_stack *stack, size_t state_num, t_token token) if (!element.node) return (1); ft_vec_init(&element.node->children, sizeof(t_parse_tree_node)); - element.node->token = ft_token_dup(token); + element.node->token = ft_token_dup(&token); if (!element.node->token.type) return (1); element.state_num = state_num; @@ -70,7 +70,7 @@ int follow_rule(t_stack *stack, size_t rule_num, const t_parsing_table *table) return (1); ft_vec_init(&element.node->children, sizeof(t_parse_tree_node)); rule = ft_vec_caccess(&table->rules, rule_num); - element.node->token = ft_token_dup(rule->result); + element.node->token = ft_token_dup(&rule->result); i = rule->constituents.size; while (i > 0) { diff --git a/ft_parse/ft_parse_inner.h b/ft_parse/ft_parse_inner.h index ac72056..e5b425a 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/28 10:23:32 by ljiriste ### ########.fr */ +/* Updated: 2024/07/04 12:21:27 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -41,7 +41,7 @@ void ft_free_rule(void *v_rule); void ft_free_state(void *v_state); void ft_free_stack_element(void *v_el); -t_token ft_token_dup(t_token token); +t_token ft_token_dup(const 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); diff --git a/ft_parse/ft_parsing_table_free.c b/ft_parse/ft_parsing_table_free.c index bf16334..3cf8b7c 100644 --- a/ft_parse/ft_parsing_table_free.c +++ b/ft_parse/ft_parsing_table_free.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/20 13:21:26 by ljiriste #+# #+# */ -/* Updated: 2024/06/21 16:56:50 by ljiriste ### ########.fr */ +/* Updated: 2024/07/04 12:25:49 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,8 @@ void ft_free_token(void *v_token) t_token *token; token = v_token; + if (!token) + return ; free(token->type); free(token->str); return ; @@ -29,6 +31,8 @@ void ft_free_rule(void *v_rule) t_grammar_rule *rule; rule = v_rule; + if (!rule) + return ; ft_free_token(&rule->result); ft_vec_free(&rule->constituents, ft_free_token); return ; @@ -39,6 +43,8 @@ void ft_free_state(void *v_state) t_parser_state *state; state = v_state; + if (!state) + return ; ft_vec_free(&state->lookahead, NULL); ft_vec_free(&state->gotos, NULL); return ; diff --git a/ft_parse/ft_parsing_table_generate.c b/ft_parse/ft_parsing_table_generate.c index e8a40ec..6f39851 100644 --- a/ft_parse/ft_parsing_table_generate.c +++ b/ft_parse/ft_parsing_table_generate.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 11:16:53 by ljiriste #+# #+# */ -/* Updated: 2024/07/04 10:21:29 by ljiriste ### ########.fr */ +/* Updated: 2024/07/04 12:29:18 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,8 @@ static const t_token empty_token = {.type = "''", .str = NULL}; void free_item(t_lr1_item *item) { + if (!item) + return ; ft_vec_free(&item->lookahead, ft_free_token); return ; } @@ -31,6 +33,8 @@ void void_free_item(void *v_item) void free_generator_state(t_generator_state *state) { + if (!state) + return ; ft_vec_free(&state->kernel, void_free_item); ft_vec_free(&state->closure, void_free_item); ft_vec_free(&state->goto_tokens, ft_free_token); @@ -109,7 +113,7 @@ t_ft_stat v_token_dup(void *dest, const void *src) { if (dest == NULL) return (alloc_fail); - *(t_token *)dest = ft_token_dup(*(t_token *)src); + *(t_token *)dest = ft_token_dup((t_token *)src); return (success); } @@ -229,7 +233,7 @@ t_ft_stat add_first(t_vec *lookahead, const t_token *token, const t_vec *rules, if (is_terminal_token(token, tokens)) { - token_copy = ft_token_dup(*token); + token_copy = ft_token_dup(token); res = ft_vec_setinsert(lookahead, token, void_cmp_token_type); if (res != success) ft_free_token(&token_copy); @@ -276,7 +280,7 @@ t_ft_stat add_to_lookahead(const t_vec *lookahead, t_vec *new_lookahead) i = 0; while (i < lookahead->size) { - token = ft_token_dup(*(const t_token *)ft_vec_caccess(lookahead, i)); + token = ft_token_dup(ft_vec_caccess(lookahead, i)); res = ft_vec_setinsert(new_lookahead, &token, void_cmp_token_type); if (res != success) ft_free_token(&token); @@ -420,10 +424,30 @@ t_ft_stat solve_gotos(t_generator_state *state, t_vec *states, const t_vec *rule return (success); } -t_ft_stat construct_first_kernel(__attribute__((unused))t_vec *kernel, __attribute__((unused))const t_vec *rules, __attribute__((unused))const t_vec *tokens) +t_ft_stat construct_first_kernel(__attribute__((unused))t_vec *kernel, __attribute__((unused))const t_vec *rules) { - ft_printf("construct_first_kernel is not yet implemented\n"); - return (success); + t_ft_stat res; + t_lr1_item item; + t_token token; + + res = ft_vec_init(&item.lookahead, sizeof(t_token)); + if (res != success) + return (res); + token = ft_token_dup(&eof_token); + if (!token.type) + return (alloc_fail); + res = ft_vec_append(&item.lookahead, &token); + if (res != success) + { + ft_free_token(&token); + return (res); + } + item.core.rule = ft_vec_caccess(rules, 0); + item.core.position = 0; + res = ft_vec_append(kernel, &item); + if (res != success) + ft_vec_free(&item.lookahead, ft_free_token); + return (res); } t_ft_stat categorize_tokens(__attribute__((unused))t_vec *tokens, __attribute__((unused))const t_vec *rules) @@ -437,7 +461,10 @@ t_ft_stat construct_states(t_vec *states, const t_vec *rules, const t_vec *token t_vec kernel; t_ft_stat res; - res = construct_first_kernel(&kernel, rules, tokens); + res = ft_vec_init(&kernel, sizeof(t_lr1_item)); + if (res != success) + return (res); + res = construct_first_kernel(&kernel, rules); if (res != success) return (res); res = construct_state(&kernel, states, rules, tokens); @@ -452,18 +479,91 @@ t_ft_stat translate_to_table(__attribute__((unused))t_parsing_table *table,__att return (success); } +t_ft_stat init_table(t_parsing_table *table) +{ + t_ft_stat res; + + res = ft_vec_init(&table->rules, sizeof(t_grammar_rule)); + if (res != success) + return (res); + res = ft_vec_init(&table->states, sizeof(t_parser_state)); + if (res != success) + return (res); + res = ft_vec_init(&table->tokens, sizeof(t_token)); + if (res != success) + return (res); + return (success); +} + +t_ft_stat add_zeroth_rule(t_vec *rules) +{ + t_ft_stat res; + t_grammar_rule rule; + t_token first_token; + + rule.result.type = NULL; + rule.result.str = NULL; + first_token = ft_token_dup(&((const t_grammar_rule *)ft_vec_caccess(rules, 0))->result); + if (!first_token.type) + return (alloc_fail); + res = ft_vec_init(&rule.constituents, sizeof(t_token)); + if (res != success) + return (res); + res = ft_vec_append(&rule.constituents, &first_token); + if (res != success) + ft_free_token(&first_token); + res = ft_vec_insert(rules, &rule, 0); + if (res != success) + ft_free_rule(&rule); + return (success); +} + +void remove_zeroth_rule(t_vec *rules) +{ + ft_vec_erase(rules, 0, ft_free_rule); + return ; +} + +t_ft_stat prepare_table(t_parsing_table *table, const char *rules_filename) +{ + t_ft_stat res; + + res = init_table(table); + if (res != success) + return (res); + res = load_rules(&table->rules, rules_filename); + if (res != success) + return (res); + res = add_zeroth_rule(&table->rules); + if (res != success) + { + ft_vec_free(&table->rules, ft_free_rule); + return (res); + } + res = categorize_tokens(&table->tokens, &table->rules); + if (res != success) + ft_vec_free(&table->rules, ft_free_rule); + return (res); +} + t_ft_stat ft_parsing_table_generate(t_parsing_table *table, const char *rules_filename) { t_ft_stat res; t_vec states; - ft_vec_init(&states, sizeof(t_generator_state *)); - res = load_rules(&table->rules, rules_filename); + res = ft_vec_init(&states, sizeof(t_generator_state *)); + if (res != success) + return (res); + res = prepare_table(table, rules_filename); if (res != success) return (res); - categorize_tokens(&table->tokens, &table->rules); res = construct_states(&states, &table->rules, &table->tokens); + if (res != success) + return (res); + remove_zeroth_rule(&table->rules); res = translate_to_table(table, &states); + if (res != success) + return (res); ft_vec_free(&states, void_free_generator_state); return (success); } diff --git a/ft_parse/helpers.c b/ft_parse/helpers.c index 14b1719..1aca55b 100644 --- a/ft_parse/helpers.c +++ b/ft_parse/helpers.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/21 15:30:29 by ljiriste #+# #+# */ -/* Updated: 2024/06/21 16:52:09 by ljiriste ### ########.fr */ +/* Updated: 2024/07/04 12:14:30 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,12 +25,18 @@ void ft_free_stack_element(void *v_el) return ; } -t_token ft_token_dup(t_token token) +t_token ft_token_dup(const t_token *token) { t_token res; - res.type = ft_strdup(token.type); - res.str = ft_strdup(token.str); + if (!token) + { + res.type = NULL; + res.str = NULL; + return (res); + } + res.type = ft_strdup(token->type); + res.str = ft_strdup(token->str); return (res); }