/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/20 20:51:36 by ljiriste #+# #+# */
-/* Updated: 2024/06/21 11:46:04 by ljiriste ### ########.fr */
+/* Updated: 2024/06/21 13:56:25 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
i = 0;
while (i < tokens->size)
{
- if (!ft_strcmp(token.type, ((t_token *)ft_vec_caccess(tokens, i))->type))
+ if (!ft_strcmp(token.type,
+ ((t_token *)ft_vec_caccess(tokens, i))->type))
return (i);
++i;
}
return (-1);
}
-ssize_t goto_state(size_t state_num, const t_parsing_table *table, t_token token)
+ssize_t goto_state(const t_parser_stack_element *el,
+ const t_parsing_table *table, t_token token)
{
const t_parser_state *state;
ssize_t column;
- state = ft_vec_caccess(&table->states, state_num);
+ state = ft_vec_caccess(&table->states, el->state_num);
column = find_token_index(token, &table->tokens);
- return (*(ssize_t *)ft_vec_caccess(&state->gotos, column - (table->terminal_tokens_num + 1)));
+ return (*(ssize_t *)ft_vec_caccess(&state->gotos,
+ column - (table->terminal_tokens_num + 1)));
+}
+
+int hang_top_from_tree(t_stack *stack, t_parse_tree_node *tree,
+ const t_token *constituent_token)
+{
+ t_parse_tree_node *node;
+
+ node = ((t_parser_stack_element *)ft_stack_pop(stack, NULL))->node;
+ if (ft_strcmp(node->token.type, constituent_token->type)
+ || ft_vec_insert(&tree->children, node, 0) != success)
+ {
+ ft_parse_tree_free(node);
+ return (1);
+ }
+ free(node);
+ return (0);
}
int follow_rule(t_stack *stack, size_t rule_num, const t_parsing_table *table)
{
const t_grammar_rule *rule;
t_parser_stack_element element;
- t_parse_tree_node *node;
size_t i;
- element.node = malloc(sizeof(*node));
+ element.node = malloc(sizeof(*element.node));
if (!element.node)
return (1);
ft_vec_init(&element.node->children, sizeof(t_parse_tree_node));
while (i > 0)
{
--i;
- node = ((t_parser_stack_element *)ft_stack_pop(stack, NULL))->node;
- if (ft_strcmp(node->token.type,
- ((t_token *)ft_vec_caccess(&rule->constituents, i))->type) ||
- ft_vec_insert(&element.node->children, node, 0) != success)
+ if (hang_top_from_tree(stack, element.node,
+ ft_vec_caccess(&rule->constituents, i)))
{
ft_parse_tree_free(element.node);
- ft_parse_tree_free(node);
return (1);
}
- free(node);
}
- element.state_num = goto_state(((t_parser_stack_element *)ft_stack_top(stack))->state_num, table, rule->result);
+ element.state_num = goto_state(ft_stack_top(stack), table, rule->result);
return (ft_stack_push(stack, &element) != success || element.state_num < 0);
}
return ;
}
+const t_parser_action *get_action(t_stack *stack, t_token token,
+ const t_parsing_table *table)
+{
+ const t_parser_state *state;
+ ssize_t column;
+
+ state = ft_vec_caccess(&table->states,
+ ((t_parser_stack_element *)ft_stack_top(stack))->state_num);
+ column = find_token_index(token, &table->tokens);
+ if (column < 0 || (size_t)column > table->terminal_tokens_num)
+ {
+ ft_stack_free(stack, ft_stack_element_free);
+ return (NULL);
+ }
+ return (ft_vec_caccess(&state->lookahead, column));
+}
+
t_parse_tree_node *ft_parse(const t_vec *tokens, const t_parsing_table *table)
{
t_stack stack;
size_t i;
t_token token;
- const t_parser_state *state;
const t_parser_action *action;
- ssize_t column;
t_parse_tree_node *root;
initialize_parser_stack(&stack);
ft_stack_free(&stack, ft_stack_element_free);
return (NULL);
}
- state = ft_vec_caccess(&table->states,
- ((t_parser_stack_element *)ft_stack_top(&stack))->state_num);
- column = find_token_index(token, &table->tokens);
- if (column < 0 || (size_t)column > table->terminal_tokens_num)
+ action = get_action(&stack, token, table);
+ if (!action || action->type == parser_refuse)
{
ft_stack_free(&stack, ft_stack_element_free);
return (NULL);
}
- action = ft_vec_caccess(&state->lookahead, column);
- if (action->type == parser_reduce)
+ else if (action->type == parser_reduce)
{
if (follow_rule(&stack, action->number, table))
{
}
++i;
}
- else if (action->type == parser_refuse)
- {
- ft_stack_free(&stack, ft_stack_element_free);
- return (NULL);
- }
else if (action->type == parser_accept)
{
root = ((t_parser_stack_element *)ft_stack_top(&stack))->node;