Simplify item set closure function
This commit is contained in:
parent
020614824a
commit
5313bb5257
6 changed files with 31 additions and 41 deletions
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue