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:
Max Brunsfeld 2017-08-02 15:13:30 -07:00 committed by Philip Turnbull
parent 418e7c8f1f
commit 119c67dd78
4 changed files with 80 additions and 0 deletions

View file

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

View 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`

View 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+"
}
}
}

View 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.