Add a function to save a table as a file
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 19 Jul 2024 11:57:12 +0000 (13:57 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Sun, 21 Jul 2024 18:21:22 +0000 (20:21 +0200)
This file is then readable by ft_parsing_table_load.
Some lazy checks are written to check that something was written to the
file, but if only partial write happens, those will not notice.

Makefile
ft_parse/ft_parsing_table_save.c [new file with mode: 0644]
inc/ft_parse.h

index 6fa3e65deef3d39e50e76faca9d09ac3f015effb..8dcafe56b38c2c2717abd48c13eeea1b6674b9d9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,7 @@ SRCparse:=    ft_parse.c                                      \
                        ft_parsing_table_generate.c     \
                        ft_parsing_table_load.c         \
                        ft_parsing_table_print.c        \
+                       ft_parsing_table_save.c \
                        ft_parsing_table_free.c         \
                        ft_parse_tree_print.c           \
                        ft_parse_tree_free.c            \
diff --git a/ft_parse/ft_parsing_table_save.c b/ft_parse/ft_parsing_table_save.c
new file mode 100644 (file)
index 0000000..04ba2ee
--- /dev/null
@@ -0,0 +1,126 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_parsing_table_save.c                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/07/10 21:45:48 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/07/19 13:55:32 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "libft.h"
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static const char      *state_string = "State";
+static const char      *acc_str = "acc";
+
+static t_ft_stat       write_header(const t_parsing_table *table, int fd)
+{
+       size_t                  i;
+       int                             chars_printed;
+       const t_token   *token;
+
+       chars_printed = ft_dprintf(fd, "%s;", state_string);
+       if ((size_t)chars_printed != ft_strlen(state_string) + 1)
+               return (file_error);
+       i = 0;
+       while (i < table->tokens.size)
+       {
+               token = ft_vec_caccess(&table->tokens, i);
+               if (i < table->tokens.size - 1)
+                       chars_printed = ft_dprintf(fd, "%s;", token->type);
+               else
+                       chars_printed = ft_dprintf(fd, "%s", token->type);
+               if ((size_t)chars_printed != ft_strlen(token->type) + (i < table->tokens.size - 1))
+                       return (file_error);
+               ++i;
+       }
+       if (ft_dprintf(fd, "\n") != 1)
+               return (file_error);
+       return (success);
+}
+
+static t_ft_stat       write_action(const t_parser_action *action, int fd)
+{
+       if (action->type == parser_refuse)
+               return (success);
+       else if (action->type == parser_accept && (size_t)ft_dprintf(fd, "%s", acc_str) == ft_strlen(acc_str) + 1)
+               return (success);
+       else if (action->type == parser_shift && ft_dprintf(fd, "s%u", action->number))
+               return (success);
+       else if (action->type == parser_reduce && ft_dprintf(fd, "r%u", action->number))
+               return (success);
+       return (file_error);
+}
+
+static t_ft_stat       write_goto(ssize_t gt, int fd)
+{
+       if (gt < 0)
+               return (success);
+       else if (ft_dprintf(fd, "%u", gt))
+               return (success);
+       return (file_error);
+}
+
+static t_ft_stat       write_row(const t_parser_state *state, int fd)
+{
+       size_t                                  i;
+       const t_parser_action   *action;
+       const ssize_t                   *gt;
+
+       i = 0;
+       while (i < state->lookahead.size)
+       {
+               action = ft_vec_caccess(&state->lookahead, i);
+               write_action(action, fd);
+               if (i < state->lookahead.size - 1 || state->gotos.size > 0)
+                       if (!ft_dprintf(fd, ";"))
+                               return (file_error);
+               ++i;
+       }
+       i = 0;
+       while (i < state->gotos.size)
+       {
+               gt = ft_vec_caccess(&state->gotos, i);
+               write_goto(*gt, fd);
+               if (i < state->gotos.size - 1)
+                       if (!ft_dprintf(fd, ";"))
+                               return (file_error);
+               ++i;
+       }
+       if (ft_dprintf(fd, "\n") != 1)
+               return (file_error);
+       return (success);
+}
+
+//     This function should also remove the output file in the case of an error
+t_ft_stat      ft_parsing_table_save(const t_parsing_table *table, const char *filename)
+{
+       int     fd;
+       size_t                                  i;
+       const t_parser_state    *state;
+
+       fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IRGRP | S_IROTH);
+       if (fd < 0)
+               return (file_error);
+       write_header(table, fd);
+       i = 0;
+       while (i < table->states.size)
+       {
+               state = ft_vec_caccess(&table->states, i);
+               if (!ft_dprintf(fd, "%u;", i))
+                       return (file_error);
+               if (write_row(state, fd) != success)
+               {
+                       close(fd);
+                       return (file_error);
+               }
+               ++i;
+       }
+       close(fd);
+       return (success);
+}
index e966078f5dd14f4353eda7a6a5e81843a978d707..4b89a5672ea0f5fca5b07265810ab8b0c3717383 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/05/27 21:21:54 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/06/28 17:07:04 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/07/18 12:41:50 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -100,6 +100,9 @@ t_ft_stat                   ft_parsing_table_load(t_parsing_table *table,
 t_parse_tree_node      *ft_parse(const t_vec *tokens,
                                                const t_parsing_table *table);
 
+t_ft_stat                      ft_parsing_table_save(const t_parsing_table *table,
+                                               const char *filename);
+
 void                           ft_parsing_table_print(t_parsing_table *table,
                                                unsigned int column_width);
 void                           ft_parse_tree_print(t_parse_tree_node *root);