Updated subtree to be more at the norme
This commit is contained in:
parent
f6d6589a3a
commit
cfd325374c
8 changed files with 429 additions and 377 deletions
|
|
@ -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 \
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@
|
|||
#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;
|
||||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -1,338 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -67,9 +67,10 @@ int subtree_compare_func(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_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);
|
||||
|
|
@ -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--;
|
||||
}
|
||||
64
parser/src/subtree/subtree_helper.c
Normal file
64
parser/src/subtree/subtree_helper.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_helper.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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);
|
||||
}
|
||||
107
parser/src/subtree/subtree_new.c
Normal file
107
parser/src/subtree/subtree_new.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_new.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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);
|
||||
}
|
||||
142
parser/src/subtree/subtree_summarize.c
Normal file
142
parser/src/subtree/subtree_summarize.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_summarize.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
parser/src/subtree/subtree_vec_helper.c
Normal file
70
parser/src/subtree/subtree_vec_helper.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_vec_helper.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue