Compute parse state group signature based on the item set
This commit is contained in:
parent
42d37656ea
commit
6cfd009503
5 changed files with 29 additions and 76 deletions
|
|
@ -146,8 +146,8 @@ class ParseTableBuilder {
|
|||
auto pair = parse_state_ids.find(item_set);
|
||||
if (pair == parse_state_ids.end()) {
|
||||
ParseStateId state_id = parse_table.add_state();
|
||||
|
||||
parse_state_ids[item_set] = state_id;
|
||||
parse_table.states[state_id].shift_actions_signature = item_set.unfinished_item_signature();
|
||||
item_sets_to_process.push_back({ std::move(item_set), state_id });
|
||||
return state_id;
|
||||
} else {
|
||||
|
|
@ -176,9 +176,6 @@ class ParseTableBuilder {
|
|||
parse_table.set_nonterminal_action(state_id, symbol.index, next_state);
|
||||
}
|
||||
}
|
||||
|
||||
ParseState &state = parse_table.states[state_id];
|
||||
state.compute_shift_actions_signature();
|
||||
}
|
||||
|
||||
void add_reduce_actions(const ParseItemSet &item_set, ParseStateId state_id) {
|
||||
|
|
@ -285,26 +282,16 @@ class ParseTableBuilder {
|
|||
|
||||
for (ParseStateId i = 0, n = parse_table.states.size(); i < n; i++) {
|
||||
ParseState &state = parse_table.states[i];
|
||||
bool did_update_state = false;
|
||||
|
||||
if (state_replacements.count(i)) {
|
||||
auto &old_group = state_indices_by_signature[state.shift_actions_signature];
|
||||
old_group.erase(i);
|
||||
state_indices_by_signature[state.shift_actions_signature].erase(i);
|
||||
} else {
|
||||
state.each_referenced_state([&state_replacements, &did_update_state](int64_t *state_index) {
|
||||
auto new_replacement = state_replacements.find(*state_index);
|
||||
if (new_replacement != state_replacements.end()) {
|
||||
*state_index = new_replacement->second;
|
||||
did_update_state = true;
|
||||
state.each_referenced_state([&state_replacements](int64_t *state_index) {
|
||||
auto replacement = state_replacements.find(*state_index);
|
||||
if (replacement != state_replacements.end()) {
|
||||
*state_index = replacement->second;
|
||||
}
|
||||
});
|
||||
|
||||
if (did_update_state) {
|
||||
auto &old_group = state_indices_by_signature[state.shift_actions_signature];
|
||||
old_group.erase(i);
|
||||
state.compute_shift_actions_signature();
|
||||
state_indices_by_signature[state.shift_actions_signature].insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include "compiler/syntax_grammar.h"
|
||||
#include "compiler/rules/built_in_symbols.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
|
|
@ -12,6 +13,9 @@ using std::string;
|
|||
using std::to_string;
|
||||
using std::hash;
|
||||
using rules::Symbol;
|
||||
using util::hash_combine;
|
||||
|
||||
ParseItem::ParseItem() : variable_index(-1), production(nullptr), step_index(0) {}
|
||||
|
||||
ParseItem::ParseItem(const Symbol &lhs, const Production &production,
|
||||
unsigned int step_index)
|
||||
|
|
@ -108,6 +112,23 @@ size_t ParseItemSet::Hash::operator()(const ParseItemSet &item_set) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
size_t ParseItemSet::unfinished_item_signature() const {
|
||||
size_t result = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ParseItemSet::TransitionMap ParseItemSet::transitions() const {
|
||||
ParseItemSet::TransitionMap result;
|
||||
for (const auto &pair : entries) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace build_tables {
|
|||
|
||||
class ParseItem {
|
||||
public:
|
||||
ParseItem();
|
||||
ParseItem(const rules::Symbol &, const Production &, unsigned int);
|
||||
|
||||
struct CompletionStatus {
|
||||
|
|
@ -54,6 +55,7 @@ class ParseItemSet {
|
|||
TransitionMap transitions() const;
|
||||
bool operator==(const ParseItemSet &) const;
|
||||
void add(const ParseItemSet &);
|
||||
size_t unfinished_item_signature() const;
|
||||
|
||||
std::map<ParseItem, LookaheadSet> entries;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue