From cfd325374c54033b8b680c244060d3d6b34d3fe1 Mon Sep 17 00:00:00 2001 From: Maieul BOYER Date: Mon, 2 Sep 2024 21:45:29 +0000 Subject: [PATCH] Updated subtree to be more at the norme --- parser/Filelist.parser.mk | 7 +- parser/src/stack/stack_iter.c | 46 +-- parser/src/subtree.c | 338 ------------------ .../{subtree_funcs1.c => subtree_funcs.c} | 32 +- parser/src/subtree/subtree_helper.c | 64 ++++ parser/src/subtree/subtree_new.c | 107 ++++++ parser/src/subtree/subtree_summarize.c | 142 ++++++++ parser/src/subtree/subtree_vec_helper.c | 70 ++++ 8 files changed, 429 insertions(+), 377 deletions(-) delete mode 100644 parser/src/subtree.c rename parser/src/subtree/{subtree_funcs1.c => subtree_funcs.c} (87%) create mode 100644 parser/src/subtree/subtree_helper.c create mode 100644 parser/src/subtree/subtree_new.c create mode 100644 parser/src/subtree/subtree_summarize.c create mode 100644 parser/src/subtree/subtree_vec_helper.c diff --git a/parser/Filelist.parser.mk b/parser/Filelist.parser.mk index fe0263ad..fe47ef0f 100644 --- a/parser/Filelist.parser.mk +++ b/parser/Filelist.parser.mk @@ -57,8 +57,11 @@ stack/stack_manipulate3 \ stack/stack_node \ stack/stack_summary \ stack/stack_version \ -subtree \ -subtree/subtree_funcs1 \ +subtree/subtree_funcs \ +subtree/subtree_helper \ +subtree/subtree_new \ +subtree/subtree_summarize \ +subtree/subtree_vec_helper \ tree/tree_funcs1 \ tree/tree_funcs2 \ diff --git a/parser/src/stack/stack_iter.c b/parser/src/stack/stack_iter.c index 043155b7..6f93a46c 100644 --- a/parser/src/stack/stack_iter.c +++ b/parser/src/stack/stack_iter.c @@ -14,23 +14,24 @@ #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; - 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; + 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); @@ -45,7 +46,8 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, t_stack_ if (goal_subtree_count >= 0) { include_subtrees = true; - vec_subtree_reserve(&new_iterator.subtrees, 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) @@ -75,7 +77,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, t_stack_ i--; i++; size--; - continue; + continue ; } j = 1; while (j <= node->link_count) @@ -90,20 +92,22 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, t_stack_ 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) { - vec_subtree_push(&next_iterator->subtrees, link.subtree); + vec_subtree_push(&next_iterator->subtrees, + link.subtree); link.subtree->ref_count++; } if (!ts_subtree_extra(link.subtree)) diff --git a/parser/src/subtree.c b/parser/src/subtree.c deleted file mode 100644 index 96262497..00000000 --- a/parser/src/subtree.c +++ /dev/null @@ -1,338 +0,0 @@ -#include -#include - -#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(t_vec_subtree self, t_vec_subtree *dest) -{ - t_usize i; - - dest->len = self.len; - dest->capacity = self.capacity; - dest->buffer = self.buffer; - if (self.capacity > 0) - { - 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(t_vec_subtree *self) -{ - t_usize i; - i = 0; - while (i < self->len) - ts_subtree_release(self->buffer[i++]); -} - -void ts_subtree_array_delete(t_vec_subtree *self) -{ - ts_subtree_array_clear(self); - vec_subtree_free(*self); -} - -void ts_subtree_array_remove_trailing_extras(t_vec_subtree *self, t_vec_subtree *destination) -{ - t_subtree last; - - destination->len = 0; - while (self->len > 0) - { - last = self->buffer[self->len - 1]; - if (ts_subtree_extra(last)) - { - self->len--; - vec_subtree_push(destination, last); - } - else - break; - } - 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; - bool extra; - t_subtree_data *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) -{ - TSSymbolMetadata metadata; - - metadata = ts_language_symbol_metadata(language, symbol); - (*self)->symbol = symbol; - (*self)->named = metadata.named; - (*self)->visible = metadata.visible; -} - -t_subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size, t_u32 bytes_scanned, TSStateId parse_state, - const TSLanguage *language) -{ - t_subtree result; - - result = ts_subtree_new_leaf(ts_builtin_sym_error, padding, size, bytes_scanned, parse_state, false, false, false, language); - result->fragile_left = true; - result->fragile_right = true; - result->lookahead_char = lookahead_char; - return (result); -} - -// Clone a subtree. -t_subtree ts_subtree_clone(t_subtree self) -{ - t_usize alloc_size; - t_usize i; - t_subtree *new_children; - t_subtree *old_children; - t_subtree_data *result; - - alloc_size = ts_subtree_alloc_size(self->child_count); - new_children = mem_alloc(alloc_size); - old_children = ts_subtree_children(self); - mem_copy(new_children, old_children, alloc_size); - result = (t_subtree_data *)&new_children[self->child_count]; - i = 0; - if (self->child_count > 0) - while (i < self->child_count) - (new_children[i++]->ref_count++); - else if (self->has_external_tokens) - result->external_scanner_state = ts_external_scanner_state_copy(&self->external_scanner_state); - result->ref_count = 1; - return ((t_subtree)result); -} - -// Get mutable version of a subtree. -// -// 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_ensure_owner(t_subtree self) -{ - t_subtree result; - - result = ts_subtree_clone(self); - ts_subtree_release(self); - return result; -} - -// Assign all of the node's properties that depend on its children. -void ts_subtree_summarize_children(t_subtree self, const TSLanguage *language) -{ - self->named_child_count = 0; - self->visible_child_count = 0; - self->error_cost = 0; - self->repeat_depth = 0; - self->visible_descendant_count = 0; - self->has_external_tokens = false; - self->depends_on_column = false; - self->has_external_scanner_state_change = false; - self->dynamic_precedence = 0; - - t_u32 structural_index = 0; - const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->production_id); - t_u32 lookahead_end_byte = 0; - - 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) - { - self->padding = ts_subtree_padding(child); - 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) - { - 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; - } - } - - self->dynamic_precedence += ts_subtree_dynamic_precedence(child); - self->visible_descendant_count += ts_subtree_visible_descendant_count(child); - - if (alias_sequence && alias_sequence[structural_index] != 0 && !ts_subtree_extra(child)) - { - 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)) - { - self->visible_descendant_count++; - self->visible_child_count++; - if (ts_subtree_named(child)) - self->named_child_count++; - } - else if (grandchild_count > 0) - { - self->visible_child_count += child->visible_child_count; - self->named_child_count += child->named_child_count; - } - - if (ts_subtree_has_external_tokens(child)) - self->has_external_tokens = true; - - if (ts_subtree_is_error(child)) - { - self->fragile_left = self->fragile_right = true; - self->parse_state = TS_TREE_STATE_NONE; - } - - if (!ts_subtree_extra(child)) - structural_index++; - } - - 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) - { - t_subtree first_child = children[0]; - t_subtree last_child = children[self->child_count - 1]; - - self->first_leaf.symbol = ts_subtree_leaf_symbol(first_child); - self->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child); - - if (ts_subtree_fragile_left(first_child)) - self->fragile_left = true; - if (ts_subtree_fragile_right(last_child)) - self->fragile_right = true; - - 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; - } - } -} - -// Create a new parent node with the given children. -// -// This takes ownership of the children array. -t_subtree ts_subtree_new_node(TSSymbol symbol, t_vec_subtree *children, t_u32 production_id, const TSLanguage *language) -{ - TSSymbolMetadata metadata; - bool fragile; - t_usize new_byte_size; - t_subtree data; - - 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->buffer = mem_realloc(children->buffer, new_byte_size); - children->capacity = (t_u32)(new_byte_size / sizeof(t_subtree)); - } - data = (t_subtree)&children->buffer[children->len]; - *data = (t_subtree_data){.ref_count = 1, - .symbol = symbol, - .child_count = children->len, - .visible = metadata.visible, - .named = metadata.named, - .has_changes = false, - .has_external_scanner_state_change = false, - .fragile_left = fragile, - .fragile_right = fragile, - .is_keyword = false, - {{ - .visible_descendant_count = 0, - .production_id = production_id, - .first_leaf = {.symbol = 0, .parse_state = 0}, - }}}; - 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(t_vec_subtree *children, bool extra, const TSLanguage *language) -{ - t_subtree result; - - result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language); - result->extra = extra; - return (result); -} - -// Create a new 'missing leaf' node. -// -// This node is treated as 'extra'. Its children are prevented from having -// 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; - - result = ts_subtree_new_leaf(symbol, padding, length_zero(), lookahead_bytes, 0, false, false, false, language); - result->is_missing = true; - return (result); -} diff --git a/parser/src/subtree/subtree_funcs1.c b/parser/src/subtree/subtree_funcs.c similarity index 87% rename from parser/src/subtree/subtree_funcs1.c rename to parser/src/subtree/subtree_funcs.c index 76f82175..f11023e6 100644 --- a/parser/src/subtree/subtree_funcs1.c +++ b/parser/src/subtree/subtree_funcs.c @@ -13,12 +13,12 @@ #include "me/vec/vec_subtree.h" #include "parser/subtree.h" -void ts_subtree_release(t_subtree self) +void ts_subtree_release(t_subtree self) { - t_vec_subtree to_free; - t_subtree tree; - t_subtree *children; - t_usize i; + 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) @@ -48,9 +48,9 @@ void ts_subtree_release(t_subtree self) vec_subtree_free(to_free); } -int subtree_compare_func(t_subtree left, t_subtree right) +int subtree_compare_func(t_subtree left, t_subtree right) { - int result; + int result; result = 0; if (ts_subtree_symbol(left) < ts_subtree_symbol(right)) @@ -64,12 +64,13 @@ int subtree_compare_func(t_subtree left, t_subtree right) return (result); } -int ts_subtree_compare(t_subtree left, t_subtree right) +int ts_subtree_compare(t_subtree left, t_subtree right) { - t_vec_subtree cmp_stack; - t_i8 result = 0; - t_usize i; + t_vec_subtree cmp_stack; + t_i8 result; + t_usize i; + result = 0; cmp_stack = vec_subtree_new(16, NULL); vec_subtree_push(&cmp_stack, (left)); vec_subtree_push(&cmp_stack, (right)); @@ -77,7 +78,6 @@ int ts_subtree_compare(t_subtree left, t_subtree right) { 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); @@ -92,10 +92,10 @@ int ts_subtree_compare(t_subtree left, t_subtree right) return (vec_subtree_free(cmp_stack), 0); } -t_subtree ts_subtree_last_external_token(t_subtree tree) +t_subtree ts_subtree_last_external_token(t_subtree tree) { - t_usize i; - t_subtree child; + t_usize i; + t_subtree child; if (!ts_subtree_has_external_tokens(tree)) return (NULL); @@ -108,7 +108,7 @@ t_subtree ts_subtree_last_external_token(t_subtree tree) if (ts_subtree_has_external_tokens(child)) { tree = child; - break; + break ; } i--; } diff --git a/parser/src/subtree/subtree_helper.c b/parser/src/subtree/subtree_helper.c new file mode 100644 index 00000000..3718dad2 --- /dev/null +++ b/parser/src/subtree/subtree_helper.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* subtree_helper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 21:34:30 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 21:39:19 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser/language.h" +#include "parser/subtree.h" + +void ts_subtree_set_symbol(t_subtree *self, TSSymbol symbol, + const TSLanguage *language) +{ + TSSymbolMetadata metadata; + + metadata = ts_language_symbol_metadata(language, symbol); + (*self)->symbol = symbol; + (*self)->named = metadata.named; + (*self)->visible = metadata.visible; +} + +// Clone a subtree. +t_subtree ts_subtree_clone(t_subtree self) +{ + t_usize alloc_size; + t_usize i; + t_subtree *new_children; + t_subtree *old_children; + t_subtree_data *result; + + alloc_size = ts_subtree_alloc_size(self->child_count); + new_children = mem_alloc(alloc_size); + old_children = ts_subtree_children(self); + mem_copy(new_children, old_children, alloc_size); + result = (t_subtree_data *)&new_children[self->child_count]; + i = 0; + if (self->child_count > 0) + { + while (i < self->child_count) + { + new_children[i]->ref_count++; + i++; + } + } + else if (self->has_external_tokens) + result->external_scanner_state = \ + ts_external_scanner_state_copy(&self->external_scanner_state); + result->ref_count = 1; + return ((t_subtree)result); +} + +t_subtree ts_subtree_ensure_owner(t_subtree self) +{ + t_subtree result; + + result = ts_subtree_clone(self); + ts_subtree_release(self); + return (result); +} diff --git a/parser/src/subtree/subtree_new.c b/parser/src/subtree/subtree_new.c new file mode 100644 index 00000000..74a77751 --- /dev/null +++ b/parser/src/subtree/subtree_new.c @@ -0,0 +1,107 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* subtree_new.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 21:33:35 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 21:41:54 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser/language.h" +#include "parser/subtree.h" + +// Create a new parent node with the given children. +// +// This takes ownership of the children array. +t_subtree ts_subtree_new_node(TSSymbol symbol, t_vec_subtree *children, + t_u32 production_id, const TSLanguage *language) +{ + TSSymbolMetadata metadata; + bool fragile; + t_subtree data; + + metadata = ts_language_symbol_metadata(language, symbol); + fragile = symbol == ts_builtin_sym_error + || symbol == ts_builtin_sym_error_repeat; + vec_subtree_reserve(children, ts_subtree_alloc_size(children->len) + / sizeof(t_subtree)); + data = (children->buffer[children->len]); + *data = (t_subtree_data){.ref_count = 1, .symbol = symbol, .child_count = \ + children->len, .visible = metadata.visible, .named = metadata.named, \ + .has_changes = false, .has_external_scanner_state_change = false, \ + .fragile_left = fragile, .fragile_right = fragile, .is_keyword = false, \ + {{.visible_descendant_count = 0, .production_id = production_id, \ + .first_leaf = {.symbol = 0, .parse_state = 0}, }}}; + 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(t_vec_subtree *children, bool extra, + const TSLanguage *language) +{ + t_subtree result; + + result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language); + result->extra = extra; + return (result); +} + +// Create a new 'missing leaf' node. +// +// This node is treated as 'extra'. Its children are prevented from having +// 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; + + result = ts_subtree_new_leaf(symbol, padding, length_zero(), + lookahead_bytes, 0, false, false, false, language); + result->is_missing = true; + return (result); +} + +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; + bool extra; + t_subtree_data *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); +} + +t_subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, + Length size, t_u32 bytes_scanned, TSStateId parse_state, + const TSLanguage *language) +{ + t_subtree result; + + result = ts_subtree_new_leaf(ts_builtin_sym_error, padding, size, + bytes_scanned, parse_state, false, false, false, language); + result->fragile_left = true; + result->fragile_right = true; + result->lookahead_char = lookahead_char; + return (result); +} diff --git a/parser/src/subtree/subtree_summarize.c b/parser/src/subtree/subtree_summarize.c new file mode 100644 index 00000000..a3ba1674 --- /dev/null +++ b/parser/src/subtree/subtree_summarize.c @@ -0,0 +1,142 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* subtree_summarize.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 21:35:24 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 21:44:43 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser/language.h" +#include "parser/subtree.h" + +// Assign all of the node's properties that depend on its children. +void ts_subtree_summarize_children(t_subtree self, + const TSLanguage *language) +{ + t_u32 structural_index; + const TSSymbol *alias_sequence; + t_u32 lookahead_end_byte; + t_subtree *children; + t_subtree child; + t_u32 child_lookahead_end_byte; + t_u32 grandchild_count; + t_subtree first_child; + t_subtree last_child; + t_usize i; + + alias_sequence = ts_language_alias_sequence(language, self->production_id); + self->named_child_count = 0; + self->visible_child_count = 0; + self->error_cost = 0; + self->repeat_depth = 0; + self->visible_descendant_count = 0; + self->has_external_tokens = false; + self->depends_on_column = false; + self->has_external_scanner_state_change = false; + self->dynamic_precedence = 0; + structural_index = 0; + lookahead_end_byte = 0; + children = ts_subtree_children(self); + i = 0; + while (i < self->child_count) + { + 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) + { + self->padding = ts_subtree_padding(child); + self->size = ts_subtree_size(child); + } + else + self->size = length_add(self->size, ts_subtree_total_size(child)); + 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); + grandchild_count = ts_subtree_child_count(child); + if (self->symbol == ts_builtin_sym_error + || self->symbol == ts_builtin_sym_error_repeat) + { + 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; + } + } + self->dynamic_precedence += ts_subtree_dynamic_precedence(child); + self->visible_descendant_count + += ts_subtree_visible_descendant_count(child); + if (alias_sequence && alias_sequence[structural_index] != 0 + && !ts_subtree_extra(child)) + { + 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)) + { + self->visible_descendant_count++; + self->visible_child_count++; + if (ts_subtree_named(child)) + self->named_child_count++; + } + else if (grandchild_count > 0) + { + self->visible_child_count += child->visible_child_count; + self->named_child_count += child->named_child_count; + } + if (ts_subtree_has_external_tokens(child)) + self->has_external_tokens = true; + if (ts_subtree_is_error(child)) + { + self->fragile_left = true; + self->fragile_right = true; + self->parse_state = TS_TREE_STATE_NONE; + } + if (!ts_subtree_extra(child)) + structural_index++; + i++; + } + 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) + { + first_child = children[0]; + last_child = children[self->child_count - 1]; + self->first_leaf.symbol = ts_subtree_leaf_symbol(first_child); + self->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child); + if (ts_subtree_fragile_left(first_child)) + self->fragile_left = true; + if (ts_subtree_fragile_right(last_child)) + self->fragile_right = true; + 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; + } + } +} diff --git a/parser/src/subtree/subtree_vec_helper.c b/parser/src/subtree/subtree_vec_helper.c new file mode 100644 index 00000000..8c33c4bb --- /dev/null +++ b/parser/src/subtree/subtree_vec_helper.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* subtree_vec_helper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/02 21:28:56 by maiboyer #+# #+# */ +/* Updated: 2024/09/02 21:42:14 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem.h" +#include "me/vec/vec_subtree.h" +#include "parser/subtree.h" + +void ts_subtree_array_copy(t_vec_subtree self, t_vec_subtree *dest) +{ + t_usize i; + + dest->len = self.len; + dest->capacity = self.capacity; + dest->buffer = self.buffer; + if (self.capacity > 0) + { + 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++; + i++; + } + } +} + +void ts_subtree_array_clear(t_vec_subtree *self) +{ + t_usize i; + + i = 0; + while (i < self->len) + ts_subtree_release(self->buffer[i++]); +} + +void ts_subtree_array_delete(t_vec_subtree *self) +{ + ts_subtree_array_clear(self); + vec_subtree_free(*self); +} + +void ts_subtree_array_remove_trailing_extras(t_vec_subtree *self, + t_vec_subtree *destination) +{ + t_subtree last; + + destination->len = 0; + while (self->len > 0) + { + last = self->buffer[self->len - 1]; + if (ts_subtree_extra(last)) + { + self->len--; + vec_subtree_push(destination, last); + } + else + break ; + } + vec_subtree_reverse(destination); +}