From 70ba76762c128e40d2488cf13b5e9b6a1745ce96 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 28 Apr 2014 18:30:50 -0700 Subject: [PATCH] Optimize item set transitions function further --- .../build_tables/item_set_transitions.cc | 47 ++++++++++++------- src/compiler/build_tables/merge_transitions.h | 4 +- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/compiler/build_tables/item_set_transitions.cc b/src/compiler/build_tables/item_set_transitions.cc index add4619f..2e595a1d 100644 --- a/src/compiler/build_tables/item_set_transitions.cc +++ b/src/compiler/build_tables/item_set_transitions.cc @@ -1,5 +1,6 @@ #include "compiler/build_tables/item_set_transitions.h" #include +#include #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 - static unordered_set merge_sets(const unordered_set &left, const unordered_set &right) { - unordered_set result = left; - result.insert(right.begin(), right.end()); - return result; + static unordered_set merge_sets(unordered_set &left, const unordered_set &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 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 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 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 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(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(result, item_transitions, [](const LexItemSet &l, const LexItemSet &r) { + merge_char_transitions(result, item_transitions, [](LexItemSet &l, const LexItemSet &r) { return merge_sets(l, r); }); } diff --git a/src/compiler/build_tables/merge_transitions.h b/src/compiler/build_tables/merge_transitions.h index 7d3794b1..d0319c5b 100644 --- a/src/compiler/build_tables/merge_transitions.h +++ b/src/compiler/build_tables/merge_transitions.h @@ -17,7 +17,7 @@ namespace tree_sitter { template void merge_sym_transitions(std::map &left, const std::map &right, - std::function merge_fn) { + std::function merge_fn) { for (auto &pair : right) { auto rule = pair.first; bool merged = false; @@ -45,7 +45,7 @@ namespace tree_sitter { template void merge_char_transitions(std::map &left, const std::map &right, - std::function merge_fn) { + std::function merge_fn) { for (auto &new_pair : right) { rules::CharacterSet new_char_set = new_pair.first; T new_value = new_pair.second;