update: almost fully normed parser/src/stack !

This commit is contained in:
maix0 2024-09-19 18:58:51 +02:00
parent bec1320c5f
commit cff5618664
9 changed files with 316 additions and 253 deletions

View file

@ -6,66 +6,18 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/31 16:52:46 by maiboyer #+# #+# */
/* Updated: 2024/08/31 16:59:20 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 18:49:32 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "parser/inner/stack_inner.h"
#include "parser/inner/stack_inner.h"
// In general,
// we preserve ambiguities until they are removed from the stack
// during a pop operation where multiple paths lead to the same node. But in
// the special case where two links directly connect the same pair of nodes,
// we can safely remove the ambiguity ahead of time without changing behavior.
void stack_node_add_link(t_stack_node *self, t_stack_link link)
void _add_link_tail(t_stack_node *self, t_stack_link link)
{
t_stack_link *existing_link;
t_i32 dynamic_precedence;
t_u32 node_count;
t_usize i;
t_usize j;
t_i32 dynamic_precedence;
t_u32 node_count;
if (link.node == self)
return ;
i = 0;
while (i < self->link_count)
{
existing_link = &self->links[i];
if (stack__subtree_is_equivalent(existing_link->subtree, link.subtree))
{
if (existing_link->node == link.node)
{
if (ts_subtree_dynamic_precedence(\
link.subtree) > ts_subtree_dynamic_precedence(existing_link->subtree))
{
(link.subtree->ref_count++);
ts_subtree_release(existing_link->subtree);
existing_link->subtree = link.subtree;
self->dynamic_precedence = link.node->dynamic_precedence
+ ts_subtree_dynamic_precedence(link.subtree);
}
return ;
}
if (existing_link->node->state == link.node->state \
&& existing_link->node->position.bytes == link.node->position.bytes
&& existing_link->node->error_cost == link.node->error_cost)
{
j = 0;
while (j < link.node->link_count)
stack_node_add_link(existing_link->node,
link.node->links[j++]);
dynamic_precedence = link.node->dynamic_precedence;
if (link.subtree)
dynamic_precedence
+= ts_subtree_dynamic_precedence(link.subtree);
if (dynamic_precedence > self->dynamic_precedence)
self->dynamic_precedence = dynamic_precedence;
return ;
}
}
i++;
}
if (self->link_count == MAX_LINK_COUNT)
return ;
stack_node_retain(link.node);
@ -83,3 +35,76 @@ void stack_node_add_link(t_stack_node *self, t_stack_link link)
if (dynamic_precedence > self->dynamic_precedence)
self->dynamic_precedence = dynamic_precedence;
}
bool _is_link_node_similar(\
t_stack_node *self, t_stack_link link, \
t_stack_link *ext_link)
{
t_usize j;
t_i32 dynamic_precedence;
if (ext_link->node->state == link.node->state \
&& ext_link->node->position.bytes == link.node->position.bytes
&& ext_link->node->error_cost == link.node->error_cost)
{
j = 0;
while (j < link.node->link_count)
stack_node_add_link(ext_link->node,
link.node->links[j++]);
dynamic_precedence = link.node->dynamic_precedence;
if (link.subtree)
dynamic_precedence
+= ts_subtree_dynamic_precedence(link.subtree);
if (dynamic_precedence > self->dynamic_precedence)
self->dynamic_precedence = dynamic_precedence;
return (true);
}
return (false);
}
bool _is_link_same_node(\
t_stack_node *self, t_stack_link link, \
t_stack_link *ext_link)
{
if (ext_link->node == link.node)
{
if (ts_subtree_dynamic_precedence(\
link.subtree) > ts_subtree_dynamic_precedence(ext_link->subtree))
{
link.subtree->ref_count++;
ts_subtree_release(ext_link->subtree);
ext_link->subtree = link.subtree;
self->dynamic_precedence = link.node->dynamic_precedence
+ ts_subtree_dynamic_precedence(link.subtree);
}
return (true);
}
return (false);
}
// In general,
// we preserve ambiguities until they are removed from the stack
// during a pop operation where multiple paths lead to the same node. But in
// the special case where two links directly connect the same pair of nodes,
// we can safely remove the ambiguity ahead of time without changing behavior.
void stack_node_add_link(t_stack_node *self, t_stack_link link)
{
t_stack_link *ext_link;
t_usize i;
if (link.node == self)
return ;
i = 0;
while (i < self->link_count)
{
ext_link = &self->links[i];
if (stack__subtree_is_equivalent(ext_link->subtree, link.subtree))
{
if (_is_link_same_node(self, link, ext_link) \
|| _is_link_node_similar(self, link, ext_link))
return ;
}
i++;
}
_add_link_tail(self, link);
}