Refactor to better comply with the Norm
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 21 Jun 2024 12:08:22 +0000 (14:08 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 21 Jun 2024 12:08:22 +0000 (14:08 +0200)
ft_parse/ft_parse.c

index 327fda28af64666c274d2dabb2f8b39ab5568b8d..ef59f8cc613add99469c08e31c7b3f8c07823aca 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/05/20 20:51:36 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/06/21 11:46:04 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/06/21 13:56:25 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -76,31 +76,49 @@ ssize_t     find_token_index(t_token token, const t_vec *tokens)
        i = 0;
        while (i < tokens->size)
        {
-               if (!ft_strcmp(token.type, ((t_token *)ft_vec_caccess(tokens, i))->type))
+               if (!ft_strcmp(token.type,
+                               ((t_token *)ft_vec_caccess(tokens, i))->type))
                        return (i);
                ++i;
        }
        return (-1);
 }
 
-ssize_t        goto_state(size_t state_num, const t_parsing_table *table, t_token token)
+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, state_num);
+       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)));
+       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;
-       t_parse_tree_node               *node;
        size_t                                  i;
 
-       element.node = malloc(sizeof(*node));
+       element.node = malloc(sizeof(*element.node));
        if (!element.node)
                return (1);
        ft_vec_init(&element.node->children, sizeof(t_parse_tree_node));
@@ -110,18 +128,14 @@ int       follow_rule(t_stack *stack, size_t rule_num, const t_parsing_table *table)
        while (i > 0)
        {
                --i;
-               node = ((t_parser_stack_element *)ft_stack_pop(stack, NULL))->node;
-               if (ft_strcmp(node->token.type,
-                                       ((t_token *)ft_vec_caccess(&rule->constituents, i))->type) ||
-                               ft_vec_insert(&element.node->children, node, 0) != success)
+               if (hang_top_from_tree(stack, element.node,
+                               ft_vec_caccess(&rule->constituents, i)))
                {
                        ft_parse_tree_free(element.node);
-                       ft_parse_tree_free(node);
                        return (1);
                }
-               free(node);
        }
-       element.state_num = goto_state(((t_parser_stack_element *)ft_stack_top(stack))->state_num, table, rule->result);
+       element.state_num = goto_state(ft_stack_top(stack), table, rule->result);
        return (ft_stack_push(stack, &element) != success || element.state_num < 0);
 }
 
@@ -136,14 +150,29 @@ void      initialize_parser_stack(t_stack *stack)
        return ;
 }
 
+const t_parser_action  *get_action(t_stack *stack, t_token token,
+               const t_parsing_table *table)
+{
+       const t_parser_state    *state;
+       ssize_t                                 column;
+
+       state = ft_vec_caccess(&table->states,
+                       ((t_parser_stack_element *)ft_stack_top(stack))->state_num);
+       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);
+               return (NULL);
+       }
+       return (ft_vec_caccess(&state->lookahead, column));
+}
+
 t_parse_tree_node      *ft_parse(const t_vec *tokens, const t_parsing_table *table)
 {
        t_stack                                 stack;
        size_t                                  i;
        t_token                                 token;
-       const t_parser_state    *state;
        const t_parser_action   *action;
-       ssize_t                                 column;
        t_parse_tree_node               *root;
 
        initialize_parser_stack(&stack);
@@ -159,16 +188,13 @@ t_parse_tree_node *ft_parse(const t_vec *tokens, const t_parsing_table *table)
                        ft_stack_free(&stack, ft_stack_element_free);
                        return (NULL);
                }
-               state = ft_vec_caccess(&table->states,
-                       ((t_parser_stack_element *)ft_stack_top(&stack))->state_num);
-               column = find_token_index(token, &table->tokens);
-               if (column < 0 || (size_t)column > table->terminal_tokens_num)
+               action = get_action(&stack, token, table);
+               if (!action || action->type == parser_refuse)
                {
                        ft_stack_free(&stack, ft_stack_element_free);
                        return (NULL);
                }
-               action = ft_vec_caccess(&state->lookahead, column);
-               if (action->type == parser_reduce)
+               else if (action->type == parser_reduce)
                {
                        if (follow_rule(&stack, action->number, table))
                        {
@@ -185,11 +211,6 @@ t_parse_tree_node  *ft_parse(const t_vec *tokens, const t_parsing_table *table)
                        }
                        ++i;
                }
-               else if (action->type == parser_refuse)
-               {
-                       ft_stack_free(&stack, ft_stack_element_free);
-                       return (NULL);
-               }
                else if (action->type == parser_accept)
                {
                        root = ((t_parser_stack_element *)ft_stack_top(&stack))->node;