Remove transition_map class
This commit is contained in:
parent
91489363ca
commit
1962c17f45
17 changed files with 1115 additions and 1177 deletions
|
|
@ -41,8 +41,7 @@ describe("computing closures of item sets", []() {
|
|||
ParseItem(Symbol("E"), grammar.rule(Symbol("E")), {}, Symbol("__END__")),
|
||||
})));
|
||||
|
||||
auto sym1 = rules::Symbol("v");
|
||||
ParseItemSet next_item_set = *sym_transitions(item_set, grammar)[sym1];
|
||||
ParseItemSet next_item_set = sym_transitions(item_set, grammar)[Symbol("v")];
|
||||
AssertThat(next_item_set, Equals(ParseItemSet({
|
||||
ParseItem(Symbol("F"), rules::blank(), { false }, Symbol("__END__")),
|
||||
ParseItem(Symbol("F"), rules::blank(), { false }, Symbol("*")),
|
||||
|
|
|
|||
|
|
@ -4,32 +4,116 @@
|
|||
using namespace rules;
|
||||
using namespace build_tables;
|
||||
|
||||
template<typename K>
|
||||
class rule_map : public map<K, rule_ptr> {
|
||||
public:
|
||||
bool operator==(const map<K, rule_ptr> &other) const {
|
||||
if (this->size() != other.size()) return false;
|
||||
for (const auto &pair : *this) {
|
||||
auto other_pair = other.find(pair.first);
|
||||
if (other_pair == other.end()) return false;
|
||||
if (!pair.second->operator==(*other_pair->second)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
rule_map(const initializer_list<pair<const K, rule_ptr>> &list) : map<K, rule_ptr>(list) {}
|
||||
};
|
||||
|
||||
START_TEST
|
||||
|
||||
describe("rule transitions", []() {
|
||||
auto symbol1 = sym("1");
|
||||
auto symbol2 = sym("2");
|
||||
auto symbol3 = sym("3");
|
||||
auto symbol4 = sym("4");
|
||||
auto char1 = character({ 'a' });
|
||||
|
||||
it("handles symbols", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(symbol1),
|
||||
Equals(transition_map<Symbol, Rule>({
|
||||
{ symbol1, blank() }
|
||||
sym_transitions(sym("1")),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol("1"), blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles choices", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(choice({ symbol1, symbol2 })),
|
||||
Equals(transition_map<Symbol, Rule>({
|
||||
{ symbol1, blank() },
|
||||
{ symbol2, blank() }
|
||||
sym_transitions(choice({ sym("1"), sym("2") })),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol("1"), blank() },
|
||||
{ Symbol("2"), blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles sequences", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({ sym("1"), sym("2") })),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol("1"), sym("2") }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles long sequences", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({
|
||||
sym("1"),
|
||||
sym("2"),
|
||||
sym("3"),
|
||||
sym("4")
|
||||
})),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol("1"), seq({ sym("2"), sym("3"), sym("4") }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles sequences whose left sides can be blank", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({
|
||||
choice({
|
||||
sym("1"),
|
||||
blank(),
|
||||
}),
|
||||
seq({
|
||||
sym("1"),
|
||||
sym("2")
|
||||
})
|
||||
})), Equals(rule_map<Symbol>({
|
||||
{ Symbol("1"), choice({ seq({ sym("1"), sym("2") }), sym("2"), }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles choices with common starting symbols", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(
|
||||
choice({
|
||||
seq({ sym("1"), sym("2") }),
|
||||
seq({ sym("1"), sym("3") }) })),
|
||||
Equals(rule_map<Symbol>({
|
||||
{ Symbol("1"), choice({ sym("2"), sym("3") }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles characters", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(character('1')),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ '1' }), blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles strings", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(str("bad")),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ 'b' }, true), seq({ character('a'), character('d') }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles patterns", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(pattern("a|b")),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ 'a' }), blank() },
|
||||
{ CharacterSet({ 'b' }), blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
|
||||
it("handles choices between overlapping character sets", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(choice({
|
||||
|
|
@ -39,108 +123,35 @@ describe("rule transitions", []() {
|
|||
seq({
|
||||
character({ { 'm', 'z' } }),
|
||||
sym("y") }) })),
|
||||
Equals(transition_map<CharacterSet, Rule>({
|
||||
{ character({ {'a','l'} }), sym("x") },
|
||||
{ character({ {'m','s'} }), choice({ sym("x"), sym("y") }) },
|
||||
{ character({ {'t','z'} }), sym("y") },
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ {'a','l'} }, true), sym("x") },
|
||||
{ CharacterSet({ {'m','s'} }, true), choice({ sym("x"), sym("y") }) },
|
||||
{ CharacterSet({ {'t','z'} }, true), sym("y") },
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles sequences", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({ symbol1, symbol2 })),
|
||||
Equals(transition_map<Symbol, Rule>({
|
||||
{ symbol1, symbol2 }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles long sequences", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({
|
||||
symbol1,
|
||||
symbol2,
|
||||
symbol3,
|
||||
symbol4
|
||||
})),
|
||||
Equals(transition_map<Symbol, Rule>({
|
||||
{ symbol1, seq({ symbol2, symbol3, symbol4 }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles sequences whose left sides can be blank", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(seq({
|
||||
choice({
|
||||
symbol1,
|
||||
blank(),
|
||||
}),
|
||||
seq({
|
||||
symbol1,
|
||||
symbol2
|
||||
})
|
||||
})), Equals(transition_map<Symbol, Rule>({
|
||||
{ symbol1, choice({ seq({ symbol1, symbol2 }), symbol2, }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles choices with common starting symbols", [&]() {
|
||||
AssertThat(
|
||||
sym_transitions(
|
||||
choice({
|
||||
seq({ symbol1, symbol2 }),
|
||||
seq({ symbol1, symbol3 }) })),
|
||||
Equals(transition_map<Symbol, Rule>({
|
||||
{ symbol1, choice({ symbol2, symbol3 }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles characters", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(char1),
|
||||
Equals(transition_map<CharacterSet, Rule>({
|
||||
{ char1, blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles strings", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(str("bad")),
|
||||
Equals(transition_map<CharacterSet, Rule>({
|
||||
{ character({ 'b' }, true), seq({ character('a'), character('d') }) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("handles patterns", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(pattern("a|b")),
|
||||
Equals(transition_map<CharacterSet, Rule>({
|
||||
{ character({ 'a' }, true), blank() },
|
||||
{ character({ 'b' }, true), blank() }
|
||||
})));
|
||||
});
|
||||
|
||||
|
||||
it("handles repeats", [&]() {
|
||||
rule_ptr rule = repeat(str("ab"));
|
||||
AssertThat(
|
||||
char_transitions(rule),
|
||||
Equals(transition_map<CharacterSet, Rule>({
|
||||
{
|
||||
character({ 'a' }, true),
|
||||
seq({
|
||||
character('b'),
|
||||
choice({
|
||||
rule,
|
||||
blank()
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{
|
||||
CharacterSet({ 'a' }),
|
||||
seq({
|
||||
character('b'),
|
||||
choice({
|
||||
rule,
|
||||
blank()
|
||||
})
|
||||
})
|
||||
})
|
||||
}})));
|
||||
}})));
|
||||
|
||||
rule = repeat(str("a"));
|
||||
AssertThat(
|
||||
char_transitions(rule),
|
||||
Equals(transition_map<CharacterSet, Rule>({
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{
|
||||
character({ 'a' }, true),
|
||||
CharacterSet({ 'a' }),
|
||||
choice({
|
||||
rule,
|
||||
blank()
|
||||
|
|
@ -158,14 +169,14 @@ describe("rule transitions", []() {
|
|||
character('"'),
|
||||
});
|
||||
|
||||
AssertThat(char_transitions(rule), Equals(transition_map<CharacterSet, Rule>({
|
||||
{ character({ '"' }, false), seq({
|
||||
AssertThat(char_transitions(rule), Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ '"' }, false), seq({
|
||||
choice({
|
||||
repeat(character({ '"' }, false)),
|
||||
blank(),
|
||||
}),
|
||||
character('"'), }) },
|
||||
{ character({ '"' }, true), blank() },
|
||||
{ CharacterSet({ '"' }, true), blank() },
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
|
|
|||
754
spec/fixtures/parsers/arithmetic.c
vendored
754
spec/fixtures/parsers/arithmetic.c
vendored
File diff suppressed because it is too large
Load diff
1102
spec/fixtures/parsers/json.c
vendored
1102
spec/fixtures/parsers/json.c
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,7 @@ namespace tree_sitter {
|
|||
map<Symbol, set<Symbol>> result;
|
||||
|
||||
for (auto pair : sym_transitions(item.rule)) {
|
||||
auto symbol = *pair.first;
|
||||
auto symbol = pair.first;
|
||||
if (grammar.has_definition(symbol)) {
|
||||
auto following_non_terminals = first_set(pair.second, grammar);
|
||||
if (rule_can_be_blank(pair.second)) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
using std::make_shared;
|
||||
using std::shared_ptr;
|
||||
using std::map;
|
||||
|
||||
namespace tree_sitter {
|
||||
using rules::CharacterSet;
|
||||
|
|
@ -17,40 +18,40 @@ namespace tree_sitter {
|
|||
return result;
|
||||
}
|
||||
|
||||
transition_map<CharacterSet, LexItemSet> char_transitions(const LexItemSet &item_set, const Grammar &grammar) {
|
||||
transition_map<CharacterSet, LexItemSet> result;
|
||||
map<CharacterSet, LexItemSet> char_transitions(const LexItemSet &item_set, const Grammar &grammar) {
|
||||
map<CharacterSet, LexItemSet> result;
|
||||
for (const LexItem &item : item_set) {
|
||||
transition_map<CharacterSet, LexItemSet> item_transitions;
|
||||
map<CharacterSet, LexItemSet> item_transitions;
|
||||
for (auto transition : char_transitions(item.rule)) {
|
||||
auto rule = transition.first;
|
||||
auto new_item = LexItem(item.lhs, transition.second);
|
||||
auto new_item_set = LexItemSet({ new_item });
|
||||
item_transitions.add(rule, make_shared<LexItemSet>(new_item_set));
|
||||
item_transitions.insert({ rule, LexItemSet(new_item_set) });
|
||||
}
|
||||
|
||||
result = merge_char_transitions<LexItemSet>(result, item_transitions, [](shared_ptr<LexItemSet> left, shared_ptr<LexItemSet> right) {
|
||||
return make_shared<LexItemSet>(merge_sets(*left, *right));
|
||||
result = merge_char_transitions<LexItemSet>(result, item_transitions, [](LexItemSet left, LexItemSet right) {
|
||||
return merge_sets(left, right);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
transition_map<rules::Symbol, ParseItemSet> sym_transitions(const ParseItemSet &item_set, const Grammar &grammar) {
|
||||
transition_map<rules::Symbol, ParseItemSet> result;
|
||||
map<rules::Symbol, ParseItemSet> sym_transitions(const ParseItemSet &item_set, const Grammar &grammar) {
|
||||
map<rules::Symbol, ParseItemSet> result;
|
||||
for (const ParseItem &item : item_set) {
|
||||
transition_map<rules::Symbol, ParseItemSet> item_transitions;
|
||||
map<rules::Symbol, ParseItemSet> item_transitions;
|
||||
for (auto transition : sym_transitions(item.rule)) {
|
||||
auto rule = transition.first;
|
||||
auto consumed_symbols = item.consumed_symbols;
|
||||
consumed_symbols.push_back(rule->is_auxiliary);
|
||||
consumed_symbols.push_back(rule.is_auxiliary);
|
||||
auto new_item = ParseItem(item.lhs, transition.second, consumed_symbols, item.lookahead_sym);
|
||||
auto new_item_set = item_set_closure(ParseItemSet({ new_item }), grammar);
|
||||
item_transitions.add(rule, make_shared<ParseItemSet>(new_item_set));
|
||||
item_transitions.insert({ rule, ParseItemSet(new_item_set) });
|
||||
}
|
||||
|
||||
result = merge_sym_transitions<ParseItemSet>(result, item_transitions, [](shared_ptr<ParseItemSet> left, shared_ptr<ParseItemSet> right) {
|
||||
return make_shared<ParseItemSet>(merge_sets(*left, *right));
|
||||
result = merge_sym_transitions<ParseItemSet>(result, item_transitions, [](ParseItemSet left, ParseItemSet right) {
|
||||
return merge_sets(left, right);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
|
||||
#include "character_set.h"
|
||||
#include "symbol.h"
|
||||
#include "transition_map.h"
|
||||
#include "item.h"
|
||||
#include <map>
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
transition_map<rules::CharacterSet, LexItemSet> char_transitions(const LexItemSet &item_set, const Grammar &grammar);
|
||||
transition_map<rules::Symbol, ParseItemSet> sym_transitions(const ParseItemSet &item_set, const Grammar &grammar);
|
||||
std::map<rules::CharacterSet, LexItemSet> char_transitions(const LexItemSet &item_set, const Grammar &grammar);
|
||||
std::map<rules::Symbol, ParseItemSet> sym_transitions(const ParseItemSet &item_set, const Grammar &grammar);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,52 +1,54 @@
|
|||
#ifndef __tree_sitter__merge_transitions__
|
||||
#define __tree_sitter__merge_transitions__
|
||||
|
||||
#include "transition_map.h"
|
||||
#include "character_set.h"
|
||||
#include "symbol.h"
|
||||
#include <map>
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
template<typename T>
|
||||
transition_map<rules::Symbol, T>
|
||||
merge_sym_transitions(const transition_map<rules::Symbol, T> &left,
|
||||
const transition_map<rules::Symbol, T> &right,
|
||||
std::function<std::shared_ptr<T>(std::shared_ptr<T>, std::shared_ptr<T>)> merge_fn) {
|
||||
transition_map<rules::Symbol, T> result(left);
|
||||
std::map<rules::Symbol, T>
|
||||
merge_sym_transitions(const std::map<rules::Symbol, T> &left,
|
||||
const std::map<rules::Symbol, T> &right,
|
||||
std::function<T(T, T)> merge_fn) {
|
||||
std::map<rules::Symbol, T> result(left);
|
||||
for (auto &pair : right) {
|
||||
auto rule = pair.first;
|
||||
bool merged = false;
|
||||
for (auto &existing_pair : result) {
|
||||
auto existing_rule = existing_pair.first;
|
||||
if (existing_rule->operator==(*rule)) {
|
||||
if (existing_rule == rule) {
|
||||
existing_pair.second = merge_fn(existing_pair.second, pair.second);
|
||||
merged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!merged)
|
||||
result.add(pair.first, pair.second);
|
||||
result.insert({ pair.first, pair.second });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
transition_map<rules::CharacterSet, T>
|
||||
merge_char_transitions(const transition_map<rules::CharacterSet, T> &left,
|
||||
const transition_map<rules::CharacterSet, T> &right,
|
||||
std::function<std::shared_ptr<T>(std::shared_ptr<T>, std::shared_ptr<T>)> merge_fn) {
|
||||
transition_map<rules::CharacterSet, T> result(left);
|
||||
std::map<rules::CharacterSet, T>
|
||||
merge_char_transitions(const std::map<rules::CharacterSet, T> &left,
|
||||
const std::map<rules::CharacterSet, T> &right,
|
||||
std::function<T(T, T)> merge_fn) {
|
||||
std::map<rules::CharacterSet, T> result(left);
|
||||
for (auto &pair : right) {
|
||||
auto rule = pair.first;
|
||||
for (auto &existing_pair : left) {
|
||||
auto existing_rule = existing_pair.first;
|
||||
auto intersection = existing_rule->remove_set(*rule);
|
||||
auto intersection = existing_rule.remove_set(rule);
|
||||
if (!intersection.is_empty()) {
|
||||
rule->remove_set(intersection);
|
||||
result.add(std::make_shared<rules::CharacterSet>(intersection), merge_fn(existing_pair.second, pair.second));
|
||||
result.erase(existing_pair.first);
|
||||
result.insert({ existing_rule, existing_pair.second });
|
||||
rule.remove_set(intersection);
|
||||
result.insert({ intersection, merge_fn(existing_pair.second, pair.second) });
|
||||
}
|
||||
}
|
||||
result.add(rule, pair.second);
|
||||
result.insert({ rule, pair.second });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ namespace tree_sitter {
|
|||
|
||||
void add_shift_actions(const ParseItemSet &item_set, size_t state_index) {
|
||||
for (auto transition : sym_transitions(item_set, grammar)) {
|
||||
rules::Symbol symbol = *transition.first;
|
||||
ParseItemSet item_set = *transition.second;
|
||||
rules::Symbol symbol = transition.first;
|
||||
ParseItemSet item_set = transition.second;
|
||||
size_t new_state_index = add_parse_state(item_set);
|
||||
parse_table.add_action(state_index, symbol, ParseAction::Shift(new_state_index));
|
||||
}
|
||||
|
|
@ -45,8 +45,8 @@ namespace tree_sitter {
|
|||
|
||||
void add_advance_actions(const LexItemSet &item_set, size_t state_index) {
|
||||
for (auto transition : char_transitions(item_set, grammar)) {
|
||||
rules::CharacterSet rule = *transition.first;
|
||||
LexItemSet item_set = *transition.second;
|
||||
rules::CharacterSet rule = transition.first;
|
||||
LexItemSet item_set = transition.second;
|
||||
size_t new_state_index = add_lex_state(item_set);
|
||||
lex_table.add_action(state_index, rule, LexAction::Advance(new_state_index));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "merge_transitions.h"
|
||||
|
||||
using namespace tree_sitter::rules;
|
||||
using std::map;
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
|
|
@ -11,36 +12,38 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
transition_map<T, Rule> merge_transitions(const transition_map<T, Rule> &left, const transition_map<T, Rule> &right);
|
||||
map<T, rule_ptr> merge_transitions(const map<T, rule_ptr> &left, const map<T, rule_ptr> &right);
|
||||
|
||||
template<>
|
||||
transition_map<CharacterSet, Rule> merge_transitions(const transition_map<CharacterSet, Rule> &left, const transition_map<CharacterSet, Rule> &right) {
|
||||
return merge_char_transitions<Rule>(left, right, [](rule_ptr left, rule_ptr right) -> rule_ptr {
|
||||
map<CharacterSet, rule_ptr> merge_transitions(const map<CharacterSet, rule_ptr> &left, const map<CharacterSet, rule_ptr> &right) {
|
||||
auto transitions = merge_char_transitions<rule_ptr>(left, right, [](rule_ptr left, rule_ptr right) -> rule_ptr {
|
||||
return choice({ left, right });
|
||||
});
|
||||
return *static_cast<map<CharacterSet, rule_ptr> *>(&transitions);
|
||||
}
|
||||
|
||||
template<>
|
||||
transition_map<Symbol, Rule> merge_transitions(const transition_map<Symbol, Rule> &left, const transition_map<Symbol, Rule> &right) {
|
||||
return merge_sym_transitions<Rule>(left, right, [](rule_ptr left, rule_ptr right) -> rule_ptr {
|
||||
map<Symbol, rule_ptr> merge_transitions(const map<Symbol, rule_ptr> &left, const map<Symbol, rule_ptr> &right) {
|
||||
auto transitions = merge_sym_transitions<rule_ptr>(left, right, [](rule_ptr left, rule_ptr right) -> rule_ptr {
|
||||
return choice({ left, right });
|
||||
});
|
||||
return *static_cast<map<Symbol, rule_ptr> *>(&transitions);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
transition_map<T, Rule> map_transitions(const transition_map<T, Rule> &initial, std::function<const rule_ptr(rule_ptr)> map_fn) {
|
||||
transition_map<T, Rule> result;
|
||||
map<T, rule_ptr> map_transitions(const map<T, rule_ptr> &initial, std::function<const rule_ptr(rule_ptr)> map_fn) {
|
||||
map<T, rule_ptr> result;
|
||||
for (auto &pair : initial)
|
||||
result.add(pair.first, map_fn(pair.second));
|
||||
result.insert({ pair.first, map_fn(pair.second) });
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class TransitionsVisitor : public rules::Visitor {
|
||||
public:
|
||||
transition_map<T, Rule> value;
|
||||
map<T, rule_ptr> value;
|
||||
|
||||
static transition_map<T, Rule> transitions(const rule_ptr rule) {
|
||||
static map<T, rule_ptr> transitions(const rule_ptr rule) {
|
||||
TransitionsVisitor<T> visitor;
|
||||
rule->accept(visitor);
|
||||
return visitor.value;
|
||||
|
|
@ -49,7 +52,8 @@ namespace tree_sitter {
|
|||
void visit_atom(const Rule *rule) {
|
||||
auto atom = dynamic_cast<const T *>(rule);
|
||||
if (atom) {
|
||||
value = transition_map<T, Rule>({{ std::make_shared<T>(*atom), blank() }});
|
||||
value = map<T, rule_ptr>();
|
||||
value.insert({ *atom, blank() });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,11 +100,11 @@ namespace tree_sitter {
|
|||
}
|
||||
};
|
||||
|
||||
transition_map<CharacterSet, Rule> char_transitions(const rule_ptr &rule) {
|
||||
map<CharacterSet, rule_ptr> char_transitions(const rule_ptr &rule) {
|
||||
return TransitionsVisitor<CharacterSet>::transitions(rule);
|
||||
}
|
||||
|
||||
transition_map<Symbol, Rule> sym_transitions(const rule_ptr &rule) {
|
||||
map<Symbol, rule_ptr> sym_transitions(const rule_ptr &rule) {
|
||||
return TransitionsVisitor<Symbol>::transitions(rule);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
|
||||
#include "character_set.h"
|
||||
#include "symbol.h"
|
||||
#include "transition_map.h"
|
||||
#include <map>
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
bool rule_can_be_blank(const rules::rule_ptr &rule);
|
||||
transition_map<rules::CharacterSet, rules::Rule> char_transitions(const rules::rule_ptr &rule);
|
||||
transition_map<rules::Symbol, rules::Rule> sym_transitions(const rules::rule_ptr &rule);
|
||||
std::map<rules::CharacterSet, rules::rule_ptr> char_transitions(const rules::rule_ptr &rule);
|
||||
std::map<rules::Symbol, rules::rule_ptr> sym_transitions(const rules::rule_ptr &rule);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
#ifndef __TreeSitter__TransitionSet__
|
||||
#define __TreeSitter__TransitionSet__
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include "rule.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
template<typename TKey, typename TValue>
|
||||
class transition_map {
|
||||
typedef std::shared_ptr<TKey> TKeyPtr;
|
||||
typedef std::shared_ptr<TValue> TValuePtr;
|
||||
typedef std::pair<TKeyPtr, TValuePtr> pair_type;
|
||||
typedef std::vector<pair_type> contents_type;
|
||||
|
||||
contents_type contents;
|
||||
|
||||
public:
|
||||
transition_map() : contents(contents_type()) {};
|
||||
transition_map(std::vector<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;
|
||||
}
|
||||
|
||||
void add(TKeyPtr key, TValuePtr value) {
|
||||
contents.push_back(pair_type(key, value));
|
||||
}
|
||||
|
||||
TValuePtr operator[](const TKey &key) const {
|
||||
for (auto pair : *this) {
|
||||
if (*pair.first == key) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
return TValuePtr();
|
||||
}
|
||||
|
||||
#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(); }
|
||||
};
|
||||
|
||||
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) {
|
||||
if (started) stream << std::string(", ");
|
||||
stream << pair.first->to_string() << std::string(" => ");
|
||||
stream << *pair.second;
|
||||
started = true;
|
||||
}
|
||||
stream << std::string("]");
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -52,8 +52,6 @@ namespace tree_sitter {
|
|||
|
||||
std::set<CharacterRange> ranges;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<CharacterSet> char_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,16 @@ namespace tree_sitter {
|
|||
return make_shared<Blank>();
|
||||
}
|
||||
|
||||
char_ptr character(char value) {
|
||||
rule_ptr character(char value) {
|
||||
set<CharacterRange> ranges = { value };
|
||||
return make_shared<CharacterSet>(ranges);
|
||||
}
|
||||
|
||||
char_ptr character(const set<CharacterRange> &ranges) {
|
||||
rule_ptr character(const set<CharacterRange> &ranges) {
|
||||
return make_shared<CharacterSet>(ranges);
|
||||
}
|
||||
|
||||
char_ptr character(const set<CharacterRange> &ranges, bool sign) {
|
||||
rule_ptr character(const set<CharacterRange> &ranges, bool sign) {
|
||||
return make_shared<CharacterSet>(ranges, sign);
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ namespace tree_sitter {
|
|||
return make_shared<String>(value);
|
||||
}
|
||||
|
||||
sym_ptr sym(const string &name) {
|
||||
rule_ptr sym(const string &name) {
|
||||
return make_shared<Symbol>(name, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,16 +16,16 @@
|
|||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
rule_ptr blank();
|
||||
char_ptr character(char value);
|
||||
char_ptr character(const std::set<CharacterRange> &matches);
|
||||
char_ptr character(const std::set<CharacterRange> &matches, bool);
|
||||
rule_ptr character(char value);
|
||||
rule_ptr character(const std::set<CharacterRange> &matches);
|
||||
rule_ptr character(const std::set<CharacterRange> &matches, bool);
|
||||
|
||||
rule_ptr choice(const std::vector<rule_ptr> &rules);
|
||||
rule_ptr pattern(const std::string &value);
|
||||
rule_ptr repeat(const rule_ptr content);
|
||||
rule_ptr seq(const std::vector<rule_ptr> &rules);
|
||||
rule_ptr str(const std::string &value);
|
||||
sym_ptr sym(const std::string &name);
|
||||
rule_ptr sym(const std::string &name);
|
||||
rule_ptr aux_sym(const std::string &name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ namespace tree_sitter {
|
|||
std::string name;
|
||||
bool is_auxiliary;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Symbol> sym_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,6 @@
|
|||
12AB4663188DCB9800DE79DF /* stream_methods.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stream_methods.h; sourceTree = "<group>"; };
|
||||
12BC470318822A17005AC502 /* parse_config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_config.cpp; sourceTree = "<group>"; };
|
||||
12BC470618830BC5005AC502 /* first_set_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = first_set_spec.cpp; sourceTree = "<group>"; };
|
||||
12C344421822F27700B07BE3 /* transition_map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = transition_map.h; path = ../build_tables/transition_map.h; sourceTree = "<group>"; };
|
||||
12D1369E18342088005F3369 /* todo.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = todo.md; sourceTree = "<group>"; };
|
||||
12D136A0183570F5005F3369 /* pattern_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pattern_spec.cpp; path = spec/compiler/rules/pattern_spec.cpp; sourceTree = SOURCE_ROOT; };
|
||||
12D136A2183678A2005F3369 /* repeat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = repeat.cpp; sourceTree = "<group>"; };
|
||||
|
|
@ -234,7 +233,6 @@
|
|||
12EDCFA518820137005A7A07 /* perform.h */,
|
||||
12EDCFA618820137005A7A07 /* rule_transitions.cpp */,
|
||||
12EDCFA718820137005A7A07 /* rule_transitions.h */,
|
||||
12C344421822F27700B07BE3 /* transition_map.h */,
|
||||
);
|
||||
path = build_tables;
|
||||
sourceTree = "<group>";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue