diff --git a/externals/crypto-algorithms b/externals/crypto-algorithms index cfbde484..c7e5c23a 160000 --- a/externals/crypto-algorithms +++ b/externals/crypto-algorithms @@ -1 +1 @@ -Subproject commit cfbde48414baacf51fc7c74f275190881f037d32 +Subproject commit c7e5c23ab04ecfb5465cbefbe17ba23d4cb3bc9d diff --git a/src/compiler/build_tables/build_parse_table.cc b/src/compiler/build_tables/build_parse_table.cc index bcb602d5..5dd12fa8 100644 --- a/src/compiler/build_tables/build_parse_table.cc +++ b/src/compiler/build_tables/build_parse_table.cc @@ -168,7 +168,6 @@ class ParseTableBuilder { ParseStateId state_id = parse_table.states.size(); parse_table.states.push_back(ParseState()); parse_state_ids[item_set] = state_id; - parse_table.states[state_id].shift_actions_signature = item_set.unfinished_item_signature(); parse_state_queue.push_back({ move(preceding_symbols), move(item_set), @@ -340,11 +339,12 @@ class ParseTableBuilder { } void remove_duplicate_parse_states() { - map> state_indices_by_signature; + unordered_map> state_indices_by_signature; - for (ParseStateId i = 0, n = parse_table.states.size(); i < n; i++) { - ParseState &state = parse_table.states[i]; - state_indices_by_signature[state.shift_actions_signature].insert(i); + for (auto &pair : parse_state_ids) { + const ParseItemSet &item_set = pair.first; + ParseStateId state_id = pair.second; + state_indices_by_signature[item_set.unfinished_item_signature()].insert(state_id); } set deleted_states; @@ -353,14 +353,18 @@ class ParseTableBuilder { map state_replacements; for (auto &pair : state_indices_by_signature) { - auto &state_group = pair.second; + auto &state_indices = pair.second; - for (ParseStateId i : state_group) { - for (ParseStateId j : state_group) { - if (j == i) break; - if (!state_replacements.count(j) && merge_parse_state(j, i)) { - state_replacements.insert({ i, j }); - deleted_states.insert(i); + for (auto i = state_indices.begin(), end = state_indices.end(); i != end;) { + for (ParseStateId j : state_indices) { + if (j == *i) { + ++i; + break; + } + if (!state_replacements.count(j) && merge_parse_state(j, *i)) { + state_replacements.insert({*i, j}); + deleted_states.insert(*i); + i = state_indices.erase(i); break; } } @@ -370,11 +374,8 @@ class ParseTableBuilder { if (state_replacements.empty()) break; for (ParseStateId i = 0, n = parse_table.states.size(); i < n; i++) { - ParseState &state = parse_table.states[i]; - - if (state_replacements.count(i)) { - state_indices_by_signature[state.shift_actions_signature].erase(i); - } else { + if (!state_replacements.count(i)) { + ParseState &state = parse_table.states[i]; state.each_referenced_state([&state_replacements](ParseStateId *state_index) { auto replacement = state_replacements.find(*state_index); if (replacement != state_replacements.end()) { @@ -414,7 +415,7 @@ class ParseTableBuilder { static bool has_entry(const ParseState &state, const ParseTableEntry &entry) { for (const auto &pair : state.terminal_entries) - if (pair.second == entry) + if (pair.second.actions == entry.actions) return true; return false; } @@ -427,13 +428,12 @@ class ParseTableBuilder { for (auto &entry : state.terminal_entries) { Symbol lookahead = entry.first; - const auto &other_entry = other.terminal_entries.find(lookahead); + const auto &other_entry = other.terminal_entries.find(lookahead); if (other_entry == other.terminal_entries.end()) { + if (lookahead.is_external()) return false; if (entry.second.actions.back().type != ParseActionTypeReduce) return false; if (!has_entry(other, entry.second)) return false; - - if (lookahead.is_external()) return false; if (!lookahead.is_built_in()) { for (const Symbol &incompatible_token : incompatible_tokens_by_index[lookahead.index]) { if (other.terminal_entries.count(incompatible_token)) return false; @@ -450,10 +450,9 @@ class ParseTableBuilder { Symbol lookahead = entry.first; if (!state.terminal_entries.count(lookahead)) { + if (lookahead.is_external()) return false; if (entry.second.actions.back().type != ParseActionTypeReduce) return false; if (!has_entry(state, entry.second)) return false; - - if (lookahead.is_external()) return false; if (!lookahead.is_built_in()) { for (const Symbol &incompatible_token : incompatible_tokens_by_index[lookahead.index]) { if (state.terminal_entries.count(incompatible_token)) return false; diff --git a/src/compiler/build_tables/parse_item.cc b/src/compiler/build_tables/parse_item.cc index b672bb1b..99acb3fc 100644 --- a/src/compiler/build_tables/parse_item.cc +++ b/src/compiler/build_tables/parse_item.cc @@ -97,13 +97,12 @@ size_t ParseItemSet::unfinished_item_signature() const { ParseItem previous_item; for (auto &pair : entries) { const ParseItem &item = pair.first; - if (item.step_index < item.production->size()) { - if (item.variable_index != previous_item.variable_index && - item.step_index != previous_item.step_index) { - hash_combine(&result, item.variable_index); - hash_combine(&result, item.step_index); - previous_item = item; - } + if (item.step_index < item.production->size() && + (item.variable_index != previous_item.variable_index || + item.step_index != previous_item.step_index)) { + hash_combine(&result, item.variable_index); + hash_combine(&result, item.step_index); + previous_item = item; } } return result; diff --git a/src/compiler/parse_table.h b/src/compiler/parse_table.h index 555dad31..8a127bed 100644 --- a/src/compiler/parse_table.h +++ b/src/compiler/parse_table.h @@ -69,7 +69,6 @@ struct ParseState { std::map terminal_entries; std::map nonterminal_entries; LexStateId lex_state_id; - size_t shift_actions_signature; }; struct ParseTableSymbolMetadata {