Compare commits
1 commit
master
...
leaf-error
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a99bfd9ff |
6 changed files with 891 additions and 710 deletions
|
|
@ -272,6 +272,7 @@ static inline void ts_language_write_symbol_as_dot_string(
|
||||||
TSSymbol symbol
|
TSSymbol symbol
|
||||||
) {
|
) {
|
||||||
const char *name = ts_language_symbol_name(self, symbol);
|
const char *name = ts_language_symbol_name(self, symbol);
|
||||||
|
printf("name: %s\n", name);
|
||||||
for (const char *chr = name; *chr; chr++) {
|
for (const char *chr = name; *chr; chr++) {
|
||||||
switch (*chr) {
|
switch (*chr) {
|
||||||
case '"':
|
case '"':
|
||||||
|
|
|
||||||
|
|
@ -206,12 +206,18 @@ static bool ts_parser__breakdown_top_of_stack(
|
||||||
}
|
}
|
||||||
|
|
||||||
ts_subtree_retain(child);
|
ts_subtree_retain(child);
|
||||||
ts_stack_push(self->stack, slice.version, child, pending, state);
|
ts_stack_push(self->stack, slice.version, child, pending, state, self->language);
|
||||||
|
LOG("push 1");
|
||||||
|
printf("push 1\n");
|
||||||
|
LOG_STACK();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t j = 1; j < slice.subtrees.size; j++) {
|
for (uint32_t j = 1; j < slice.subtrees.size; j++) {
|
||||||
Subtree tree = slice.subtrees.contents[j];
|
Subtree tree = slice.subtrees.contents[j];
|
||||||
ts_stack_push(self->stack, slice.version, tree, false, state);
|
ts_stack_push(self->stack, slice.version, tree, false, state, self->language);
|
||||||
|
LOG("push 2");
|
||||||
|
printf("push 2\n");
|
||||||
|
LOG_STACK();
|
||||||
}
|
}
|
||||||
|
|
||||||
ts_subtree_release(&self->tree_pool, parent);
|
ts_subtree_release(&self->tree_pool, parent);
|
||||||
|
|
@ -913,7 +919,10 @@ static void ts_parser__shift(
|
||||||
subtree_to_push = ts_subtree_from_mut(result);
|
subtree_to_push = ts_subtree_from_mut(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ts_stack_push(self->stack, version, subtree_to_push, !is_leaf, state);
|
ts_stack_push(self->stack, version, subtree_to_push, !is_leaf, state, self->language);
|
||||||
|
LOG("push 3");
|
||||||
|
printf("push 3\n");
|
||||||
|
LOG_STACK();
|
||||||
if (ts_subtree_has_external_tokens(subtree_to_push)) {
|
if (ts_subtree_has_external_tokens(subtree_to_push)) {
|
||||||
ts_stack_set_last_external_token(
|
ts_stack_set_last_external_token(
|
||||||
self->stack, version, ts_subtree_last_external_token(subtree_to_push)
|
self->stack, version, ts_subtree_last_external_token(subtree_to_push)
|
||||||
|
|
@ -1016,9 +1025,15 @@ static StackVersion ts_parser__reduce(
|
||||||
|
|
||||||
// Push the parent node onto the stack, along with any extra tokens that
|
// Push the parent node onto the stack, along with any extra tokens that
|
||||||
// were previously on top of the stack.
|
// were previously on top of the stack.
|
||||||
ts_stack_push(self->stack, slice_version, ts_subtree_from_mut(parent), false, next_state);
|
ts_stack_push(self->stack, slice_version, ts_subtree_from_mut(parent), false, next_state, self->language);
|
||||||
|
LOG("push 4");
|
||||||
|
printf("push 4\n");
|
||||||
|
LOG_STACK();
|
||||||
for (uint32_t j = 0; j < self->trailing_extras.size; j++) {
|
for (uint32_t j = 0; j < self->trailing_extras.size; 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.contents[j], false, next_state, self->language);
|
||||||
|
LOG("push 5");
|
||||||
|
printf("push 5\n");
|
||||||
|
LOG_STACK();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (StackVersion j = 0; j < slice_version; j++) {
|
for (StackVersion j = 0; j < slice_version; j++) {
|
||||||
|
|
@ -1042,9 +1057,15 @@ static void ts_parser__accept(
|
||||||
Subtree lookahead
|
Subtree lookahead
|
||||||
) {
|
) {
|
||||||
assert(ts_subtree_is_eof(lookahead));
|
assert(ts_subtree_is_eof(lookahead));
|
||||||
ts_stack_push(self->stack, version, lookahead, false, 1);
|
ts_stack_push(self->stack, version, lookahead, false, 1, self->language);
|
||||||
|
LOG("push 6");
|
||||||
|
printf("push 6\n");
|
||||||
|
LOG_STACK();
|
||||||
|
|
||||||
StackSliceArray pop = ts_stack_pop_all(self->stack, version);
|
LOG("POP ALL")
|
||||||
|
printf("POP ALL\n");
|
||||||
|
StackSliceArray pop = ts_stack_pop_all(self->stack, version, self->dot_graph_file);
|
||||||
|
LOG_STACK();
|
||||||
for (uint32_t i = 0; i < pop.size; i++) {
|
for (uint32_t i = 0; i < pop.size; i++) {
|
||||||
SubtreeArray trees = pop.contents[i].subtrees;
|
SubtreeArray trees = pop.contents[i].subtrees;
|
||||||
|
|
||||||
|
|
@ -1222,14 +1243,20 @@ static bool ts_parser__recover_to_state(
|
||||||
|
|
||||||
if (slice.subtrees.size > 0) {
|
if (slice.subtrees.size > 0) {
|
||||||
Subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language);
|
Subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language);
|
||||||
ts_stack_push(self->stack, slice.version, error, false, goal_state);
|
ts_stack_push(self->stack, slice.version, error, false, goal_state, self->language);
|
||||||
|
LOG("push 7");
|
||||||
|
printf("push 7\n");
|
||||||
|
LOG_STACK();
|
||||||
} else {
|
} else {
|
||||||
array_delete(&slice.subtrees);
|
array_delete(&slice.subtrees);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned j = 0; j < self->trailing_extras.size; j++) {
|
for (unsigned j = 0; j < self->trailing_extras.size; j++) {
|
||||||
Subtree tree = self->trailing_extras.contents[j];
|
Subtree tree = self->trailing_extras.contents[j];
|
||||||
ts_stack_push(self->stack, slice.version, tree, false, goal_state);
|
ts_stack_push(self->stack, slice.version, tree, false, goal_state, self->language);
|
||||||
|
LOG("push 8");
|
||||||
|
printf("push 8\n");
|
||||||
|
LOG_STACK();
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_version = slice.version;
|
previous_version = slice.version;
|
||||||
|
|
@ -1339,7 +1366,10 @@ static void ts_parser__recover(
|
||||||
LOG("recover_eof");
|
LOG("recover_eof");
|
||||||
SubtreeArray children = array_new();
|
SubtreeArray children = array_new();
|
||||||
Subtree parent = ts_subtree_new_error_node(&children, false, self->language);
|
Subtree parent = ts_subtree_new_error_node(&children, false, self->language);
|
||||||
ts_stack_push(self->stack, version, parent, false, 1);
|
ts_stack_push(self->stack, version, parent, false, 1, self->language);
|
||||||
|
LOG("push 9");
|
||||||
|
printf("push 9\n");
|
||||||
|
LOG_STACK();
|
||||||
ts_parser__accept(self, version, lookahead);
|
ts_parser__accept(self, version, lookahead);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1407,7 +1437,10 @@ static void ts_parser__recover(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the new ERROR onto the stack.
|
// Push the new ERROR onto the stack.
|
||||||
ts_stack_push(self->stack, version, ts_subtree_from_mut(error_repeat), false, ERROR_STATE);
|
ts_stack_push(self->stack, version, ts_subtree_from_mut(error_repeat), false, ERROR_STATE, self->language);
|
||||||
|
LOG("push 10");
|
||||||
|
printf("push 10\n");
|
||||||
|
LOG_STACK();
|
||||||
if (ts_subtree_has_external_tokens(lookahead)) {
|
if (ts_subtree_has_external_tokens(lookahead)) {
|
||||||
ts_stack_set_last_external_token(
|
ts_stack_set_last_external_token(
|
||||||
self->stack, version, ts_subtree_last_external_token(lookahead)
|
self->stack, version, ts_subtree_last_external_token(lookahead)
|
||||||
|
|
@ -1469,8 +1502,11 @@ static void ts_parser__handle_error(
|
||||||
ts_stack_push(
|
ts_stack_push(
|
||||||
self->stack, version_with_missing_tree,
|
self->stack, version_with_missing_tree,
|
||||||
missing_tree, false,
|
missing_tree, false,
|
||||||
state_after_missing_symbol
|
state_after_missing_symbol, self->language
|
||||||
);
|
);
|
||||||
|
LOG("push 11");
|
||||||
|
printf("push 11\n");
|
||||||
|
LOG_STACK();
|
||||||
|
|
||||||
if (ts_parser__do_all_potential_reductions(
|
if (ts_parser__do_all_potential_reductions(
|
||||||
self, version_with_missing_tree,
|
self, version_with_missing_tree,
|
||||||
|
|
@ -1488,7 +1524,10 @@ static void ts_parser__handle_error(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ts_stack_push(self->stack, v, NULL_SUBTREE, false, ERROR_STATE);
|
ts_stack_push(self->stack, v, NULL_SUBTREE, false, ERROR_STATE, self->language);
|
||||||
|
LOG("push 12");
|
||||||
|
printf("push 12\n");
|
||||||
|
LOG_STACK();
|
||||||
v = (v == version) ? previous_version_count : v + 1;
|
v = (v == version) ? previous_version_count : v + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1847,7 +1886,7 @@ TSParser *ts_parser_new(void) {
|
||||||
array_init(&self->reduce_actions);
|
array_init(&self->reduce_actions);
|
||||||
array_reserve(&self->reduce_actions, 4);
|
array_reserve(&self->reduce_actions, 4);
|
||||||
self->tree_pool = ts_subtree_pool_new(32);
|
self->tree_pool = ts_subtree_pool_new(32);
|
||||||
self->stack = ts_stack_new(&self->tree_pool);
|
self->stack = ts_stack_new(&self->tree_pool, self->language);
|
||||||
self->finished_tree = NULL_SUBTREE;
|
self->finished_tree = NULL_SUBTREE;
|
||||||
self->reusable_node = reusable_node_new();
|
self->reusable_node = reusable_node_new();
|
||||||
self->dot_graph_file = NULL;
|
self->dot_graph_file = NULL;
|
||||||
|
|
@ -1915,6 +1954,8 @@ bool ts_parser_set_language(TSParser *self, const TSLanguage *language) {
|
||||||
}
|
}
|
||||||
|
|
||||||
self->language = ts_language_copy(language);
|
self->language = ts_language_copy(language);
|
||||||
|
ts_stack_set_language(self->stack, ts_language_copy(language));
|
||||||
|
ts_stack_set_lexer(self->stack, &self->lexer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
436
lib/src/stack.c
436
lib/src/stack.c
|
|
@ -1,9 +1,10 @@
|
||||||
#include "./alloc.h"
|
|
||||||
#include "./language.h"
|
|
||||||
#include "./subtree.h"
|
|
||||||
#include "./array.h"
|
|
||||||
#include "./stack.h"
|
#include "./stack.h"
|
||||||
|
#include "./alloc.h"
|
||||||
|
#include "./array.h"
|
||||||
|
#include "./language.h"
|
||||||
#include "./length.h"
|
#include "./length.h"
|
||||||
|
#include "./lexer.h"
|
||||||
|
#include "./subtree.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -18,6 +19,32 @@
|
||||||
#define forceinline static inline __attribute__((always_inline))
|
#define forceinline static inline __attribute__((always_inline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LOG(...) \
|
||||||
|
if (self->lexer->logger.log || dot_graph_file) { \
|
||||||
|
snprintf(self->lexer->debug_buffer, TREE_SITTER_SERIALIZATION_BUFFER_SIZE, __VA_ARGS__); \
|
||||||
|
ts_stack__log(self, dot_graph_file); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOG_TREE(subtree) \
|
||||||
|
if (dot_graph_file) { \
|
||||||
|
printf("self->language:%p\n", (void *)self->language); \
|
||||||
|
ts_subtree_print_dot_graph(subtree, self->language, dot_graph_file); \
|
||||||
|
fputs("\n", dot_graph_file); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOG_LINKS() \
|
||||||
|
for (uint32_t k = 0; k < node->link_count; k++) { \
|
||||||
|
printf("link %d\n", k); \
|
||||||
|
printf("node:%p\n", node->links[k].node); \
|
||||||
|
printf("subtree:%p\n", node->links[k].subtree.ptr); \
|
||||||
|
if (node->links[k].subtree.ptr) { \
|
||||||
|
LOG("LINK TREE %d", k); \
|
||||||
|
LOG_TREE(node->links[k].subtree); \
|
||||||
|
} else { \
|
||||||
|
LOG("LINK NO TREE %d", k); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct StackNode StackNode;
|
typedef struct StackNode StackNode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -68,9 +95,12 @@ struct Stack {
|
||||||
StackNodeArray node_pool;
|
StackNodeArray node_pool;
|
||||||
StackNode *base_node;
|
StackNode *base_node;
|
||||||
SubtreePool *subtree_pool;
|
SubtreePool *subtree_pool;
|
||||||
|
const TSLanguage *language;
|
||||||
|
Lexer *lexer;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef unsigned StackAction;
|
typedef unsigned StackAction;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
StackActionNone,
|
StackActionNone,
|
||||||
StackActionStop = 1,
|
StackActionStop = 1,
|
||||||
|
|
@ -87,25 +117,40 @@ static void stack_node_retain(StackNode *self) {
|
||||||
assert(self->ref_count != 0);
|
assert(self->ref_count != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stack_node_release(
|
static void ts_stack__log(Stack *self, FILE *dot_graph_file) {
|
||||||
StackNode *self,
|
if (self->lexer->logger.log) {
|
||||||
StackNodeArray *pool,
|
self->lexer->logger.log(self->lexer->logger.payload, TSLogTypeParse, self->lexer->debug_buffer);
|
||||||
SubtreePool *subtree_pool
|
}
|
||||||
) {
|
|
||||||
|
if (dot_graph_file) {
|
||||||
|
fprintf(dot_graph_file, "graph {\nlabel=\"");
|
||||||
|
for (char *chr = &self->lexer->debug_buffer[0]; *chr != 0; chr++) {
|
||||||
|
if (*chr == '"' || *chr == '\\')
|
||||||
|
fputc('\\', dot_graph_file);
|
||||||
|
fputc(*chr, dot_graph_file);
|
||||||
|
}
|
||||||
|
fprintf(dot_graph_file, "\"\n}\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stack_node_release(StackNode *self, StackNodeArray *pool, SubtreePool *subtree_pool) {
|
||||||
recur:
|
recur:
|
||||||
assert(self->ref_count != 0);
|
assert(self->ref_count != 0);
|
||||||
self->ref_count--;
|
self->ref_count--;
|
||||||
if (self->ref_count > 0) return;
|
if (self->ref_count > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
StackNode *first_predecessor = NULL;
|
StackNode *first_predecessor = NULL;
|
||||||
if (self->link_count > 0) {
|
if (self->link_count > 0) {
|
||||||
for (unsigned i = self->link_count - 1; i > 0; i--) {
|
for (unsigned i = self->link_count - 1; i > 0; i--) {
|
||||||
StackLink link = self->links[i];
|
StackLink link = self->links[i];
|
||||||
if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);
|
if (link.subtree.ptr)
|
||||||
|
ts_subtree_release(subtree_pool, link.subtree);
|
||||||
stack_node_release(link.node, pool, subtree_pool);
|
stack_node_release(link.node, pool, subtree_pool);
|
||||||
}
|
}
|
||||||
StackLink link = self->links[0];
|
StackLink link = self->links[0];
|
||||||
if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);
|
if (link.subtree.ptr)
|
||||||
|
ts_subtree_release(subtree_pool, link.subtree);
|
||||||
first_predecessor = self->links[0].node;
|
first_predecessor = self->links[0].node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,31 +170,22 @@ recur:
|
||||||
/// how much progress has been made by a given version of the stack.
|
/// how much progress has been made by a given version of the stack.
|
||||||
static uint32_t stack__subtree_node_count(Subtree subtree) {
|
static uint32_t stack__subtree_node_count(Subtree subtree) {
|
||||||
uint32_t count = ts_subtree_visible_descendant_count(subtree);
|
uint32_t count = ts_subtree_visible_descendant_count(subtree);
|
||||||
if (ts_subtree_visible(subtree)) count++;
|
if (ts_subtree_visible(subtree))
|
||||||
|
count++;
|
||||||
|
|
||||||
// Count intermediate error nodes even though they are not visible,
|
// Count intermediate error nodes even though they are not visible,
|
||||||
// because a stack version's node count is used to check whether it
|
// because a stack version's node count is used to check whether it
|
||||||
// has made any progress since the last time it encountered an error.
|
// has made any progress since the last time it encountered an error.
|
||||||
if (ts_subtree_symbol(subtree) == ts_builtin_sym_error_repeat) count++;
|
if (ts_subtree_symbol(subtree) == ts_builtin_sym_error_repeat)
|
||||||
|
count++;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StackNode *stack_node_new(
|
static StackNode *stack_node_new(StackNode *previous_node, Subtree subtree, bool is_pending, TSStateId state,
|
||||||
StackNode *previous_node,
|
StackNodeArray *pool) {
|
||||||
Subtree subtree,
|
StackNode *node = pool->size > 0 ? array_pop(pool) : ts_malloc(sizeof(StackNode));
|
||||||
bool is_pending,
|
*node = (StackNode){.ref_count = 1, .link_count = 0, .state = state};
|
||||||
TSStateId state,
|
|
||||||
StackNodeArray *pool
|
|
||||||
) {
|
|
||||||
StackNode *node = pool->size > 0
|
|
||||||
? array_pop(pool)
|
|
||||||
: ts_malloc(sizeof(StackNode));
|
|
||||||
*node = (StackNode) {
|
|
||||||
.ref_count = 1,
|
|
||||||
.link_count = 0,
|
|
||||||
.state = state
|
|
||||||
};
|
|
||||||
|
|
||||||
if (previous_node) {
|
if (previous_node) {
|
||||||
node->link_count = 1;
|
node->link_count = 1;
|
||||||
|
|
@ -172,37 +208,35 @@ static StackNode *stack_node_new(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node->position = length_zero();
|
node->position = length_zero();
|
||||||
node->error_cost = 0;
|
// node->error_cost = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool stack__subtree_is_equivalent(Subtree left, Subtree right) {
|
static bool stack__subtree_is_equivalent(Subtree left, Subtree right) {
|
||||||
if (left.ptr == right.ptr) return true;
|
if (left.ptr == right.ptr)
|
||||||
if (!left.ptr || !right.ptr) return false;
|
return true;
|
||||||
|
if (!left.ptr || !right.ptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Symbols must match
|
// Symbols must match
|
||||||
if (ts_subtree_symbol(left) != ts_subtree_symbol(right)) return false;
|
if (ts_subtree_symbol(left) != ts_subtree_symbol(right))
|
||||||
|
return false;
|
||||||
|
|
||||||
// If both have errors, don't bother keeping both.
|
// If both have errors, don't bother keeping both.
|
||||||
if (ts_subtree_error_cost(left) > 0 && ts_subtree_error_cost(right) > 0) return true;
|
if (ts_subtree_error_cost(left) > 0 && ts_subtree_error_cost(right) > 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
return (
|
return (ts_subtree_padding(left).bytes == ts_subtree_padding(right).bytes &&
|
||||||
ts_subtree_padding(left).bytes == ts_subtree_padding(right).bytes &&
|
|
||||||
ts_subtree_size(left).bytes == ts_subtree_size(right).bytes &&
|
ts_subtree_size(left).bytes == ts_subtree_size(right).bytes &&
|
||||||
ts_subtree_child_count(left) == ts_subtree_child_count(right) &&
|
ts_subtree_child_count(left) == ts_subtree_child_count(right) &&
|
||||||
ts_subtree_extra(left) == ts_subtree_extra(right) &&
|
ts_subtree_extra(left) == ts_subtree_extra(right) && ts_subtree_external_scanner_state_eq(left, right));
|
||||||
ts_subtree_external_scanner_state_eq(left, right)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stack_node_add_link(
|
static void stack_node_add_link(StackNode *self, StackLink link, SubtreePool *subtree_pool) {
|
||||||
StackNode *self,
|
if (link.node == self)
|
||||||
StackLink link,
|
return;
|
||||||
SubtreePool *subtree_pool
|
|
||||||
) {
|
|
||||||
if (link.node == self) return;
|
|
||||||
|
|
||||||
for (int i = 0; i < self->link_count; i++) {
|
for (int i = 0; i < self->link_count; i++) {
|
||||||
StackLink *existing_link = &self->links[i];
|
StackLink *existing_link = &self->links[i];
|
||||||
|
|
@ -212,10 +246,8 @@ static void stack_node_add_link(
|
||||||
// the special case where two links directly connect the same pair of nodes,
|
// 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.
|
// we can safely remove the ambiguity ahead of time without changing behavior.
|
||||||
if (existing_link->node == link.node) {
|
if (existing_link->node == link.node) {
|
||||||
if (
|
if (ts_subtree_dynamic_precedence(link.subtree) >
|
||||||
ts_subtree_dynamic_precedence(link.subtree) >
|
ts_subtree_dynamic_precedence(existing_link->subtree)) {
|
||||||
ts_subtree_dynamic_precedence(existing_link->subtree)
|
|
||||||
) {
|
|
||||||
ts_subtree_retain(link.subtree);
|
ts_subtree_retain(link.subtree);
|
||||||
ts_subtree_release(subtree_pool, existing_link->subtree);
|
ts_subtree_release(subtree_pool, existing_link->subtree);
|
||||||
existing_link->subtree = link.subtree;
|
existing_link->subtree = link.subtree;
|
||||||
|
|
@ -226,11 +258,9 @@ static void stack_node_add_link(
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the previous nodes are mergeable, merge them recursively.
|
// If the previous nodes are mergeable, merge them recursively.
|
||||||
if (
|
if (existing_link->node->state == link.node->state &&
|
||||||
existing_link->node->state == link.node->state &&
|
|
||||||
existing_link->node->position.bytes == link.node->position.bytes &&
|
existing_link->node->position.bytes == link.node->position.bytes &&
|
||||||
existing_link->node->error_cost == link.node->error_cost
|
existing_link->node->error_cost == link.node->error_cost) {
|
||||||
) {
|
|
||||||
for (int j = 0; j < link.node->link_count; j++) {
|
for (int j = 0; j < link.node->link_count; j++) {
|
||||||
stack_node_add_link(existing_link->node, link.node->links[j], subtree_pool);
|
stack_node_add_link(existing_link->node, link.node->links[j], subtree_pool);
|
||||||
}
|
}
|
||||||
|
|
@ -246,7 +276,8 @@ static void stack_node_add_link(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->link_count == MAX_LINK_COUNT) return;
|
if (self->link_count == MAX_LINK_COUNT)
|
||||||
|
return;
|
||||||
|
|
||||||
stack_node_retain(link.node);
|
stack_node_retain(link.node);
|
||||||
unsigned node_count = link.node->node_count;
|
unsigned node_count = link.node->node_count;
|
||||||
|
|
@ -259,15 +290,13 @@ static void stack_node_add_link(
|
||||||
dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
|
dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node_count > self->node_count) self->node_count = node_count;
|
if (node_count > self->node_count)
|
||||||
if (dynamic_precedence > self->dynamic_precedence) self->dynamic_precedence = dynamic_precedence;
|
self->node_count = node_count;
|
||||||
|
if (dynamic_precedence > self->dynamic_precedence)
|
||||||
|
self->dynamic_precedence = dynamic_precedence;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stack_head_delete(
|
static void stack_head_delete(StackHead *self, StackNodeArray *pool, SubtreePool *subtree_pool) {
|
||||||
StackHead *self,
|
|
||||||
StackNodeArray *pool,
|
|
||||||
SubtreePool *subtree_pool
|
|
||||||
) {
|
|
||||||
if (self->node) {
|
if (self->node) {
|
||||||
if (self->last_external_token.ptr) {
|
if (self->last_external_token.ptr) {
|
||||||
ts_subtree_release(subtree_pool, self->last_external_token);
|
ts_subtree_release(subtree_pool, self->last_external_token);
|
||||||
|
|
@ -283,11 +312,7 @@ static void stack_head_delete(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static StackVersion ts_stack__add_version(
|
static StackVersion ts_stack__add_version(Stack *self, StackVersion original_version, StackNode *node) {
|
||||||
Stack *self,
|
|
||||||
StackVersion original_version,
|
|
||||||
StackNode *node
|
|
||||||
) {
|
|
||||||
StackHead head = {
|
StackHead head = {
|
||||||
.node = node,
|
.node = node,
|
||||||
.node_count_at_last_error = self->heads.contents[original_version].node_count_at_last_error,
|
.node_count_at_last_error = self->heads.contents[original_version].node_count_at_last_error,
|
||||||
|
|
@ -297,16 +322,12 @@ static StackVersion ts_stack__add_version(
|
||||||
};
|
};
|
||||||
array_push(&self->heads, head);
|
array_push(&self->heads, head);
|
||||||
stack_node_retain(node);
|
stack_node_retain(node);
|
||||||
if (head.last_external_token.ptr) ts_subtree_retain(head.last_external_token);
|
if (head.last_external_token.ptr)
|
||||||
|
ts_subtree_retain(head.last_external_token);
|
||||||
return (StackVersion)(self->heads.size - 1);
|
return (StackVersion)(self->heads.size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_stack__add_slice(
|
static void ts_stack__add_slice(Stack *self, StackVersion original_version, StackNode *node, SubtreeArray *subtrees) {
|
||||||
Stack *self,
|
|
||||||
StackVersion original_version,
|
|
||||||
StackNode *node,
|
|
||||||
SubtreeArray *subtrees
|
|
||||||
) {
|
|
||||||
for (uint32_t i = self->slices.size - 1; i + 1 > 0; i--) {
|
for (uint32_t i = self->slices.size - 1; i + 1 > 0; i--) {
|
||||||
StackVersion version = self->slices.contents[i].version;
|
StackVersion version = self->slices.contents[i].version;
|
||||||
if (self->heads.contents[version].node == node) {
|
if (self->heads.contents[version].node == node) {
|
||||||
|
|
@ -321,13 +342,8 @@ static void ts_stack__add_slice(
|
||||||
array_push(&self->slices, slice);
|
array_push(&self->slices, slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
static StackSliceArray stack__iter(
|
static StackSliceArray stack__iter(Stack *self, StackVersion version, StackCallback callback, void *payload,
|
||||||
Stack *self,
|
int goal_subtree_count, FILE *dot_graph_file) {
|
||||||
StackVersion version,
|
|
||||||
StackCallback callback,
|
|
||||||
void *payload,
|
|
||||||
int goal_subtree_count
|
|
||||||
) {
|
|
||||||
array_clear(&self->slices);
|
array_clear(&self->slices);
|
||||||
array_clear(&self->iterators);
|
array_clear(&self->iterators);
|
||||||
|
|
||||||
|
|
@ -342,10 +358,13 @@ static StackSliceArray stack__iter(
|
||||||
bool include_subtrees = false;
|
bool include_subtrees = false;
|
||||||
if (goal_subtree_count >= 0) {
|
if (goal_subtree_count >= 0) {
|
||||||
include_subtrees = true;
|
include_subtrees = true;
|
||||||
array_reserve(&new_iterator.subtrees, (uint32_t)ts_subtree_alloc_size(goal_subtree_count) / sizeof(Subtree));
|
array_reserve(&new_iterator.subtrees,
|
||||||
|
(uint32_t)ts_subtree_alloc_size(goal_subtree_count ? 1 : goal_subtree_count) / sizeof(Subtree));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("iterator len: %d\n", self->iterators.size);
|
||||||
array_push(&self->iterators, new_iterator);
|
array_push(&self->iterators, new_iterator);
|
||||||
|
printf("iterator len: %d\n", self->iterators.size);
|
||||||
|
|
||||||
while (self->iterators.size > 0) {
|
while (self->iterators.size > 0) {
|
||||||
for (uint32_t i = 0, size = self->iterators.size; i < size; i++) {
|
for (uint32_t i = 0, size = self->iterators.size; i < size; i++) {
|
||||||
|
|
@ -355,19 +374,45 @@ static StackSliceArray stack__iter(
|
||||||
StackAction action = callback(payload, iterator);
|
StackAction action = callback(payload, iterator);
|
||||||
bool should_pop = action & StackActionPop;
|
bool should_pop = action & StackActionPop;
|
||||||
bool should_stop = action & StackActionStop || node->link_count == 0;
|
bool should_stop = action & StackActionStop || node->link_count == 0;
|
||||||
|
printf("should_pop: %d\n", should_pop);
|
||||||
|
printf("should_stop: %d\n", should_stop);
|
||||||
|
|
||||||
if (should_pop) {
|
if (should_pop) {
|
||||||
SubtreeArray subtrees = iterator->subtrees;
|
SubtreeArray subtrees = iterator->subtrees;
|
||||||
|
for (uint32_t j = 0; j < subtrees.size; j++) {
|
||||||
|
LOG("TREE %d", j);
|
||||||
|
LOG_TREE(subtrees.contents[j]);
|
||||||
|
}
|
||||||
if (!should_stop) {
|
if (!should_stop) {
|
||||||
ts_subtree_array_copy(subtrees, &subtrees);
|
ts_subtree_array_copy(subtrees, &subtrees);
|
||||||
|
LOG("[0] PRE COPY LEN %d", subtrees.size);
|
||||||
|
for (uint32_t k = 0; k < subtrees.size; k++) {
|
||||||
|
LOG("[0] PRE COPY TREE %d", k);
|
||||||
|
LOG_TREE(subtrees.contents[k]);
|
||||||
|
}
|
||||||
|
LOG("[0] NEW PTR: %p\n", (void *)subtrees.contents)
|
||||||
|
LOG("[0] POST COPY LEN %d", subtrees.size);
|
||||||
|
for (uint32_t k = 0; k < subtrees.size; k++) {
|
||||||
|
LOG("[0] POST COPY TREE %d", k);
|
||||||
|
LOG_TREE(subtrees.contents[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint32_t k = 0; k < subtrees.size; k++) {
|
||||||
|
LOG("[0] PRE REVERSE TREE %d", k);
|
||||||
|
LOG_TREE(subtrees.contents[k]);
|
||||||
}
|
}
|
||||||
ts_subtree_array_reverse(&subtrees);
|
ts_subtree_array_reverse(&subtrees);
|
||||||
ts_stack__add_slice(
|
for (uint32_t k = 0; k < subtrees.size; k++) {
|
||||||
self,
|
LOG("[0] POST REVERSE TREE %d", k);
|
||||||
version,
|
LOG_TREE(subtrees.contents[k]);
|
||||||
node,
|
}
|
||||||
&subtrees
|
ts_stack__add_slice(self, version, node, &subtrees);
|
||||||
);
|
printf("ADD SLICE\n");
|
||||||
|
LOG("ADD SLICE\n");
|
||||||
|
for (uint32_t j = 0; j < subtrees.size; j++) {
|
||||||
|
LOG("ADD SLICE TREE %d", j);
|
||||||
|
LOG_TREE(subtrees.contents[j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_stop) {
|
if (should_stop) {
|
||||||
|
|
@ -383,21 +428,50 @@ static StackSliceArray stack__iter(
|
||||||
StackIterator *next_iterator;
|
StackIterator *next_iterator;
|
||||||
StackLink link;
|
StackLink link;
|
||||||
if (j == node->link_count) {
|
if (j == node->link_count) {
|
||||||
|
printf("link set 1\n");
|
||||||
link = node->links[0];
|
link = node->links[0];
|
||||||
|
LOG("# of links=%d", node->link_count);
|
||||||
|
for (uint32_t k = 0; k < node->link_count; k++) {
|
||||||
|
printf("link %d\n", k);
|
||||||
|
printf("node:%p\n", node->links[k].node);
|
||||||
|
printf("subtree:%p\n", node->links[k].subtree.ptr);
|
||||||
|
if (node->links[k].subtree.ptr) {
|
||||||
|
LOG("LINK TREE %d", k);
|
||||||
|
LOG_TREE(node->links[k].subtree);
|
||||||
|
} else {
|
||||||
|
LOG("LINK NO TREE %d", k);
|
||||||
|
}
|
||||||
|
}
|
||||||
next_iterator = &self->iterators.contents[i];
|
next_iterator = &self->iterators.contents[i];
|
||||||
} else {
|
} else {
|
||||||
if (self->iterators.size >= MAX_ITERATOR_COUNT) continue;
|
if (self->iterators.size >= MAX_ITERATOR_COUNT)
|
||||||
|
continue;
|
||||||
link = node->links[j];
|
link = node->links[j];
|
||||||
StackIterator current_iterator = self->iterators.contents[i];
|
StackIterator current_iterator = self->iterators.contents[i];
|
||||||
array_push(&self->iterators, current_iterator);
|
array_push(&self->iterators, current_iterator);
|
||||||
next_iterator = array_back(&self->iterators);
|
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);
|
||||||
|
LOG("[1] PRE COPY LEN %d", next_iterator->subtrees.size);
|
||||||
|
for (uint32_t k = 0; k < next_iterator->subtrees.size; k++) {
|
||||||
|
LOG("[1] PRE COPY TREE %d", k);
|
||||||
|
LOG_TREE(next_iterator->subtrees.contents[k]);
|
||||||
|
}
|
||||||
|
LOG("[1] NEW PTR: %p\n", (void *)next_iterator->subtrees.contents)
|
||||||
|
LOG("[1] POST COPY LEN %d", next_iterator->subtrees.size);
|
||||||
|
for (uint32_t k = 0; k < next_iterator->subtrees.size; k++) {
|
||||||
|
LOG("[1] POST COPY TREE %d", k);
|
||||||
|
LOG_TREE(next_iterator->subtrees.contents[k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next_iterator->node = link.node;
|
next_iterator->node = link.node;
|
||||||
if (link.subtree.ptr) {
|
if (link.subtree.ptr) {
|
||||||
if (include_subtrees) {
|
if (include_subtrees) {
|
||||||
|
printf("PUSH INCLUDE SUBTREE\n");
|
||||||
|
LOG("PUSH INCLUDING SUBTREE");
|
||||||
|
LOG_TREE(link.subtree);
|
||||||
array_push(&next_iterator->subtrees, link.subtree);
|
array_push(&next_iterator->subtrees, link.subtree);
|
||||||
|
|
||||||
ts_subtree_retain(link.subtree);
|
ts_subtree_retain(link.subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -418,7 +492,7 @@ static StackSliceArray stack__iter(
|
||||||
return self->slices;
|
return self->slices;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack *ts_stack_new(SubtreePool *subtree_pool) {
|
Stack *ts_stack_new(SubtreePool *subtree_pool, const TSLanguage *language) {
|
||||||
Stack *self = ts_calloc(1, sizeof(Stack));
|
Stack *self = ts_calloc(1, sizeof(Stack));
|
||||||
|
|
||||||
array_init(&self->heads);
|
array_init(&self->heads);
|
||||||
|
|
@ -432,6 +506,8 @@ Stack *ts_stack_new(SubtreePool *subtree_pool) {
|
||||||
|
|
||||||
self->subtree_pool = subtree_pool;
|
self->subtree_pool = subtree_pool;
|
||||||
self->base_node = stack_node_new(NULL, NULL_SUBTREE, false, 1, &self->node_pool);
|
self->base_node = stack_node_new(NULL, NULL_SUBTREE, false, 1, &self->node_pool);
|
||||||
|
self->language = language;
|
||||||
|
printf("language:%p\n", language);
|
||||||
ts_stack_clear(self);
|
ts_stack_clear(self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
@ -456,9 +532,7 @@ void ts_stack_delete(Stack *self) {
|
||||||
ts_free(self);
|
ts_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ts_stack_version_count(const Stack *self) {
|
uint32_t ts_stack_version_count(const Stack *self) { return self->heads.size; }
|
||||||
return self->heads.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSStateId ts_stack_state(const Stack *self, StackVersion version) {
|
TSStateId ts_stack_state(const Stack *self, StackVersion version) {
|
||||||
return array_get(&self->heads, version)->node->state;
|
return array_get(&self->heads, version)->node->state;
|
||||||
|
|
@ -474,17 +548,25 @@ Subtree ts_stack_last_external_token(const Stack *self, StackVersion version) {
|
||||||
|
|
||||||
void ts_stack_set_last_external_token(Stack *self, StackVersion version, Subtree token) {
|
void ts_stack_set_last_external_token(Stack *self, StackVersion version, Subtree token) {
|
||||||
StackHead *head = array_get(&self->heads, version);
|
StackHead *head = array_get(&self->heads, version);
|
||||||
if (token.ptr) ts_subtree_retain(token);
|
if (token.ptr)
|
||||||
if (head->last_external_token.ptr) ts_subtree_release(self->subtree_pool, head->last_external_token);
|
ts_subtree_retain(token);
|
||||||
|
if (head->last_external_token.ptr)
|
||||||
|
ts_subtree_release(self->subtree_pool, head->last_external_token);
|
||||||
head->last_external_token = token;
|
head->last_external_token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ts_stack_set_language(Stack *self, const TSLanguage *language) { self->language = language; }
|
||||||
|
|
||||||
|
void ts_stack_set_lexer(Stack *self, Lexer *lexer) { self->lexer = lexer; }
|
||||||
|
|
||||||
unsigned ts_stack_error_cost(const Stack *self, StackVersion version) {
|
unsigned ts_stack_error_cost(const Stack *self, StackVersion version) {
|
||||||
StackHead *head = array_get(&self->heads, version);
|
StackHead *head = array_get(&self->heads, version);
|
||||||
unsigned result = head->node->error_cost;
|
unsigned result = head->node->error_cost;
|
||||||
if (
|
if (head->status == StackStatusPaused || (head->node->state == ERROR_STATE && !head->node->links[0].subtree.ptr)) {
|
||||||
head->status == StackStatusPaused ||
|
if (head->node->links[0].subtree.data.is_inline) {
|
||||||
(head->node->state == ERROR_STATE && !head->node->links[0].subtree.ptr)) {
|
printf("DID += FOR %s\n",
|
||||||
|
ts_language_symbol_name(self->language, ts_subtree_symbol(head->node->links[0].subtree)));
|
||||||
|
}
|
||||||
result += ERROR_COST_PER_RECOVERY;
|
result += ERROR_COST_PER_RECOVERY;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -498,16 +580,19 @@ unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version
|
||||||
return head->node->node_count - head->node_count_at_last_error;
|
return head->node->node_count - head->node_count_at_last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_stack_push(
|
void ts_stack_push(Stack *self, StackVersion version, Subtree subtree, bool pending, TSStateId state,
|
||||||
Stack *self,
|
const TSLanguage *l) {
|
||||||
StackVersion version,
|
|
||||||
Subtree subtree,
|
|
||||||
bool pending,
|
|
||||||
TSStateId state
|
|
||||||
) {
|
|
||||||
StackHead *head = array_get(&self->heads, version);
|
StackHead *head = array_get(&self->heads, version);
|
||||||
StackNode *new_node = stack_node_new(head->node, subtree, pending, state, &self->node_pool);
|
StackNode *new_node = stack_node_new(head->node, subtree, pending, state, &self->node_pool);
|
||||||
if (!subtree.ptr) head->node_count_at_last_error = new_node->node_count;
|
if (!subtree.ptr)
|
||||||
|
head->node_count_at_last_error = new_node->node_count;
|
||||||
|
else {
|
||||||
|
const char *s = ts_language_symbol_name(l, ts_subtree_symbol(subtree));
|
||||||
|
printf("sym=%s\n", s);
|
||||||
|
if (strcmp(s, "ERROR") == 0) {
|
||||||
|
(void)s;
|
||||||
|
}
|
||||||
|
}
|
||||||
head->node = new_node;
|
head->node = new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -521,7 +606,7 @@ forceinline StackAction pop_count_callback(void *payload, const StackIterator *i
|
||||||
}
|
}
|
||||||
|
|
||||||
StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count) {
|
StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count) {
|
||||||
return stack__iter(self, version, pop_count_callback, &count, (int)count);
|
return stack__iter(self, version, pop_count_callback, &count, (int)count, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline StackAction pop_pending_callback(void *payload, const StackIterator *iterator) {
|
forceinline StackAction pop_pending_callback(void *payload, const StackIterator *iterator) {
|
||||||
|
|
@ -538,7 +623,7 @@ forceinline StackAction pop_pending_callback(void *payload, const StackIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version) {
|
StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version) {
|
||||||
StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, 0);
|
StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, 0, NULL);
|
||||||
if (pop.size > 0) {
|
if (pop.size > 0) {
|
||||||
ts_stack_renumber_version(self, pop.contents[0].version, version);
|
ts_stack_renumber_version(self, pop.contents[0].version, version);
|
||||||
pop.contents[0].version = version;
|
pop.contents[0].version = version;
|
||||||
|
|
@ -565,7 +650,7 @@ SubtreeArray ts_stack_pop_error(Stack *self, StackVersion version) {
|
||||||
for (unsigned i = 0; i < node->link_count; i++) {
|
for (unsigned i = 0; i < node->link_count; i++) {
|
||||||
if (node->links[i].subtree.ptr && ts_subtree_is_error(node->links[i].subtree)) {
|
if (node->links[i].subtree.ptr && ts_subtree_is_error(node->links[i].subtree)) {
|
||||||
bool found_error = false;
|
bool found_error = false;
|
||||||
StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, 1);
|
StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, 1, NULL);
|
||||||
if (pop.size > 0) {
|
if (pop.size > 0) {
|
||||||
assert(pop.size == 1);
|
assert(pop.size == 1);
|
||||||
ts_stack_renumber_version(self, pop.contents[0].version, version);
|
ts_stack_renumber_version(self, pop.contents[0].version, version);
|
||||||
|
|
@ -582,8 +667,8 @@ forceinline StackAction pop_all_callback(void *payload, const StackIterator *ite
|
||||||
return iterator->node->link_count == 0 ? StackActionPop : StackActionNone;
|
return iterator->node->link_count == 0 ? StackActionPop : StackActionNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version) {
|
StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version, FILE *dot_graph_file) {
|
||||||
return stack__iter(self, version, pop_all_callback, NULL, 0);
|
return stack__iter(self, version, pop_all_callback, NULL, 0, dot_graph_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -595,11 +680,14 @@ forceinline StackAction summarize_stack_callback(void *payload, const StackItera
|
||||||
SummarizeStackSession *session = payload;
|
SummarizeStackSession *session = payload;
|
||||||
TSStateId state = iterator->node->state;
|
TSStateId state = iterator->node->state;
|
||||||
unsigned depth = iterator->subtree_count;
|
unsigned depth = iterator->subtree_count;
|
||||||
if (depth > session->max_depth) return StackActionStop;
|
if (depth > session->max_depth)
|
||||||
|
return StackActionStop;
|
||||||
for (unsigned i = session->summary->size - 1; i + 1 > 0; i--) {
|
for (unsigned i = session->summary->size - 1; i + 1 > 0; i--) {
|
||||||
StackSummaryEntry entry = session->summary->contents[i];
|
StackSummaryEntry entry = session->summary->contents[i];
|
||||||
if (entry.depth < depth) break;
|
if (entry.depth < depth)
|
||||||
if (entry.depth == depth && entry.state == state) return StackActionNone;
|
break;
|
||||||
|
if (entry.depth == depth && entry.state == state)
|
||||||
|
return StackActionNone;
|
||||||
}
|
}
|
||||||
array_push(session->summary, ((StackSummaryEntry){
|
array_push(session->summary, ((StackSummaryEntry){
|
||||||
.position = iterator->node->position,
|
.position = iterator->node->position,
|
||||||
|
|
@ -610,12 +698,9 @@ forceinline StackAction summarize_stack_callback(void *payload, const StackItera
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_depth) {
|
void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_depth) {
|
||||||
SummarizeStackSession session = {
|
SummarizeStackSession session = {.summary = ts_malloc(sizeof(StackSummary)), .max_depth = max_depth};
|
||||||
.summary = ts_malloc(sizeof(StackSummary)),
|
|
||||||
.max_depth = max_depth
|
|
||||||
};
|
|
||||||
array_init(session.summary);
|
array_init(session.summary);
|
||||||
stack__iter(self, version, summarize_stack_callback, &session, -1);
|
stack__iter(self, version, summarize_stack_callback, &session, -1, NULL);
|
||||||
StackHead *head = &self->heads.contents[version];
|
StackHead *head = &self->heads.contents[version];
|
||||||
if (head->summary) {
|
if (head->summary) {
|
||||||
array_delete(head->summary);
|
array_delete(head->summary);
|
||||||
|
|
@ -635,17 +720,15 @@ int ts_stack_dynamic_precedence(Stack *self, StackVersion version) {
|
||||||
bool ts_stack_has_advanced_since_error(const Stack *self, StackVersion version) {
|
bool ts_stack_has_advanced_since_error(const Stack *self, StackVersion version) {
|
||||||
const StackHead *head = array_get(&self->heads, version);
|
const StackHead *head = array_get(&self->heads, version);
|
||||||
const StackNode *node = head->node;
|
const StackNode *node = head->node;
|
||||||
if (node->error_cost == 0) return true;
|
if (node->error_cost == 0)
|
||||||
|
return true;
|
||||||
while (node) {
|
while (node) {
|
||||||
if (node->link_count > 0) {
|
if (node->link_count > 0) {
|
||||||
Subtree subtree = node->links[0].subtree;
|
Subtree subtree = node->links[0].subtree;
|
||||||
if (subtree.ptr) {
|
if (subtree.ptr) {
|
||||||
if (ts_subtree_total_bytes(subtree) > 0) {
|
if (ts_subtree_total_bytes(subtree) > 0) {
|
||||||
return true;
|
return true;
|
||||||
} else if (
|
} else if (node->node_count > head->node_count_at_last_error && ts_subtree_error_cost(subtree) == 0) {
|
||||||
node->node_count > head->node_count_at_last_error &&
|
|
||||||
ts_subtree_error_cost(subtree) == 0
|
|
||||||
) {
|
|
||||||
node = node->links[0].node;
|
node = node->links[0].node;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -662,7 +745,8 @@ void ts_stack_remove_version(Stack *self, StackVersion version) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2) {
|
void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2) {
|
||||||
if (v1 == v2) return;
|
if (v1 == v2)
|
||||||
|
return;
|
||||||
assert(v2 < v1);
|
assert(v2 < v1);
|
||||||
assert((uint32_t)v1 < self->heads.size);
|
assert((uint32_t)v1 < self->heads.size);
|
||||||
StackHead *source_head = &self->heads.contents[v1];
|
StackHead *source_head = &self->heads.contents[v1];
|
||||||
|
|
@ -687,13 +771,15 @@ StackVersion ts_stack_copy_version(Stack *self, StackVersion version) {
|
||||||
array_push(&self->heads, self->heads.contents[version]);
|
array_push(&self->heads, self->heads.contents[version]);
|
||||||
StackHead *head = array_back(&self->heads);
|
StackHead *head = array_back(&self->heads);
|
||||||
stack_node_retain(head->node);
|
stack_node_retain(head->node);
|
||||||
if (head->last_external_token.ptr) ts_subtree_retain(head->last_external_token);
|
if (head->last_external_token.ptr)
|
||||||
|
ts_subtree_retain(head->last_external_token);
|
||||||
head->summary = NULL;
|
head->summary = NULL;
|
||||||
return self->heads.size - 1;
|
return self->heads.size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2) {
|
bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2) {
|
||||||
if (!ts_stack_can_merge(self, version1, version2)) return false;
|
if (!ts_stack_can_merge(self, version1, version2))
|
||||||
|
return false;
|
||||||
StackHead *head1 = &self->heads.contents[version1];
|
StackHead *head1 = &self->heads.contents[version1];
|
||||||
StackHead *head2 = &self->heads.contents[version2];
|
StackHead *head2 = &self->heads.contents[version2];
|
||||||
for (uint32_t i = 0; i < head2->node->link_count; i++) {
|
for (uint32_t i = 0; i < head2->node->link_count; i++) {
|
||||||
|
|
@ -709,18 +795,13 @@ bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2) {
|
||||||
bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2) {
|
bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2) {
|
||||||
StackHead *head1 = &self->heads.contents[version1];
|
StackHead *head1 = &self->heads.contents[version1];
|
||||||
StackHead *head2 = &self->heads.contents[version2];
|
StackHead *head2 = &self->heads.contents[version2];
|
||||||
return
|
return head1->status == StackStatusActive && head2->status == StackStatusActive &&
|
||||||
head1->status == StackStatusActive &&
|
head1->node->state == head2->node->state && head1->node->position.bytes == head2->node->position.bytes &&
|
||||||
head2->status == StackStatusActive &&
|
|
||||||
head1->node->state == head2->node->state &&
|
|
||||||
head1->node->position.bytes == head2->node->position.bytes &&
|
|
||||||
head1->node->error_cost == head2->node->error_cost &&
|
head1->node->error_cost == head2->node->error_cost &&
|
||||||
ts_subtree_external_scanner_state_eq(head1->last_external_token, head2->last_external_token);
|
ts_subtree_external_scanner_state_eq(head1->last_external_token, head2->last_external_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_stack_halt(Stack *self, StackVersion version) {
|
void ts_stack_halt(Stack *self, StackVersion version) { array_get(&self->heads, version)->status = StackStatusHalted; }
|
||||||
array_get(&self->heads, version)->status = StackStatusHalted;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ts_stack_pause(Stack *self, StackVersion version, Subtree lookahead) {
|
void ts_stack_pause(Stack *self, StackVersion version, Subtree lookahead) {
|
||||||
StackHead *head = array_get(&self->heads, version);
|
StackHead *head = array_get(&self->heads, version);
|
||||||
|
|
@ -766,7 +847,8 @@ void ts_stack_clear(Stack *self) {
|
||||||
|
|
||||||
bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f) {
|
bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f) {
|
||||||
array_reserve(&self->iterators, 32);
|
array_reserve(&self->iterators, 32);
|
||||||
if (!f) f = stderr;
|
if (!f)
|
||||||
|
f = stderr;
|
||||||
|
|
||||||
fprintf(f, "digraph stack {\n");
|
fprintf(f, "digraph stack {\n");
|
||||||
fprintf(f, "rankdir=\"RL\";\n");
|
fprintf(f, "rankdir=\"RL\";\n");
|
||||||
|
|
@ -777,7 +859,8 @@ bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f)
|
||||||
array_clear(&self->iterators);
|
array_clear(&self->iterators);
|
||||||
for (uint32_t i = 0; i < self->heads.size; i++) {
|
for (uint32_t i = 0; i < self->heads.size; i++) {
|
||||||
StackHead *head = &self->heads.contents[i];
|
StackHead *head = &self->heads.contents[i];
|
||||||
if (head->status == StackStatusHalted) continue;
|
if (head->status == StackStatusHalted)
|
||||||
|
continue;
|
||||||
|
|
||||||
fprintf(f, "node_head_%u [shape=none, label=\"\"]\n", i);
|
fprintf(f, "node_head_%u [shape=none, label=\"\"]\n", i);
|
||||||
fprintf(f, "node_head_%u -> node_%p [", i, (void *)head->node);
|
fprintf(f, "node_head_%u -> node_%p [", i, (void *)head->node);
|
||||||
|
|
@ -785,29 +868,25 @@ bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f)
|
||||||
if (head->status == StackStatusPaused) {
|
if (head->status == StackStatusPaused) {
|
||||||
fprintf(f, "color=red ");
|
fprintf(f, "color=red ");
|
||||||
}
|
}
|
||||||
fprintf(f,
|
fprintf(f, "label=%u, fontcolor=blue, weight=10000, labeltooltip=\"node_count: %u\nerror_cost: %u", i,
|
||||||
"label=%u, fontcolor=blue, weight=10000, labeltooltip=\"node_count: %u\nerror_cost: %u",
|
ts_stack_node_count_since_error(self, i), ts_stack_error_cost(self, i));
|
||||||
i,
|
|
||||||
ts_stack_node_count_since_error(self, i),
|
|
||||||
ts_stack_error_cost(self, i)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (head->summary) {
|
if (head->summary) {
|
||||||
fprintf(f, "\nsummary:");
|
fprintf(f, "\nsummary:");
|
||||||
for (uint32_t j = 0; j < head->summary->size; j++) fprintf(f, " %u", head->summary->contents[j].state);
|
for (uint32_t j = 0; j < head->summary->size; j++)
|
||||||
|
fprintf(f, " %u", head->summary->contents[j].state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (head->last_external_token.ptr) {
|
if (head->last_external_token.ptr) {
|
||||||
const ExternalScannerState *state = &head->last_external_token.ptr->external_scanner_state;
|
const ExternalScannerState *state = &head->last_external_token.ptr->external_scanner_state;
|
||||||
const char *data = ts_external_scanner_state_data(state);
|
const char *data = ts_external_scanner_state_data(state);
|
||||||
fprintf(f, "\nexternal_scanner_state:");
|
fprintf(f, "\nexternal_scanner_state:");
|
||||||
for (uint32_t j = 0; j < state->length; j++) fprintf(f, " %2X", data[j]);
|
for (uint32_t j = 0; j < state->length; j++)
|
||||||
|
fprintf(f, " %2X", data[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "\"]\n");
|
fprintf(f, "\"]\n");
|
||||||
array_push(&self->iterators, ((StackIterator) {
|
array_push(&self->iterators, ((StackIterator){.node = head->node}));
|
||||||
.node = head->node
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool all_iterators_done = false;
|
bool all_iterators_done = false;
|
||||||
|
|
@ -825,53 +904,66 @@ bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node) continue;
|
if (!node)
|
||||||
|
continue;
|
||||||
all_iterators_done = false;
|
all_iterators_done = false;
|
||||||
|
|
||||||
fprintf(f, "node_%p [", (void *)node);
|
fprintf(f, "node_%p [", (void *)node);
|
||||||
if (node->state == ERROR_STATE) {
|
if (node->state == ERROR_STATE) {
|
||||||
fprintf(f, "label=\"?\"");
|
fprintf(f, "label=\"?\"");
|
||||||
} else if (
|
} else if (node->link_count == 1 && node->links[0].subtree.ptr &&
|
||||||
node->link_count == 1 &&
|
ts_subtree_extra(node->links[0].subtree)) {
|
||||||
node->links[0].subtree.ptr &&
|
|
||||||
ts_subtree_extra(node->links[0].subtree)
|
|
||||||
) {
|
|
||||||
fprintf(f, "shape=point margin=0 label=\"\"");
|
fprintf(f, "shape=point margin=0 label=\"\"");
|
||||||
} else {
|
} else {
|
||||||
fprintf(f, "label=\"%d\"", node->state);
|
fprintf(f, "label=\"%d\"", node->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(
|
fprintf(f, " tooltip=\"position: %u,%u\nnode_count:%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",
|
||||||
f,
|
node->position.extent.row + 1, node->position.extent.column, node->node_count, node->error_cost,
|
||||||
" tooltip=\"position: %u,%u\nnode_count:%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",
|
node->dynamic_precedence);
|
||||||
node->position.extent.row + 1,
|
|
||||||
node->position.extent.column,
|
|
||||||
node->node_count,
|
|
||||||
node->error_cost,
|
|
||||||
node->dynamic_precedence
|
|
||||||
);
|
|
||||||
|
|
||||||
for (int j = 0; j < node->link_count; j++) {
|
for (int j = 0; j < node->link_count; j++) {
|
||||||
StackLink link = node->links[j];
|
StackLink link = node->links[j];
|
||||||
fprintf(f, "node_%p -> node_%p [", (void *)node, (void *)link.node);
|
fprintf(f, "node_%p -> node_%p [", (void *)node, (void *)link.node);
|
||||||
if (link.is_pending) fprintf(f, "style=dashed ");
|
if (link.is_pending)
|
||||||
if (link.subtree.ptr && ts_subtree_extra(link.subtree)) fprintf(f, "fontcolor=gray ");
|
fprintf(f, "style=dashed ");
|
||||||
|
if (link.subtree.ptr && ts_subtree_extra(link.subtree))
|
||||||
|
fprintf(f, "fontcolor=gray ");
|
||||||
|
|
||||||
if (!link.subtree.ptr) {
|
if (!link.subtree.ptr) {
|
||||||
fprintf(f, "color=red");
|
fprintf(f, "color=red");
|
||||||
} else {
|
} else {
|
||||||
fprintf(f, "label=\"");
|
fprintf(f, "label=\"");
|
||||||
bool quoted = ts_subtree_visible(link.subtree) && !ts_subtree_named(link.subtree);
|
bool quoted = ts_subtree_visible(link.subtree) && !ts_subtree_named(link.subtree);
|
||||||
if (quoted) fprintf(f, "'");
|
if (quoted)
|
||||||
|
fprintf(f, "'");
|
||||||
ts_language_write_symbol_as_dot_string(language, f, ts_subtree_symbol(link.subtree));
|
ts_language_write_symbol_as_dot_string(language, f, ts_subtree_symbol(link.subtree));
|
||||||
if (quoted) fprintf(f, "'");
|
printf("[1]ts_subtree_error_cost(link.subtree)=%u\n", ts_subtree_error_cost(link.subtree));
|
||||||
|
if (quoted)
|
||||||
|
fprintf(f, "'");
|
||||||
fprintf(f, "\"");
|
fprintf(f, "\"");
|
||||||
fprintf(
|
fprintf(f, "labeltooltip=\"ptr: %p\nerror_cost: %u\ndynamic_precedence: %" PRId32,
|
||||||
f,
|
(void *)link.subtree.ptr, ts_subtree_error_cost(link.subtree),
|
||||||
"labeltooltip=\"error_cost: %u\ndynamic_precedence: %" PRId32 "\"",
|
ts_subtree_dynamic_precedence(link.subtree));
|
||||||
ts_subtree_error_cost(link.subtree),
|
if (ts_subtree_is_error(link.subtree) && ts_subtree_child_count(link.subtree) == 0 &&
|
||||||
ts_subtree_dynamic_precedence(link.subtree)
|
link.subtree.ptr->lookahead_char != 0) {
|
||||||
);
|
fprintf(f, "\ncharacter: '%c'", link.subtree.ptr->lookahead_char);
|
||||||
|
} else {
|
||||||
|
fprintf(f, "\nno character");
|
||||||
|
}
|
||||||
|
if (link.subtree.data.is_inline) {
|
||||||
|
fprintf(f, "\nis_inline:%d", link.subtree.data.is_inline);
|
||||||
|
} else {
|
||||||
|
fprintf(f, "\nog_ptr:%p", (void *)link.subtree.ptr->og_ptr);
|
||||||
|
}
|
||||||
|
fprintf(f, "\"");
|
||||||
|
if (ts_subtree_error_cost(link.subtree) == 500 &&
|
||||||
|
ts_language_symbol_name(language, ts_subtree_symbol(link.subtree)) != NULL) {
|
||||||
|
printf("ptr to target stack tree node: %p\n", (void *)link.subtree.ptr);
|
||||||
|
} else if (ts_subtree_error_cost(link.subtree) == 0 &&
|
||||||
|
ts_language_symbol_name(language, ts_subtree_symbol(link.subtree)) != NULL) {
|
||||||
|
printf("ptr to bad target stack tree node: %p\n", (void *)link.subtree.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "];\n");
|
fprintf(f, "];\n");
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ extern "C" {
|
||||||
|
|
||||||
#include "./array.h"
|
#include "./array.h"
|
||||||
#include "./subtree.h"
|
#include "./subtree.h"
|
||||||
|
#include "./lexer.h"
|
||||||
#include "./error_costs.h"
|
#include "./error_costs.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
@ -29,7 +30,7 @@ typedef struct {
|
||||||
typedef Array(StackSummaryEntry) StackSummary;
|
typedef Array(StackSummaryEntry) StackSummary;
|
||||||
|
|
||||||
// Create a stack.
|
// Create a stack.
|
||||||
Stack *ts_stack_new(SubtreePool *);
|
Stack *ts_stack_new(SubtreePool *, const TSLanguage*);
|
||||||
|
|
||||||
// Release the memory reserved for a given stack.
|
// Release the memory reserved for a given stack.
|
||||||
void ts_stack_delete(Stack *);
|
void ts_stack_delete(Stack *);
|
||||||
|
|
@ -47,6 +48,10 @@ Subtree ts_stack_last_external_token(const Stack *, StackVersion);
|
||||||
// Set the last external token associated with a given version of the stack.
|
// Set the last external token associated with a given version of the stack.
|
||||||
void ts_stack_set_last_external_token(Stack *, StackVersion, Subtree );
|
void ts_stack_set_last_external_token(Stack *, StackVersion, Subtree );
|
||||||
|
|
||||||
|
void ts_stack_set_language(Stack *self, const TSLanguage *language);
|
||||||
|
|
||||||
|
void ts_stack_set_lexer(Stack *self, Lexer *lexer);
|
||||||
|
|
||||||
// Get the position of the given version of the stack within the document.
|
// Get the position of the given version of the stack within the document.
|
||||||
Length ts_stack_position(const Stack *, StackVersion);
|
Length ts_stack_position(const Stack *, StackVersion);
|
||||||
|
|
||||||
|
|
@ -55,7 +60,7 @@ Length ts_stack_position(const Stack *, StackVersion);
|
||||||
// This transfers ownership of the tree to the Stack. Callers that
|
// This transfers ownership of the tree to the Stack. Callers that
|
||||||
// need to retain ownership of the tree for their own purposes should
|
// need to retain ownership of the tree for their own purposes should
|
||||||
// first retain the tree.
|
// first retain the tree.
|
||||||
void ts_stack_push(Stack *, StackVersion, Subtree , bool, TSStateId);
|
void ts_stack_push(Stack *, StackVersion, Subtree , bool, TSStateId, const TSLanguage*);
|
||||||
|
|
||||||
// Pop the given number of entries from the given version of the stack. This
|
// Pop the given number of entries from the given version of the stack. This
|
||||||
// operation can increase the number of stack versions by revealing multiple
|
// operation can increase the number of stack versions by revealing multiple
|
||||||
|
|
@ -71,7 +76,7 @@ SubtreeArray ts_stack_pop_error(Stack *, StackVersion);
|
||||||
StackSliceArray ts_stack_pop_pending(Stack *, StackVersion);
|
StackSliceArray ts_stack_pop_pending(Stack *, StackVersion);
|
||||||
|
|
||||||
// Remove any all trees from the given version of the stack.
|
// Remove any all trees from the given version of the stack.
|
||||||
StackSliceArray ts_stack_pop_all(Stack *, StackVersion);
|
StackSliceArray ts_stack_pop_all(Stack *, StackVersion, FILE*);
|
||||||
|
|
||||||
// Get the maximum number of tree nodes reachable from this version of the stack
|
// Get the maximum number of tree nodes reachable from this version of the stack
|
||||||
// since the last error was detected.
|
// since the last error was detected.
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ typedef struct {
|
||||||
#define TS_MAX_INLINE_TREE_LENGTH UINT8_MAX
|
#define TS_MAX_INLINE_TREE_LENGTH UINT8_MAX
|
||||||
#define TS_MAX_TREE_POOL_SIZE 32
|
#define TS_MAX_TREE_POOL_SIZE 32
|
||||||
|
|
||||||
|
|
||||||
// ExternalScannerState
|
// ExternalScannerState
|
||||||
|
|
||||||
void ts_external_scanner_state_init(ExternalScannerState *self, const char *data, unsigned length) {
|
void ts_external_scanner_state_init(ExternalScannerState *self, const char *data, unsigned length) {
|
||||||
|
|
@ -196,8 +197,10 @@ Subtree ts_subtree_new_leaf(
|
||||||
}};
|
}};
|
||||||
} else {
|
} else {
|
||||||
SubtreeHeapData *data = ts_subtree_pool_allocate(pool);
|
SubtreeHeapData *data = ts_subtree_pool_allocate(pool);
|
||||||
|
printf("[1] ALLOCATED %p\n", (void *)data);
|
||||||
*data = (SubtreeHeapData) {
|
*data = (SubtreeHeapData) {
|
||||||
.ref_count = 1,
|
.ref_count = 1,
|
||||||
|
.og_ptr = (size_t)data,
|
||||||
.padding = padding,
|
.padding = padding,
|
||||||
.size = size,
|
.size = size,
|
||||||
.lookahead_bytes = lookahead_bytes,
|
.lookahead_bytes = lookahead_bytes,
|
||||||
|
|
@ -272,6 +275,7 @@ MutableSubtree ts_subtree_clone(Subtree self) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
result->ref_count = 1;
|
result->ref_count = 1;
|
||||||
|
printf("NEW SUBTREE: %p\n", result);
|
||||||
return (MutableSubtree) {.ptr = result};
|
return (MutableSubtree) {.ptr = result};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,7 +379,10 @@ void ts_subtree_summarize_children(
|
||||||
|
|
||||||
self.ptr->named_child_count = 0;
|
self.ptr->named_child_count = 0;
|
||||||
self.ptr->visible_child_count = 0;
|
self.ptr->visible_child_count = 0;
|
||||||
|
if (!ts_subtree_is_error(ts_subtree_from_mut(self))) {
|
||||||
|
printf("SET 0: %s\n", ts_language_symbol_name(language, self.ptr->symbol));
|
||||||
self.ptr->error_cost = 0;
|
self.ptr->error_cost = 0;
|
||||||
|
}
|
||||||
self.ptr->repeat_depth = 0;
|
self.ptr->repeat_depth = 0;
|
||||||
self.ptr->visible_descendant_count = 0;
|
self.ptr->visible_descendant_count = 0;
|
||||||
self.ptr->has_external_tokens = false;
|
self.ptr->has_external_tokens = false;
|
||||||
|
|
@ -422,16 +429,27 @@ void ts_subtree_summarize_children(
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t grandchild_count = ts_subtree_child_count(child);
|
uint32_t grandchild_count = ts_subtree_child_count(child);
|
||||||
|
printf("HI: %s\n", ts_language_symbol_name(language, self.ptr->symbol));
|
||||||
if (
|
if (
|
||||||
self.ptr->symbol == ts_builtin_sym_error ||
|
self.ptr->symbol == ts_builtin_sym_error ||
|
||||||
self.ptr->symbol == ts_builtin_sym_error_repeat
|
self.ptr->symbol == ts_builtin_sym_error_repeat
|
||||||
) {
|
) {
|
||||||
|
printf("THE FIRST BLOCK\n");
|
||||||
if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {
|
if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {
|
||||||
if (ts_subtree_visible(child)) {
|
if (ts_subtree_visible(child)) {
|
||||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;
|
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;
|
||||||
} else if (grandchild_count > 0) {
|
} else if (grandchild_count > 0) {
|
||||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;
|
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
printf("FALSE BLOCK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ts_subtree_is_error(child) && grandchild_count == 0) {
|
||||||
|
MutableSubtree child_mut = ts_subtree_to_mut_unsafe(child);
|
||||||
|
child_mut.ptr->error_cost = ERROR_COST_PER_RECOVERY +
|
||||||
|
ERROR_COST_PER_SKIPPED_CHAR * child.ptr->size.bytes +
|
||||||
|
ERROR_COST_PER_SKIPPED_LINE * child.ptr->size.extent.row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -465,10 +483,13 @@ void ts_subtree_summarize_children(
|
||||||
|
|
||||||
self.ptr->lookahead_bytes = lookahead_end_byte - self.ptr->size.bytes - self.ptr->padding.bytes;
|
self.ptr->lookahead_bytes = lookahead_end_byte - self.ptr->size.bytes - self.ptr->padding.bytes;
|
||||||
|
|
||||||
|
printf("HI 2: %d\n", self.ptr->symbol);
|
||||||
|
printf("HI 2: %s\n", ts_language_symbol_name(language, self.ptr->symbol));
|
||||||
if (
|
if (
|
||||||
self.ptr->symbol == ts_builtin_sym_error ||
|
self.ptr->symbol == ts_builtin_sym_error ||
|
||||||
self.ptr->symbol == ts_builtin_sym_error_repeat
|
self.ptr->symbol == ts_builtin_sym_error_repeat
|
||||||
) {
|
) {
|
||||||
|
printf("HI 3\n");
|
||||||
self.ptr->error_cost +=
|
self.ptr->error_cost +=
|
||||||
ERROR_COST_PER_RECOVERY +
|
ERROR_COST_PER_RECOVERY +
|
||||||
ERROR_COST_PER_SKIPPED_CHAR * self.ptr->size.bytes +
|
ERROR_COST_PER_SKIPPED_CHAR * self.ptr->size.bytes +
|
||||||
|
|
@ -519,9 +540,10 @@ MutableSubtree ts_subtree_new_node(
|
||||||
children->capacity = (uint32_t)(new_byte_size / sizeof(Subtree));
|
children->capacity = (uint32_t)(new_byte_size / sizeof(Subtree));
|
||||||
}
|
}
|
||||||
SubtreeHeapData *data = (SubtreeHeapData *)&children->contents[children->size];
|
SubtreeHeapData *data = (SubtreeHeapData *)&children->contents[children->size];
|
||||||
|
printf("[0]ALLOCATED %p\n", (void *)data);
|
||||||
*data = (SubtreeHeapData) {
|
*data = (SubtreeHeapData) {
|
||||||
.ref_count = 1,
|
.ref_count = 1,
|
||||||
|
.og_ptr = (size_t)data,
|
||||||
.symbol = symbol,
|
.symbol = symbol,
|
||||||
.child_count = children->size,
|
.child_count = children->size,
|
||||||
.visible = metadata.visible,
|
.visible = metadata.visible,
|
||||||
|
|
@ -538,6 +560,11 @@ MutableSubtree ts_subtree_new_node(
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
MutableSubtree result = {.ptr = data};
|
MutableSubtree result = {.ptr = data};
|
||||||
|
if (symbol == ts_builtin_sym_error_repeat) {
|
||||||
|
printf("ptr: %p\n", (void *)result.ptr);
|
||||||
|
} else if (symbol == ts_builtin_sym_error) {
|
||||||
|
printf("ptr: %p\n", (void *)result.ptr);
|
||||||
|
}
|
||||||
ts_subtree_summarize_children(result, language);
|
ts_subtree_summarize_children(result, language);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -981,6 +1008,7 @@ void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset,
|
||||||
uint32_t end_offset = start_offset + ts_subtree_total_bytes(*self);
|
uint32_t end_offset = start_offset + ts_subtree_total_bytes(*self);
|
||||||
fprintf(f, "tree_%p [label=\"", (void *)self);
|
fprintf(f, "tree_%p [label=\"", (void *)self);
|
||||||
ts_language_write_symbol_as_dot_string(language, f, symbol);
|
ts_language_write_symbol_as_dot_string(language, f, symbol);
|
||||||
|
printf("[0]ts_subtree_error_cost(link.subtree)=%u\n", ts_subtree_error_cost(*self));
|
||||||
fprintf(f, "\"");
|
fprintf(f, "\"");
|
||||||
|
|
||||||
if (ts_subtree_child_count(*self) == 0) fprintf(f, ", shape=plaintext");
|
if (ts_subtree_child_count(*self) == 0) fprintf(f, ", shape=plaintext");
|
||||||
|
|
@ -994,7 +1022,8 @@ void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset,
|
||||||
"depends-on-column: %u\n"
|
"depends-on-column: %u\n"
|
||||||
"descendant-count: %u\n"
|
"descendant-count: %u\n"
|
||||||
"repeat-depth: %u\n"
|
"repeat-depth: %u\n"
|
||||||
"lookahead-bytes: %u",
|
"lookahead-bytes: %u\n"
|
||||||
|
"ptr: %p",
|
||||||
start_offset, end_offset,
|
start_offset, end_offset,
|
||||||
ts_subtree_parse_state(*self),
|
ts_subtree_parse_state(*self),
|
||||||
ts_subtree_error_cost(*self),
|
ts_subtree_error_cost(*self),
|
||||||
|
|
@ -1002,11 +1031,23 @@ void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset,
|
||||||
ts_subtree_depends_on_column(*self),
|
ts_subtree_depends_on_column(*self),
|
||||||
ts_subtree_visible_descendant_count(*self),
|
ts_subtree_visible_descendant_count(*self),
|
||||||
ts_subtree_repeat_depth(*self),
|
ts_subtree_repeat_depth(*self),
|
||||||
ts_subtree_lookahead_bytes(*self)
|
ts_subtree_lookahead_bytes(*self),
|
||||||
|
(void*)self->ptr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (self->data.is_inline) {
|
||||||
|
fprintf(f, "\nis_inline: %d", self->data.is_inline);
|
||||||
|
} else {
|
||||||
|
fprintf(f, "\nog_ptr: %p", (void*)self->ptr->og_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
if (ts_subtree_is_error(*self) && ts_subtree_child_count(*self) == 0 && self->ptr->lookahead_char != 0) {
|
if (ts_subtree_is_error(*self) && ts_subtree_child_count(*self) == 0 && self->ptr->lookahead_char != 0) {
|
||||||
fprintf(f, "\ncharacter: '%c'", self->ptr->lookahead_char);
|
fprintf(f, "\ncharacter: '%c'", self->ptr->lookahead_char);
|
||||||
|
printf("ptr %p is error with an error cost of %d\n", (void*)self->ptr, ts_subtree_error_cost(*self));
|
||||||
|
printf("branch [1] %d %p\n", ts_subtree_missing(*self), self->ptr);
|
||||||
|
printf("branch [2] %d\n", self->data.is_inline);
|
||||||
|
} else {
|
||||||
|
printf("no call!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "\"]\n");
|
fprintf(f, "\"]\n");
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ struct SubtreeInlineData {
|
||||||
// the inline representation.
|
// the inline representation.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
volatile uint32_t ref_count;
|
volatile uint32_t ref_count;
|
||||||
|
size_t og_ptr;
|
||||||
Length padding;
|
Length padding;
|
||||||
Length size;
|
Length size;
|
||||||
uint32_t lookahead_bytes;
|
uint32_t lookahead_bytes;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue