Reduce allocations when computing rule transitions
This commit is contained in:
parent
3b388d66cd
commit
e8f2b788d4
4 changed files with 39 additions and 46 deletions
|
|
@ -45,9 +45,9 @@ namespace tree_sitter {
|
|||
map<CharacterSet, LexItemSet> result;
|
||||
for (const LexItem &item : item_set) {
|
||||
map<CharacterSet, LexItemSet> item_transitions = char_transitions(item);
|
||||
result = merge_char_transitions<LexItemSet>(result,
|
||||
item_transitions,
|
||||
[](LexItemSet left, LexItemSet right) {
|
||||
merge_char_transitions<LexItemSet>(result,
|
||||
item_transitions,
|
||||
[](LexItemSet left, LexItemSet right) {
|
||||
return merge_sets(left, right);
|
||||
});
|
||||
}
|
||||
|
|
@ -59,9 +59,9 @@ namespace tree_sitter {
|
|||
map<ISymbol, ParseItemSet> result;
|
||||
for (const ParseItem &item : item_set) {
|
||||
map<ISymbol, ParseItemSet> item_transitions = sym_transitions(item, grammar);
|
||||
result = merge_sym_transitions<ParseItemSet>(result,
|
||||
item_transitions,
|
||||
[&](ParseItemSet left, ParseItemSet right) {
|
||||
merge_sym_transitions<ParseItemSet>(result,
|
||||
item_transitions,
|
||||
[&](ParseItemSet left, ParseItemSet right) {
|
||||
return merge_sets(left, right);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,13 @@ namespace tree_sitter {
|
|||
* using the given function.
|
||||
*/
|
||||
template<typename T>
|
||||
std::map<rules::ISymbol, T>
|
||||
merge_sym_transitions(const std::map<rules::ISymbol, T> &left,
|
||||
const std::map<rules::ISymbol, T> &right,
|
||||
std::function<T(T, T)> merge_fn) {
|
||||
std::map<rules::ISymbol, T> result(left);
|
||||
void merge_sym_transitions(std::map<rules::ISymbol, T> &left,
|
||||
const std::map<rules::ISymbol, T> &right,
|
||||
std::function<T(T, T)> merge_fn) {
|
||||
for (auto &pair : right) {
|
||||
auto rule = pair.first;
|
||||
bool merged = false;
|
||||
for (auto &existing_pair : result) {
|
||||
for (auto &existing_pair : left) {
|
||||
auto existing_rule = existing_pair.first;
|
||||
if (existing_rule == rule) {
|
||||
existing_pair.second = merge_fn(existing_pair.second, pair.second);
|
||||
|
|
@ -32,9 +30,8 @@ namespace tree_sitter {
|
|||
}
|
||||
}
|
||||
if (!merged)
|
||||
result.insert({ pair.first, pair.second });
|
||||
left.insert({ pair.first, pair.second });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -44,19 +41,17 @@ namespace tree_sitter {
|
|||
* merging the two previous values using the given function.
|
||||
*/
|
||||
template<typename T>
|
||||
std::map<rules::CharacterSet, T>
|
||||
merge_char_transitions(const std::map<rules::CharacterSet, T> &left,
|
||||
const std::map<rules::CharacterSet, T> &right,
|
||||
std::function<T(T, T)> merge_fn) {
|
||||
std::map<rules::CharacterSet, T> result(left);
|
||||
void merge_char_transitions(std::map<rules::CharacterSet, T> &left,
|
||||
const std::map<rules::CharacterSet, T> &right,
|
||||
std::function<T(T, T)> merge_fn) {
|
||||
for (auto &new_pair : right) {
|
||||
rules::CharacterSet new_char_set = new_pair.first;
|
||||
T new_value = new_pair.second;
|
||||
|
||||
std::map<rules::CharacterSet, T> pairs_to_insert;
|
||||
|
||||
auto iter = result.begin();
|
||||
while (iter != result.end()) {
|
||||
auto iter = left.begin();
|
||||
while (iter != left.end()) {
|
||||
rules::CharacterSet char_set = iter->first;
|
||||
T value = iter->second;
|
||||
|
||||
|
|
@ -66,18 +61,17 @@ namespace tree_sitter {
|
|||
if (!char_set.is_empty())
|
||||
pairs_to_insert.insert({ char_set, value });
|
||||
pairs_to_insert.insert({ intersection, merge_fn(value, new_value) });
|
||||
result.erase(iter++);
|
||||
left.erase(iter++);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
result.insert(pairs_to_insert.begin(), pairs_to_insert.end());
|
||||
left.insert(pairs_to_insert.begin(), pairs_to_insert.end());
|
||||
|
||||
if (!new_char_set.is_empty())
|
||||
result.insert({ new_char_set, new_pair.second });
|
||||
left.insert({ new_char_set, new_pair.second });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,21 +24,18 @@ namespace tree_sitter {
|
|||
|
||||
namespace build_tables {
|
||||
template<typename T>
|
||||
map<T, rule_ptr>
|
||||
merge_transitions(const map<T, rule_ptr> &left, const map<T, rule_ptr> &right);
|
||||
void merge_transitions(map<T, rule_ptr> &left, const map<T, rule_ptr> &right);
|
||||
|
||||
template<>
|
||||
map<CharacterSet, rule_ptr>
|
||||
merge_transitions(const map<CharacterSet, rule_ptr> &left, const map<CharacterSet, rule_ptr> &right) {
|
||||
return merge_char_transitions<rule_ptr>(left, right, [](rule_ptr left, rule_ptr right) {
|
||||
void merge_transitions(map<CharacterSet, rule_ptr> &left, const map<CharacterSet, rule_ptr> &right) {
|
||||
merge_char_transitions<rule_ptr>(left, right, [](rule_ptr left, rule_ptr right) {
|
||||
return make_shared<rules::Choice>(left, right);
|
||||
});
|
||||
}
|
||||
|
||||
template<>
|
||||
map<ISymbol, rule_ptr>
|
||||
merge_transitions(const map<ISymbol, rule_ptr> &left, const map<ISymbol, rule_ptr> &right) {
|
||||
return merge_sym_transitions<rule_ptr>(left, right, [](rule_ptr left, rule_ptr right) {
|
||||
void merge_transitions(map<ISymbol, rule_ptr> &left, const map<ISymbol, rule_ptr> &right) {
|
||||
merge_sym_transitions<rule_ptr>(left, right, [](rule_ptr left, rule_ptr right) {
|
||||
return make_shared<rules::Choice>(left, right);
|
||||
});
|
||||
}
|
||||
|
|
@ -71,9 +68,9 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const rules::Choice *rule) {
|
||||
auto left_transitions = this->apply(rule->left);
|
||||
auto right_transitions = this->apply(rule->right);
|
||||
return merge_transitions<T>(left_transitions, right_transitions);
|
||||
auto result = this->apply(rule->left);
|
||||
merge_transitions<T>(result, this->apply(rule->right));
|
||||
return result;
|
||||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const rules::Seq *rule) {
|
||||
|
|
@ -81,8 +78,7 @@ namespace tree_sitter {
|
|||
return rules::Seq::Build({ left_rule, rule->right });
|
||||
});
|
||||
if (rule_can_be_blank(rule->left)) {
|
||||
auto right_transitions = this->apply(rule->right);
|
||||
result = merge_transitions<T>(result, right_transitions);
|
||||
merge_transitions<T>(result, this->apply(rule->right));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue