Don't store node_count and dynamic_precedence for leaf nodes

This commit is contained in:
Max Brunsfeld 2018-09-14 11:02:11 -07:00
parent c7306722dd
commit 93926fc82e
3 changed files with 41 additions and 24 deletions

View file

@ -142,8 +142,12 @@ static StackNode *stack_node_new(StackNode *previous_node, const Subtree *subtre
if (subtree) {
node->error_cost += subtree->error_cost;
node->position = length_add(node->position, ts_subtree_total_size(subtree));
node->dynamic_precedence += subtree->dynamic_precedence;
if (!subtree->extra) node->node_count += subtree->node_count;
if (subtree->child_count) {
node->node_count += subtree->node_count;
node->dynamic_precedence += subtree->dynamic_precedence;
} else {
node->node_count++;
}
}
} else {
node->position = length_zero();
@ -162,6 +166,7 @@ static bool stack__subtree_is_equivalent(const Subtree *left, const Subtree *rig
((left->error_cost > 0 && right->error_cost > 0) ||
(left->padding.bytes == right->padding.bytes &&
left->size.bytes == right->size.bytes &&
left->child_count == right->child_count &&
left->extra == right->extra &&
ts_subtree_external_scanner_state_eq(left, right))));
}
@ -177,7 +182,10 @@ static void stack_node_add_link(StackNode *self, StackLink link, SubtreePool *su
// the special case where two links directly connect the same pair of nodes,
// we can safely remove the ambiguity ahead of time without changing behavior.
if (existing_link->node == link.node) {
if (link.subtree->dynamic_precedence > existing_link->subtree->dynamic_precedence) {
if (
link.subtree->child_count > 0 &&
link.subtree->dynamic_precedence > existing_link->subtree->dynamic_precedence
) {
ts_subtree_retain(link.subtree);
ts_subtree_release(subtree_pool, existing_link->subtree);
existing_link->subtree = link.subtree;
@ -205,15 +213,21 @@ static void stack_node_add_link(StackNode *self, StackLink link, SubtreePool *su
if (self->link_count == MAX_LINK_COUNT) return;
stack_node_retain(link.node);
if (link.subtree) ts_subtree_retain(link.subtree);
unsigned node_count = link.node->node_count;
int dynamic_precedence = link.node->dynamic_precedence;
self->links[self->link_count++] = link;
unsigned node_count = link.node->node_count;
if (link.subtree) node_count += link.subtree->node_count;
if (node_count > self->node_count) self->node_count = node_count;
if (link.subtree) {
ts_subtree_retain(link.subtree);
if (link.subtree->child_count > 0) {
node_count += link.subtree->node_count;
dynamic_precedence += link.subtree->dynamic_precedence;
} else {
node_count++;
}
}
int dynamic_precedence = link.node->dynamic_precedence;
if (link.subtree) dynamic_precedence += link.subtree->dynamic_precedence;
if (node_count > self->node_count) self->node_count = node_count;
if (dynamic_precedence > self->dynamic_precedence) self->dynamic_precedence = dynamic_precedence;
}

View file

@ -171,8 +171,6 @@ Subtree *ts_subtree_new_leaf(SubtreePool *pool, TSSymbol symbol, Length padding,
result->ref_count = 1;
result->bytes_scanned = 0;
result->error_cost = 0;
result->node_count = 0;
result->dynamic_precedence = 0;
result->child_count = 0;
result->is_small = is_small;
result->visible = metadata.visible;
@ -336,8 +334,13 @@ void ts_subtree_set_children(Subtree *self, const Subtree **children, uint32_t c
if (child->symbol != ts_builtin_sym_error_repeat) {
self->error_cost += child->error_cost;
}
self->dynamic_precedence += child->dynamic_precedence;
self->node_count += child->node_count;
if (child->child_count > 0) {
self->dynamic_precedence += child->dynamic_precedence;
self->node_count += child->node_count;
} else {
self->node_count++;
}
if (alias_sequence && alias_sequence[non_extra_index] != 0 && !child->extra) {
self->visible_child_count++;

View file

@ -17,7 +17,7 @@ extern TSStateId TS_TREE_STATE_NONE;
typedef struct {
union {
char *long_data;
char short_data[16];
char short_data[24];
};
uint32_t length;
} ExternalScannerState;
@ -25,14 +25,18 @@ typedef struct {
typedef struct Subtree Subtree;
struct Subtree {
volatile uint32_t ref_count;
Length padding;
Length size;
volatile uint32_t ref_count;
uint32_t bytes_scanned;
uint32_t error_cost;
uint32_t node_count;
int32_t dynamic_precedence;
uint32_t child_count;
TSSymbol symbol;
TSStateId parse_state;
struct {
TSSymbol symbol;
TSLexMode lex_mode;
} first_leaf;
bool is_small : 1;
bool visible : 1;
@ -44,12 +48,6 @@ struct Subtree {
bool has_external_tokens : 1;
bool is_missing : 1;
bool is_keyword : 1;
TSSymbol symbol;
TSStateId parse_state;
struct {
TSSymbol symbol;
TSLexMode lex_mode;
} first_leaf;
union {
// Non-terminal subtrees (`child_count > 0`)
@ -57,11 +55,13 @@ struct Subtree {
const Subtree **children;
uint32_t visible_child_count;
uint32_t named_child_count;
uint32_t node_count;
uint32_t repeat_depth;
int32_t dynamic_precedence;
uint16_t alias_sequence_id;
};
// Normal terminal subtrees (`child_count == 0 && symbol != ts_builtin_sym_error`)
// External terminal subtrees (`child_count == 0 && has_external_tokens`)
ExternalScannerState external_scanner_state;
// Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`)