/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/27 11:16:53 by ljiriste #+# #+# */
-/* Updated: 2024/07/18 12:16:01 by ljiriste ### ########.fr */
+/* Updated: 2024/11/26 13:01:45 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_parse.h"
#include <stdlib.h>
-static const t_token eof_token = {.type = "$", .str = NULL};
-static const t_token empty_token = {.type = "''", .str = NULL};
+static const t_token g_eof_token = {.type = "$", .str = NULL};
+static const t_token g_empty_token = {.type = "''", .str = NULL};
void free_item(t_lr1_item *item)
{
int cmp_token_type(const t_token *token1, const t_token *token2)
{
if ((!token1 && !token2))
- return(0);
+ return (0);
else if (!token1 || !token2)
- return(1);
+ return (1);
if ((!token1->type && !token2->type))
- return(0);
+ return (0);
else if (!token1->type || !token2->type)
- return(1);
+ return (1);
return (ft_strcmp(token1->type, token2->type));
}
int cmp_rules(const t_grammar_rule *rule1, const t_grammar_rule *rule2)
{
return (cmp_token_type(&rule1->result, &rule2->result)
- || !ft_vec_is_equal(&rule1->constituents,
- &rule2->constituents, void_cmp_token_type));
+ || !ft_vec_is_equal(&rule1->constituents,
+ &rule2->constituents, void_cmp_token_type));
}
int void_cmp_rules(const void *v_rule1, const void *v_rule2)
{
const t_token *wanted_token;
- wanted_token = ft_vec_caccess(&item->core.rule->constituents, item->core.position);
+ wanted_token
+ = ft_vec_caccess(&item->core.rule->constituents, item->core.position);
return (cmp_token_type(wanted_token, token) == 0);
}
-t_ft_stat add_viable_items(t_vec *kernel, const t_vec *candidate_items, const t_token *token)
+t_ft_stat add_viable_items(t_vec *kernel,
+ const t_vec *candidate_items, const t_token *token)
{
const t_lr1_item *item;
t_lr1_item *new_item;
return (success);
}
-t_ft_stat create_goto_kernel(t_vec *kernel, const t_generator_state *state, const t_token *token)
+t_ft_stat create_goto_kernel(t_vec *kernel,
+ const t_generator_state *state, const t_token *token)
{
t_ft_stat res;
size_t find_kernel(const t_vec *kernel, const t_vec *states)
{
- size_t i;
+ size_t i;
const t_vec *state_kernel;
i = 0;
while (i < states->size)
{
- state_kernel = &(*(t_generator_state **)(ft_vec_caccess(states, i)))->kernel;
+ state_kernel
+ = &(*(t_generator_state **)(ft_vec_caccess(states, i)))->kernel;
if (ft_vec_is_setequal(state_kernel, kernel, void_cmp_items))
return (i);
++i;
const t_token *table_token;
i = 0;
- while ((i == 0 || cmp_token_type(table_token, &eof_token)) && i < tokens->size)
+ while ((i == 0 || cmp_token_type(table_token, &g_eof_token))
+ && i < tokens->size)
{
table_token = ft_vec_caccess(tokens, i);
if (!cmp_token_type(table_token, token))
t_ft_stat expand_lookahead(t_vec *lookahead, const t_marked_grammar_rule *rule, const t_vec *rules, const t_vec *tokens);
-t_ft_stat add_first(t_vec *lookahead, const t_token *token, const t_vec *rules, const t_vec *tokens)
+t_ft_stat add_first(t_vec *lookahead, const t_token *token,
+ const t_vec *rules, const t_vec *tokens)
{
t_ft_stat res;
size_t i;
t_marked_grammar_rule rule;
t_token token_copy;
- if (is_terminal_token(token, tokens) || !cmp_token_type(token, &empty_token))
+ if (is_terminal_token(token, tokens)
+ || !cmp_token_type(token, &g_empty_token))
{
token_copy = ft_token_dup(token);
res = ft_vec_setinsert(lookahead, &token_copy, void_cmp_token_type);
}
}
-t_ft_stat expand_lookahead(t_vec *lookahead, const t_marked_grammar_rule *rule, const t_vec *rules, const t_vec *tokens)
+t_ft_stat expand_lookahead(t_vec *lookahead, const t_marked_grammar_rule *rule,
+ const t_vec *rules, const t_vec *tokens)
{
size_t i;
t_ft_stat res;
const t_token *token;
- res = append_token(lookahead, &empty_token);
+ res = append_token(lookahead, &g_empty_token);
if (res != success)
return (res);
i = rule->position;
- while (ft_vec_contains(lookahead, &empty_token, void_cmp_token_type) && i < rule->rule->constituents.size)
+ while (ft_vec_contains(lookahead, &g_empty_token, void_cmp_token_type)
+ && i < rule->rule->constituents.size)
{
- remove_token(lookahead, &empty_token);
+ remove_token(lookahead, &g_empty_token);
token = ft_vec_caccess(&rule->rule->constituents, i);
if (!ft_vec_contains(lookahead, token, void_cmp_token_type))
{
while (i < tokens->size)
{
token = ft_vec_caccess(tokens, i);
- if (!cmp_token_type(token, &eof_token))
+ if (!cmp_token_type(token, &g_eof_token))
break ;
++i;
}
return ;
}
-t_ft_stat add_lookahead(t_lr1_item *new, t_lr1_item *item, const t_vec *rules, const t_vec *tokens)
+t_ft_stat add_lookahead(t_lr1_item *new, t_lr1_item *item,
+ const t_vec *rules, const t_vec *tokens)
{
t_ft_stat res;
ft_vec_free(&new->lookahead, ft_free_token);
return (res);
}
- if (ft_vec_contains(&new->lookahead, &empty_token, void_cmp_token_type))
+ if (ft_vec_contains(&new->lookahead, &g_empty_token, void_cmp_token_type))
{
- remove_token(&new->lookahead, &empty_token);
+ remove_token(&new->lookahead, &g_empty_token);
res = add_to_lookahead(&item->lookahead, &new->lookahead);
}
return (res);
}
-t_ft_stat add_predictions(t_vec *closure, t_lr1_item *item, const t_vec *rules, const t_vec *tokens)
+t_ft_stat add_predictions(t_vec *closure, t_lr1_item *item,
+ const t_vec *rules, const t_vec *tokens)
{
size_t i;
t_lr1_item new_item;
while (i < rules->size)
{
new_item.core.rule = ft_vec_caccess(rules, i);
- if (!cmp_token_type(&new_item.core.rule->result, get_next_token(&item->core)))
+ if (!cmp_token_type
+ (&new_item.core.rule->result, get_next_token(&item->core)))
{
new_item.core.position = 0;
res = add_lookahead(&new_item, item, rules, tokens);
return (success);
}
-t_ft_stat fill_closure2(t_vec *closure, const t_vec *rules, const t_vec *tokens)
+t_ft_stat fill_closure2(
+ t_vec *closure, const t_vec *rules, const t_vec *tokens)
{
size_t i;
t_lr1_item *item;
return (success);
}
-t_ft_stat fill_closure(t_vec *closure, t_vec *kernel, const t_vec *rules, const t_vec *tokens)
+t_ft_stat fill_closure(t_vec *closure, t_vec *kernel,
+ const t_vec *rules, const t_vec *tokens)
{
size_t i;
- t_lr1_item *item;
+ t_lr1_item *item;
t_ft_stat res;
i = 0;
t_ft_stat solve_gotos(t_generator_state *state, t_vec *states, const t_vec *rules, const t_vec *tokens);
-t_ft_stat construct_state(t_vec *kernel, t_vec *states, const t_vec *rules, const t_vec *tokens)
+t_ft_stat construct_state(t_vec *kernel, t_vec *states,
+ const t_vec *rules, const t_vec *tokens)
{
t_generator_state *state;
t_ft_stat res;
while (i < state->kernel.size)
{
item = ft_vec_caccess(&state->kernel, i);
- if (!cmp_token_type(token, ft_vec_caccess(&item->core.rule->constituents, item->core.position)))
+ if (!cmp_token_type(token,
+ ft_vec_caccess(&item->core.rule->constituents,
+ item->core.position)))
return (1);
++i;
}
while (i < state->closure.size)
{
item = ft_vec_caccess(&state->closure, i);
- if (!cmp_token_type(token, ft_vec_caccess(&item->core.rule->constituents, item->core.position)))
+ if (!cmp_token_type(token,
+ ft_vec_caccess(&item->core.rule->constituents,
+ item->core.position)))
return (1);
++i;
}
return (0);
}
-t_ft_stat solve_gotos(t_generator_state *state, t_vec *states, const t_vec *rules, const t_vec *tokens)
+t_ft_stat solve_gotos(t_generator_state *state, t_vec *states,
+ const t_vec *rules, const t_vec *tokens)
{
size_t i;
const t_token *token;
t_ft_stat res;
t_lr1_item item;
t_token token;
-
+
res = ft_vec_init(&item.lookahead, sizeof(t_token));
if (res != success)
return (res);
- token = ft_token_dup(&eof_token);
+ token = ft_token_dup(&g_eof_token);
if (!token.type)
return (alloc_fail);
res = ft_vec_append(&item.lookahead, &token);
return (0);
}
-t_ft_stat add_constituents(t_vec *tokens, const t_vec *constituents, const t_vec *rules)
+t_ft_stat add_constituents(
+ t_vec *tokens, const t_vec *constituents, const t_vec *rules)
{
t_ft_stat res;
size_t i;
while (i < constituents->size)
{
token = ft_vec_caccess(constituents, i);
- if (ft_vec_contains(tokens, token, void_cmp_token_type) || !cmp_token_type(token, &empty_token))
+ if (ft_vec_contains(tokens, token, void_cmp_token_type)
+ || !cmp_token_type(token, &g_empty_token))
{
++i;
continue ;
size_t i;
const t_grammar_rule *rule;
- res = append_token(tokens, &eof_token);
+ res = append_token(tokens, &g_eof_token);
if (res != success)
return (res);
i = 1;
return (success);
}
-t_ft_stat construct_states(t_vec *states, const t_vec *rules, const t_vec *tokens)
+t_ft_stat construct_states(
+ t_vec *states, const t_vec *rules, const t_vec *tokens)
{
t_vec kernel;
t_ft_stat res;
t_ft_stat prefill_lookahead(t_vec *lookahead, size_t size)
{
- t_ft_stat res;
- size_t i;
- const t_parser_action refuse = {.type = parser_refuse, .number = 0};
+ t_ft_stat res;
+ size_t i;
+ const t_parser_action refuse = {.type = parser_refuse, .number = 0};
res = ft_vec_reserve(lookahead, size);
if (res != success)
res = prefill_lookahead(&new_row.lookahead, table->terminal_tokens_num + 1);
if (res != success)
return (res);
- res = prefill_gotos(&new_row.gotos, table->tokens.size - table->terminal_tokens_num - 1);
+ res = prefill_gotos(&new_row.gotos,
+ table->tokens.size - table->terminal_tokens_num - 1);
if (res != success)
{
ft_vec_free(&new_row.gotos, NULL);
return (res);
}
res = ft_vec_append(&table->states, &new_row);
- if (res != success)
- {
- ft_vec_free(&new_row.lookahead, NULL);
- ft_vec_free(&new_row.gotos, NULL);
- }
+ if (res == success)
+ return (res);
+ ft_vec_free(&new_row.lookahead, NULL);
+ ft_vec_free(&new_row.gotos, NULL);
return (res);
}
return (i);
}
-void convert_shifts(t_vec *lookahead, const t_generator_state *state, const t_vec *tokens)
+void convert_shifts(t_vec *lookahead,
+ const t_generator_state *state, const t_vec *tokens)
{
size_t i;
const t_token *token;
while (i < state->goto_tokens.size)
{
token = ft_vec_caccess(&state->goto_tokens, i);
- if (is_terminal_token(token, tokens) || !ft_strcmp(token->type, eof_token.type))
- add_shift(ft_vec_access(lookahead, get_token_position(token, tokens)), ft_vec_caccess(&state->goto_states, i));
+ if (is_terminal_token(token, tokens)
+ || !ft_strcmp(token->type, g_eof_token.type))
+ add_shift(
+ ft_vec_access(lookahead, get_token_position(token, tokens)),
+ ft_vec_caccess(&state->goto_states, i));
++i;
}
return ;
}
-void convert_gotos(t_vec *gotos, const t_generator_state *state, const t_vec *tokens)
+void convert_gotos(t_vec *gotos,
+ const t_generator_state *state, const t_vec *tokens)
{
size_t i;
const t_token *token;
while (i < state->goto_tokens.size)
{
token = ft_vec_caccess(&state->goto_tokens, i);
- if (!(is_terminal_token(token, tokens) || !ft_strcmp(token->type, eof_token.type)))
- *(ssize_t *)ft_vec_access(gotos, get_token_position(token, tokens) - get_token_position(&eof_token, tokens) - 1) = *(const ssize_t *)ft_vec_caccess(&state->goto_states, i);
+ if (!(is_terminal_token(token, tokens)
+ || !ft_strcmp(token->type, g_eof_token.type)))
+ *(ssize_t *)ft_vec_access(gotos, get_token_position(token, tokens)
+ - get_token_position(&g_eof_token, tokens) - 1)
+ = *(const ssize_t *)ft_vec_caccess(&state->goto_states, i);
++i;
}
return ;
return (i);
}
-void add_reduce(t_vec *lookahead, const t_lr1_item *item, const t_vec *tokens, const t_vec *rules)
+void add_reduce(t_vec *lookahead, const t_lr1_item *item,
+ const t_vec *tokens, const t_vec *rules)
{
- size_t i;
- size_t rule_num;
+ size_t i;
+ size_t rule_num;
const t_token *token;
t_parser_action *action;
return ;
}
-void convert_reduces(t_vec *lookahead, const t_generator_state *state, const t_vec *tokens, const t_vec *rules)
+void convert_reduces(t_vec *lookahead, const t_generator_state *state,
+ const t_vec *tokens, const t_vec *rules)
{
size_t i;
const t_lr1_item *item;
while (i < state->kernel.size)
{
item = ft_vec_caccess(&state->kernel, i);
- if (item->core.position == item->core.rule->constituents.size || !cmp_token_type(item->core.rule->constituents.vec, &empty_token))
+ if (item->core.position == item->core.rule->constituents.size
+ || !cmp_token_type(item->core.rule->constituents.vec, &g_empty_token))
add_reduce(lookahead, item, tokens, rules);
++i;
}
while (i < state->closure.size)
{
item = ft_vec_caccess(&state->closure, i);
- if (item->core.position == item->core.rule->constituents.size || !cmp_token_type(item->core.rule->constituents.vec, &empty_token))
+ if (item->core.position == item->core.rule->constituents.size
+ || !cmp_token_type(item->core.rule->constituents.vec, &g_empty_token))
add_reduce(lookahead, item, tokens, rules);
++i;
}
return ;
}
-t_ft_stat add_table_row(t_parsing_table *table, const t_generator_state *state)
+t_ft_stat add_table_row(
+ t_parsing_table *table, const t_generator_state *state)
{
t_ft_stat res;
t_parser_state *new_row;
t_ft_stat translate_to_table(t_parsing_table *table, const t_vec *states)
{
- size_t i;
- t_ft_stat res;
+ size_t i;
+ t_ft_stat res;
t_generator_state *const *state;
i = 0;
rule.result.type = NULL;
rule.result.str = NULL;
- first_token = ft_token_dup(&((const t_grammar_rule *)ft_vec_caccess(rules, 0))->result);
+ first_token = ft_token_dup(
+ &((const t_grammar_rule *)ft_vec_caccess(rules, 0))->result);
if (!first_token.type)
return (alloc_fail);
res = ft_vec_init(&rule.constituents, sizeof(t_token));
return (res);
}
-t_ft_stat ft_parsing_table_generate(t_parsing_table *table, const char *rules_filename)
+t_ft_stat ft_parsing_table_generate(
+ t_parsing_table *table, const char *rules_filename)
{
t_ft_stat res;
t_vec states;
/* 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 */
+/* Updated: 2024/11/26 11:58:12 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
#include <sys/stat.h>
#include <fcntl.h>
-static const char *state_string = "State";
-static const char *acc_str = "acc";
+static const char *g_state_string = "State";
+static const char *g_accept_string = "acc";
static t_ft_stat write_header(const t_parsing_table *table, int fd)
{
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)
+ chars_printed = ft_dprintf(fd, "%s;", g_state_string);
+ if ((size_t)chars_printed != ft_strlen(g_state_string) + 1)
return (file_error);
i = 0;
while (i < table->tokens.size)
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))
+ if ((size_t)chars_printed
+ != ft_strlen(token->type) + (i < table->tokens.size - 1))
return (file_error);
++i;
}
{
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)
+ else if (action->type == parser_accept
+ && (size_t)ft_dprintf(fd, "%s", g_accept_string)
+ == ft_strlen(g_accept_string) + 1)
return (success);
- else if (action->type == parser_shift && ft_dprintf(fd, "s%u", action->number))
+ 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))
+ else if (action->type == parser_reduce
+ && ft_dprintf(fd, "r%u", action->number))
return (success);
return (file_error);
}
{
action = ft_vec_caccess(&state->lookahead, i);
write_action(action, fd);
- if (i < state->lookahead.size - 1 || state->gotos.size > 0)
+ 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 (i++ < state->gotos.size - 1)
if (!ft_dprintf(fd, ";"))
return (file_error);
- ++i;
}
if (ft_dprintf(fd, "\n") != 1)
return (file_error);
}
// 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)
+t_ft_stat ft_parsing_table_save(
+ const t_parsing_table *table, const char *filename)
{
- int fd;
+ 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);
+ 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);