Improve type-safety of ItemSet transitions methods
This commit is contained in:
parent
9667b3fd6c
commit
323184f981
8 changed files with 42 additions and 46 deletions
|
|
@ -33,7 +33,7 @@ Describe(item_sets) {
|
|||
|
||||
AssertThat(
|
||||
set.sym_transitions(grammar),
|
||||
Equals(transition_map<rules::Rule, ItemSet>({
|
||||
Equals(transition_map<rules::Symbol, ItemSet>({
|
||||
{ sym("variable"), item_set({ Item("factor", blank(), 1) }) },
|
||||
{ sym("number"), item_set({ Item("factor", blank(), 1) }) },
|
||||
{ sym("left_paren"), std::make_shared<ItemSet>(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<rules::Rule, ItemSet>({
|
||||
Equals(transition_map<rules::Character, ItemSet>({
|
||||
{ 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) }) }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#include "item_set.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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<rules::Rule, ItemSet> ItemSet::char_transitions(const Grammar &grammar) const {
|
||||
transition_map<rules::Rule, ItemSet> 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<ItemSet>([&](const item_ptr &item) -> item_set_ptr {
|
||||
return std::make_shared<ItemSet>(*item, grammar);
|
||||
});
|
||||
result.merge(new_set, [&](const item_set_ptr left, const item_set_ptr right) -> item_set_ptr {
|
||||
return left;
|
||||
});
|
||||
template<typename RuleClass>
|
||||
static transition_map<RuleClass, ItemSet> transitions(const ItemSet &item_set, const Grammar &grammar) {
|
||||
transition_map<RuleClass, ItemSet> result;
|
||||
for (auto item : item_set) {
|
||||
auto item_transitions = item.transitions();
|
||||
for (auto pair : item_transitions) {
|
||||
std::shared_ptr<const RuleClass> rule = dynamic_pointer_cast<const RuleClass>(pair.first);
|
||||
Item item = *pair.second;
|
||||
if (rule.get() != nullptr)
|
||||
result.add(rule, std::make_shared<ItemSet>(item, grammar));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
transition_map<rules::Rule, ItemSet> ItemSet::sym_transitions(const Grammar &grammar) const {
|
||||
transition_map<rules::Rule, ItemSet> 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<ItemSet>([&](const item_ptr &item) -> item_set_ptr {
|
||||
return std::make_shared<ItemSet>(*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<rules::Character, ItemSet> ItemSet::char_transitions(const Grammar &grammar) const {
|
||||
return transitions<rules::Character>(*this, grammar);
|
||||
}
|
||||
|
||||
transition_map<rules::Symbol, ItemSet> ItemSet::sym_transitions(const Grammar &grammar) const {
|
||||
return transitions<rules::Symbol>(*this, grammar);
|
||||
}
|
||||
|
||||
bool ItemSet::operator==(const tree_sitter::lr::ItemSet &other) const {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ namespace tree_sitter {
|
|||
const_iterator end() const;
|
||||
size_t size() const;
|
||||
|
||||
transition_map<rules::Rule, ItemSet> char_transitions(const Grammar &grammar) const;
|
||||
transition_map<rules::Rule, ItemSet> sym_transitions(const Grammar &grammar) const;
|
||||
transition_map<rules::Character, ItemSet> char_transitions(const Grammar &grammar) const;
|
||||
transition_map<rules::Symbol, ItemSet> sym_transitions(const Grammar &grammar) const;
|
||||
|
||||
bool operator==(const ItemSet &other) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<const rules::Symbol>(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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ namespace tree_sitter {
|
|||
|
||||
const CharMatch value;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<const Character> char_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ namespace tree_sitter {
|
|||
return make_shared<Blank>();
|
||||
}
|
||||
|
||||
rule_ptr character(char value) {
|
||||
char_ptr character(char value) {
|
||||
return make_shared<Character>(value);
|
||||
}
|
||||
|
||||
rule_ptr character(CharClass value) {
|
||||
char_ptr character(CharClass value) {
|
||||
return make_shared<Character>(value);
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ namespace tree_sitter {
|
|||
return make_shared<String>(value);
|
||||
}
|
||||
|
||||
rule_ptr sym(const string &name) {
|
||||
sym_ptr sym(const string &name) {
|
||||
return make_shared<Symbol>(name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<rule_ptr> &rules);
|
||||
rule_ptr pattern(const std::string &value);
|
||||
rule_ptr repeat(const rule_ptr content);
|
||||
rule_ptr seq(const std::initializer_list<rule_ptr> &rules);
|
||||
rule_ptr str(const std::string &value);
|
||||
rule_ptr sym(const std::string &name);
|
||||
sym_ptr sym(const std::string &name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ namespace tree_sitter {
|
|||
void accept(Visitor &visitor) const;
|
||||
|
||||
const std::string name;
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<const Symbol> sym_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue