Optimize item set transitions function further

This commit is contained in:
Max Brunsfeld 2014-04-28 18:30:50 -07:00
parent ae2450d282
commit 70ba76762c
2 changed files with 33 additions and 18 deletions

View file

@ -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);
});
}

View file

@ -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;