From 323184f981f1ddfacd192d7a48af9b1a8c1d6c24 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sun, 22 Dec 2013 00:19:55 -0800 Subject: [PATCH] Improve type-safety of ItemSet transitions methods --- spec/compiler/lr/item_set_spec.cpp | 4 +- src/compiler/lr/item_set.cpp | 53 ++++++++++--------------- src/compiler/lr/item_set.h | 4 +- src/compiler/lr/parse_table_builder.cpp | 7 ++-- src/compiler/rules/character.h | 2 + src/compiler/rules/rules.cpp | 6 +-- src/compiler/rules/rules.h | 8 ++-- src/compiler/rules/symbol.h | 4 +- 8 files changed, 42 insertions(+), 46 deletions(-) diff --git a/spec/compiler/lr/item_set_spec.cpp b/spec/compiler/lr/item_set_spec.cpp index 8eaaec9f..8895d364 100644 --- a/spec/compiler/lr/item_set_spec.cpp +++ b/spec/compiler/lr/item_set_spec.cpp @@ -33,7 +33,7 @@ Describe(item_sets) { AssertThat( set.sym_transitions(grammar), - Equals(transition_map({ + Equals(transition_map({ { sym("variable"), item_set({ Item("factor", blank(), 1) }) }, { sym("number"), item_set({ Item("factor", blank(), 1) }) }, { sym("left_paren"), std::make_shared(Item("factor", seq({ sym("expression"), sym("right_paren") }), 1), grammar) }, @@ -46,7 +46,7 @@ Describe(item_sets) { AssertThat( set.char_transitions(grammar), - Equals(transition_map({ + Equals(transition_map({ { character(CharClassWord), item_set({ Item("variable", choice({ repeat(character(CharClassWord)), blank() }), 1) }) }, { character(CharClassDigit), item_set({ Item("number", choice({ repeat(character(CharClassDigit)), blank() }), 1) }) }, { character('('), item_set({ Item("left_paren", blank(), 1) }) } diff --git a/src/compiler/lr/item_set.cpp b/src/compiler/lr/item_set.cpp index bf320817..fef8c66c 100644 --- a/src/compiler/lr/item_set.cpp +++ b/src/compiler/lr/item_set.cpp @@ -1,8 +1,10 @@ #include "item_set.h" -#include - -using namespace std; +using std::vector; +using std::initializer_list; +using std::dynamic_pointer_cast; +using std::ostream; +using std::string; namespace tree_sitter { namespace lr { @@ -31,38 +33,27 @@ namespace tree_sitter { ItemSet::ItemSet(const Item &item, const Grammar &grammar) : contents(closure_in_grammar(item, grammar)) {} - transition_map ItemSet::char_transitions(const Grammar &grammar) const { - transition_map result; - for (auto item : *this) { - auto new_set = item.transitions() - .where([&](rules::rule_ptr on_rule) -> bool { - return typeid(*on_rule) != typeid(rules::Symbol); - }) - .map([&](const item_ptr &item) -> item_set_ptr { - return std::make_shared(*item, grammar); - }); - result.merge(new_set, [&](const item_set_ptr left, const item_set_ptr right) -> item_set_ptr { - return left; - }); + template + static transition_map transitions(const ItemSet &item_set, const Grammar &grammar) { + transition_map result; + for (auto item : item_set) { + auto item_transitions = item.transitions(); + for (auto pair : item_transitions) { + std::shared_ptr rule = dynamic_pointer_cast(pair.first); + Item item = *pair.second; + if (rule.get() != nullptr) + result.add(rule, std::make_shared(item, grammar)); + } } return result; } - transition_map ItemSet::sym_transitions(const Grammar &grammar) const { - transition_map result; - for (auto item : *this) { - auto new_set = item.transitions() - .where([&](rules::rule_ptr on_rule) -> bool { - return typeid(*on_rule) == typeid(rules::Symbol); - }) - .map([&](const item_ptr &item) -> item_set_ptr { - return std::make_shared(*item, grammar); - }); - result.merge(new_set, [&](const item_set_ptr left, const item_set_ptr right) -> item_set_ptr { - return left; - }); - } - return result; + transition_map ItemSet::char_transitions(const Grammar &grammar) const { + return transitions(*this, grammar); + } + + transition_map ItemSet::sym_transitions(const Grammar &grammar) const { + return transitions(*this, grammar); } bool ItemSet::operator==(const tree_sitter::lr::ItemSet &other) const { diff --git a/src/compiler/lr/item_set.h b/src/compiler/lr/item_set.h index 128cad52..a662282a 100644 --- a/src/compiler/lr/item_set.h +++ b/src/compiler/lr/item_set.h @@ -22,8 +22,8 @@ namespace tree_sitter { const_iterator end() const; size_t size() const; - transition_map char_transitions(const Grammar &grammar) const; - transition_map sym_transitions(const Grammar &grammar) const; + transition_map char_transitions(const Grammar &grammar) const; + transition_map sym_transitions(const Grammar &grammar) const; bool operator==(const ItemSet &other) const; }; diff --git a/src/compiler/lr/parse_table_builder.cpp b/src/compiler/lr/parse_table_builder.cpp index fbe95164..e0bb055b 100644 --- a/src/compiler/lr/parse_table_builder.cpp +++ b/src/compiler/lr/parse_table_builder.cpp @@ -23,9 +23,10 @@ namespace tree_sitter { void add_shift_actions(const ItemSet &item_set, size_t state_index) { for (auto transition : item_set.sym_transitions(grammar)) { - auto symbol = static_pointer_cast(transition.first); - size_t new_state_index = add_item_set(*transition.second); - table.add_action(state_index, symbol->name, ParseAction::Shift(new_state_index)); + rules::Symbol symbol = *transition.first; + ItemSet item_set = *transition.second; + size_t new_state_index = add_item_set(item_set); + table.add_action(state_index, symbol.name, ParseAction::Shift(new_state_index)); } } diff --git a/src/compiler/rules/character.h b/src/compiler/rules/character.h index 26213bfc..23568cbb 100644 --- a/src/compiler/rules/character.h +++ b/src/compiler/rules/character.h @@ -17,6 +17,8 @@ namespace tree_sitter { const CharMatch value; }; + + typedef std::shared_ptr char_ptr; } } diff --git a/src/compiler/rules/rules.cpp b/src/compiler/rules/rules.cpp index a1f95433..f43caa79 100644 --- a/src/compiler/rules/rules.cpp +++ b/src/compiler/rules/rules.cpp @@ -10,11 +10,11 @@ namespace tree_sitter { return make_shared(); } - rule_ptr character(char value) { + char_ptr character(char value) { return make_shared(value); } - rule_ptr character(CharClass value) { + char_ptr character(CharClass value) { return make_shared(value); } @@ -46,7 +46,7 @@ namespace tree_sitter { return make_shared(value); } - rule_ptr sym(const string &name) { + sym_ptr sym(const string &name) { return make_shared(name); } } diff --git a/src/compiler/rules/rules.h b/src/compiler/rules/rules.h index 46732977..41e4611d 100644 --- a/src/compiler/rules/rules.h +++ b/src/compiler/rules/rules.h @@ -15,15 +15,15 @@ namespace tree_sitter { namespace rules { rule_ptr blank(); - rule_ptr character(char value); - rule_ptr character(char min, char max); - rule_ptr character(CharClass value); + char_ptr character(char value); + char_ptr character(char min, char max); + char_ptr character(CharClass value); rule_ptr choice(const std::initializer_list &rules); rule_ptr pattern(const std::string &value); rule_ptr repeat(const rule_ptr content); rule_ptr seq(const std::initializer_list &rules); rule_ptr str(const std::string &value); - rule_ptr sym(const std::string &name); + sym_ptr sym(const std::string &name); } } diff --git a/src/compiler/rules/symbol.h b/src/compiler/rules/symbol.h index 7c9b0aa6..dbb0d24a 100644 --- a/src/compiler/rules/symbol.h +++ b/src/compiler/rules/symbol.h @@ -13,7 +13,9 @@ namespace tree_sitter { void accept(Visitor &visitor) const; const std::string name; - }; + }; + + typedef std::shared_ptr sym_ptr; } }