Don't store unfinished item signature on ParseStates
This commit is contained in:
parent
1586d70cbe
commit
2755b07222
4 changed files with 29 additions and 32 deletions
2
externals/crypto-algorithms
vendored
2
externals/crypto-algorithms
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit cfbde48414baacf51fc7c74f275190881f037d32
|
||||
Subproject commit c7e5c23ab04ecfb5465cbefbe17ba23d4cb3bc9d
|
||||
|
|
@ -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<size_t, set<ParseStateId>> state_indices_by_signature;
|
||||
unordered_map<size_t, set<ParseStateId>> 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<ParseStateId> deleted_states;
|
||||
|
|
@ -353,14 +353,18 @@ class ParseTableBuilder {
|
|||
map<ParseStateId, ParseStateId> 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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ struct ParseState {
|
|||
std::map<rules::Symbol, ParseTableEntry> terminal_entries;
|
||||
std::map<rules::Symbol::Index, ParseStateId> nonterminal_entries;
|
||||
LexStateId lex_state_id;
|
||||
size_t shift_actions_signature;
|
||||
};
|
||||
|
||||
struct ParseTableSymbolMetadata {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue