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:
Max Brunsfeld 2015-12-15 22:36:04 -08:00
commit d0e107eb84
6 changed files with 23236 additions and 22983 deletions

View file

@ -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
==========================================

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -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++) {

View file

@ -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);