From 653570487071d0673e19a2410ffad23075c27908 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sat, 28 May 2016 21:22:10 -0700 Subject: [PATCH] Replace stack_merge_new function with two simpler functions - merge(version1, version2) - split(version) --- spec/runtime/stack_spec.cc | 2 +- src/runtime/parser.c | 38 +++++++++++++++----------------------- src/runtime/stack.c | 37 ++++++++++++++++++++++--------------- src/runtime/stack.h | 7 ++++--- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/spec/runtime/stack_spec.cc b/spec/runtime/stack_spec.cc index 79075c0e..e12d19ff 100644 --- a/spec/runtime/stack_spec.cc +++ b/spec/runtime/stack_spec.cc @@ -127,7 +127,7 @@ describe("Stack", [&]() { // ↑ // └───2─── C* ts_stack_push(stack, 0, trees[0], false, stateA); - ts_stack_pop_count(stack, 0, 0); + ts_stack_split(stack, 0); ts_stack_push(stack, 0, trees[1], false, stateB); ts_stack_push(stack, 1, trees[2], false, stateC); }); diff --git a/src/runtime/parser.c b/src/runtime/parser.c index 2f2fb482..f5631e46 100644 --- a/src/runtime/parser.c +++ b/src/runtime/parser.c @@ -692,9 +692,6 @@ error: static bool ts_parser__handle_error(TSParser *self, StackVersion version, TSStateId state, TSTree *lookahead) { - size_t previous_version_count = ts_stack_version_count(self->stack); - - bool has_shift_action = false; array_clear(&self->reduce_actions); for (TSSymbol symbol = 0; symbol < self->language->symbol_count; symbol++) { size_t action_count; @@ -702,12 +699,7 @@ static bool ts_parser__handle_error(TSParser *self, StackVersion version, ts_language_actions(self->language, state, symbol, &action_count); for (size_t i = 0; i < action_count; i++) { TSParseAction action = actions[i]; - if (action.extra) - continue; - if (action.type == TSParseActionTypeShift || - action.type == TSParseActionTypeRecover) - has_shift_action = true; - if (action.type == TSParseActionTypeReduce) + if (action.type == TSParseActionTypeReduce && !action.extra) CHECK(ts_reduce_action_set_add( &self->reduce_actions, (ReduceAction){ @@ -716,25 +708,25 @@ static bool ts_parser__handle_error(TSParser *self, StackVersion version, } } - Reduction reduction; + StackVersion scratch_version = ts_stack_split(self->stack, version); + CHECK(scratch_version != STACK_VERSION_NONE); + CHECK(ts_stack_push(self->stack, version, NULL, false, ts_parse_state_error)); + + size_t previous_version_count = ts_stack_version_count(self->stack); for (size_t i = 0; i < self->reduce_actions.size; i++) { - ReduceAction repair = self->reduce_actions.contents[i]; - reduction = ts_parser__reduce(self, version, repair.symbol, repair.count, - false, true); + ReduceAction action = self->reduce_actions.contents[i]; + Reduction reduction = ts_parser__reduce(self, scratch_version, action.symbol, + action.count, false, true); CHECK(reduction.status != ReduceFailed); assert(reduction.status == ReduceSucceeded); - CHECK(ts_stack_push(self->stack, reduction.slice.version, NULL, false, - ts_parse_state_error)); + while (ts_stack_version_count(self->stack) > previous_version_count) { + CHECK(ts_stack_push(self->stack, previous_version_count, NULL, false, + ts_parse_state_error)); + assert(ts_stack_merge(self->stack, version, previous_version_count)); + } } - if (has_shift_action) { - CHECK(ts_stack_push(self->stack, version, NULL, false, ts_parse_state_error)); - } else { - ts_stack_renumber_version(self->stack, reduction.slice.version, version); - } - - ts_stack_merge_new(self->stack, version, previous_version_count); - assert(ts_stack_version_count(self->stack) == previous_version_count); + ts_stack_remove_version(self->stack, scratch_version); return true; diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 73a087a9..7b3d8fc6 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -458,6 +458,28 @@ StackVersion ts_stack_duplicate_version(Stack *self, StackVersion version) { return self->heads.size - 1; } +StackVersion ts_stack_split(Stack *self, StackVersion version) { + if (!array_push(&self->heads, self->heads.contents[version])) + return STACK_VERSION_NONE; + stack_node_retain(self->heads.contents[version].node); + return self->heads.size - 1; +} + +bool ts_stack_merge(Stack *self, StackVersion version, StackVersion new_version) { + StackNode *node = self->heads.contents[version].node; + StackNode *new_node = self->heads.contents[new_version].node; + + if (new_node->state == node->state && + new_node->position.chars == node->position.chars) { + for (size_t j = 0; j < new_node->link_count; j++) + stack_node_add_link(node, new_node->links[j]); + ts_stack_remove_version(self, new_version); + return true; + } else { + return false; + } +} + void ts_stack_merge_from(Stack *self, StackVersion start_version) { for (size_t i = start_version; i < self->heads.size; i++) { if (self->heads.contents[i].is_halted) { @@ -487,21 +509,6 @@ void ts_stack_merge_from(Stack *self, StackVersion start_version) { } } -void ts_stack_merge_new(Stack *self, StackVersion reference_version, - StackVersion first_new_version) { - StackNode *reference_node = self->heads.contents[reference_version].node; - for (size_t i = first_new_version; i < self->heads.size; i++) { - StackNode *node = self->heads.contents[i].node; - if (reference_node->state == node->state && - reference_node->position.chars == node->position.chars) { - for (size_t j = 0; j < node->link_count; j++) - stack_node_add_link(reference_node, node->links[j]); - ts_stack_remove_version(self, i); - i--; - } - } -} - void ts_stack_merge_all(Stack *self) { ts_stack_merge_from(self, 0); } diff --git a/src/runtime/stack.h b/src/runtime/stack.h index a03de83e..a36c5dae 100644 --- a/src/runtime/stack.h +++ b/src/runtime/stack.h @@ -103,13 +103,14 @@ StackPopResult ts_stack_pop_pending(Stack *, StackVersion); StackPopResult ts_stack_pop_all(Stack *, StackVersion); +StackVersion ts_stack_split(Stack *, StackVersion); + +bool ts_stack_merge(Stack *, StackVersion, StackVersion); + void ts_stack_merge_from(Stack *, StackVersion); void ts_stack_merge_all(Stack *); -void ts_stack_merge_new(Stack *, StackVersion base_version, - StackVersion new_version); - void ts_stack_renumber_version(Stack *, StackVersion, StackVersion); StackVersion ts_stack_duplicate_version(Stack *, StackVersion);