From 7e94a4f1b26b9c59a24086fb0c54cfcb4c5b46ef Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 18 Mar 2014 13:23:21 -0700 Subject: [PATCH] Start work on reading input incrementally --- include/tree_sitter/parser.h | 29 +++++++++++++++++++++++++++-- spec/runtime/parser_spec.cc | 9 ++++----- spec/runtime/runtime_specs.cc | 2 +- src/runtime/stack.c | 5 +++++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index 7a6dae43..7063dc37 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -153,6 +153,7 @@ ts_tree * ts_stack_reduce(ts_stack *stack, ts_symbol symbol, int immediate_child void ts_stack_shrink(ts_stack *stack, size_t new_size); void ts_stack_push(ts_stack *stack, state_id state, ts_tree *node); state_id ts_stack_top_state(const ts_stack *stack); +ts_tree * ts_stack_top_node(const ts_stack *stack); /* @@ -267,13 +268,37 @@ static ts_lr_parser * ts_lr_parser_make() { result->stack = ts_stack_make(); return result; } + +static size_t ts_lr_parser_breakdown_stack(ts_lr_parser *parser, ts_input_edit *edit) { + if (parser->stack.size == 0) return 0; + + ts_tree *node = ts_stack_top_node(&parser->stack); + parser->stack.size--; + state_id parse_state = 0; + + size_t position = 0; + size_t child_count; + ts_tree ** children = ts_tree_children(node, &child_count); + for (size_t i = 0; i < child_count; i++) { + ts_tree *child = children[i]; + + position += child->offset + child->size; + ts_tree_retain(child); + ts_stack_push(&parser->stack, parse_state, child); + parse_state = ts_parse_actions[parse_state][child->symbol].data.to_state; + } + + ts_tree_release(node); + return position; +} static void ts_lr_parser_initialize(ts_lr_parser *parser, ts_input input, ts_input_edit *edit) { - ts_stack_shrink(&parser->stack, 0); parser->lookahead = NULL; parser->next_lookahead = NULL; - input.seek_fn(input.data, 0); + size_t position = ts_lr_parser_breakdown_stack(parser, edit); + input.seek_fn(input.data, position); + parser->lexer = ts_lexer_make(); parser->lexer.input = input; ts_lexer_advance(&parser->lexer); diff --git a/spec/runtime/parser_spec.cc b/spec/runtime/parser_spec.cc index 33c0e340..ad2a4646 100644 --- a/spec/runtime/parser_spec.cc +++ b/spec/runtime/parser_spec.cc @@ -41,7 +41,7 @@ describe("parsing", [&]() { describe("modifying the input", [&]() { before_each([&]() { size_t position(string("{ \"key\": [1, 2]").length()); - string inserted_text(", \"key2\": 4 "); + string inserted_text(", \"key2\": 4"); reader->content.insert(position, inserted_text); ts_document_edit(doc, { @@ -64,10 +64,9 @@ describe("parsing", [&]() { )); }); - it_skip("re-reads only the changed portion of the input", [&]() { - AssertThat(reader->chunks_read, Equals(vector({ - "" - }))); + it("re-reads only the changed portion of the input", [&]() { + AssertThat(reader->strings_read.size(), Equals(2)); + AssertThat(reader->strings_read[1], Equals("\"key2\": 4 }")); }); }); }); diff --git a/spec/runtime/runtime_specs.cc b/spec/runtime/runtime_specs.cc index 586fac0c..904fae3e 100644 --- a/spec/runtime/runtime_specs.cc +++ b/spec/runtime/runtime_specs.cc @@ -5,7 +5,7 @@ int main(int argc, char *argv[]) { "", "--no-color", "--only=" - "" + "re-reads only" }; return bandit::run(4, const_cast(args)); } diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 63a267ba..27d7513b 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -28,6 +28,11 @@ state_id ts_stack_top_state(const ts_stack *stack) { return stack->entries[stack->size - 1].state; } +ts_tree * ts_stack_top_node(const ts_stack *stack) { + if (stack->size == 0) return NULL; + return stack->entries[stack->size - 1].node; +} + ts_tree * ts_stack_root(const ts_stack *stack) { return stack->entries[0].node; }