--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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);
+}
/* 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 */
/* */
/* ************************************************************************** */
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);