diff --git a/src/compiler/build_tables/build_parse_table.cc b/src/compiler/build_tables/build_parse_table.cc index d50deb5b..18511787 100644 --- a/src/compiler/build_tables/build_parse_table.cc +++ b/src/compiler/build_tables/build_parse_table.cc @@ -1,5 +1,4 @@ - #include "compiler/build_tables/build_parse_table.h" - #include +#include "compiler/build_tables/build_parse_table.h" #include #include #include @@ -172,6 +171,8 @@ class ParseTableBuilder { for (const Symbol::Index lookahead : *lookahead_symbols.entries) { ParseTableEntry &entry = parse_table.states[state_id].terminal_entries[lookahead]; + // Only add the highest-precedence Reduce actions to the parse table. + // If other lower-precedence actions are possible, ignore them. if (entry.actions.empty()) { parse_table.add_terminal_action(state_id, lookahead, action); } else { @@ -185,9 +186,10 @@ class ParseTableBuilder { fragile_productions.insert(old_action.production); entry.actions.clear(); entry.actions.push_back(action); + lookaheads_with_conflicts.erase(lookahead); } else if (precedence == existing_precedence) { - lookaheads_with_conflicts.insert(lookahead); entry.actions.push_back(action); + lookaheads_with_conflicts.insert(lookahead); } else { fragile_productions.insert(item.production); } @@ -209,16 +211,18 @@ class ParseTableBuilder { } } + // Add a Shift action for each possible successor state. Shift actions for + // terminal lookaheads can conflict with Reduce actions added previously. for (auto &pair : terminal_successors) { Symbol::Index lookahead = pair.first; ParseItemSet &next_item_set = pair.second; ParseStateId next_state_id = add_parse_state(next_item_set); - bool had_existing_action = !parse_table.states[state_id].terminal_entries[lookahead].actions.empty(); + ParseState &state = parse_table.states[state_id]; + bool had_existing_action = !state.terminal_entries[lookahead].actions.empty(); parse_table.add_terminal_action(state_id, lookahead, ParseAction::Shift(next_state_id)); if (!allow_any_conflict) { - if (had_existing_action) { + if (had_existing_action) lookaheads_with_conflicts.insert(lookahead); - } recovery_states[Symbol(lookahead, true)].add(next_item_set); } } @@ -229,7 +233,6 @@ class ParseTableBuilder { ParseItemSet &next_item_set = pair.second; ParseStateId next_state = add_parse_state(next_item_set); parse_table.set_nonterminal_action(state_id, lookahead, next_state); - if (!allow_any_conflict) recovery_states[Symbol(lookahead, false)].add(next_item_set); } @@ -331,7 +334,7 @@ class ParseTableBuilder { vector new_state_ids(parse_table.states.size()); size_t deleted_state_count = 0; auto deleted_state_iter = deleted_states.begin(); - for (size_t i = 0; i < new_state_ids.size(); i++) { + for (ParseStateId i = 0; i < new_state_ids.size(); i++) { while (deleted_state_iter != deleted_states.end() && *deleted_state_iter < i) { deleted_state_count++; deleted_state_iter++; diff --git a/src/compiler/build_tables/parse_item_set_builder.cc b/src/compiler/build_tables/parse_item_set_builder.cc index 9f41fc9c..45406f88 100644 --- a/src/compiler/build_tables/parse_item_set_builder.cc +++ b/src/compiler/build_tables/parse_item_set_builder.cc @@ -50,9 +50,9 @@ ParseItemSetBuilder::ParseItemSetBuilder(const SyntaxGrammar &grammar, first_sets.insert({symbol, first_set}); } - for (int i = 0; i < lexical_grammar.variables.size(); i++) { + for (size_t i = 0; i < lexical_grammar.variables.size(); i++) { Symbol symbol(i, true); - first_sets.insert({symbol, LookaheadSet({ i })}); + first_sets.insert({symbol, LookaheadSet({ static_cast(i) })}); } } diff --git a/src/compiler/parse_table.cc b/src/compiler/parse_table.cc index 108a3db3..e6e4badd 100644 --- a/src/compiler/parse_table.cc +++ b/src/compiler/parse_table.cc @@ -18,8 +18,8 @@ ParseAction::ParseAction(ParseActionType type, ParseStateId state_index, : type(type), extra(false), fragile(false), - symbol(symbol), state_index(state_index), + symbol(symbol), consumed_symbol_count(consumed_symbol_count), production(production) {} @@ -27,8 +27,8 @@ ParseAction::ParseAction() : type(ParseActionTypeError), extra(false), fragile(false), - symbol(Symbol(-1)), state_index(-1), + symbol(Symbol(-1)), consumed_symbol_count(0), production(nullptr) {}