Merge pull request #53 from tree-sitter/precedence-fix

Avoid incorrect application of precedence
This commit is contained in:
Max Brunsfeld 2016-12-01 10:33:20 -08:00 committed by GitHub
commit 269ee1c120
2 changed files with 155 additions and 1 deletions

View file

@ -243,6 +243,160 @@ describe("compile_grammar", []() {
"(block (expression (identifier)))))))");
});
it("handles precedence applied to specific rule subsequences (regression)", [&]() {
TSCompileResult result = ts_compile_grammar(R"JSON({
"name": "precedence_on_subsequence",
"extras": [
{"type": "STRING", "value": " "}
],
"rules": {
"expression": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "function_call"},
{"type": "SYMBOL", "name": "identifier"},
{"type": "SYMBOL", "name": "scope_resolution"}
]
}
},
"function_call": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "identifier"},
{"type": "SYMBOL", "name": "expression"}
]
},
{
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "identifier"},
{"type": "SYMBOL", "name": "block"}
]
}
},
{
"type": "PREC",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "identifier"},
{"type": "SYMBOL", "name": "do_block"}
]
}
},
{
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "identifier"},
{
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "SYMBOL", "name": "block"}
]
}
}
]
},
{
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "identifier"},
{
"type": "PREC",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "SYMBOL", "name": "do_block"}
]
}
}
]
}
]
},
"scope_resolution": {
"type": "PREC_LEFT",
"value": 1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": "::"},
{"type": "SYMBOL", "name": "expression"}
]
},
{
"type": "SEQ",
"members": [
{"type": "STRING", "value": "::"},
{"type": "SYMBOL", "name": "expression"},
]
}
]
}
},
"block": {
"type": "STRING",
"value": "{}"
},
"do_block": {
"type": "STRING",
"value": "do end"
},
"identifier": {
"type": "PATTERN",
"value": "[a-zA-Z]+"
}
}
})JSON");
auto language = load_compile_result("precedence_on_subsequence", result);
ts_document_set_language(document, language);
ts_document_set_input_string(document, "a b {}");
ts_document_parse(document);
assert_root_node("(expression (function_call "
"(identifier) "
"(expression (function_call (identifier) (block)))))");
ts_document_set_input_string(document, "a b do end");
ts_document_parse(document);
assert_root_node("(expression (function_call "
"(identifier) "
"(expression (identifier)) "
"(do_block)))");
});
it("does not allow conflicting precedences", [&]() {
string grammar_template = R"JSON({
"name": "conflicting_precedence_example",

View file

@ -377,7 +377,7 @@ class ParseTableBuilder {
LookaheadSet first_set = item_set_builder.get_first_set(item.next_symbol());
if (first_set.contains(lookahead)) {
shift_items.insert(item);
shift_precedence.add(item.precedence());
shift_precedence.add(item.production->at(item.step_index - 1).precedence);
}
}
}