Simplify item set closure function

This commit is contained in:
Max Brunsfeld 2014-04-23 13:35:21 -07:00
parent 020614824a
commit 5313bb5257
6 changed files with 31 additions and 41 deletions

View file

@ -19,9 +19,9 @@ describe("computing closures of item sets", []() {
}, {});
it("adds items at the beginnings of referenced rules", [&]() {
ParseItemSet item_set = item_set_closure(ParseItemSet({
ParseItem(ISymbol(0), grammar.rule(ISymbol(0)), 0, ISymbol(10, SymbolOptionToken))
}), grammar);
ParseItemSet item_set = item_set_closure(
ParseItem(ISymbol(0), grammar.rule(ISymbol(0)), 0, ISymbol(10, SymbolOptionToken)),
grammar);
AssertThat(item_set, Equals(ParseItemSet({
ParseItem(ISymbol(1), grammar.rule(ISymbol(1)), 0, ISymbol(11, SymbolOptionToken)),

View file

@ -185,7 +185,7 @@ namespace tree_sitter {
void build() {
auto start_symbol = make_shared<ISymbol>(0);
ParseItem item(rules::START(), start_symbol, {}, rules::END_OF_INPUT());
ParseItemSet item_set = item_set_closure(ParseItemSet({ item }), grammar);
ParseItemSet item_set = item_set_closure(item, grammar);
add_parse_state(item_set);
add_error_lex_state();
}

View file

@ -32,11 +32,10 @@ namespace tree_sitter {
}
}
const ParseItemSet item_set_closure(const ParseItemSet &item_set,
const ParseItemSet item_set_closure(const ParseItem &item,
const PreparedGrammar &grammar) {
ParseItemSet result;
for (const ParseItem &item : item_set)
add_item(&result, item, grammar);
add_item(&result, item, grammar);
return result;
}
}

View file

@ -7,7 +7,7 @@ namespace tree_sitter {
class PreparedGrammar;
namespace build_tables {
const ParseItemSet item_set_closure(const ParseItemSet &item_set,
const ParseItemSet item_set_closure(const ParseItem &item,
const PreparedGrammar &grammar);
}
}

View file

@ -12,27 +12,6 @@ namespace tree_sitter {
using rules::ISymbol;
namespace build_tables {
map<CharacterSet, LexItemSet>
char_transitions(const LexItem &item) {
map<CharacterSet, LexItemSet> result;
for (auto &transition : char_transitions(item.rule)) {
LexItem next_item(item.lhs, transition.second);
result.insert({ transition.first, LexItemSet({ next_item }) });
}
return result;
}
map<ISymbol, ParseItemSet>
sym_transitions(const ParseItem &item, const PreparedGrammar &grammar) {
map<ISymbol, ParseItemSet> result;
for (auto transition : sym_transitions(item.rule)) {
ISymbol rule = transition.first;
ParseItem new_item(item.lhs, transition.second, item.consumed_symbol_count + 1, item.lookahead_sym);
result.insert({ rule, item_set_closure(ParseItemSet({ new_item }), grammar) });
}
return result;
}
template<typename T>
static unordered_set<T> merge_sets(const unordered_set<T> &left, const unordered_set<T> &right) {
unordered_set<T> result = left;
@ -44,11 +23,16 @@ namespace tree_sitter {
char_transitions(const LexItemSet &item_set, const PreparedGrammar &grammar) {
map<CharacterSet, LexItemSet> result;
for (const LexItem &item : item_set) {
map<CharacterSet, LexItemSet> item_transitions = char_transitions(item);
merge_char_transitions<LexItemSet>(result,
item_transitions,
[](LexItemSet left, LexItemSet right) {
return merge_sets(left, right);
map<CharacterSet, LexItemSet> item_transitions;
for (auto &transition : char_transitions(item.rule)) {
LexItem next_item(item.lhs, transition.second);
item_transitions.insert({
transition.first,
LexItemSet({ next_item })
});
}
merge_char_transitions<LexItemSet>(result, item_transitions, [](const LexItemSet &l, const LexItemSet &r) {
return merge_sets(l, r);
});
}
return result;
@ -58,11 +42,16 @@ namespace tree_sitter {
sym_transitions(const ParseItemSet &item_set, const PreparedGrammar &grammar) {
map<ISymbol, ParseItemSet> result;
for (const ParseItem &item : item_set) {
map<ISymbol, ParseItemSet> item_transitions = sym_transitions(item, grammar);
merge_sym_transitions<ParseItemSet>(result,
item_transitions,
[&](ParseItemSet left, ParseItemSet right) {
return merge_sets(left, right);
map<ISymbol, ParseItemSet> item_transitions;
for (auto &transition : sym_transitions(item.rule)) {
ParseItem new_item(item.lhs, transition.second, item.consumed_symbol_count + 1, item.lookahead_sym);
item_transitions.insert({
transition.first,
item_set_closure(new_item, grammar)
});
}
merge_sym_transitions<ParseItemSet>(result, item_transitions, [&](const ParseItemSet &l, const ParseItemSet &r) {
return merge_sets(l, r);
});
}
return result;

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(T, T)> merge_fn) {
std::function<T(const T &, const T &)> merge_fn) {
for (auto &pair : right) {
auto rule = pair.first;
bool merged = false;
@ -27,6 +27,8 @@ namespace tree_sitter {
existing_pair.second = merge_fn(existing_pair.second, pair.second);
merged = true;
break;
} else if (rule < existing_rule) {
break;
}
}
if (!merged)
@ -43,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(T, T)> merge_fn) {
std::function<T(const T &, const T &)> merge_fn) {
for (auto &new_pair : right) {
rules::CharacterSet new_char_set = new_pair.first;
T new_value = new_pair.second;