Handle conflicts in repeat rules after external tokens

Signed-off-by: Rick Winfrey <rewinfrey@github.com>
This commit is contained in:
Max Brunsfeld 2018-02-14 11:24:51 -08:00 committed by Rick Winfrey
parent facafcd6e4
commit 2daae48fe0
4 changed files with 100 additions and 3 deletions

View file

@ -602,9 +602,9 @@ class ParseTableBuilderImpl : public ParseTableBuilder {
for (auto &preceding_symbol : preceding_symbols) {
ParseState &preceding_state = parse_table.states[preceding_state_id];
if (preceding_state.nonterminal_entries.count(symbol.index)) break;
preceding_state_id = preceding_symbol.is_terminal() ?
preceding_state.terminal_entries[preceding_symbol].actions.back().state_index :
preceding_state.nonterminal_entries[preceding_symbol.index];
preceding_state_id = preceding_symbol.is_non_terminal() ?
preceding_state.nonterminal_entries[preceding_symbol.index] :
preceding_state.terminal_entries[preceding_symbol].actions.back().state_index;
}
const ParseItemSet &preceding_item_set = *item_sets_by_state_id[preceding_state_id];
for (auto &preceding_entry : preceding_item_set.entries) {

View file

@ -0,0 +1,14 @@
Unresolved conflict for symbol sequence:
_program_start '[' identifier • ']' …
Possible interpretations:
1: _program_start '[' (array_repeat1 identifier) • ']' …
2: _program_start '[' (array_type_repeat1 identifier) • ']' …
Possible resolutions:
1: Specify a higher precedence in `array_repeat1` than in the other rules.
2: Specify a higher precedence in `array_type_repeat1` than in the other rules.
3: Add a conflict for these rules: `array` `array_type`

View file

@ -0,0 +1,82 @@
{
"name": "conflict_in_repeat_rule_after_external_token",
"externals": [
{"type": "SYMBOL", "name": "_program_start"},
],
"rules": {
"statement": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "_program_start"},
{"type": "SYMBOL", "name": "array"},
{"type": "STRING", "value": ";"}
]
},
{
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "_program_start"},
{"type": "SYMBOL", "name": "array_type"},
{"type": "SYMBOL", "name": "identifier"},
{"type": "STRING", "value": ";"}
]
}
]
},
"array": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "identifier"},
{"type": "STRING", "value": "0"}
]
}
},
{
"type": "STRING",
"value": "]"
}
]
},
"array_type": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "identifier"},
{"type": "STRING", "value": "void"}
]
}
},
{
"type": "STRING",
"value": "]"
}
]
},
"identifier": {"type": "PATTERN", "value": "[a-z]+"}
}
}

View file

@ -0,0 +1 @@
This grammar is similar to the `conflict_in_repeat_rule` grammar, except that the conflict occurs after an external token is consumed. This tests that the logic for determining the repeat rule's "parent" rule works in the presence of external tokens.