Remove now-unused symbol rule-transition functions
This commit is contained in:
parent
c4ef228397
commit
39a0934088
6 changed files with 72 additions and 164 deletions
|
|
@ -6,11 +6,11 @@ using namespace build_tables;
|
|||
|
||||
START_TEST
|
||||
|
||||
describe("merge_char_transitions", []() {
|
||||
describe("merge_transition", []() {
|
||||
typedef map<CharacterSet, int> int_map;
|
||||
|
||||
auto do_merge = [&](int_map *left, const pair<CharacterSet, int> &new_pair) {
|
||||
merge_char_transition<int>(left, new_pair, [](int *l, const int *r) {
|
||||
merge_transition<int>(left, new_pair, [](int *l, const int *r) {
|
||||
*l = *l | *r;
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,10 +5,9 @@
|
|||
using namespace rules;
|
||||
using namespace build_tables;
|
||||
|
||||
template<typename K>
|
||||
class rule_map : public std::map<K, rule_ptr> {
|
||||
class transition_map : public std::map<CharacterSet, rule_ptr> {
|
||||
public:
|
||||
bool operator==(const std::map<K, rule_ptr> &other) const {
|
||||
bool operator==(const std::map<CharacterSet, rule_ptr> &other) const {
|
||||
if (this->size() != other.size()) return false;
|
||||
for (const auto &pair : *this) {
|
||||
auto other_pair = other.find(pair.first);
|
||||
|
|
@ -18,108 +17,72 @@ class rule_map : public std::map<K, rule_ptr> {
|
|||
return true;
|
||||
}
|
||||
|
||||
rule_map(const std::initializer_list<std::pair<const K, rule_ptr>> &list) : std::map<K, rule_ptr>(list) {}
|
||||
transition_map(const std::initializer_list<std::pair<const CharacterSet, rule_ptr>> &list) :
|
||||
std::map<CharacterSet, rule_ptr>(list) {}
|
||||
};
|
||||
|
||||
START_TEST
|
||||
|
||||
describe("sym_transitions", []() {
|
||||
it("handles symbols", [&]() {
|
||||
describe("rule_transitions", []() {
|
||||
it("handles single characters", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(i_sym(1)),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol(1), blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles choices", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(choice({ i_sym(1), i_sym(2) })),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol(1), blank() },
|
||||
{ Symbol(2), blank() }
|
||||
rule_transitions(character({ '1' })),
|
||||
Equals(transition_map({
|
||||
{ CharacterSet().include('1'), blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles sequences", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({ i_sym(1), i_sym(2) })),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol(1), i_sym(2) }
|
||||
rule_transitions(seq({ character({ '1' }), character({ '2' }) })),
|
||||
Equals(transition_map({
|
||||
{ CharacterSet().include('1'), character({ '2' }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles long sequences", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({
|
||||
i_sym(1),
|
||||
i_sym(2),
|
||||
i_sym(3),
|
||||
i_sym(4)
|
||||
rule_transitions(seq({
|
||||
character({ '1' }),
|
||||
character({ '2' }),
|
||||
character({ '3' }),
|
||||
character({ '4' })
|
||||
})),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol(1), seq({ i_sym(2), i_sym(3), i_sym(4) }) }
|
||||
Equals(transition_map({
|
||||
{
|
||||
CharacterSet().include('1'),
|
||||
seq({ character({ '2' }), character({ '3' }), character({ '4' }) }),
|
||||
}
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles sequences whose left sides can be blank", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({
|
||||
rule_transitions(seq({
|
||||
choice({
|
||||
i_sym(1),
|
||||
character({ '1' }),
|
||||
blank() }),
|
||||
seq({
|
||||
i_sym(1),
|
||||
i_sym(2) })
|
||||
})), Equals(rule_map<Symbol>({
|
||||
{ Symbol(1), choice({ seq({ i_sym(1), i_sym(2) }), i_sym(2), }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles choices with common starting symbols", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(
|
||||
choice({
|
||||
seq({ i_sym(1), i_sym(2) }),
|
||||
seq({ i_sym(1), i_sym(3) }) })),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol(1), choice({ i_sym(2), i_sym(3) }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("preserves metadata", [&]() {
|
||||
map<MetadataKey, int> metadata_value({
|
||||
{ PRECEDENCE, 5 }
|
||||
});
|
||||
|
||||
rule_ptr rule = make_shared<Metadata>(seq({ i_sym(1), i_sym(2) }), metadata_value);
|
||||
AssertThat(
|
||||
sym_transitions(rule),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol(1), make_shared<Metadata>(i_sym(2), metadata_value)},
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
||||
describe("char_transitions", []() {
|
||||
it("handles characters", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(character({ '1' })),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet().include('1'), blank() }
|
||||
character({ '1' }),
|
||||
character({ '2' }) })
|
||||
})), Equals(transition_map({
|
||||
{
|
||||
CharacterSet().include('1'),
|
||||
choice({ seq({ character({ '1' }), character({ '2' }) }), character({ '2' }), }),
|
||||
}
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles choices between overlapping character sets", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(choice({
|
||||
rule_transitions(choice({
|
||||
seq({
|
||||
character({ 'a', 'b', 'c', 'd' }),
|
||||
sym("x") }),
|
||||
seq({
|
||||
character({ 'c', 'd', 'e', 'f' }),
|
||||
sym("y") }) })),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
Equals(transition_map({
|
||||
{ CharacterSet().include('a', 'b'), sym("x") },
|
||||
{ CharacterSet().include('c', 'd'), choice({ sym("x"), sym("y") }) },
|
||||
{ CharacterSet().include('e', 'f'), sym("y") },
|
||||
|
|
@ -128,7 +91,7 @@ describe("char_transitions", []() {
|
|||
|
||||
it("handles choices between whitelisted and blacklisted character sets", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(seq({
|
||||
rule_transitions(seq({
|
||||
choice({
|
||||
character({ '/' }, false),
|
||||
seq({
|
||||
|
|
@ -136,7 +99,7 @@ describe("char_transitions", []() {
|
|||
character({ '/' }) }) }),
|
||||
character({ '/' }) })),
|
||||
|
||||
Equals(rule_map<CharacterSet>({
|
||||
Equals(transition_map({
|
||||
{ CharacterSet()
|
||||
.include_all()
|
||||
.exclude('/')
|
||||
|
|
@ -154,42 +117,42 @@ describe("char_transitions", []() {
|
|||
|
||||
it("handles choices between a subset and a superset of characters", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(choice({
|
||||
rule_transitions(choice({
|
||||
seq({
|
||||
character({ 'b', 'c', 'd' }),
|
||||
sym("x") }),
|
||||
seq({
|
||||
character({ 'a', 'b', 'c', 'd', 'e', 'f' }),
|
||||
sym("y") }) })),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
Equals(transition_map({
|
||||
{ CharacterSet().include('b', 'd'), choice({ sym("x"), sym("y") }) },
|
||||
{ CharacterSet().include('a').include('e', 'f'), sym("y") },
|
||||
})));
|
||||
|
||||
AssertThat(
|
||||
char_transitions(choice({
|
||||
rule_transitions(choice({
|
||||
seq({
|
||||
character({ 'a', 'b', 'c', 'd', 'e', 'f' }),
|
||||
sym("x") }),
|
||||
seq({
|
||||
character({ 'b', 'c', 'd' }),
|
||||
sym("y") }) })),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
Equals(transition_map({
|
||||
{ CharacterSet().include('b', 'd'), choice({ sym("x"), sym("y") }) },
|
||||
{ CharacterSet().include('a').include('e', 'f'), sym("x") },
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles blanks", [&]() {
|
||||
AssertThat(char_transitions(blank()), Equals(rule_map<CharacterSet>({})));
|
||||
AssertThat(rule_transitions(blank()), Equals(transition_map({})));
|
||||
});
|
||||
|
||||
it("handles repeats", [&]() {
|
||||
rule_ptr rule = repeat(seq({ character({ 'a' }), character({ 'b' }) }));
|
||||
|
||||
AssertThat(
|
||||
char_transitions(rule),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
rule_transitions(rule),
|
||||
Equals(transition_map({
|
||||
{
|
||||
CharacterSet().include('a'),
|
||||
seq({
|
||||
|
|
@ -200,8 +163,8 @@ describe("char_transitions", []() {
|
|||
rule = repeat(character({ 'a' }));
|
||||
|
||||
AssertThat(
|
||||
char_transitions(rule),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
rule_transitions(rule),
|
||||
Equals(transition_map({
|
||||
{ CharacterSet().include('a'), rule }
|
||||
})));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ map<Symbol, ParseItemSet> sym_transitions(const ParseItemSet &input_item_set,
|
|||
map<CharacterSet, LexItemSet> char_transitions(const LexItemSet &item_set) {
|
||||
map<CharacterSet, LexItemSet> result;
|
||||
for (const LexItem &item : item_set) {
|
||||
for (auto &transition : char_transitions(item.rule)) {
|
||||
for (auto &transition : rule_transitions(item.rule)) {
|
||||
LexItem next_item(item.lhs, transition.second);
|
||||
merge_char_transition<LexItemSet>(
|
||||
merge_transition<LexItemSet>(
|
||||
&result, { transition.first, LexItemSet({ next_item }) },
|
||||
[](LexItemSet *left, const LexItemSet *right) {
|
||||
left->insert(right->begin(), right->end());
|
||||
|
|
|
|||
|
|
@ -9,29 +9,6 @@
|
|||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
|
||||
/*
|
||||
* Merges a new transition into a map with symbol keys.
|
||||
* If the symbol already exists in the map, the new value for that
|
||||
* symbol will be computed by merging the old and new values
|
||||
* using the given function.
|
||||
*/
|
||||
template <typename T>
|
||||
void merge_sym_transition(std::map<rules::Symbol, T> *left,
|
||||
const std::pair<rules::Symbol, T> &new_pair,
|
||||
std::function<void(T *, const T *)> merge_fn) {
|
||||
auto new_symbol = new_pair.first;
|
||||
for (auto &existing_pair : *left) {
|
||||
auto existing_symbol = existing_pair.first;
|
||||
if (new_symbol < existing_symbol)
|
||||
break;
|
||||
if (existing_symbol == new_symbol) {
|
||||
merge_fn(&existing_pair.second, &new_pair.second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
left->insert(new_pair);
|
||||
}
|
||||
|
||||
/*
|
||||
* Merges two transition maps with character set keys. If the
|
||||
* two maps contain values for overlapping character sets, the
|
||||
|
|
@ -39,9 +16,9 @@ void merge_sym_transition(std::map<rules::Symbol, T> *left,
|
|||
* merging the old and new values using the given function.
|
||||
*/
|
||||
template <typename T>
|
||||
void merge_char_transition(std::map<rules::CharacterSet, T> *left,
|
||||
const std::pair<rules::CharacterSet, T> &new_pair,
|
||||
std::function<void(T *, const T *)> merge_fn) {
|
||||
void merge_transition(std::map<rules::CharacterSet, T> *left,
|
||||
const std::pair<rules::CharacterSet, T> &new_pair,
|
||||
std::function<void(T *, const T *)> merge_fn) {
|
||||
rules::CharacterSet new_char_set = new_pair.first;
|
||||
T new_value = new_pair.second;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,72 +19,46 @@ using rules::CharacterSet;
|
|||
using rules::Choice;
|
||||
using rules::Symbol;
|
||||
|
||||
template <typename T>
|
||||
void merge_transitions(map<T, rule_ptr> *, const map<T, rule_ptr> &);
|
||||
|
||||
struct MergeAsChoice {
|
||||
void operator()(rule_ptr *left, const rule_ptr *right) {
|
||||
*left = Choice::build({ *left, *right });
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
void merge_transitions(map<CharacterSet, rule_ptr> *left,
|
||||
const map<CharacterSet, rule_ptr> &right) {
|
||||
for (auto &pair : right)
|
||||
merge_char_transition<rule_ptr>(left, pair, MergeAsChoice());
|
||||
}
|
||||
|
||||
template <>
|
||||
void merge_transitions(map<Symbol, rule_ptr> *left,
|
||||
const map<Symbol, rule_ptr> &right) {
|
||||
for (auto &pair : right)
|
||||
merge_sym_transition<rule_ptr>(left, pair, MergeAsChoice());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class RuleTransitions : public rules::RuleFn<map<T, rule_ptr>> {
|
||||
class RuleTransitions : public rules::RuleFn<map<CharacterSet, rule_ptr>> {
|
||||
private:
|
||||
map<T, rule_ptr> apply_to_primitive(const Rule *rule) {
|
||||
auto primitive = dynamic_cast<const T *>(rule);
|
||||
if (primitive)
|
||||
return map<T, rule_ptr>({ { *primitive, make_shared<rules::Blank>() } });
|
||||
else
|
||||
return map<T, rule_ptr>();
|
||||
void merge_transitions(map<CharacterSet, rule_ptr> *left,
|
||||
const map<CharacterSet, rule_ptr> &right) {
|
||||
for (auto &pair : right)
|
||||
merge_transition<rule_ptr>(
|
||||
left, pair, [](rule_ptr *left, const rule_ptr *right) {
|
||||
*left = Choice::build({ *left, *right });
|
||||
});
|
||||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const CharacterSet *rule) {
|
||||
return apply_to_primitive(rule);
|
||||
map<CharacterSet, rule_ptr> apply_to(const CharacterSet *rule) {
|
||||
return map<CharacterSet, rule_ptr>(
|
||||
{ { *rule, make_shared<rules::Blank>() } });
|
||||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const Symbol *rule) {
|
||||
return apply_to_primitive(rule);
|
||||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const rules::Choice *rule) {
|
||||
map<T, rule_ptr> result;
|
||||
map<CharacterSet, rule_ptr> apply_to(const rules::Choice *rule) {
|
||||
map<CharacterSet, rule_ptr> result;
|
||||
for (const auto &el : rule->elements)
|
||||
merge_transitions<T>(&result, this->apply(el));
|
||||
merge_transitions(&result, this->apply(el));
|
||||
return result;
|
||||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const rules::Seq *rule) {
|
||||
map<CharacterSet, rule_ptr> apply_to(const rules::Seq *rule) {
|
||||
auto result = this->apply(rule->left);
|
||||
for (auto &pair : result)
|
||||
pair.second = rules::Seq::build({ pair.second, rule->right });
|
||||
if (rule_can_be_blank(rule->left))
|
||||
merge_transitions<T>(&result, this->apply(rule->right));
|
||||
merge_transitions(&result, this->apply(rule->right));
|
||||
return result;
|
||||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const rules::Repeat *rule) {
|
||||
map<CharacterSet, rule_ptr> apply_to(const rules::Repeat *rule) {
|
||||
auto result = this->apply(rule->content);
|
||||
for (auto &pair : result)
|
||||
pair.second = rules::Seq::build({ pair.second, rule->copy() });
|
||||
return result;
|
||||
}
|
||||
|
||||
map<T, rule_ptr> apply_to(const rules::Metadata *rule) {
|
||||
map<CharacterSet, rule_ptr> apply_to(const rules::Metadata *rule) {
|
||||
auto result = this->apply(rule->rule);
|
||||
for (auto &pair : result)
|
||||
pair.second = make_shared<rules::Metadata>(pair.second, rule->value);
|
||||
|
|
@ -92,12 +66,8 @@ class RuleTransitions : public rules::RuleFn<map<T, rule_ptr>> {
|
|||
}
|
||||
};
|
||||
|
||||
map<CharacterSet, rule_ptr> char_transitions(const rule_ptr &rule) {
|
||||
return RuleTransitions<CharacterSet>().apply(rule);
|
||||
}
|
||||
|
||||
map<Symbol, rule_ptr> sym_transitions(const rule_ptr &rule) {
|
||||
return RuleTransitions<Symbol>().apply(rule);
|
||||
map<CharacterSet, rule_ptr> rule_transitions(const rule_ptr &rule) {
|
||||
return RuleTransitions().apply(rule);
|
||||
}
|
||||
|
||||
} // namespace build_tables
|
||||
|
|
|
|||
|
|
@ -8,9 +8,7 @@
|
|||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
|
||||
std::map<rules::CharacterSet, rule_ptr> char_transitions(const rule_ptr &rule);
|
||||
|
||||
std::map<rules::Symbol, rule_ptr> sym_transitions(const rule_ptr &rule);
|
||||
std::map<rules::CharacterSet, rule_ptr> rule_transitions(const rule_ptr &);
|
||||
|
||||
} // namespace build_tables
|
||||
} // namespace tree_sitter
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue