Remove rule-specific logic from transition map
This commit is contained in:
parent
c10bcf4fab
commit
b3b5b8a05a
13 changed files with 86 additions and 97 deletions
|
|
@ -15,7 +15,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12E71793181D02A80051A649"
|
||||
BuildableName = "specs"
|
||||
BuildableName = "compiler_specs"
|
||||
BlueprintName = "compiler_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12E71793181D02A80051A649"
|
||||
BuildableName = "specs"
|
||||
BuildableName = "compiler_specs"
|
||||
BlueprintName = "compiler_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12E71793181D02A80051A649"
|
||||
BuildableName = "specs"
|
||||
BuildableName = "compiler_specs"
|
||||
BlueprintName = "compiler_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12E71793181D02A80051A649"
|
||||
BuildableName = "specs"
|
||||
BuildableName = "compiler_specs"
|
||||
BlueprintName = "compiler_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12FD40B1185EEB5E0041A84E"
|
||||
BuildableName = "specs copy"
|
||||
BuildableName = "runtime_specs"
|
||||
BlueprintName = "runtime_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12FD40B1185EEB5E0041A84E"
|
||||
BuildableName = "specs copy"
|
||||
BuildableName = "runtime_specs"
|
||||
BlueprintName = "runtime_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12FD40B1185EEB5E0041A84E"
|
||||
BuildableName = "specs copy"
|
||||
BuildableName = "runtime_specs"
|
||||
BlueprintName = "runtime_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "12FD40B1185EEB5E0041A84E"
|
||||
BuildableName = "specs copy"
|
||||
BuildableName = "runtime_specs"
|
||||
BlueprintName = "runtime_specs"
|
||||
ReferencedContainer = "container:TreeSitter.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ Describe(item_sets) {
|
|||
|
||||
AssertThat(
|
||||
set.sym_transitions(grammar),
|
||||
EqualsContainer(TransitionMap<ItemSet>({
|
||||
Equals(transition_map<rules::Rule, 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) },
|
||||
}), TransitionMap<ItemSet>::elements_equal));
|
||||
})));
|
||||
}
|
||||
|
||||
It(computes_character_transitions) {
|
||||
|
|
@ -46,11 +46,11 @@ Describe(item_sets) {
|
|||
|
||||
AssertThat(
|
||||
set.char_transitions(grammar),
|
||||
EqualsContainer(TransitionMap<ItemSet>({
|
||||
Equals(transition_map<rules::Rule, ItemSet>({
|
||||
{ char_class(CharClassTypeWord), item_set({ Item("variable", choice({ repeat(char_class(CharClassTypeWord)), blank() }), 1) }) },
|
||||
{ char_class(CharClassTypeDigit), item_set({ Item("number", choice({ repeat(char_class(CharClassTypeDigit)), blank() }), 1) }) },
|
||||
{ character('('), item_set({ Item("left_paren", blank(), 1) }) }
|
||||
}), TransitionMap<ItemSet>::elements_equal));
|
||||
})));
|
||||
}
|
||||
|
||||
It(can_be_hashed) {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Describe(Rules) {
|
|||
It(handles_symbols) {
|
||||
AssertThat(
|
||||
rules::transitions(symbol1),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ symbol1, rules::blank() }
|
||||
})));
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ Describe(Rules) {
|
|||
It(handles_characters) {
|
||||
AssertThat(
|
||||
rules::transitions(char1),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ char1, rules::blank() }
|
||||
})));
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ Describe(Rules) {
|
|||
auto rule = rules::char_class(rules::CharClassTypeDigit);
|
||||
AssertThat(
|
||||
rules::transitions(rule),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ rule, rules::blank() }
|
||||
})));
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ Describe(Rules) {
|
|||
It(handles_choices) {
|
||||
AssertThat(
|
||||
rules::transitions(rules::choice({ symbol1, symbol2 })),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ symbol1, rules::blank() },
|
||||
{ symbol2, rules::blank() }
|
||||
})));
|
||||
|
|
@ -64,7 +64,7 @@ Describe(Rules) {
|
|||
It(handles_sequences) {
|
||||
AssertThat(
|
||||
rules::transitions(rules::seq({ symbol1, symbol2 })),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ symbol1, symbol2 }
|
||||
})));
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ Describe(Rules) {
|
|||
symbol3,
|
||||
symbol4
|
||||
})),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ symbol1, rules::seq({ symbol2, symbol3, symbol4 }) }
|
||||
})));
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ Describe(Rules) {
|
|||
rules::choice({
|
||||
rules::seq({ symbol1, symbol2 }),
|
||||
rules::seq({ symbol1, symbol3 }) })),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ symbol1, rules::choice({ symbol2, symbol3 }) }
|
||||
})));
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ Describe(Rules) {
|
|||
It(handles_strings) {
|
||||
AssertThat(
|
||||
rules::transitions(rules::str("bad")),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{
|
||||
rules::character('b'),
|
||||
rules::seq({ rules::character('a'), rules::character('d') })
|
||||
|
|
@ -107,7 +107,7 @@ Describe(Rules) {
|
|||
It(handles_patterns) {
|
||||
AssertThat(
|
||||
rules::transitions(rules::pattern("a|b")),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{ rules::character('a'), rules::blank() },
|
||||
{ rules::character('b'), rules::blank() }
|
||||
})));
|
||||
|
|
@ -117,7 +117,7 @@ Describe(Rules) {
|
|||
rules::rule_ptr repeat = rules::repeat(rules::str("ab"));
|
||||
AssertThat(
|
||||
rules::transitions(repeat),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{
|
||||
rules::character('a'),
|
||||
rules::seq({
|
||||
|
|
@ -132,7 +132,7 @@ Describe(Rules) {
|
|||
repeat = rules::repeat(rules::str("a"));
|
||||
AssertThat(
|
||||
rules::transitions(repeat),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
Equals(transition_map<rules::Rule, rules::Rule>({
|
||||
{
|
||||
rules::character('a'),
|
||||
rules::choice({
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
#include "spec_helper.h"
|
||||
|
||||
|
||||
EqualsContainerConstraint<TransitionMap<rules::Rule>, rule_tmap_comparator> EqualsTransitionMap(const TransitionMap<rules::Rule> &expected) {
|
||||
return EqualsContainer(expected, TransitionMap<rules::Rule>::elements_equal);
|
||||
}
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace lr {
|
||||
std::ostream& operator<<(std::ostream &stream, const unordered_map<string, unordered_set<ParseAction>> &map) {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,6 @@ using namespace tree_sitter;
|
|||
using namespace std;
|
||||
using namespace igloo;
|
||||
|
||||
// Assertion helpers for transition maps
|
||||
typedef bool (* rule_tmap_comparator)(const std::pair<rules::rule_ptr, rules::rule_ptr> &, const std::pair<rules::rule_ptr, rules::rule_ptr> &);
|
||||
EqualsContainerConstraint<TransitionMap<rules::Rule>, rule_tmap_comparator> EqualsTransitionMap(const TransitionMap<rules::Rule> &expected);
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace lr {
|
||||
std::ostream& operator<<(std::ostream &stream, const unordered_map<string, unordered_set<ParseAction>> &map);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ namespace tree_sitter {
|
|||
return Item(rule_name, grammar.rule(rule_name), 0);
|
||||
}
|
||||
|
||||
TransitionMap<Item> Item::transitions() const {
|
||||
return rules::transitions(rule).map<Item>([&](rules::rule_ptr to_rule) {
|
||||
transition_map<rules::Rule, Item> Item::transitions() const {
|
||||
return rules::transitions(rule).map<Item>([&](rules::rule_ptr to_rule) -> item_ptr {
|
||||
return std::make_shared<Item>(rule_name, to_rule, consumed_sym_count + 1);
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,12 +10,15 @@ namespace tree_sitter {
|
|||
class Grammar;
|
||||
|
||||
namespace lr {
|
||||
class Item;
|
||||
typedef std::shared_ptr<const Item> item_ptr;
|
||||
|
||||
class Item {
|
||||
public:
|
||||
Item(const std::string &rule_name, const rules::rule_ptr rule, int consumed_sym_count);
|
||||
static Item at_beginning_of_rule(const std::string &rule_name, const Grammar &grammar);
|
||||
|
||||
TransitionMap<Item> transitions() const;
|
||||
transition_map<rules::Rule, Item> transitions() const;
|
||||
std::vector<rules::Symbol> next_symbols() const;
|
||||
bool operator==(const Item &other) const;
|
||||
bool is_done() const;
|
||||
|
|
@ -25,7 +28,7 @@ namespace tree_sitter {
|
|||
const int consumed_sym_count;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<const Item> item_ptr;
|
||||
// typedef std::shared_ptr<const Item> item_ptr;
|
||||
std::ostream& operator<<(std::ostream &stream, const Item &item);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ namespace tree_sitter {
|
|||
|
||||
ItemSet::ItemSet(const Item &item, const Grammar &grammar) : contents(closure_in_grammar(item, grammar)) {}
|
||||
|
||||
TransitionMap<ItemSet> ItemSet::char_transitions(const Grammar &grammar) const {
|
||||
auto result = TransitionMap<ItemSet>();
|
||||
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([&](const rules::rule_ptr &on_rule) -> bool {
|
||||
.where([&](rules::rule_ptr on_rule) -> bool {
|
||||
return typeid(*on_rule) != typeid(rules::Symbol);
|
||||
})
|
||||
.map<ItemSet>([&](const item_ptr &item) -> item_set_ptr {
|
||||
|
|
@ -48,11 +48,11 @@ namespace tree_sitter {
|
|||
return result;
|
||||
}
|
||||
|
||||
TransitionMap<ItemSet> ItemSet::sym_transitions(const Grammar &grammar) const {
|
||||
auto result = TransitionMap<ItemSet>();
|
||||
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([&](const rules::rule_ptr &on_rule) -> bool {
|
||||
.where([&](rules::rule_ptr on_rule) -> bool {
|
||||
return typeid(*on_rule) == typeid(rules::Symbol);
|
||||
})
|
||||
.map<ItemSet>([&](const item_ptr &item) -> item_set_ptr {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ namespace tree_sitter {
|
|||
const_iterator end() const;
|
||||
size_t size() const;
|
||||
|
||||
TransitionMap<ItemSet> sym_transitions(const Grammar &grammar) const;
|
||||
TransitionMap<ItemSet> char_transitions(const Grammar &grammar) const;
|
||||
transition_map<rules::Rule, ItemSet> char_transitions(const Grammar &grammar) const;
|
||||
transition_map<rules::Rule, ItemSet> sym_transitions(const Grammar &grammar) const;
|
||||
|
||||
bool operator==(const ItemSet &other) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,22 +5,22 @@ namespace tree_sitter {
|
|||
namespace rules {
|
||||
class TransitionsVisitor : public Visitor {
|
||||
public:
|
||||
TransitionMap<Rule> value;
|
||||
transition_map<Rule, Rule> value;
|
||||
|
||||
void visit(const Blank *rule) {
|
||||
value = TransitionMap<Rule>();
|
||||
value = transition_map<Rule, Rule>();
|
||||
}
|
||||
|
||||
void visit(const CharClass *rule) {
|
||||
value = TransitionMap<Rule>({{ char_class(rule->value), blank() }});
|
||||
value = transition_map<Rule, Rule>({{ char_class(rule->value), blank() }});
|
||||
}
|
||||
|
||||
void visit(const Char *rule) {
|
||||
value = TransitionMap<Rule>({{ character(rule->value), blank() }});
|
||||
value = transition_map<Rule, Rule>({{ character(rule->value), blank() }});
|
||||
}
|
||||
|
||||
void visit(const Symbol *rule) {
|
||||
value = TransitionMap<Rule>({{ sym(rule->name), blank() }});
|
||||
value = transition_map<Rule, Rule>({{ sym(rule->name), blank() }});
|
||||
}
|
||||
|
||||
void visit(const Choice *rule) {
|
||||
|
|
@ -31,7 +31,7 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
void visit(const Seq *rule) {
|
||||
value = transitions(rule->left).map<Rule>([&](rule_ptr left_rule) -> rule_ptr {
|
||||
value = transitions(rule->left).map<Rule>([&](const rule_ptr left_rule) -> rule_ptr {
|
||||
if (typeid(*left_rule) == typeid(Blank))
|
||||
return rule->right;
|
||||
else
|
||||
|
|
@ -57,7 +57,7 @@ namespace tree_sitter {
|
|||
}
|
||||
};
|
||||
|
||||
TransitionMap<Rule> transitions(const rule_ptr &rule) {
|
||||
transition_map<Rule, Rule> transitions(const rule_ptr &rule) {
|
||||
TransitionsVisitor visitor;
|
||||
rule->accept(visitor);
|
||||
return visitor.value;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
TransitionMap<Rule> transitions(const rule_ptr &rule);
|
||||
transition_map<Rule, Rule> transitions(const rule_ptr &rule);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,50 +7,34 @@
|
|||
#include "rule.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
template<typename MappedType>
|
||||
class TransitionMap {
|
||||
typedef std::shared_ptr<const rules::Rule> rule_ptr;
|
||||
typedef std::shared_ptr<const MappedType> mapped_ptr;
|
||||
typedef std::pair<rule_ptr, mapped_ptr> pair_type;
|
||||
template<typename TKey, typename TValue>
|
||||
class transition_map {
|
||||
typedef std::shared_ptr<const TKey> TKeyPtr;
|
||||
typedef std::shared_ptr<const TValue> TValuePtr;
|
||||
typedef std::pair<const TKeyPtr, TValuePtr> pair_type;
|
||||
typedef std::vector<pair_type> contents_type;
|
||||
|
||||
public:
|
||||
static bool elements_equal(const pair_type &left, const pair_type &right) {
|
||||
return (*left.first == *right.first) && (*left.second == *right.second);
|
||||
|
||||
transition_map() : contents(contents_type()) {};
|
||||
transition_map(std::initializer_list<pair_type> pairs) : contents(pairs) {};
|
||||
|
||||
bool operator==(const transition_map<TKey, TValue> &other) const {
|
||||
if (size() != other.size()) return false;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
auto left = contents[i];
|
||||
auto right = other.contents[i];
|
||||
if (!(*left.first == *right.first) ||
|
||||
!(*left.second == *right.second)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TransitionMap() : contents(contents_type()) {};
|
||||
TransitionMap(std::initializer_list<std::pair<rule_ptr, mapped_ptr>> pairs) : contents(pairs) {};
|
||||
|
||||
typedef typename contents_type::const_iterator const_iterator;
|
||||
typedef typename contents_type::iterator iterator;
|
||||
|
||||
iterator begin() { return contents.begin(); }
|
||||
iterator end() { return contents.end(); }
|
||||
const_iterator begin() const { return contents.begin(); }
|
||||
const_iterator end() const { return contents.end(); }
|
||||
|
||||
void add(const rule_ptr on_rule, const mapped_ptr to_value) {
|
||||
contents.push_back(pair_type(on_rule, to_value));
|
||||
void add(TKeyPtr key, TValuePtr value) {
|
||||
contents.push_back(pair_type(key, value));
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return contents.size();
|
||||
}
|
||||
|
||||
mapped_ptr operator[](rules::Rule const &on_rule) const {
|
||||
pair_type *pair = pair_for_key(on_rule);
|
||||
if (pair)
|
||||
return pair->second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mapped_ptr operator[](int i) const {
|
||||
return contents[i].second;
|
||||
}
|
||||
|
||||
void merge(const TransitionMap<MappedType> &other, std::function<mapped_ptr(mapped_ptr, mapped_ptr)> merge_fn) {
|
||||
void merge(const transition_map<TKey, TValue> &other, std::function<TValuePtr(TValuePtr, TValuePtr)> merge_fn) {
|
||||
for (pair_type other_pair : other) {
|
||||
if (pair_type *current_pair = pair_for_key(*other_pair.first))
|
||||
current_pair->second = merge_fn(current_pair->second, other_pair.second);
|
||||
|
|
@ -59,18 +43,17 @@ namespace tree_sitter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
TransitionMap<MappedType> where(std::function<bool(rule_ptr)> filter_fn) {
|
||||
TransitionMap<MappedType> result;
|
||||
transition_map<TKey, TValue> where(std::function<bool(TKeyPtr)> filter_fn) {
|
||||
transition_map<TKey, TValue> result;
|
||||
for (pair_type pair : *this)
|
||||
if (filter_fn(pair.first))
|
||||
result.add(pair.first, pair.second);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename NewMappedType>
|
||||
TransitionMap<NewMappedType> map(std::function<std::shared_ptr<const NewMappedType>(mapped_ptr)> map_fn) {
|
||||
TransitionMap<NewMappedType> result;
|
||||
template<typename NewV>
|
||||
transition_map<TKey, NewV> map(std::function<const std::shared_ptr<const NewV>(TValuePtr)> map_fn) {
|
||||
transition_map<TKey, NewV> result;
|
||||
for (pair_type pair : *this) {
|
||||
auto new_value = map_fn(pair.second);
|
||||
result.add(pair.first, new_value);
|
||||
|
|
@ -78,8 +61,19 @@ namespace tree_sitter {
|
|||
return result;
|
||||
}
|
||||
|
||||
#pragma mark - Container
|
||||
|
||||
typedef typename contents_type::const_iterator const_iterator;
|
||||
typedef typename contents_type::iterator iterator;
|
||||
iterator begin() { return contents.begin(); }
|
||||
iterator end() { return contents.end(); }
|
||||
const_iterator begin() const { return contents.begin(); }
|
||||
const_iterator end() const { return contents.end(); }
|
||||
size_t size() const { return contents.size(); }
|
||||
|
||||
private:
|
||||
pair_type * pair_for_key(rules::Rule const &key) {
|
||||
|
||||
pair_type * pair_for_key(const TKey &key) {
|
||||
for (int i = 0; i < contents.size(); i++) {
|
||||
pair_type *pair = &contents[i];
|
||||
if (*pair->first == key) return pair;
|
||||
|
|
@ -90,8 +84,8 @@ namespace tree_sitter {
|
|||
contents_type contents;
|
||||
};
|
||||
|
||||
template<typename MappedType>
|
||||
std::ostream& operator<<(std::ostream &stream, const TransitionMap<MappedType> &map) {
|
||||
template<typename K, typename V>
|
||||
std::ostream& operator<<(std::ostream &stream, const transition_map<K, V> &map) {
|
||||
stream << std::string("[");
|
||||
bool started = false;
|
||||
for (auto pair : map) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue