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 "compiler/build_tables/item_set_transitions.h"
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
#include "compiler/build_tables/item_set_closure.h"
|
#include "compiler/build_tables/item_set_closure.h"
|
||||||
#include "compiler/build_tables/rule_transitions.h"
|
#include "compiler/build_tables/rule_transitions.h"
|
||||||
#include "compiler/build_tables/merge_transitions.h"
|
#include "compiler/build_tables/merge_transitions.h"
|
||||||
|
|
@ -7,26 +8,27 @@
|
||||||
|
|
||||||
namespace tree_sitter {
|
namespace tree_sitter {
|
||||||
using std::map;
|
using std::map;
|
||||||
|
using std::vector;
|
||||||
using std::unordered_set;
|
using std::unordered_set;
|
||||||
using rules::CharacterSet;
|
using rules::CharacterSet;
|
||||||
using rules::ISymbol;
|
using rules::ISymbol;
|
||||||
|
|
||||||
namespace build_tables {
|
namespace build_tables {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static unordered_set<T> merge_sets(const unordered_set<T> &left, const unordered_set<T> &right) {
|
static unordered_set<T> merge_sets(unordered_set<T> &left, const unordered_set<T> &right) {
|
||||||
unordered_set<T> result = left;
|
left.insert(right.begin(), right.end());
|
||||||
result.insert(right.begin(), right.end());
|
return left;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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);
|
auto pair = self->transitions_cache.find(rule);
|
||||||
if (pair != self->transitions_cache.end()) return pair->second;
|
if (pair != self->transitions_cache.end()) return pair->second;
|
||||||
map<ISymbol, ParseItemSet> result;
|
map<ISymbol, ParseItemSet> result;
|
||||||
for (auto &transition : sym_transitions(rule)) {
|
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({
|
result.insert({
|
||||||
transition.first,
|
transition.first,
|
||||||
item_set_closure(new_item, grammar)
|
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) {
|
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);
|
auto result = sym_transitions_for_rule(self, item.rule, grammar);
|
||||||
for (auto &pair : result) {
|
for (auto &pair : result) {
|
||||||
ParseItemSet new_items;
|
vector<ParseItem> new_items;
|
||||||
for (auto &i : pair.second) {
|
auto &items = pair.second;
|
||||||
ParseItem new_item(i);
|
for (auto iter = items.begin(), end = items.end(); iter != end;) {
|
||||||
if (new_item.consumed_symbol_count > 0)
|
ParseItem new_item(*iter);
|
||||||
|
bool changed = false;
|
||||||
|
if (new_item.consumed_symbol_count > 0) {
|
||||||
new_item.consumed_symbol_count = item.consumed_symbol_count + 1;
|
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;
|
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_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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +76,7 @@ namespace tree_sitter {
|
||||||
for (const ParseItem &item : item_set)
|
for (const ParseItem &item : item_set)
|
||||||
merge_sym_transitions<ParseItemSet>(result,
|
merge_sym_transitions<ParseItemSet>(result,
|
||||||
sym_transitions_for_item(this, item, grammar),
|
sym_transitions_for_item(this, item, grammar),
|
||||||
[&](const ParseItemSet &l, const ParseItemSet &r) {
|
[&](ParseItemSet &l, const ParseItemSet &r) {
|
||||||
return merge_sets(l, r);
|
return merge_sets(l, r);
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -79,7 +94,7 @@ namespace tree_sitter {
|
||||||
LexItemSet({ next_item })
|
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);
|
return merge_sets(l, r);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace tree_sitter {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void merge_sym_transitions(std::map<rules::ISymbol, T> &left,
|
void merge_sym_transitions(std::map<rules::ISymbol, T> &left,
|
||||||
const std::map<rules::ISymbol, T> &right,
|
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) {
|
for (auto &pair : right) {
|
||||||
auto rule = pair.first;
|
auto rule = pair.first;
|
||||||
bool merged = false;
|
bool merged = false;
|
||||||
|
|
@ -45,7 +45,7 @@ namespace tree_sitter {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void merge_char_transitions(std::map<rules::CharacterSet, T> &left,
|
void merge_char_transitions(std::map<rules::CharacterSet, T> &left,
|
||||||
const std::map<rules::CharacterSet, T> &right,
|
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) {
|
for (auto &new_pair : right) {
|
||||||
rules::CharacterSet new_char_set = new_pair.first;
|
rules::CharacterSet new_char_set = new_pair.first;
|
||||||
T new_value = new_pair.second;
|
T new_value = new_pair.second;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue