diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index 7ae106c4..085835bb 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -102,8 +102,7 @@ typedef struct { } ts_stack; ts_stack ts_stack_make(); -ts_tree * ts_stack_root(const ts_stack *stack); -ts_tree * ts_stack_reduce(ts_stack *stack, ts_symbol symbol, int immediate_child_count, const int *hidden_symbol_flags, const int *ubiquitous_symbol_flags); +ts_tree * ts_stack_reduce(ts_stack *stack, ts_symbol symbol, size_t immediate_child_count, const int *hidden_symbol_flags, const int *ubiquitous_symbol_flags); void ts_stack_shrink(ts_stack *stack, size_t new_size); void ts_stack_push(ts_stack *stack, ts_state_id state, ts_tree *node); ts_state_id ts_stack_top_state(const ts_stack *stack); @@ -292,7 +291,7 @@ static void ts_lr_parser_shift(ts_lr_parser *parser, ts_state_id parse_state) { parser->next_lookahead = NULL; } -static void ts_lr_parser_reduce(ts_lr_parser *parser, ts_symbol symbol, int child_count) { +static void ts_lr_parser_reduce(ts_lr_parser *parser, ts_symbol symbol, size_t child_count) { parser->next_lookahead = parser->lookahead; parser->lookahead = ts_stack_reduce(&parser->stack, symbol, child_count, parser->hidden_symbol_flags, parser->ubiquitous_symbol_flags); } @@ -326,7 +325,7 @@ static int ts_lr_parser_handle_error(ts_lr_parser *parser) { ts_lexer_advance(&parser->lexer); if (ts_tree_symbol(parser->lookahead) == ts_builtin_sym_end) { - parser->stack.entries[0].node = error; + ts_stack_push(&parser->stack, 0, error); return 0; } @@ -349,6 +348,29 @@ static int ts_lr_parser_handle_error(ts_lr_parser *parser) { } } } + +static ts_tree * ts_lr_parser_tree_root(ts_lr_parser *parser) { + ts_stack *stack = &parser->stack; + ts_tree *top_node = ts_stack_top_node(stack); + if (stack->size <= 1) + return top_node; + + size_t immediate_child_count; + ts_tree **immedate_children = ts_tree_immediate_children(top_node, &immediate_child_count); + + stack->size--; + for (size_t i = 0; i < immediate_child_count; i++) { + ts_tree *child = immedate_children[i]; + ts_tree_retain(child); + ts_state_id state = ts_stack_top_state(stack); + ts_state_id next_state = ts_lr_parser_table_actions(parser, state)[ts_tree_symbol(child)].data.to_state; + ts_stack_push(stack, next_state, child); + } + + ts_tree *new_node = ts_stack_reduce(stack, ts_tree_symbol(top_node), stack->size, parser->hidden_symbol_flags, NULL); + ts_tree_release(top_node); + return new_node; +} static const ts_tree * ts_parse(void *data, ts_input input, ts_input_edit *edit) { ts_lr_parser *parser = (ts_lr_parser *)data; @@ -381,7 +403,7 @@ static const ts_tree * ts_parse(void *data, ts_input input, ts_input_edit *edit) } } - return ts_stack_root(&parser->stack); + return ts_lr_parser_tree_root(parser); } #ifdef __cplusplus diff --git a/spec/runtime/languages/javascript/main.txt b/spec/runtime/languages/javascript/main.txt index 62259e89..d9654270 100644 --- a/spec/runtime/languages/javascript/main.txt +++ b/spec/runtime/languages/javascript/main.txt @@ -97,6 +97,8 @@ print(object[propertyName()]); ========================================== parses comments ========================================== +// this is the beginning of the script. +// here we go. var thing = { // this is a property. @@ -108,14 +110,17 @@ var thing = { } }; --- -(program (var_declaration (assignment (identifier) (object +(program (comment) (comment) - (identifier) (function_expression - (formal_parameters (identifier) (comment)) - (statement_block - (comment) - (expression_statement (function_call (identifier))))))))) + (var_declaration (assignment (identifier) (object + (comment) + (comment) + (identifier) (function_expression + (formal_parameters (identifier) (comment)) + (statement_block + (comment) + (expression_statement (function_call (identifier))))))))) ====================================== parses real code diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 8b06859c..9850b605 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -32,10 +32,6 @@ ts_tree * ts_stack_top_node(const ts_stack *stack) { return stack->entries[stack->size - 1].node; } -ts_tree * ts_stack_root(const ts_stack *stack) { - return stack->entries[0].node; -} - void ts_stack_push(ts_stack *stack, state_id state, ts_tree *node) { stack->entries[stack->size].state = state; stack->entries[stack->size].node = node; @@ -59,7 +55,7 @@ size_t ts_stack_right_position(const ts_stack *stack) { ts_tree * ts_stack_reduce(ts_stack *stack, ts_symbol symbol, - int immediate_child_count, + size_t immediate_child_count, const int *hidden_symbol_flags, const int *ubiquitous_symbol_flags) { @@ -70,7 +66,7 @@ ts_tree * ts_stack_reduce(ts_stack *stack, // which don't count towards the child node count. static int collapse_flags[100]; int child_count = 0; - for (int i = 0; i < immediate_child_count; i++) { + for (size_t i = 0; i < immediate_child_count; i++) { size_t stack_index = stack->size - 1 - i; ts_tree *child = stack->entries[stack_index].node; size_t grandchild_count; @@ -84,7 +80,7 @@ ts_tree * ts_stack_reduce(ts_stack *stack, child_count += collapse_flags[i] ? grandchild_count : 1; - if (ubiquitous_symbol_flags[child_symbol]) + if (ubiquitous_symbol_flags && ubiquitous_symbol_flags[child_symbol]) immediate_child_count++; } @@ -99,7 +95,7 @@ ts_tree * ts_stack_reduce(ts_stack *stack, ts_tree **children = malloc((child_count + immediate_child_count) * sizeof(ts_tree *)); ts_tree **immediate_children = children + child_count; - for (int i = 0; i < immediate_child_count; i++) { + for (size_t i = 0; i < immediate_child_count; i++) { ts_tree *child = stack->entries[stack->size - 1 - i].node; immediate_children[immediate_child_count - 1 - i] = child;