Merge pull request #15 from maxbrunsfeld/fix-es6-ambiguity-bug
Fix ambiguity-handling bug that arises in javascript w/ ES6 support
This commit is contained in:
commit
d0e107eb84
6 changed files with 23236 additions and 22983 deletions
43
spec/fixtures/corpus/javascript/control_flow.txt
vendored
43
spec/fixtures/corpus/javascript/control_flow.txt
vendored
|
|
@ -30,6 +30,49 @@ if (isReady()) {
|
|||
(statement_block (expression_statement
|
||||
(function_call (member_access (identifier) (identifier)) (arguments (identifier)))))))
|
||||
|
||||
==========================================
|
||||
if statements whose bodies are objects
|
||||
==========================================
|
||||
|
||||
if (a) {
|
||||
b()
|
||||
{
|
||||
c();
|
||||
},
|
||||
|
||||
d: 'e'
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(program (if_statement (identifier)
|
||||
(expression_statement (object
|
||||
(method_definition (identifier) (statement_block (expression_statement (function_call (identifier) (arguments)))))
|
||||
(pair (identifier) (string))))))
|
||||
|
||||
============================================
|
||||
if statements whose bodies look like objects
|
||||
============================================
|
||||
|
||||
if (f) {
|
||||
g()
|
||||
{
|
||||
h();
|
||||
i();
|
||||
}
|
||||
j()
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(program (if_statement (identifier)
|
||||
(statement_block
|
||||
(expression_statement (function_call (identifier) (arguments)))
|
||||
(statement_block
|
||||
(expression_statement (function_call (identifier) (arguments)))
|
||||
(expression_statement (function_call (identifier) (arguments))))
|
||||
(expression_statement (function_call (identifier) (arguments))))))
|
||||
|
||||
==========================================
|
||||
if-else statements
|
||||
==========================================
|
||||
|
|
|
|||
12
spec/fixtures/grammars/javascript.cc
vendored
12
spec/fixtures/grammars/javascript.cc
vendored
|
|
@ -202,7 +202,9 @@ extern const Grammar javascript = Grammar({
|
|||
sym("true"),
|
||||
sym("_paren_expression") }) },
|
||||
|
||||
{ "object", in_braces(comma_sep(err(sym("pair")))) },
|
||||
{ "object", in_braces(comma_sep(err(choice({
|
||||
sym("pair"),
|
||||
sym("method_definition") })))) },
|
||||
|
||||
{ "array", in_brackets(comma_sep(err(sym("_expression")))) },
|
||||
|
||||
|
|
@ -340,12 +342,20 @@ extern const Grammar javascript = Grammar({
|
|||
str(":"),
|
||||
sym("_expression") }) },
|
||||
|
||||
{ "method_definition", seq({
|
||||
sym("identifier"),
|
||||
str("("),
|
||||
comma_sep(sym("identifier")),
|
||||
str(")"),
|
||||
sym("statement_block") }) },
|
||||
|
||||
}).ubiquitous_tokens({
|
||||
sym("comment"),
|
||||
sym("_line_break"),
|
||||
pattern("[ \t\r]"),
|
||||
}).expected_conflicts({
|
||||
{ "for_in_statement", "_expression" },
|
||||
{ "method_definition", "_expression" },
|
||||
});
|
||||
|
||||
} // namespace tree_sitter_examples
|
||||
|
|
|
|||
46144
spec/fixtures/parsers/javascript.c
vendored
46144
spec/fixtures/parsers/javascript.c
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -115,7 +115,7 @@ static void ts_parser__pop_reusable_subtree(LookaheadState *state) {
|
|||
}
|
||||
|
||||
static bool ts_parser__can_reuse(TSParser *self, int head, TSTree *subtree) {
|
||||
if (!subtree || subtree->symbol == ts_builtin_sym_error)
|
||||
if (!subtree || subtree->symbol == ts_builtin_sym_error || ts_tree_is_fragile(subtree))
|
||||
return false;
|
||||
TSStateId state = ts_stack_top_state(self->stack, head);
|
||||
const TSParseAction *action =
|
||||
|
|
@ -151,15 +151,11 @@ static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head) {
|
|||
}
|
||||
LOG("breakdown_changed sym:%s", SYM_NAME(state->reusable_subtree->symbol));
|
||||
can_reuse = false;
|
||||
} else if (ts_tree_is_fragile(state->reusable_subtree)) {
|
||||
LOG("breakdown_fragile sym:%s", SYM_NAME(state->reusable_subtree->symbol));
|
||||
can_reuse = false;
|
||||
} else if (ts_tree_is_extra(state->reusable_subtree)) {
|
||||
LOG("breakdown_extra sym:%s", SYM_NAME(state->reusable_subtree->symbol));
|
||||
can_reuse = false;
|
||||
} else if (state->reusable_subtree->child_count > 0 &&
|
||||
!ts_parser__can_reuse(self, head, state->reusable_subtree)) {
|
||||
LOG("breakdown_unexpected sym:%s", SYM_NAME(state->reusable_subtree->symbol));
|
||||
} else if (!ts_parser__can_reuse(self, head, state->reusable_subtree)) {
|
||||
LOG("breakdown_non_reusable sym:%s", SYM_NAME(state->reusable_subtree->symbol));
|
||||
can_reuse = false;
|
||||
}
|
||||
|
||||
|
|
@ -225,6 +221,9 @@ static bool ts_parser__shift(TSParser *self, int head,
|
|||
|
||||
static bool ts_parser__shift_extra(TSParser *self, int head, TSStateId state,
|
||||
TSTree *lookahead) {
|
||||
TSSymbolMetadata metadata = self->language->symbol_metadata[lookahead->symbol];
|
||||
if (!metadata.extra && ts_stack_head_count(self->stack) > 1)
|
||||
lookahead = ts_tree_make_copy(lookahead);
|
||||
ts_tree_set_extra(lookahead);
|
||||
return ts_parser__shift(self, head, state, lookahead);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@ TSTree *ts_tree_make_error(TSLength size, TSLength padding, char lookahead_char)
|
|||
return result;
|
||||
}
|
||||
|
||||
TSTree *ts_tree_make_copy(TSTree *self) {
|
||||
TSTree *result = malloc(sizeof(TSTree));
|
||||
*result = *self;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ts_tree_assign_parents(TSTree *self) {
|
||||
TSLength offset = ts_length_zero();
|
||||
for (size_t i = 0; i < self->child_count; i++) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct TSTree {
|
|||
|
||||
TSTree *ts_tree_make_leaf(TSSymbol, TSLength, TSLength, TSSymbolMetadata);
|
||||
TSTree *ts_tree_make_node(TSSymbol, size_t, TSTree **, TSSymbolMetadata);
|
||||
TSTree *ts_tree_make_copy(TSTree *child);
|
||||
TSTree *ts_tree_make_error(TSLength, TSLength, char);
|
||||
void ts_tree_retain(TSTree *tree);
|
||||
void ts_tree_release(TSTree *tree);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue