Merge pull request #106 from tree-sitter/sort-stack-versions-by-dynamic-precedence
Take total dynamic precedence into account in stack version sorting
This commit is contained in:
commit
d2ae16747c
3 changed files with 27 additions and 3 deletions
|
|
@ -40,6 +40,7 @@ static const unsigned MAX_COST_DIFFERENCE = 16 * ERROR_COST_PER_SKIPPED_TREE;
|
|||
typedef struct {
|
||||
unsigned cost;
|
||||
unsigned push_count;
|
||||
int dynamic_precedence;
|
||||
bool is_in_error;
|
||||
} ErrorStatus;
|
||||
|
||||
|
|
@ -167,6 +168,9 @@ static ErrorComparison parser__compare_versions(Parser *self, ErrorStatus a, Err
|
|||
}
|
||||
}
|
||||
|
||||
if (a.dynamic_precedence > b.dynamic_precedence) return ErrorComparisonPreferLeft;
|
||||
if (b.dynamic_precedence > a.dynamic_precedence) return ErrorComparisonPreferRight;
|
||||
|
||||
return ErrorComparisonNone;
|
||||
}
|
||||
|
||||
|
|
@ -174,13 +178,19 @@ static bool parser__better_version_exists(Parser *self, StackVersion version,
|
|||
bool is_in_error, unsigned cost) {
|
||||
if (self->finished_tree && self->finished_tree->error_cost <= cost) return true;
|
||||
|
||||
ErrorStatus status = {.cost = cost, .is_in_error = is_in_error, .push_count = 0};
|
||||
ErrorStatus status = {
|
||||
.cost = cost,
|
||||
.is_in_error = is_in_error,
|
||||
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
|
||||
.push_count = 0,
|
||||
};
|
||||
|
||||
for (StackVersion i = 0, n = ts_stack_version_count(self->stack); i < n; i++) {
|
||||
if (i == version || ts_stack_is_halted(self->stack, i)) continue;
|
||||
ErrorStatus status_i = {
|
||||
.cost = ts_stack_error_cost(self->stack, i),
|
||||
.is_in_error = ts_stack_top_state(self->stack, i) == ERROR_STATE,
|
||||
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, i),
|
||||
.push_count = ts_stack_push_count(self->stack, i)
|
||||
};
|
||||
switch (parser__compare_versions(self, status, status_i)) {
|
||||
|
|
@ -210,6 +220,7 @@ static bool parser__condense_stack(Parser *self) {
|
|||
ErrorStatus status_i = {
|
||||
.cost = ts_stack_error_cost(self->stack, i),
|
||||
.push_count = ts_stack_push_count(self->stack, i),
|
||||
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, i),
|
||||
.is_in_error = ts_stack_top_state(self->stack, i) == ERROR_STATE,
|
||||
};
|
||||
if (!status_i.is_in_error) all_versions_have_error = false;
|
||||
|
|
@ -219,6 +230,7 @@ static bool parser__condense_stack(Parser *self) {
|
|||
ErrorStatus status_j = {
|
||||
.cost = ts_stack_error_cost(self->stack, j),
|
||||
.push_count = ts_stack_push_count(self->stack, j),
|
||||
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, j),
|
||||
.is_in_error = ts_stack_top_state(self->stack, j) == ERROR_STATE,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ struct StackNode {
|
|||
uint32_t ref_count;
|
||||
unsigned error_cost;
|
||||
unsigned depth;
|
||||
int dynamic_precedence;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -121,6 +122,7 @@ static StackNode *stack_node_new(StackNode *previous_node, Tree *tree, bool is_p
|
|||
|
||||
node->position = previous_node->position;
|
||||
node->error_cost = previous_node->error_cost;
|
||||
node->dynamic_precedence = previous_node->dynamic_precedence;
|
||||
|
||||
if (tree) {
|
||||
node->depth = previous_node->depth;
|
||||
|
|
@ -128,6 +130,7 @@ static StackNode *stack_node_new(StackNode *previous_node, Tree *tree, bool is_p
|
|||
ts_tree_retain(tree);
|
||||
node->error_cost += tree->error_cost;
|
||||
node->position = length_add(node->position, ts_tree_total_size(tree));
|
||||
node->dynamic_precedence += tree->dynamic_precedence;
|
||||
if (state == ERROR_STATE && !tree->extra) {
|
||||
node->error_cost +=
|
||||
ERROR_COST_PER_SKIPPED_TREE * ((tree->visible || tree->child_count == 0) ? 1 : tree->visible_child_count) +
|
||||
|
|
@ -517,6 +520,10 @@ unsigned ts_stack_depth_since_error(Stack *self, StackVersion version) {
|
|||
return array_get(&self->heads, version)->node->depth;
|
||||
}
|
||||
|
||||
int ts_stack_dynamic_precedence(Stack *self, StackVersion version) {
|
||||
return array_get(&self->heads, version)->node->dynamic_precedence;
|
||||
}
|
||||
|
||||
void ts_stack_remove_version(Stack *self, StackVersion version) {
|
||||
stack_head_delete(array_get(&self->heads, version), &self->node_pool);
|
||||
array_erase(&self->heads, version);
|
||||
|
|
@ -658,8 +665,11 @@ bool ts_stack_print_dot_graph(Stack *self, const char **symbol_names, FILE *f) {
|
|||
|
||||
fprintf(
|
||||
f,
|
||||
" tooltip=\"position: %u,%u\nerror_cost: %u\"];\n",
|
||||
node->position.extent.row, node->position.extent.column, node->error_cost
|
||||
" tooltip=\"position: %u,%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",
|
||||
node->position.extent.row,
|
||||
node->position.extent.column,
|
||||
node->error_cost,
|
||||
node->dynamic_precedence
|
||||
);
|
||||
|
||||
for (int j = 0; j < node->link_count; j++) {
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ StackPopResult ts_stack_pop_all(Stack *, StackVersion);
|
|||
|
||||
unsigned ts_stack_depth_since_error(Stack *, StackVersion);
|
||||
|
||||
int ts_stack_dynamic_precedence(Stack *, StackVersion);
|
||||
|
||||
void ts_stack_record_summary(Stack *, StackVersion, unsigned max_depth);
|
||||
|
||||
StackSummary *ts_stack_get_summary(Stack *, StackVersion);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue