Fix conflict reporting for shift/reduce conflicts w/ multiple reductions
We were failing to rule out shift actions with lower precedence. Signed-off-by: Philip Turnbull <philipturnbull@github.com>
This commit is contained in:
parent
418e7c8f1f
commit
119c67dd78
4 changed files with 80 additions and 0 deletions
|
|
@ -544,6 +544,13 @@ class ParseTableBuilder {
|
|||
(shift_precedence.max == reduction_precedence &&
|
||||
shift_precedence.min < reduction_precedence)) {
|
||||
entry.actions.pop_back();
|
||||
for (auto item_iter = conflicting_items.begin(); item_iter != conflicting_items.end();) {
|
||||
if (item_iter->is_done()) {
|
||||
++item_iter;
|
||||
} else {
|
||||
item_iter = conflicting_items.erase(item_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the shift action has the same precedence as the reduce actions,
|
||||
|
|
|
|||
14
test/fixtures/test_grammars/partially_resolved_conflict/expected_error.txt
vendored
Normal file
14
test/fixtures/test_grammars/partially_resolved_conflict/expected_error.txt
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Unresolved conflict for symbol sequence:
|
||||
|
||||
'!' expression • '<' …
|
||||
|
||||
Possible interpretations:
|
||||
|
||||
1: (unary_a '!' expression) • '<' …
|
||||
2: (unary_b '!' expression) • '<' …
|
||||
|
||||
Possible resolutions:
|
||||
|
||||
1: Specify a higher precedence in `unary_a` than in the other rules.
|
||||
2: Specify a higher precedence in `unary_b` than in the other rules.
|
||||
3: Add a conflict for these rules: `unary_a` `unary_b`
|
||||
58
test/fixtures/test_grammars/partially_resolved_conflict/grammar.json
vendored
Normal file
58
test/fixtures/test_grammars/partially_resolved_conflict/grammar.json
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"name": "partially_resolved_conflict",
|
||||
|
||||
"rules": {
|
||||
"expression": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{"type": "SYMBOL", "name": "binary"},
|
||||
{"type": "SYMBOL", "name": "identifier"}
|
||||
]
|
||||
},
|
||||
|
||||
"unary_a": {
|
||||
"type": "PREC",
|
||||
"value": 2,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{"type": "STRING", "value": "!"},
|
||||
{"type": "SYMBOL", "name": "expression"}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"unary_b": {
|
||||
"type": "PREC",
|
||||
"value": 2,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{"type": "STRING", "value": "!"},
|
||||
{"type": "SYMBOL", "name": "expression"}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"binary": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{"type": "SYMBOL", "name": "unary_a"},
|
||||
{"type": "SYMBOL", "name": "unary_b"},
|
||||
{"type": "SYMBOL", "name": "expression"}
|
||||
]
|
||||
},
|
||||
{"type": "STRING", "value": "<"},
|
||||
{"type": "SYMBOL", "name": "expression"}
|
||||
]
|
||||
},
|
||||
|
||||
"identifier": {
|
||||
"type": "PATTERN",
|
||||
"value": "\\a+"
|
||||
}
|
||||
}
|
||||
}
|
||||
1
test/fixtures/test_grammars/partially_resolved_conflict/readme.txt
vendored
Normal file
1
test/fixtures/test_grammars/partially_resolved_conflict/readme.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
This grammar has a conflict with three possible actions: a shift in the middle of the `binary` rule and two reductions: one for `unary_a` and one for `unary_b`. Both `unary_a` and `unary_b` have a higher precedence than `binary`, therefore we can rule out the interpretation where a `binary` occurs *inside* of a `unary_a` or `unary_b`, so the error message (and suggested `conflict`) should not include that interpretation.
|
||||
Loading…
Add table
Add a link
Reference in a new issue