/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/27 11:16:53 by ljiriste #+# #+# */
-/* Updated: 2024/07/09 11:06:22 by ljiriste ### ########.fr */
+/* Updated: 2024/07/10 00:27:24 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
return (success);
}
-t_ft_stat translate_to_table(__attribute__((unused))t_parsing_table *table,__attribute__((unused)) const t_vec *states)
+t_ft_stat prefill_lookahead(t_vec *lookahead, size_t size)
{
- ft_printf("translate_to_table is not yet implemented\n");
+ t_ft_stat res;
+ const t_parser_action refuse = {.type = parser_refuse, .number = 0};
+
+ res = ft_vec_reserve(lookahead, size);
+ if (res != success)
+ return (res);
+ res = ft_vec_insert_range(lookahead, &refuse, size, 0);
+ return (res);
+}
+
+t_ft_stat prefill_gotos(t_vec *gotos, size_t size)
+{
+ t_ft_stat res;
+ const ssize_t refuse = -1;
+
+ res = ft_vec_reserve(gotos, size);
+ if (res != success)
+ return (res);
+ res = ft_vec_insert_range(gotos, &refuse, size, 0);
+ return (res);
+}
+
+t_ft_stat init_new_row(t_parsing_table *table)
+{
+ t_ft_stat res;
+ t_parser_state new_row;
+
+ res = ft_vec_init(&new_row.lookahead, sizeof(t_parser_action));
+ if (res != success)
+ return (res);
+ res = ft_vec_init(&new_row.gotos, sizeof(ssize_t));
+ if (res != success)
+ return (res);
+ 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);
+ 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);
+ }
+ return (res);
+}
+
+void add_shift(t_parser_action *action, const ssize_t *goto_state)
+{
+ action->type = parser_shift;
+ action->number = *goto_state;
+ return ;
+}
+
+size_t get_token_position(const t_token *token, const t_vec *tokens)
+{
+ size_t i;
+
+ i = 0;
+ while (i < tokens->size)
+ {
+ if (!cmp_token_type(token, ft_vec_caccess(tokens, i)))
+ return (i);
+ ++i;
+ }
+ return (i);
+}
+
+void convert_shifts(t_vec *lookahead, const t_generator_state *state, const t_vec *tokens)
+{
+ size_t i;
+ const t_token *token;
+
+ i = 0;
+ 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));
+ ++i;
+ }
+ return ;
+}
+
+void convert_gotos(t_vec *gotos, const t_generator_state *state, const t_vec *tokens)
+{
+ size_t i;
+ const t_token *token;
+
+ i = 0;
+ 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)) = *(const ssize_t *)ft_vec_caccess(&state->goto_states, i);
+ ++i;
+ }
+ return ;
+}
+
+size_t get_rule_index(const t_grammar_rule *rule, const t_vec *rules)
+{
+ size_t i;
+
+ i = 0;
+ while (i < rules->size)
+ {
+ if (!cmp_rules(rule, ft_vec_caccess(rules, i)))
+ return (i);
+ ++i;
+ }
+ return (i);
+}
+
+void add_reduce(t_vec *lookahead, const t_lr1_item *item, const t_vec *tokens, const t_vec *rules)
+{
+ size_t i;
+ const t_token *token;
+ t_parser_action *action;
+
+ i = 0;
+ while (i < item->lookahead.size)
+ {
+ token = ft_vec_caccess(&item->lookahead, i);
+ action = ft_vec_access(lookahead, get_token_position(token, tokens));
+ action->type = parser_reduce;
+ action->number = get_rule_index(item->core.rule, rules);
+ ++i;
+ }
+ return ;
+}
+
+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;
+
+ i = 0;
+ while (i < state->kernel.size)
+ {
+ item = ft_vec_caccess(&state->kernel, i);
+ if (item->core.position == item->core.rule->constituents.size)
+ add_reduce(lookahead, item, tokens, rules);
+ ++i;
+ }
+ i = 0;
+ while (i < state->closure.size)
+ {
+ item = ft_vec_caccess(&state->closure, i);
+ if (item->core.position == item->core.rule->constituents.size)
+ 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 res;
+ t_parser_state *new_row;
+
+ res = init_new_row(table);
+ if (res != success)
+ return (res);
+ new_row = ft_vec_access(&table->states, table->states.size - 1);
+ convert_shifts(&new_row->lookahead, state, &table->tokens);
+ convert_gotos(&new_row->gotos, state, &table->tokens);
+ convert_reduces(&new_row->lookahead, state, &table->tokens, &table->rules);
+ return (success);
+}
+
+t_ft_stat translate_to_table(t_parsing_table *table, const t_vec *states)
+{
+ size_t i;
+ t_ft_stat res;
+ const t_generator_state *state;
+
+ i = 0;
+ while (i < states->size)
+ {
+ state = ft_vec_caccess(states, i);
+ res = add_table_row(table, state);
+ if (res != success)
+ return (res);
+ ++i;
+ }
return (success);
}