Refactor ft_parse.c to comply with the Norm
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 21 Jun 2024 13:44:09 +0000 (15:44 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 21 Jun 2024 13:44:09 +0000 (15:44 +0200)
Makefile
ft_parse/actions.c [new file with mode: 0644]
ft_parse/ft_parse.c
ft_parse/ft_parse_inner.h
ft_parse/ft_parse_tree_free.c [new file with mode: 0644]
ft_parse/helpers.c [new file with mode: 0644]
inc/ft_parse.h

index 00ad5e065ecea041ed6379570a6798b7657585ef..6ed432a59929ebbc6251cb96b4a80d861489ed35 100644 (file)
--- 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 (file)
index 0000000..a84b040
--- /dev/null
@@ -0,0 +1,87 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   actions.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 <stdlib.h>
+
+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);
+}
index 7a47bd69801f4fd59b0c7e55aee96c36dad6553f..083f8c27cb4e167f3b2a7977c96fac6bada3cfdc 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 15:22:31 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/06/21 15:36:40 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "libft.h"
 #include <stdlib.h>
 
-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)
index 2b15263ff1d7ab2179d73e863330ededa095a66e..8c70ea2a36200926f8d6220b26867f3f282d63bf 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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       */
 /*                                                                            */
 /* ************************************************************************** */
 
 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 (file)
index 0000000..287507a
--- /dev/null
@@ -0,0 +1,33 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_parse_tree_free.c                               :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 <stdlib.h>
+
+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 (file)
index 0000000..adb9867
--- /dev/null
@@ -0,0 +1,52 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   helpers.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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);
+}
index d567af4f6581dde633bfc22baf44953d4449d50f..609390e7248f18b090e3a87af609723b758c35c8 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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