Updated stuff to be more normed

This commit is contained in:
Maieul BOYER 2024-09-02 21:23:36 +00:00
parent 2247d3662e
commit f6d6589a3a
39 changed files with 1838 additions and 1288 deletions

View file

@ -1,5 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/02 20:48:07 by maiboyer #+# #+# */
/* Updated: 2024/09/02 21:14:40 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/mem/mem.h"
#include "me/types.h"
#include "me/vec/vec_subtree.h"
#include "parser/api.h"
#include "parser/array.h"
#include "parser/language.h"
@ -30,9 +43,9 @@ struct TSParser
const TSLanguage *language;
ReduceActionSet reduce_actions;
t_subtree finished_tree;
SubtreeArray trailing_extras;
SubtreeArray trailing_extras2;
SubtreeArray scratch_trees;
t_vec_subtree trailing_extras;
t_vec_subtree trailing_extras2;
t_vec_subtree scratch_trees;
void *external_scanner_payload;
t_u32 accept_count;
t_u32 operation_count;
@ -101,7 +114,7 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, t_stack_version ve
{
t_stack_slice slice = pop.contents[i];
TSStateId state = ts_stack_state(self->stack, slice.version);
t_subtree parent = *array_front(&slice.subtrees);
t_subtree parent = *slice.subtrees.buffer;
for (t_u32 j = 0, n = ts_subtree_child_count(parent); j < n; j++)
{
@ -121,9 +134,9 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, t_stack_version ve
ts_stack_push(self->stack, slice.version, child, pending, state);
}
for (t_u32 j = 1; j < slice.subtrees.size; j++)
for (t_u32 j = 1; j < slice.subtrees.len; j++)
{
t_subtree tree = slice.subtrees.contents[j];
t_subtree tree = slice.subtrees.buffer[j];
ts_stack_push(self->stack, slice.version, tree, false, state);
}
@ -505,17 +518,13 @@ static bool ts_parser__select_tree(TSParser *self, t_subtree left, t_subtree rig
// Determine if a given tree's children should be replaced by an alternative
// array of children.
static bool ts_parser__select_children(TSParser *self, t_subtree left, const SubtreeArray *children)
static bool ts_parser__select_children(TSParser *self, t_subtree left, const t_vec_subtree *children)
{
array_assign(&self->scratch_trees, children);
t_subtree scratch_tree;
// Create a temporary subtree using the scratch trees array. This node does
// not perform any allocation except for possibly growing the array to make
// room for its own heap data. The scratch tree is never explicitly released,
// so the same 'scratch trees' array can be reused again later.
t_subtree scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left), &self->scratch_trees, 0, self->language);
return ts_parser__select_tree(self, left, (scratch_tree));
vec_subtree_copy_into(&self->scratch_trees, (void *)children);
scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left), &self->scratch_trees, 0, self->language);
return (ts_parser__select_tree(self, left, (scratch_tree)));
}
static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId state, t_subtree lookahead, bool extra)
@ -524,7 +533,7 @@ static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId
t_subtree subtree_to_push = lookahead;
if (extra != ts_subtree_extra(lookahead) && is_leaf)
{
t_subtree result = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
t_subtree result = ts_subtree_ensure_owner(/*&self->tree_pool,*/ lookahead);
ts_subtree_set_extra(&result, extra);
subtree_to_push = (result);
}
@ -576,7 +585,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
// Extra tokens on top of the stack should not be included in this new parent
// node. They will be re-pushed onto the stack after the parent node is
// created and pushed.
SubtreeArray children = slice.subtrees;
t_vec_subtree children = slice.subtrees;
ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras);
t_subtree parent = ts_subtree_new_node(symbol, &children, production_id, self->language);
@ -592,7 +601,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
break;
i++;
SubtreeArray next_slice_children = next_slice.subtrees;
t_vec_subtree next_slice_children = next_slice.subtrees;
ts_subtree_array_remove_trailing_extras(&next_slice_children, &self->trailing_extras2);
if (ts_parser__select_children(self, (parent), &next_slice_children))
@ -604,7 +613,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
}
else
{
array_clear(&self->trailing_extras2);
self->trailing_extras2.len = 0;
ts_subtree_array_delete(/*&self->tree_pool,*/ &next_slice.subtrees);
}
}
@ -630,9 +639,9 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
// Push the parent node onto the stack, along with any extra tokens that
// were previously on top of the stack.
ts_stack_push(self->stack, slice_version, (parent), false, next_state);
for (t_u32 j = 0; j < self->trailing_extras.size; j++)
for (t_u32 j = 0; j < self->trailing_extras.len; j++)
{
ts_stack_push(self->stack, slice_version, self->trailing_extras.contents[j], false, next_state);
ts_stack_push(self->stack, slice_version, self->trailing_extras.buffer[j], false, next_state);
}
for (t_stack_version j = 0; j < slice_version; j++)
@ -659,46 +668,37 @@ static void ts_parser__accept(TSParser *self, t_stack_version version, t_subtree
t_stack_slice_array pop = ts_stack_pop_all(self->stack, version);
for (t_u32 i = 0; i < pop.size; i++)
{
SubtreeArray trees = pop.contents[i].subtrees;
t_vec_subtree trees = pop.contents[i].subtrees;
t_subtree root = NULL;
t_subtree root = NULL;
for (t_u32 j = trees.size - 1; j + 1 > 0; j--)
for (t_u32 j = trees.len - 1; j + 1 > 0; j--)
{
t_subtree tree = trees.contents[j];
t_subtree tree = trees.buffer[j];
if (!ts_subtree_extra(tree))
{
t_u32 child_count = ts_subtree_child_count(tree);
const t_subtree *children = ts_subtree_children(tree);
for (t_u32 k = 0; k < child_count; k++)
{
(children[k]->ref_count++);
}
array_splice(&trees, j, 1, child_count, children);
children[k]->ref_count++;
vec_subtree_splice(&trees, vec_subtree_splice_args(j, 1, child_count, children));
root = (ts_subtree_new_node(ts_subtree_symbol(tree), &trees, tree->production_id, self->language));
ts_subtree_release(/*&self->tree_pool, */ tree);
break;
}
}
assert(root);
self->accept_count++;
if (self->finished_tree)
{
if (ts_parser__select_tree(self, self->finished_tree, root))
{
ts_subtree_release(/*&self->tree_pool,*/ self->finished_tree);
ts_subtree_release(self->finished_tree);
self->finished_tree = root;
}
else
{
ts_subtree_release(/*&self->tree_pool,*/ root);
}
ts_subtree_release(root);
}
else
{
self->finished_tree = root;
}
}
ts_stack_remove_version(self->stack, pop.contents[0].version);
@ -834,18 +834,17 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version,
continue;
}
SubtreeArray error_trees = ts_stack_pop_error(self->stack, slice.version);
if (error_trees.size > 0)
t_vec_subtree error_trees = ts_stack_pop_error(self->stack, slice.version);
if (error_trees.len > 0)
{
assert(error_trees.size == 1);
t_subtree error_tree = error_trees.contents[0];
t_subtree error_tree = error_trees.buffer[0];
t_u32 error_child_count = ts_subtree_child_count(error_tree);
if (error_child_count > 0)
{
array_splice(&slice.subtrees, 0, 0, error_child_count, ts_subtree_children(error_tree));
vec_subtree_splice(&slice.subtrees, vec_subtree_splice_args(0, 0, error_child_count, ts_subtree_children(error_tree)));
for (t_u32 j = 0; j < error_child_count; j++)
{
(slice.subtrees.contents[j]->ref_count++);
(slice.subtrees.buffer[j]->ref_count++);
}
}
ts_subtree_array_delete(/*&self->tree_pool,*/ &error_trees);
@ -853,19 +852,19 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version,
ts_subtree_array_remove_trailing_extras(&slice.subtrees, &self->trailing_extras);
if (slice.subtrees.size > 0)
if (slice.subtrees.len > 0)
{
t_subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language);
ts_stack_push(self->stack, slice.version, error, false, goal_state);
}
else
{
array_delete(&slice.subtrees);
vec_subtree_free(slice.subtrees);
}
for (t_u32 j = 0; j < self->trailing_extras.size; j++)
for (t_u32 j = 0; j < self->trailing_extras.len; j++)
{
t_subtree tree = self->trailing_extras.contents[j];
t_subtree tree = self->trailing_extras.buffer[j];
ts_stack_push(self->stack, slice.version, tree, false, goal_state);
}
@ -976,7 +975,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtre
// in an ERROR node and terminate.
if (ts_subtree_is_eof(lookahead))
{
SubtreeArray children = array_new();
t_vec_subtree children = vec_subtree_new(16, NULL);
t_subtree parent = ts_subtree_new_error_node(&children, false, self->language);
ts_stack_push(self->stack, version, parent, false, 1);
ts_parser__accept(self, version, lookahead);
@ -999,15 +998,14 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtre
const TSParseAction *actions = ts_language_actions(self->language, 1, ts_subtree_symbol(lookahead), &n);
if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n - 1].shift.extra)
{
t_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
t_subtree mutable_lookahead = ts_subtree_ensure_owner(/*&self->tree_pool,*/ lookahead);
ts_subtree_set_extra(&mutable_lookahead, true);
lookahead = (mutable_lookahead);
}
// Wrap the lookahead token in an ERROR.
SubtreeArray children = array_new();
array_reserve(&children, 1);
array_push(&children, lookahead);
t_vec_subtree children = vec_subtree_new(1, NULL);
vec_subtree_push(&children, lookahead);
t_subtree error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &children, 0, self->language);
// If other tokens have already been skipped, so there is already an ERROR at the top of the
@ -1034,7 +1032,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtre
}
ts_stack_renumber_version(self->stack, pop.contents[0].version, version);
array_push(&pop.contents[0].subtrees, (error_repeat));
vec_subtree_push(&pop.contents[0].subtrees, (error_repeat));
error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &pop.contents[0].subtrees, 0, self->language);
}
@ -1248,7 +1246,7 @@ static bool ts_parser__advance(TSParser *self, t_stack_version version, bool all
ts_language_table_entry(self->language, state, self->language->keyword_capture_token, &table_entry);
if (table_entry.action_count > 0)
{
t_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
t_subtree mutable_lookahead = ts_subtree_ensure_owner(/*&self->tree_pool,*/ lookahead);
ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language);
lookahead = (mutable_lookahead);
continue;
@ -1526,7 +1524,6 @@ TSTree *ts_parser_parse(TSParser *self, TSInput input)
if (self->finished_tree == NULL)
me_abort("self->finished_tree == NULL");
ts_subtree_balance(self->finished_tree, self->language);
result = ts_tree_new(self->finished_tree, self->language);
self->finished_tree = NULL;
ts_parser_reset(self);

View file

@ -73,7 +73,7 @@ t_stack_version ts_stack__add_version(t_stack *self,
}
void ts_stack__add_slice(t_stack *self, \
t_stack_version original_version, t_stack_node *node, SubtreeArray *subtrees)
t_stack_version original_version, t_stack_node *node, t_vec_subtree *subtrees)
{
t_u32 i;
t_stack_version version;

View file

@ -6,38 +6,38 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/31 16:46:43 by maiboyer #+# #+# */
/* Updated: 2024/08/31 16:47:21 by maiboyer ### ########.fr */
/* Updated: 2024/09/02 21:22:19 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/vec/vec_subtree.h"
#include "parser/inner/stack.h"
#include "parser/stack.h"
t_stack_slice_array stack__iter(t_stack *self, t_stack_version version,
t_stack_callback callback, void *payload, int goal_subtree_count)
t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, t_stack_callback callback, void *payload, int goal_subtree_count)
{
t_stack_head *head;
bool include_subtrees;
t_stack_iterator *iterator;
t_stack_node *node;
t_stack_action action;
bool should_pop;
bool should_stop;
SubtreeArray subtrees;
t_stack_iterator *next_iterator;
t_stack_link link;
t_stack_iterator current_iterator;
t_stack_iterator new_iterator;
t_usize i;
t_usize j;
t_usize size;
t_stack_head *head;
bool include_subtrees;
t_stack_iterator *iterator;
t_stack_node *node;
t_stack_action action;
bool should_pop;
bool should_stop;
t_vec_subtree subtrees;
t_stack_iterator *next_iterator;
t_stack_link link;
t_stack_iterator current_iterator;
t_stack_iterator new_iterator;
t_usize i;
t_usize j;
t_usize size;
array_clear(&self->slices);
array_clear(&self->iterators);
head = array_get(&self->heads, version);
new_iterator = (t_stack_iterator){
.node = head->node,
.subtrees = array_new(),
.subtrees = vec_subtree_new(16, NULL),
.subtree_count = 0,
.is_pending = true,
};
@ -45,8 +45,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version,
if (goal_subtree_count >= 0)
{
include_subtrees = true;
array_reserve(&new_iterator.subtrees,
(t_u32)ts_subtree_alloc_size(goal_subtree_count) / sizeof(t_subtree));
vec_subtree_reserve(&new_iterator.subtrees, ts_subtree_alloc_size(goal_subtree_count) / sizeof(t_subtree));
}
array_push(&self->iterators, new_iterator);
while (self->iterators.size > 0)
@ -65,7 +64,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version,
subtrees = iterator->subtrees;
if (!should_stop)
ts_subtree_array_copy(subtrees, &subtrees);
ts_subtree_array_reverse(&subtrees);
vec_subtree_reverse(&subtrees);
ts_stack__add_slice(self, version, node, &subtrees);
}
if (should_stop)
@ -76,7 +75,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version,
i--;
i++;
size--;
continue ;
continue;
}
j = 1;
while (j <= node->link_count)
@ -91,22 +90,21 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version,
if (self->iterators.size >= MAX_ITERATOR_COUNT)
{
j++;
continue ;
continue;
}
link = node->links[j];
current_iterator = self->iterators.contents[i];
array_push(&self->iterators, current_iterator);
next_iterator = array_back(&self->iterators);
ts_subtree_array_copy(next_iterator->subtrees,
&next_iterator->subtrees);
ts_subtree_array_copy(next_iterator->subtrees, &next_iterator->subtrees);
}
next_iterator->node = link.node;
if (link.subtree)
{
if (include_subtrees)
{
array_push(&next_iterator->subtrees, link.subtree);
(link.subtree->ref_count++);
vec_subtree_push(&next_iterator->subtrees, link.subtree);
link.subtree->ref_count++;
}
if (!ts_subtree_extra(link.subtree))
{

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/31 17:00:07 by maiboyer #+# #+# */
/* Updated: 2024/08/31 17:00:41 by maiboyer ### ########.fr */
/* Updated: 2024/09/02 20:53:54 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -18,11 +18,11 @@ t_stack_action pop_error_callback(void *payload,
{
bool *found_error;
if (iterator->subtrees.size > 0)
if (iterator->subtrees.len > 0)
{
found_error = payload;
if (!*found_error
&& ts_subtree_is_error(iterator->subtrees.contents[0]))
&& ts_subtree_is_error(iterator->subtrees.buffer[0]))
{
*found_error = true;
return (SActionPop | SActionStop);
@ -34,7 +34,7 @@ t_stack_action pop_error_callback(void *payload,
return (SActionNone);
}
SubtreeArray ts_stack_pop_error(t_stack *self, t_stack_version version)
t_vec_subtree ts_stack_pop_error(t_stack *self, t_stack_version version)
{
t_stack_node *node;
bool found_error;
@ -62,7 +62,7 @@ SubtreeArray ts_stack_pop_error(t_stack *self, t_stack_version version)
}
i++;
}
return ((SubtreeArray){.size = 0});
return ((t_vec_subtree){NULL, 0, 0, NULL});
}
t_stack_action pop_all_callback(void *payload,

View file

@ -3,97 +3,94 @@
#include "me/mem/mem.h"
#include "me/types.h"
#include "me/vec/vec_subtree.h"
#include "parser/array.h"
#include "parser/external_scanner_state.h"
#include "parser/language.h"
#include "parser/length.h"
#include "parser/subtree.h"
void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest)
void ts_subtree_array_copy(t_vec_subtree self, t_vec_subtree *dest)
{
dest->size = self.size;
t_usize i;
dest->len = self.len;
dest->capacity = self.capacity;
dest->contents = self.contents;
dest->buffer = self.buffer;
if (self.capacity > 0)
{
dest->contents = mem_alloc_array(self.capacity, sizeof(t_subtree));
mem_copy(dest->contents, self.contents, self.size * sizeof(t_subtree));
for (t_u32 i = 0; i < self.size; i++)
(dest->contents[i]->ref_count++);
dest->buffer = mem_alloc_array(self.capacity, sizeof(t_subtree));
mem_copy(dest->buffer, self.buffer, self.len * sizeof(t_subtree));
i = 0;
while (i < self.len)
dest->buffer[i++]->ref_count++;
}
}
void ts_subtree_array_clear(SubtreeArray *self)
void ts_subtree_array_clear(t_vec_subtree *self)
{
for (t_u32 i = 0; i < self->size; i++)
ts_subtree_release(self->contents[i]);
array_clear(self);
t_usize i;
i = 0;
while (i < self->len)
ts_subtree_release(self->buffer[i++]);
}
void ts_subtree_array_delete(SubtreeArray *self)
void ts_subtree_array_delete(t_vec_subtree *self)
{
ts_subtree_array_clear(self);
array_delete(self);
vec_subtree_free(*self);
}
void ts_subtree_array_remove_trailing_extras(SubtreeArray *self, SubtreeArray *destination)
void ts_subtree_array_remove_trailing_extras(t_vec_subtree *self, t_vec_subtree *destination)
{
array_clear(destination);
while (self->size > 0)
t_subtree last;
destination->len = 0;
while (self->len > 0)
{
t_subtree last = self->contents[self->size - 1];
last = self->buffer[self->len - 1];
if (ts_subtree_extra(last))
{
self->size--;
array_push(destination, last);
self->len--;
vec_subtree_push(destination, last);
}
else
break;
}
ts_subtree_array_reverse(destination);
}
void ts_subtree_array_reverse(SubtreeArray *self)
{
for (t_u32 i = 0, limit = self->size / 2; i < limit; i++)
{
size_t reverse_index = self->size - 1 - i;
t_subtree swap = self->contents[i];
self->contents[i] = self->contents[reverse_index];
self->contents[reverse_index] = swap;
}
vec_subtree_reverse(destination);
}
t_subtree ts_subtree_new_leaf(TSSymbol symbol, Length padding, Length size, t_u32 lookahead_bytes, TSStateId parse_state,
bool has_external_tokens, bool depends_on_column, bool is_keyword, const TSLanguage *language)
{
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
bool extra = symbol == ts_builtin_sym_end;
TSSymbolMetadata metadata;
bool extra;
t_subtree_data *data;
{
t_subtree_data *data = mem_alloc(sizeof(*data));
*data = (t_subtree_data){.ref_count = 1,
.padding = padding,
.size = size,
.lookahead_bytes = lookahead_bytes,
.error_cost = 0,
.child_count = 0,
.symbol = symbol,
.parse_state = parse_state,
.visible = metadata.visible,
.named = metadata.named,
.extra = extra,
.fragile_left = false,
.fragile_right = false,
.has_changes = false,
.has_external_tokens = has_external_tokens,
.has_external_scanner_state_change = false,
.depends_on_column = depends_on_column,
.is_missing = false,
.is_keyword = is_keyword,
{{.first_leaf = {.symbol = 0, .parse_state = 0}}}};
return (t_subtree)data;
}
extra = symbol == ts_builtin_sym_end;
metadata = ts_language_symbol_metadata(language, symbol);
data = mem_alloc(sizeof(*data));
*data = (t_subtree_data){.ref_count = 1,
.padding = padding,
.size = size,
.lookahead_bytes = lookahead_bytes,
.error_cost = 0,
.child_count = 0,
.symbol = symbol,
.parse_state = parse_state,
.visible = metadata.visible,
.named = metadata.named,
.extra = extra,
.fragile_left = false,
.fragile_right = false,
.has_changes = false,
.has_external_tokens = has_external_tokens,
.has_external_scanner_state_change = false,
.depends_on_column = depends_on_column,
.is_missing = false,
.is_keyword = is_keyword,
{{.first_leaf = {.symbol = 0, .parse_state = 0}}}};
return ((t_subtree)data);
}
void ts_subtree_set_symbol(t_subtree *self, TSSymbol symbol, const TSLanguage *language)
@ -115,7 +112,7 @@ t_subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size
result->fragile_left = true;
result->fragile_right = true;
result->lookahead_char = lookahead_char;
return result;
return (result);
}
// Clone a subtree.
@ -147,7 +144,7 @@ t_subtree ts_subtree_clone(t_subtree self)
// This takes ownership of the subtree. If the subtree has only one owner,
// this will directly convert it into a mutable version. Otherwise, it will
// perform a copy.
t_subtree ts_subtree_make_mut(t_subtree self)
t_subtree ts_subtree_ensure_owner(t_subtree self)
{
t_subtree result;
@ -156,88 +153,6 @@ t_subtree ts_subtree_make_mut(t_subtree self)
return result;
}
static void ts_subtree__compress(t_subtree self, t_u32 count, const TSLanguage *language, SubtreeArray *stack)
{
t_u32 initial_stack_size;
t_subtree tree;
TSSymbol symbol;
t_usize i;
t_subtree child_grandchild[2];
initial_stack_size = stack->size;
tree = self;
symbol = tree->symbol;
i = 0;
while (i < count)
{
if (tree->ref_count > 1 || tree->child_count < 2)
break;
child_grandchild[0] = (ts_subtree_children(tree)[0]);
if (child_grandchild[0]->child_count < 2 || child_grandchild[0]->ref_count > 1 || child_grandchild[0]->symbol != symbol)
break;
child_grandchild[1] = (ts_subtree_children(child_grandchild[0])[0]);
if (child_grandchild[1]->child_count < 2 || child_grandchild[1]->ref_count > 1 || child_grandchild[1]->symbol != symbol)
break;
ts_subtree_children(tree)[0] = (child_grandchild[1]);
ts_subtree_children(child_grandchild[0])[0] = ts_subtree_children(child_grandchild[1])[child_grandchild[1]->child_count - 1];
ts_subtree_children(child_grandchild[1])[child_grandchild[1]->child_count - 1] = (child_grandchild[0]);
array_push(stack, tree);
tree = child_grandchild[1];
i++;
}
while (stack->size > initial_stack_size)
{
tree = array_pop(stack);
child_grandchild[0] = (ts_subtree_children(tree)[0]);
child_grandchild[1] = (ts_subtree_children(child_grandchild[0])[child_grandchild[0]->child_count - 1]);
ts_subtree_summarize_children(child_grandchild[1], language);
ts_subtree_summarize_children(child_grandchild[0], language);
ts_subtree_summarize_children(tree, language);
}
}
void ts_subtree_balance(t_subtree self, const TSLanguage *language)
{
SubtreeArray balance_stack;
balance_stack = (SubtreeArray)array_new();
array_clear(&balance_stack);
if (ts_subtree_child_count(self) > 0 && self->ref_count == 1)
array_push(&balance_stack, self);
while (balance_stack.size > 0)
{
t_subtree tree = array_pop(&balance_stack);
if (tree->repeat_depth > 0)
{
t_subtree child1 = ts_subtree_children(tree)[0];
t_subtree child2 = ts_subtree_children(tree)[tree->child_count - 1];
long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2);
if (repeat_delta > 0)
{
t_u32 n = (t_u32)repeat_delta;
for (t_u32 i = n / 2; i > 0; i /= 2)
{
ts_subtree__compress(tree, i, language, &balance_stack);
n -= i;
}
}
}
for (t_u32 i = 0; i < tree->child_count; i++)
{
t_subtree child = ts_subtree_children(tree)[i];
if (ts_subtree_child_count(child) > 0 && child->ref_count == 1)
array_push(&balance_stack, child);
}
}
array_delete(&balance_stack);
}
// Assign all of the node's properties that depend on its children.
void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
{
@ -255,20 +170,16 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->production_id);
t_u32 lookahead_end_byte = 0;
const t_subtree *children = ts_subtree_children(self);
t_subtree *children = ts_subtree_children(self);
for (t_u32 i = 0; i < self->child_count; i++)
{
t_subtree child = children[i];
if (self->size.extent.row == 0 && ts_subtree_depends_on_column(child))
{
self->depends_on_column = true;
}
if (ts_subtree_has_external_scanner_state_change(child))
{
self->has_external_scanner_state_change = true;
}
if (i == 0)
{
@ -276,20 +187,14 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
self->size = ts_subtree_size(child);
}
else
{
self->size = length_add(self->size, ts_subtree_total_size(child));
}
t_u32 child_lookahead_end_byte = self->padding.bytes + self->size.bytes + ts_subtree_lookahead_bytes(child);
if (child_lookahead_end_byte > lookahead_end_byte)
{
lookahead_end_byte = child_lookahead_end_byte;
}
if (ts_subtree_symbol(child) != ts_builtin_sym_error_repeat)
{
self->error_cost += ts_subtree_error_cost(child);
}
t_u32 grandchild_count = ts_subtree_child_count(child);
if (self->symbol == ts_builtin_sym_error || self->symbol == ts_builtin_sym_error_repeat)
@ -297,13 +202,9 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0))
{
if (ts_subtree_visible(child))
{
self->error_cost += ERROR_COST_PER_SKIPPED_TREE;
}
else if (grandchild_count > 0)
{
self->error_cost += ERROR_COST_PER_SKIPPED_TREE * child->visible_child_count;
}
}
}
@ -315,9 +216,7 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
self->visible_descendant_count++;
self->visible_child_count++;
if (ts_language_symbol_metadata(language, alias_sequence[structural_index]).named)
{
self->named_child_count++;
}
}
else if (ts_subtree_visible(child))
{
@ -348,10 +247,8 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
self->lookahead_bytes = lookahead_end_byte - self->size.bytes - self->padding.bytes;
if (self->symbol == ts_builtin_sym_error || self->symbol == ts_builtin_sym_error_repeat)
{
self->error_cost +=
ERROR_COST_PER_RECOVERY + ERROR_COST_PER_SKIPPED_CHAR * self->size.bytes + ERROR_COST_PER_SKIPPED_LINE * self->size.extent.row;
}
if (self->child_count > 0)
{
@ -369,13 +266,9 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
if (self->child_count >= 2 && !self->visible && !self->named && ts_subtree_symbol(first_child) == self->symbol)
{
if (ts_subtree_repeat_depth(first_child) > ts_subtree_repeat_depth(last_child))
{
self->repeat_depth = ts_subtree_repeat_depth(first_child) + 1;
}
else
{
self->repeat_depth = ts_subtree_repeat_depth(last_child) + 1;
}
}
}
}
@ -383,23 +276,25 @@ void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language)
// Create a new parent node with the given children.
//
// This takes ownership of the children array.
t_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 production_id, const TSLanguage *language)
t_subtree ts_subtree_new_node(TSSymbol symbol, t_vec_subtree *children, t_u32 production_id, const TSLanguage *language)
{
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;
TSSymbolMetadata metadata;
bool fragile;
t_usize new_byte_size;
t_subtree data;
// Allocate the node's data at the end of the array of children.
size_t new_byte_size = ts_subtree_alloc_size(children->size);
metadata = ts_language_symbol_metadata(language, symbol);
fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;
new_byte_size = ts_subtree_alloc_size(children->len);
if (children->capacity * sizeof(t_subtree) < new_byte_size)
{
children->contents = mem_realloc(children->contents, new_byte_size);
children->buffer = mem_realloc(children->buffer, new_byte_size);
children->capacity = (t_u32)(new_byte_size / sizeof(t_subtree));
}
t_subtree_data *data = (t_subtree_data *)&children->contents[children->size];
data = (t_subtree)&children->buffer[children->len];
*data = (t_subtree_data){.ref_count = 1,
.symbol = symbol,
.child_count = children->size,
.child_count = children->len,
.visible = metadata.visible,
.named = metadata.named,
.has_changes = false,
@ -412,20 +307,21 @@ t_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 pro
.production_id = production_id,
.first_leaf = {.symbol = 0, .parse_state = 0},
}}};
t_subtree result = data;
ts_subtree_summarize_children(result, language);
return result;
ts_subtree_summarize_children(data, language);
return (data);
}
// Create a new error node containing the given children.
//
// This node is treated as 'extra'. Its children are prevented from having
// having any effect on the parse state.
t_subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TSLanguage *language)
t_subtree ts_subtree_new_error_node(t_vec_subtree *children, bool extra, const TSLanguage *language)
{
t_subtree result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language);
t_subtree result;
result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language);
result->extra = extra;
return ((result));
return (result);
}
// Create a new 'missing leaf' node.
@ -434,104 +330,9 @@ t_subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TS
// having any effect on the parse state.
t_subtree ts_subtree_new_missing_leaf(TSSymbol symbol, Length padding, t_u32 lookahead_bytes, const TSLanguage *language)
{
t_subtree result = ts_subtree_new_leaf(symbol, padding, length_zero(), lookahead_bytes, 0, false, false, false, language);
((t_subtree_data *)result)->is_missing = true;
return result;
}
void ts_subtree_release(t_subtree self)
{
SubtreeArray to_free;
to_free = (SubtreeArray)array_new();
array_clear(&to_free);
assert(self->ref_count > 0);
if (--(*(t_u32 *)(&self->ref_count)) == 0)
array_push(&to_free, (self));
while (to_free.size > 0)
{
t_subtree tree = array_pop(&to_free);
if (tree->child_count > 0)
{
t_subtree *children = ts_subtree_children(tree);
for (t_u32 i = 0; i < tree->child_count; i++)
{
t_subtree child = children[i];
assert(child->ref_count > 0);
if (--(*(t_u32 *)(&child->ref_count)) == 0)
array_push(&to_free, (child));
}
mem_free(children);
}
else
{
if (tree->has_external_tokens)
ts_external_scanner_state_delete(&tree->external_scanner_state);
mem_free(tree);
}
}
array_delete(&to_free);
}
int ts_subtree_compare(t_subtree left, t_subtree right)
{
SubtreeArray compare_stack = array_new();
array_push(&compare_stack, (left));
array_push(&compare_stack, (right));
while (compare_stack.size > 0)
{
right = (array_pop(&compare_stack));
left = (array_pop(&compare_stack));
int result = 0;
if (ts_subtree_symbol(left) < ts_subtree_symbol(right))
result = -1;
else if (ts_subtree_symbol(right) < ts_subtree_symbol(left))
result = 1;
else if (ts_subtree_child_count(left) < ts_subtree_child_count(right))
result = -1;
else if (ts_subtree_child_count(right) < ts_subtree_child_count(left))
result = 1;
if (result != 0)
{
array_clear(&compare_stack);
array_delete(&compare_stack);
return result;
}
for (t_u32 i = ts_subtree_child_count(left); i > 0; i--)
{
t_subtree left_child = ts_subtree_children(left)[i - 1];
t_subtree right_child = ts_subtree_children(right)[i - 1];
array_push(&compare_stack, (left_child));
array_push(&compare_stack, (right_child));
}
}
array_delete(&compare_stack);
return 0;
}
t_subtree ts_subtree_last_external_token(t_subtree tree)
{
if (!ts_subtree_has_external_tokens(tree))
return NULL;
while (tree->child_count > 0)
{
for (t_u32 i = tree->child_count - 1; i + 1 > 0; i--)
{
t_subtree child = ts_subtree_children(tree)[i];
if (ts_subtree_has_external_tokens(child))
{
tree = child;
break;
}
}
}
return tree;
t_subtree result;
result = ts_subtree_new_leaf(symbol, padding, length_zero(), lookahead_bytes, 0, false, false, false, language);
result->is_missing = true;
return (result);
}

View file

@ -0,0 +1,117 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* subtree_funcs1.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/02 20:36:10 by maiboyer #+# #+# */
/* Updated: 2024/09/02 20:39:57 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/vec/vec_subtree.h"
#include "parser/subtree.h"
void ts_subtree_release(t_subtree self)
{
t_vec_subtree to_free;
t_subtree tree;
t_subtree *children;
t_usize i;
to_free = vec_subtree_new(16, NULL);
if (--self->ref_count == 0)
vec_subtree_push(&to_free, self);
while (to_free.len > 0)
{
vec_subtree_pop(&to_free, &tree);
if (tree->child_count > 0)
{
i = 0;
children = ts_subtree_children(tree);
while (i < tree->child_count)
{
if (--(children[i])->ref_count == 0)
vec_subtree_push(&to_free, children[i]);
i++;
}
mem_free(children);
}
else
{
if (tree->has_external_tokens)
ts_external_scanner_state_delete(&tree->external_scanner_state);
mem_free(tree);
}
}
vec_subtree_free(to_free);
}
int subtree_compare_func(t_subtree left, t_subtree right)
{
int result;
result = 0;
if (ts_subtree_symbol(left) < ts_subtree_symbol(right))
result = -1;
else if (ts_subtree_symbol(right) < ts_subtree_symbol(left))
result = 1;
else if (ts_subtree_child_count(left) < ts_subtree_child_count(right))
result = -1;
else if (ts_subtree_child_count(right) < ts_subtree_child_count(left))
result = 1;
return (result);
}
int ts_subtree_compare(t_subtree left, t_subtree right)
{
t_vec_subtree cmp_stack;
t_i8 result = 0;
t_usize i;
cmp_stack = vec_subtree_new(16, NULL);
vec_subtree_push(&cmp_stack, (left));
vec_subtree_push(&cmp_stack, (right));
while (cmp_stack.len >= 2)
{
vec_subtree_pop(&cmp_stack, &left);
vec_subtree_pop(&cmp_stack, &right);
result = subtree_compare_func(left, right);
if (result != 0)
return (vec_subtree_free(cmp_stack), result);
i = ts_subtree_child_count(left);
while (i > 0)
{
vec_subtree_push(&cmp_stack, ts_subtree_children(left)[i - 1]);
vec_subtree_push(&cmp_stack, ts_subtree_children(right)[i - 1]);
i--;
}
}
return (vec_subtree_free(cmp_stack), 0);
}
t_subtree ts_subtree_last_external_token(t_subtree tree)
{
t_usize i;
t_subtree child;
if (!ts_subtree_has_external_tokens(tree))
return (NULL);
while (tree->child_count > 0)
{
i = tree->child_count - 1;
while (i + 1 > 0)
{
child = ts_subtree_children(tree)[i];
if (ts_subtree_has_external_tokens(child))
{
tree = child;
break;
}
i--;
}
}
return (tree);
}