Clean up stack
This commit is contained in:
parent
1850951b4f
commit
5a34d74702
5 changed files with 117 additions and 116 deletions
|
|
@ -102,7 +102,7 @@ describe("Stack", [&]() {
|
|||
/*
|
||||
* . <--0-- A*
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateA, trees[0]);
|
||||
ts_stack_push(stack, 0, trees[0], stateA);
|
||||
const StackEntry *entry1 = ts_stack_head(stack, 0);
|
||||
AssertThat(*entry1, Equals<StackEntry>({stateA, tree_len}));
|
||||
AssertThat(ts_stack_entry_next_count(entry1), Equals(1));
|
||||
|
|
@ -111,7 +111,7 @@ describe("Stack", [&]() {
|
|||
/*
|
||||
* . <--0-- A <--1-- B*
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateB, trees[1]);
|
||||
ts_stack_push(stack, 0, trees[1], stateB);
|
||||
const StackEntry *entry2 = ts_stack_head(stack, 0);
|
||||
AssertThat(*entry2, Equals<StackEntry>({stateB, tree_len * 2}));
|
||||
AssertThat(ts_stack_entry_next_count(entry2), Equals(1));
|
||||
|
|
@ -120,7 +120,7 @@ describe("Stack", [&]() {
|
|||
/*
|
||||
* . <--0-- A <--1-- B <--2-- C*
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateC, trees[2]);
|
||||
ts_stack_push(stack, 0, trees[2], stateC);
|
||||
const StackEntry *entry3 = ts_stack_head(stack, 0);
|
||||
AssertThat(*entry3, Equals<StackEntry>({stateC, tree_len * 3}));
|
||||
AssertThat(ts_stack_entry_next_count(entry3), Equals(1));
|
||||
|
|
@ -133,9 +133,9 @@ describe("Stack", [&]() {
|
|||
/*
|
||||
* . <--0-- A <--1-- B <--2-- C*
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateA, trees[0]);
|
||||
ts_stack_push(stack, 0, stateB, trees[1]);
|
||||
ts_stack_push(stack, 0, stateC, trees[2]);
|
||||
ts_stack_push(stack, 0, trees[0], stateA);
|
||||
ts_stack_push(stack, 0, trees[1], stateB);
|
||||
ts_stack_push(stack, 0, trees[2], stateC);
|
||||
});
|
||||
|
||||
it("removes the given number of nodes from the stack", [&]() {
|
||||
|
|
@ -198,9 +198,9 @@ describe("Stack", [&]() {
|
|||
/*
|
||||
* . <--0-- A <--1-- B <--2-- C*
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateA, trees[0]);
|
||||
ts_stack_push(stack, 0, stateB, trees[1]);
|
||||
ts_stack_push(stack, 0, stateC, trees[2]);
|
||||
ts_stack_push(stack, 0, trees[0], stateA);
|
||||
ts_stack_push(stack, 0, trees[1], stateB);
|
||||
ts_stack_push(stack, 0, trees[2], stateC);
|
||||
|
||||
/*
|
||||
* . <--0-- A <--1-- B <--2-- C*
|
||||
|
|
@ -217,7 +217,7 @@ describe("Stack", [&]() {
|
|||
* ↑
|
||||
* `-*
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateD, trees[3]);
|
||||
ts_stack_push(stack, 0, trees[3], stateD);
|
||||
StackPopResultArray pop_results = ts_stack_pop(stack, 1, 1, false);
|
||||
|
||||
AssertThat(ts_stack_head_count(stack), Equals(2));
|
||||
|
|
@ -233,8 +233,8 @@ describe("Stack", [&]() {
|
|||
* ↑
|
||||
* `---4--- E <--5-- F*
|
||||
*/
|
||||
ts_stack_push(stack, 1, stateE, trees[4]);
|
||||
ts_stack_push(stack, 1, stateF, trees[5]);
|
||||
ts_stack_push(stack, 1, trees[4], stateE);
|
||||
ts_stack_push(stack, 1, trees[5], stateF);
|
||||
|
||||
AssertThat(ts_stack_head_count(stack), Equals(2));
|
||||
AssertThat(*ts_stack_head(stack, 0), Equals<StackEntry>({stateD, tree_len * 4}));
|
||||
|
|
@ -249,13 +249,13 @@ describe("Stack", [&]() {
|
|||
* ↑
|
||||
* `---4--- E <--5-- F*
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateA, trees[0]);
|
||||
ts_stack_push(stack, 0, stateB, trees[1]);
|
||||
ts_stack_push(stack, 0, trees[0], stateA);
|
||||
ts_stack_push(stack, 0, trees[1], stateB);
|
||||
ts_stack_split(stack, 0);
|
||||
ts_stack_push(stack, 0, stateC, trees[2]);
|
||||
ts_stack_push(stack, 0, stateD, trees[3]);
|
||||
ts_stack_push(stack, 1, stateE, trees[4]);
|
||||
ts_stack_push(stack, 1, stateF, trees[5]);
|
||||
ts_stack_push(stack, 0, trees[2], stateC);
|
||||
ts_stack_push(stack, 0, trees[3], stateD);
|
||||
ts_stack_push(stack, 1, trees[4], stateE);
|
||||
ts_stack_push(stack, 1, trees[5], stateF);
|
||||
|
||||
AssertThat(ts_stack_head_count(stack), Equals(2));
|
||||
AssertThat(*ts_stack_head(stack, 0), Equals<StackEntry>({stateD, tree_len * 4}));
|
||||
|
|
@ -268,8 +268,8 @@ describe("Stack", [&]() {
|
|||
* ^ |
|
||||
* `---4--- E <--5-- F <--7---'
|
||||
*/
|
||||
AssertThat(ts_stack_push(stack, 0, stateG, trees[6]), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, stateG, trees[7]), Equals(StackPushResultMerged));
|
||||
AssertThat(ts_stack_push(stack, 0, trees[6], stateG), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, trees[7], stateG), Equals(StackPushResultMerged));
|
||||
|
||||
AssertThat(ts_stack_head_count(stack), Equals(1));
|
||||
const StackEntry *entry1 = ts_stack_head(stack, 0);
|
||||
|
|
@ -286,16 +286,16 @@ describe("Stack", [&]() {
|
|||
* ↑
|
||||
* `---4--- E <--5-- F <--8-- G*
|
||||
*/
|
||||
AssertThat(ts_stack_push(stack, 0, stateG, trees[6]), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 0, stateH, trees[7]), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, stateG, trees[6]), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 0, trees[6], stateG), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 0, trees[7], stateH), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, trees[6], stateG), Equals(StackPushResultContinued));
|
||||
|
||||
/*
|
||||
* . <--0-- A <--1-- B <--2-- C <--3-- D <--6-- G <--7--H*
|
||||
* ↑ |
|
||||
* `---4--- E <--5-- F <--8---'
|
||||
*/
|
||||
AssertThat(ts_stack_push(stack, 1, stateH, trees[7]), Equals(StackPushResultMerged));
|
||||
AssertThat(ts_stack_push(stack, 1, trees[7], stateH), Equals(StackPushResultMerged));
|
||||
|
||||
AssertThat(ts_stack_head_count(stack), Equals(1));
|
||||
StackEntry *head = ts_stack_head(stack, 0);
|
||||
|
|
@ -321,9 +321,9 @@ describe("Stack", [&]() {
|
|||
*/
|
||||
ts_stack_clear(stack);
|
||||
ts_stack_split(stack, 0);
|
||||
AssertThat(ts_stack_push(stack, 0, stateC, parent), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, stateB, trees[2]), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, stateC, trees[3]), Equals(StackPushResultMerged));
|
||||
AssertThat(ts_stack_push(stack, 0, parent, stateC), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, trees[2], stateB), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 1, trees[3], stateC), Equals(StackPushResultMerged));
|
||||
|
||||
AssertThat(ts_stack_head_count(stack), Equals(1));
|
||||
StackEntry *head = ts_stack_head(stack, 0);
|
||||
|
|
@ -345,15 +345,15 @@ describe("Stack", [&]() {
|
|||
* ^ |
|
||||
* `---5--- F <--6-- G <--7---'
|
||||
*/
|
||||
ts_stack_push(stack, 0, stateA, trees[0]);
|
||||
ts_stack_push(stack, 0, stateB, trees[1]);
|
||||
ts_stack_push(stack, 0, trees[0], stateA);
|
||||
ts_stack_push(stack, 0, trees[1], stateB);
|
||||
ts_stack_split(stack, 0);
|
||||
ts_stack_push(stack, 0, stateC, trees[2]);
|
||||
ts_stack_push(stack, 0, stateD, trees[3]);
|
||||
ts_stack_push(stack, 0, stateE, trees[4]);
|
||||
ts_stack_push(stack, 1, stateF, trees[5]);
|
||||
ts_stack_push(stack, 1, stateG, trees[6]);
|
||||
ts_stack_push(stack, 1, stateE, trees[7]);
|
||||
ts_stack_push(stack, 0, trees[2], stateC);
|
||||
ts_stack_push(stack, 0, trees[3], stateD);
|
||||
ts_stack_push(stack, 0, trees[4], stateE);
|
||||
ts_stack_push(stack, 1, trees[5], stateF);
|
||||
ts_stack_push(stack, 1, trees[6], stateG);
|
||||
ts_stack_push(stack, 1, trees[7], stateE);
|
||||
|
||||
AssertThat(ts_stack_head_count(stack), Equals(1));
|
||||
AssertThat(ts_stack_top_state(stack, 0), Equals(stateE));
|
||||
|
|
@ -395,7 +395,7 @@ describe("Stack", [&]() {
|
|||
* ^ |
|
||||
* `---5--- F <--6-- G <--7---'
|
||||
*/
|
||||
AssertThat(ts_stack_push(stack, 0, stateH, trees[8]), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_push(stack, 0, trees[8], stateH), Equals(StackPushResultContinued));
|
||||
AssertThat(ts_stack_head_count(stack), Equals(1));
|
||||
AssertThat(ts_stack_top_state(stack, 0), Equals(stateH));
|
||||
|
||||
|
|
@ -470,21 +470,21 @@ describe("Stack", [&]() {
|
|||
* `---7--- G <--8-- H <--9---'
|
||||
*/
|
||||
ts_stack_clear(stack);
|
||||
ts_stack_push(stack, 0, stateA, trees[0]);
|
||||
ts_stack_push(stack, 0, trees[0], stateA);
|
||||
ts_stack_split(stack, 0);
|
||||
ts_stack_split(stack, 1);
|
||||
ts_stack_push(stack, 0, stateB, trees[1]);
|
||||
ts_stack_push(stack, 0, stateC, trees[2]);
|
||||
ts_stack_push(stack, 0, stateD, trees[3]);
|
||||
ts_stack_push(stack, 1, stateE, trees[4]);
|
||||
ts_stack_push(stack, 1, stateF, trees[5]);
|
||||
ts_stack_push(stack, 1, stateD, trees[6]);
|
||||
ts_stack_push(stack, 1, stateG, trees[7]);
|
||||
ts_stack_push(stack, 1, stateH, trees[8]);
|
||||
ts_stack_push(stack, 1, stateD, trees[9]);
|
||||
ts_stack_push(stack, 0, trees[1], stateB);
|
||||
ts_stack_push(stack, 0, trees[2], stateC);
|
||||
ts_stack_push(stack, 0, trees[3], stateD);
|
||||
ts_stack_push(stack, 1, trees[4], stateE);
|
||||
ts_stack_push(stack, 1, trees[5], stateF);
|
||||
ts_stack_push(stack, 1, trees[6], stateD);
|
||||
ts_stack_push(stack, 1, trees[7], stateG);
|
||||
ts_stack_push(stack, 1, trees[8], stateH);
|
||||
ts_stack_push(stack, 1, trees[9], stateD);
|
||||
AssertThat(ts_stack_head_count(stack), Equals(1));
|
||||
AssertThat(ts_stack_entry_next_count(ts_stack_head(stack, 0)), Equals(3));
|
||||
ts_stack_push(stack, 0, stateI, trees[10]);
|
||||
ts_stack_push(stack, 0, trees[10], stateI);
|
||||
AssertThat(ts_stack_entry_next_count(ts_stack_head(stack, 0)), Equals(1));
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ extern "C" {
|
|||
|
||||
#define array_delete(self) array__delete((VoidArray *)self)
|
||||
|
||||
#define array_push(self, element) \
|
||||
(((self)->size < (self)->capacity || \
|
||||
#define array_push(self, element) \
|
||||
(((self)->size < (self)->capacity || \
|
||||
array_grow((self), (self)->capacity ? (self)->capacity * 2 : 4)) && \
|
||||
((self)->contents[(self)->size++] = (element), true))
|
||||
|
||||
|
|
|
|||
|
|
@ -94,14 +94,14 @@ static ParseActionResult ts_parser__breakdown_top_of_stack(TSParser *self,
|
|||
LOG("breakdown_push sym:%s, size:%lu", SYM_NAME(last_child->symbol),
|
||||
ts_tree_total_size(last_child).chars);
|
||||
|
||||
last_push = ts_stack_push(self->stack, head_index, state, last_child);
|
||||
last_push = ts_stack_push(self->stack, head_index, last_child, state);
|
||||
if (last_push == StackPushResultFailed)
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (size_t j = 1, count = pop_result.trees.size; j < count; j++) {
|
||||
TSTree *tree = pop_result.trees.contents[j];
|
||||
last_push = ts_stack_push(self->stack, head_index, state, tree);
|
||||
last_push = ts_stack_push(self->stack, head_index, tree, state);
|
||||
if (last_push == StackPushResultFailed)
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -286,7 +286,7 @@ static int ts_parser__select_tree(void *data, TSTree *left, TSTree *right) {
|
|||
static ParseActionResult ts_parser__shift(TSParser *self, int head,
|
||||
TSStateId parse_state,
|
||||
TSTree *lookahead) {
|
||||
switch (ts_stack_push(self->stack, head, parse_state, lookahead)) {
|
||||
switch (ts_stack_push(self->stack, head, lookahead, parse_state)) {
|
||||
case StackPushResultFailed:
|
||||
return FailedToUpdateStackHead;
|
||||
case StackPushResultMerged:
|
||||
|
|
@ -348,8 +348,8 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head,
|
|||
}
|
||||
|
||||
size_t popped_child_count = pop_result.trees.size - trailing_extra_count;
|
||||
parent = ts_tree_make_node(symbol, popped_child_count, pop_result.trees.contents,
|
||||
metadata);
|
||||
parent = ts_tree_make_node(symbol, popped_child_count,
|
||||
pop_result.trees.contents, metadata);
|
||||
if (!parent) {
|
||||
for (size_t i = 0; i < pop_result.trees.size; i++)
|
||||
ts_tree_release(pop_result.trees.contents[i]);
|
||||
|
|
@ -409,7 +409,7 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head,
|
|||
* If the given state already existed at a different head of the stack,
|
||||
* then remove the lookahead state for the head.
|
||||
*/
|
||||
switch (ts_stack_push(self->stack, new_head, state, parent)) {
|
||||
switch (ts_stack_push(self->stack, new_head, parent, state)) {
|
||||
case StackPushResultFailed:
|
||||
ts_tree_release(parent);
|
||||
goto error;
|
||||
|
|
@ -426,7 +426,7 @@ static ParseActionResult ts_parser__reduce(TSParser *self, int head,
|
|||
for (size_t j = 0; j < trailing_extra_count; j++) {
|
||||
size_t index = pop_result.trees.size - trailing_extra_count + j;
|
||||
TSTree *tree = pop_result.trees.contents[index];
|
||||
switch (ts_stack_push(self->stack, new_head, state, tree)) {
|
||||
switch (ts_stack_push(self->stack, new_head, tree, state)) {
|
||||
case StackPushResultFailed:
|
||||
return FailedToUpdateStackHead;
|
||||
case StackPushResultMerged:
|
||||
|
|
@ -812,8 +812,8 @@ TSTree *ts_parser_parse(TSParser *self, TSInput input, TSTree *previous_tree) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
LOG("lookahead sym:(%s,%d), size:%lu", SYM_NAME(lookahead->symbol), lookahead->symbol,
|
||||
ts_tree_total_chars(lookahead));
|
||||
LOG("lookahead sym:(%s,%d), size:%lu", SYM_NAME(lookahead->symbol),
|
||||
lookahead->symbol, ts_tree_total_chars(lookahead));
|
||||
|
||||
switch (ts_parser__consume_lookahead(self, head, lookahead)) {
|
||||
case FailedToUpdateStackHead:
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@ typedef struct {
|
|||
bool is_shared;
|
||||
} PopPath;
|
||||
|
||||
typedef Array(StackNode *) StackNodeArray;
|
||||
|
||||
struct Stack {
|
||||
Array(StackNode *) heads;
|
||||
StackPopResultArray pop_results;
|
||||
Array(PopPath) pop_paths;
|
||||
Array(StackNode *) node_pool;
|
||||
StackNodeArray node_pool;
|
||||
void *tree_selection_payload;
|
||||
TreeSelectionFunction tree_selection_function;
|
||||
};
|
||||
|
|
@ -97,18 +99,18 @@ error:
|
|||
* Section: Reading from the stack
|
||||
*/
|
||||
|
||||
TSStateId ts_stack_top_state(const Stack *self, int head) {
|
||||
StackEntry *entry = ts_stack_head((Stack *)self, head);
|
||||
TSStateId ts_stack_top_state(const Stack *self, int head_index) {
|
||||
StackEntry *entry = ts_stack_head((Stack *)self, head_index);
|
||||
return entry ? entry->state : 0;
|
||||
}
|
||||
|
||||
TSLength ts_stack_top_position(const Stack *self, int head) {
|
||||
StackEntry *entry = ts_stack_head((Stack *)self, head);
|
||||
TSLength ts_stack_top_position(const Stack *self, int head_index) {
|
||||
StackEntry *entry = ts_stack_head((Stack *)self, head_index);
|
||||
return entry ? entry->position : ts_length_zero();
|
||||
}
|
||||
|
||||
StackEntry *ts_stack_head(Stack *self, int head) {
|
||||
StackNode *node = self->heads.contents[head];
|
||||
StackEntry *ts_stack_head(Stack *self, int head_index) {
|
||||
StackNode *node = self->heads.contents[head_index];
|
||||
return node ? &node->entry : NULL;
|
||||
}
|
||||
|
||||
|
|
@ -120,8 +122,8 @@ int ts_stack_entry_next_count(const StackEntry *entry) {
|
|||
return ((const StackNode *)entry)->successor_count;
|
||||
}
|
||||
|
||||
StackEntry *ts_stack_entry_next(const StackEntry *entry, int i) {
|
||||
return &((const StackNode *)entry)->successors[i].node->entry;
|
||||
StackEntry *ts_stack_entry_next(const StackEntry *entry, int successor_index) {
|
||||
return &((const StackNode *)entry)->successors[successor_index].node->entry;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -135,38 +137,34 @@ static void stack_node_retain(StackNode *self) {
|
|||
self->ref_count++;
|
||||
}
|
||||
|
||||
static bool stack_node_release(Stack *self, StackNode *node) {
|
||||
if (!node)
|
||||
return false;
|
||||
assert(node->ref_count != 0);
|
||||
node->ref_count--;
|
||||
if (node->ref_count == 0) {
|
||||
for (int i = 0; i < node->successor_count; i++) {
|
||||
stack_node_release(self, node->successors[i].node);
|
||||
ts_tree_release(node->successors[i].tree);
|
||||
static void stack_node_release(StackNode *self, StackNodeArray *pool) {
|
||||
if (!self)
|
||||
return;
|
||||
assert(self->ref_count != 0);
|
||||
self->ref_count--;
|
||||
if (self->ref_count == 0) {
|
||||
for (int i = 0; i < self->successor_count; i++) {
|
||||
stack_node_release(self->successors[i].node, pool);
|
||||
ts_tree_release(self->successors[i].tree);
|
||||
}
|
||||
|
||||
if (self->node_pool.size >= MAX_NODE_POOL_SIZE)
|
||||
ts_free(node);
|
||||
if (pool->size >= MAX_NODE_POOL_SIZE)
|
||||
ts_free(self);
|
||||
else
|
||||
array_push(&self->node_pool, node);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
array_push(pool, self);
|
||||
}
|
||||
}
|
||||
|
||||
static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state,
|
||||
TSTree *tree) {
|
||||
static StackNode *stack_node_new(StackNode *next, TSTree *tree, TSStateId state,
|
||||
StackNodeArray *pool) {
|
||||
assert(tree->ref_count > 0);
|
||||
StackNode *node;
|
||||
if (self->node_pool.size == 0) {
|
||||
if (pool->size == 0) {
|
||||
node = ts_malloc(sizeof(StackNode));
|
||||
if (!node)
|
||||
return NULL;
|
||||
} else {
|
||||
node = array_pop(&self->node_pool);
|
||||
node = array_pop(pool);
|
||||
}
|
||||
|
||||
ts_tree_retain(tree);
|
||||
|
|
@ -177,7 +175,7 @@ static StackNode *stack_node_new(Stack *self, StackNode *next, TSStateId state,
|
|||
*node = (StackNode){
|
||||
.ref_count = 1,
|
||||
.successor_count = 1,
|
||||
.successors = { {next, tree} },
|
||||
.successors = { { next, tree } },
|
||||
.entry = {.state = state, .position = position },
|
||||
};
|
||||
return node;
|
||||
|
|
@ -219,8 +217,7 @@ static void ts_stack__add_alternative_pop_result(Stack *self,
|
|||
}
|
||||
}
|
||||
|
||||
static void stack_node__add_successor(StackNode *self,
|
||||
TSTree *new_tree,
|
||||
static void stack_node__add_successor(StackNode *self, TSTree *new_tree,
|
||||
StackNode *new_node) {
|
||||
for (int i = 0; i < self->successor_count; i++) {
|
||||
StackLink successor = self->successors[i];
|
||||
|
|
@ -230,8 +227,8 @@ static void stack_node__add_successor(StackNode *self,
|
|||
if (successor.node && new_node &&
|
||||
successor.node->entry.state == new_node->entry.state) {
|
||||
for (int j = 0; j < new_node->successor_count; j++) {
|
||||
stack_node__add_successor(successor.node,
|
||||
new_node->successors[j].tree, new_node->successors[j].node);
|
||||
stack_node__add_successor(successor.node, new_node->successors[j].tree,
|
||||
new_node->successors[j].node);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -241,8 +238,7 @@ static void stack_node__add_successor(StackNode *self,
|
|||
stack_node_retain(new_node);
|
||||
ts_tree_retain(new_tree);
|
||||
self->successors[self->successor_count++] = (StackLink){
|
||||
new_node,
|
||||
new_tree,
|
||||
new_node, new_tree,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -269,7 +265,7 @@ static int ts_stack__find_head(Stack *self, StackNode *node) {
|
|||
|
||||
void ts_stack_remove_head(Stack *self, int head_index) {
|
||||
StackNode *node = *array_get(&self->heads, head_index);
|
||||
stack_node_release(self, node);
|
||||
stack_node_release(node, &self->node_pool);
|
||||
array_erase(&self->heads, head_index);
|
||||
}
|
||||
|
||||
|
|
@ -277,8 +273,8 @@ void ts_stack_remove_head(Stack *self, int head_index) {
|
|||
* Section: Mutating the stack (Public)
|
||||
*/
|
||||
|
||||
StackPushResult ts_stack_push(Stack *self, int head_index, TSStateId state,
|
||||
TSTree *tree) {
|
||||
StackPushResult ts_stack_push(Stack *self, int head_index, TSTree *tree,
|
||||
TSStateId state) {
|
||||
TSLength position = ts_tree_total_size(tree);
|
||||
StackNode *current_head = *array_get(&self->heads, head_index);
|
||||
if (current_head)
|
||||
|
|
@ -295,11 +291,12 @@ StackPushResult ts_stack_push(Stack *self, int head_index, TSStateId state,
|
|||
}
|
||||
}
|
||||
|
||||
StackNode *new_head = stack_node_new(self, current_head, state, tree);
|
||||
StackNode *new_head =
|
||||
stack_node_new(current_head, tree, state, &self->node_pool);
|
||||
if (!new_head)
|
||||
return StackPushResultFailed;
|
||||
|
||||
stack_node_release(self, current_head);
|
||||
stack_node_release(current_head, &self->node_pool);
|
||||
self->heads.contents[head_index] = new_head;
|
||||
return StackPushResultContinued;
|
||||
}
|
||||
|
|
@ -374,7 +371,8 @@ StackPopResultArray ts_stack_pop(Stack *self, int head_index, int child_count,
|
|||
goto error;
|
||||
|
||||
/*
|
||||
* Children that are 'extra' do not count towards the total child count.
|
||||
* Children that are 'extra' do not count towards the total child
|
||||
* count.
|
||||
*/
|
||||
if (successor.tree->extra && !count_extra)
|
||||
next_path->goal_tree_count++;
|
||||
|
|
@ -421,7 +419,7 @@ StackPopResultArray ts_stack_pop(Stack *self, int head_index, int child_count,
|
|||
goto error;
|
||||
}
|
||||
|
||||
stack_node_release(self, previous_head);
|
||||
stack_node_release(previous_head, &self->node_pool);
|
||||
return self->pop_results;
|
||||
|
||||
error:
|
||||
|
|
@ -440,13 +438,13 @@ void ts_stack_shrink(Stack *self, int head_index, int count) {
|
|||
new_head = new_head->successors[0].node;
|
||||
}
|
||||
stack_node_retain(new_head);
|
||||
stack_node_release(self, head);
|
||||
stack_node_release(head, &self->node_pool);
|
||||
self->heads.contents[head_index] = new_head;
|
||||
}
|
||||
|
||||
void ts_stack_clear(Stack *self) {
|
||||
for (size_t i = 0; i < self->heads.size; i++)
|
||||
stack_node_release(self, self->heads.contents[i]);
|
||||
stack_node_release(self->heads.contents[i], &self->node_pool);
|
||||
array_clear(&self->heads);
|
||||
array_push(&self->heads, NULL);
|
||||
}
|
||||
|
|
@ -485,7 +483,7 @@ size_t ts_stack__write_dot_graph(Stack *self, char *string, size_t n,
|
|||
cursor += snprintf(*s, n, "digraph stack {\n");
|
||||
cursor += snprintf(*s, n, "rankdir=\"RL\";\n");
|
||||
|
||||
Array(StackNode *) visited_nodes;
|
||||
Array(StackNode *)visited_nodes;
|
||||
array_init(&visited_nodes);
|
||||
|
||||
array_clear(&self->pop_paths);
|
||||
|
|
@ -493,7 +491,7 @@ size_t ts_stack__write_dot_graph(Stack *self, char *string, size_t n,
|
|||
StackNode *node = self->heads.contents[i];
|
||||
const char *color = COLORS[i % COLOR_COUNT];
|
||||
cursor += snprintf(*s, n, "node_%p [color=%s];\n", node, color);
|
||||
array_push(&self->pop_paths, ((PopPath){ .node = node }));
|
||||
array_push(&self->pop_paths, ((PopPath){.node = node }));
|
||||
}
|
||||
|
||||
bool all_paths_done = false;
|
||||
|
|
@ -515,11 +513,13 @@ size_t ts_stack__write_dot_graph(Stack *self, char *string, size_t n,
|
|||
continue;
|
||||
all_paths_done = false;
|
||||
|
||||
cursor += snprintf(*s, n, "node_%p [label=%d];\n", node, node->entry.state);
|
||||
cursor +=
|
||||
snprintf(*s, n, "node_%p [label=%d];\n", node, node->entry.state);
|
||||
|
||||
for (int j = 0; j < node->successor_count; j++) {
|
||||
StackLink successor = node->successors[j];
|
||||
cursor += snprintf(*s, n, "node_%p -> node_%p [label=\"", node, successor.node);
|
||||
cursor +=
|
||||
snprintf(*s, n, "node_%p -> node_%p [label=\"", node, successor.node);
|
||||
|
||||
const char *name = symbol_names[successor.tree->symbol];
|
||||
for (const char *c = name; *c; c++) {
|
||||
|
|
|
|||
|
|
@ -50,18 +50,18 @@ int ts_stack_head_count(const Stack *);
|
|||
* Get the state at given head of the stack. If the stack is empty, this
|
||||
* returns the initial state (0).
|
||||
*/
|
||||
TSStateId ts_stack_top_state(const Stack *, int head);
|
||||
TSStateId ts_stack_top_state(const Stack *, int head_index);
|
||||
|
||||
/*
|
||||
* Get the position of the given head of the stack. If the stack is empty, this
|
||||
* returns {0, 0}.
|
||||
*/
|
||||
TSLength ts_stack_top_position(const Stack *, int head);
|
||||
TSLength ts_stack_top_position(const Stack *, int head_index);
|
||||
|
||||
/*
|
||||
* Get the entry at the given head of the stack.
|
||||
*/
|
||||
StackEntry *ts_stack_head(Stack *, int head);
|
||||
StackEntry *ts_stack_head(Stack *, int head_index);
|
||||
|
||||
/*
|
||||
* Get the number of successors for the parse stack entry.
|
||||
|
|
@ -71,13 +71,13 @@ int ts_stack_entry_next_count(const StackEntry *);
|
|||
/*
|
||||
* Get the given successor for the parse stack entry.
|
||||
*/
|
||||
StackEntry *ts_stack_entry_next(const StackEntry *, int);
|
||||
StackEntry *ts_stack_entry_next(const StackEntry *, int head_index);
|
||||
|
||||
/*
|
||||
* Push a (tree, state) pair onto the given head of the stack. This could cause
|
||||
* the head to merge with an existing head.
|
||||
*/
|
||||
StackPushResult ts_stack_push(Stack *, int head, TSStateId, TSTree *);
|
||||
StackPushResult ts_stack_push(Stack *, int head_index, TSTree *, TSStateId);
|
||||
|
||||
/*
|
||||
* Pop the given number of entries from the given head of the stack. This
|
||||
|
|
@ -85,24 +85,25 @@ StackPushResult ts_stack_push(Stack *, int head, TSStateId, TSTree *);
|
|||
* which had previously been merged. It returns a struct that indicates the
|
||||
* index of each revealed head and the trees removed from that head.
|
||||
*/
|
||||
StackPopResultArray ts_stack_pop(Stack *, int head, int count, bool count_extra);
|
||||
StackPopResultArray ts_stack_pop(Stack *, int head_index, int count,
|
||||
bool count_extra);
|
||||
|
||||
/*
|
||||
* Remove the given number of entries from the given head of the stack.
|
||||
*/
|
||||
void ts_stack_shrink(Stack *, int head, int count);
|
||||
void ts_stack_shrink(Stack *, int head_index, int count);
|
||||
|
||||
/*
|
||||
* Split the given stack head into two heads, so that the stack can be
|
||||
* transformed from its current state in multiple alternative ways. Returns
|
||||
* the index of the newly-created head.
|
||||
*/
|
||||
int ts_stack_split(Stack *, int head);
|
||||
int ts_stack_split(Stack *, int head_index);
|
||||
|
||||
/*
|
||||
* Remove the given head from the stack.
|
||||
*/
|
||||
void ts_stack_remove_head(Stack *, int head);
|
||||
void ts_stack_remove_head(Stack *, int head_index);
|
||||
|
||||
/*
|
||||
* Remove all entries from the stack.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue