Remove transition_map class

This commit is contained in:
Max Brunsfeld 2014-02-11 13:15:44 -08:00
parent 91489363ca
commit 1962c17f45
17 changed files with 1115 additions and 1177 deletions

View file

@ -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("*")),

View file

@ -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() },
})));
});
});

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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)) {

View file

@ -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);
});
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -52,8 +52,6 @@ namespace tree_sitter {
std::set<CharacterRange> ranges;
};
typedef std::shared_ptr<CharacterSet> char_ptr;
}
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -22,8 +22,6 @@ namespace tree_sitter {
std::string name;
bool is_auxiliary;
};
typedef std::shared_ptr<Symbol> sym_ptr;
}
}

View file

@ -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>";