Include 'goal' non-terminal names in conflict description

This commit is contained in:
Max Brunsfeld 2015-04-16 17:43:30 -07:00
parent e8db35af6b
commit a54d293317
4 changed files with 60 additions and 32 deletions

View file

@ -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 &current_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:

View file

@ -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" +

View file

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