Include 'goal' non-terminal names in conflict description
This commit is contained in:
parent
e8db35af6b
commit
a54d293317
4 changed files with 60 additions and 32 deletions
|
|
@ -93,7 +93,7 @@ class ParseTableBuilder {
|
|||
|
||||
ParseAction new_action =
|
||||
ParseAction::Shift(0, precedence_values_for_item_set(next_item_set));
|
||||
if (should_add_action(state_id, symbol, new_action)) {
|
||||
if (should_add_action(state_id, item_set, symbol, new_action)) {
|
||||
ParseStateId new_state_id = add_parse_state(next_item_set);
|
||||
new_action.state_index = new_state_id;
|
||||
parse_table.add_action(state_id, symbol, new_action);
|
||||
|
|
@ -115,7 +115,7 @@ class ParseTableBuilder {
|
|||
conflict_manager.get_production_id(item.consumed_symbols));
|
||||
|
||||
for (const auto &lookahead_sym : lookahead_symbols)
|
||||
if (should_add_action(state_id, lookahead_sym, action))
|
||||
if (should_add_action(state_id, item_set, lookahead_sym, action))
|
||||
parse_table.add_action(state_id, lookahead_sym, action);
|
||||
}
|
||||
}
|
||||
|
|
@ -147,22 +147,22 @@ class ParseTableBuilder {
|
|||
for (const auto &pair : actions) {
|
||||
const Symbol &lookahead_sym = pair.first;
|
||||
ParseAction reduce_extra = ParseAction::ReduceExtra(ubiquitous_symbol);
|
||||
if (should_add_action(shift_state_id, lookahead_sym, reduce_extra))
|
||||
if (should_add_action(shift_state_id, ParseItemSet(), lookahead_sym, reduce_extra))
|
||||
parse_table.add_action(shift_state_id, lookahead_sym, reduce_extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool should_add_action(ParseStateId state_id, const Symbol &symbol,
|
||||
const ParseAction &action) {
|
||||
bool should_add_action(ParseStateId state_id, const ParseItemSet &item_set,
|
||||
const Symbol &symbol, const ParseAction &action) {
|
||||
auto ¤t_actions = parse_table.states[state_id].actions;
|
||||
auto current_action = current_actions.find(symbol);
|
||||
if (current_action == current_actions.end())
|
||||
return true;
|
||||
|
||||
auto result = conflict_manager.resolve(action, current_action->second,
|
||||
symbol);
|
||||
symbol, item_set);
|
||||
|
||||
switch (get<1>(result)) {
|
||||
case ConflictTypeResolved:
|
||||
|
|
|
|||
|
|
@ -23,9 +23,10 @@ ParseConflictManager::ParseConflictManager(const SyntaxGrammar &syntax_grammar,
|
|||
tuple<bool, ConflictType, string>
|
||||
ParseConflictManager::resolve(const ParseAction &new_action,
|
||||
const ParseAction &old_action,
|
||||
const rules::Symbol &symbol) const {
|
||||
const rules::Symbol &symbol,
|
||||
const ParseItemSet &item_set) const {
|
||||
if (new_action.type < old_action.type) {
|
||||
auto opposite = resolve(old_action, new_action, symbol);
|
||||
auto opposite = resolve(old_action, new_action, symbol, item_set);
|
||||
return make_tuple(!get<0>(opposite), get<1>(opposite), get<2>(opposite));
|
||||
}
|
||||
|
||||
|
|
@ -49,10 +50,10 @@ ParseConflictManager::resolve(const ParseAction &new_action,
|
|||
case rules::AssociativityRight:
|
||||
return make_tuple(false, ConflictTypeResolved, "");
|
||||
default:
|
||||
return make_tuple(false, ConflictTypeError, conflict_description(new_action, old_action, symbol));
|
||||
return make_tuple(false, ConflictTypeError, conflict_description(new_action, old_action, symbol, item_set));
|
||||
}
|
||||
} else {
|
||||
return make_tuple(false, ConflictTypeError, conflict_description(new_action, old_action, symbol));
|
||||
return make_tuple(false, ConflictTypeError, conflict_description(new_action, old_action, symbol, item_set));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ ParseConflictManager::resolve(const ParseAction &new_action,
|
|||
} else if (new_precedence < old_precedence) {
|
||||
return make_tuple(false, ConflictTypeResolved, "");
|
||||
} else {
|
||||
return make_tuple(false, ConflictTypeError, conflict_description(new_action, old_action, symbol));
|
||||
return make_tuple(false, ConflictTypeError, conflict_description(new_action, old_action, symbol, item_set));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,10 +86,26 @@ size_t ParseConflictManager::get_production_id(const vector<rules::Symbol> &symb
|
|||
return iter - begin;
|
||||
}
|
||||
|
||||
string ParseConflictManager::item_set_description(const ParseItemSet &item_set) const {
|
||||
string result;
|
||||
bool started = false;
|
||||
for (const auto &pair : item_set) {
|
||||
const ParseItem &item = pair.first;
|
||||
if (!item.consumed_symbols.empty()) {
|
||||
if (started) result += ", ";
|
||||
result += symbol_name(item.lhs);
|
||||
started = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
string ParseConflictManager::conflict_description(const ParseAction &new_action,
|
||||
const ParseAction &old_action,
|
||||
const rules::Symbol &symbol) const {
|
||||
const rules::Symbol &symbol,
|
||||
const ParseItemSet &item_set) const {
|
||||
return
|
||||
"Within: " + item_set_description(item_set) + "\n"
|
||||
"Lookahead: " + symbol_name(symbol) + "\n" +
|
||||
"Possible Actions:\n"
|
||||
"* " + action_description(old_action) + "\n" +
|
||||
|
|
|
|||
|
|
@ -29,12 +29,13 @@ class ParseConflictManager {
|
|||
ParseConflictManager(const SyntaxGrammar &, const LexicalGrammar &);
|
||||
size_t get_production_id(const std::vector<rules::Symbol> &);
|
||||
std::tuple<bool, ConflictType, std::string> resolve(
|
||||
const ParseAction &, const ParseAction &, const rules::Symbol &) const;
|
||||
const ParseAction &, const ParseAction &, const rules::Symbol &, const ParseItemSet &) const;
|
||||
|
||||
private:
|
||||
std::string symbol_name(const rules::Symbol &) const;
|
||||
std::string item_set_description(const ParseItemSet &) const;
|
||||
std::string action_description(const ParseAction &) const;
|
||||
std::string conflict_description(const ParseAction &, const ParseAction &, const rules::Symbol &) const;
|
||||
std::string conflict_description(const ParseAction &, const ParseAction &, const rules::Symbol &, const ParseItemSet &) const;
|
||||
};
|
||||
|
||||
} // namespace build_tables
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue