Optimize item set transitions function further
This commit is contained in:
parent
ae2450d282
commit
70ba76762c
2 changed files with 33 additions and 18 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#include "compiler/build_tables/item_set_transitions.h"
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include "compiler/build_tables/item_set_closure.h"
|
||||
#include "compiler/build_tables/rule_transitions.h"
|
||||
#include "compiler/build_tables/merge_transitions.h"
|
||||
|
|
@ -7,26 +8,27 @@
|
|||
|
||||
namespace tree_sitter {
|
||||
using std::map;
|
||||
using std::vector;
|
||||
using std::unordered_set;
|
||||
using rules::CharacterSet;
|
||||
using rules::ISymbol;
|
||||
|
||||
namespace build_tables {
|
||||
template<typename T>
|
||||
static unordered_set<T> merge_sets(const unordered_set<T> &left, const unordered_set<T> &right) {
|
||||
unordered_set<T> result = left;
|
||||
result.insert(right.begin(), right.end());
|
||||
return result;
|
||||
static unordered_set<T> merge_sets(unordered_set<T> &left, const unordered_set<T> &right) {
|
||||
left.insert(right.begin(), right.end());
|
||||
return left;
|
||||
}
|
||||
|
||||
const ISymbol placeholder = ISymbol(-99);
|
||||
const ISymbol placeholder_lookahead = ISymbol(-100);
|
||||
const ISymbol placeholder_lhs = ISymbol(-101);
|
||||
|
||||
static map<ISymbol, ParseItemSet> sym_transitions_for_rule(SymTransitions *self, const rules::rule_ptr &rule, const PreparedGrammar &grammar) {
|
||||
auto pair = self->transitions_cache.find(rule);
|
||||
if (pair != self->transitions_cache.end()) return pair->second;
|
||||
map<ISymbol, ParseItemSet> result;
|
||||
for (auto &transition : sym_transitions(rule)) {
|
||||
ParseItem new_item(placeholder, transition.second, 10, placeholder);
|
||||
ParseItem new_item(placeholder_lhs, transition.second, 1, placeholder_lookahead);
|
||||
result.insert({
|
||||
transition.first,
|
||||
item_set_closure(new_item, grammar)
|
||||
|
|
@ -39,18 +41,31 @@ namespace tree_sitter {
|
|||
static map<ISymbol, ParseItemSet> sym_transitions_for_item(SymTransitions *self, const ParseItem &item, const PreparedGrammar &grammar) {
|
||||
auto result = sym_transitions_for_rule(self, item.rule, grammar);
|
||||
for (auto &pair : result) {
|
||||
ParseItemSet new_items;
|
||||
for (auto &i : pair.second) {
|
||||
ParseItem new_item(i);
|
||||
if (new_item.consumed_symbol_count > 0)
|
||||
vector<ParseItem> new_items;
|
||||
auto &items = pair.second;
|
||||
for (auto iter = items.begin(), end = items.end(); iter != end;) {
|
||||
ParseItem new_item(*iter);
|
||||
bool changed = false;
|
||||
if (new_item.consumed_symbol_count > 0) {
|
||||
new_item.consumed_symbol_count = item.consumed_symbol_count + 1;
|
||||
if (new_item.lookahead_sym == placeholder)
|
||||
changed = true;
|
||||
}
|
||||
if (new_item.lookahead_sym == placeholder_lookahead) {
|
||||
new_item.lookahead_sym = item.lookahead_sym;
|
||||
if (new_item.lhs == placeholder)
|
||||
changed = true;
|
||||
}
|
||||
if (new_item.lhs == placeholder_lhs) {
|
||||
new_item.lhs = item.lhs;
|
||||
new_items.insert(new_item);
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
iter = pair.second.erase(iter);
|
||||
new_items.push_back(new_item);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
pair.second = new_items;
|
||||
pair.second.insert(new_items.begin(), new_items.end());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -61,7 +76,7 @@ namespace tree_sitter {
|
|||
for (const ParseItem &item : item_set)
|
||||
merge_sym_transitions<ParseItemSet>(result,
|
||||
sym_transitions_for_item(this, item, grammar),
|
||||
[&](const ParseItemSet &l, const ParseItemSet &r) {
|
||||
[&](ParseItemSet &l, const ParseItemSet &r) {
|
||||
return merge_sets(l, r);
|
||||
});
|
||||
return result;
|
||||
|
|
@ -79,7 +94,7 @@ namespace tree_sitter {
|
|||
LexItemSet({ next_item })
|
||||
});
|
||||
}
|
||||
merge_char_transitions<LexItemSet>(result, item_transitions, [](const LexItemSet &l, const LexItemSet &r) {
|
||||
merge_char_transitions<LexItemSet>(result, item_transitions, [](LexItemSet &l, const LexItemSet &r) {
|
||||
return merge_sets(l, r);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace tree_sitter {
|
|||
template<typename T>
|
||||
void merge_sym_transitions(std::map<rules::ISymbol, T> &left,
|
||||
const std::map<rules::ISymbol, T> &right,
|
||||
std::function<T(const T &, const T &)> merge_fn) {
|
||||
std::function<T(T &, const T &)> merge_fn) {
|
||||
for (auto &pair : right) {
|
||||
auto rule = pair.first;
|
||||
bool merged = false;
|
||||
|
|
@ -45,7 +45,7 @@ namespace tree_sitter {
|
|||
template<typename T>
|
||||
void merge_char_transitions(std::map<rules::CharacterSet, T> &left,
|
||||
const std::map<rules::CharacterSet, T> &right,
|
||||
std::function<T(const T &, const T &)> merge_fn) {
|
||||
std::function<T(T &, const T &)> merge_fn) {
|
||||
for (auto &new_pair : right) {
|
||||
rules::CharacterSet new_char_set = new_pair.first;
|
||||
T new_value = new_pair.second;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue