From: Lukas Jiriste Date: Fri, 19 Jul 2024 11:57:12 +0000 (+0200) Subject: Add a function to save a table as a file X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=95a5108171ba6cfe4525e1c21f216fb34230b962;p=Libft.git Add a function to save a table as a file 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. --- diff --git a/Makefile b/Makefile index 6fa3e65..8dcafe5 100644 --- 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 index 0000000..04ba2ee --- /dev/null +++ b/ft_parse/ft_parsing_table_save.c @@ -0,0 +1,126 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_parsing_table_save.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 21:45:48 by ljiriste #+# #+# */ +/* Updated: 2024/07/19 13:55:32 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include +#include +#include + +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); +} diff --git a/inc/ft_parse.h b/inc/ft_parse.h index e966078..4b89a56 100644 --- a/inc/ft_parse.h +++ b/inc/ft_parse.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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);