Add first kernel construction and its support
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 4 Jul 2024 10:32:26 +0000 (12:32 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Sun, 21 Jul 2024 18:21:20 +0000 (20:21 +0200)
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.

ft_parse/actions.c
ft_parse/ft_parse_inner.h
ft_parse/ft_parsing_table_free.c
ft_parse/ft_parsing_table_generate.c
ft_parse/helpers.c

index accc57cb687325ae365fe3f5c6f80682a78085ce..9dcc13fa5fd54c4b92257f6d291d1bd2851d259b 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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)
        {
index ac72056e1379d692cf303c79afdd485991aa258d..e5b425a521166fa8c23616c64dc8448ec53ef522 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
index bf1633445ed1277bc66c03f0382253957b8cd926..3cf8b7c72ecf31189dedb5035df2638b124e2923 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 ;
index e8a40ecf277d47d6c5ccc87892f70c58db11451f..6f398519d3c09e16bbcce55c2f2c725c92a97a92 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
 }
index 14b1719244d7a181784ef08569e0e0b4edcebcb5..1aca55bc8ef52d03465b26be6529236b9d353785 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
 }