diff --git a/spec/compiler/build_tables/first_set_spec.cpp b/spec/compiler/build_tables/first_set_spec.cpp new file mode 100644 index 00000000..3776c2f4 --- /dev/null +++ b/spec/compiler/build_tables/first_set_spec.cpp @@ -0,0 +1,53 @@ +#include "spec_helper.h" +#include "build_tables/first_set.h" +#include "grammar.h" +#include "rules.h" + +using std::set; +using namespace build_tables; +using namespace rules; + +START_TEST + +describe("computing FIRST sets", []() { + Grammar grammar({ + { "A", choice({ + seq({ + sym("B"), + sym("x"), + sym("B") }), + sym("B") }) }, + { "B", choice({ + seq({ + sym("y"), + sym("z"), + sym("y") }), + sym("y") }) }, + { "C", seq({ + choice({ + sym("x"), + blank() }), + sym("y") }) } + }); + + describe("for a rule starting with a non-terminal B", [&]() { + it("includes FIRST(B)", [&]() { + auto terminals = first_set(grammar.rules.find("A")->second, grammar); + AssertThat(terminals, Equals(set({ + Symbol("y") + }))); + }); + }); + + describe("for a sequence xy", [&]() { + it("includes FIRST(y) when x can be blank", [&]() { + auto terminals = first_set(grammar.rules.find("C")->second, grammar); + AssertThat(terminals, Equals(set({ + Symbol("x"), + Symbol("y") + }))); + }); + }); +}); + +END_TEST \ No newline at end of file diff --git a/spec/compiler/build_tables/next_symbols_spec.cpp b/spec/compiler/build_tables/next_symbols_spec.cpp deleted file mode 100644 index df932471..00000000 --- a/spec/compiler/build_tables/next_symbols_spec.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "spec_helper.h" -#include "build_tables/next_symbols.h" -#include "grammar.h" -#include "rules.h" - -using std::set; -using namespace build_tables; -using namespace rules; - -START_TEST - -describe("computing FIRST sets", []() { - Grammar grammar({ - { "A", choice({ - seq({ - sym("B"), - sym("x"), - sym("B") }), - sym("B") }) }, - { "B", choice({ - seq({ - sym("y"), - sym("z"), - sym("y") }), - sym("y") }) }, - }); - - describe("for a rule", [&]() { - it("searches the tree for terminals", [&]() { - auto terminals = next_terminals(grammar.rules.find("A")->second, grammar); - AssertThat(terminals, Equals(set({ - Symbol("y") - }))); - }); - }); -}); - -END_TEST \ No newline at end of file diff --git a/src/compiler/build_tables/next_symbols.cpp b/src/compiler/build_tables/first_set.cpp similarity index 56% rename from src/compiler/build_tables/next_symbols.cpp rename to src/compiler/build_tables/first_set.cpp index 35f0c51f..47f259e4 100644 --- a/src/compiler/build_tables/next_symbols.cpp +++ b/src/compiler/build_tables/first_set.cpp @@ -1,4 +1,4 @@ -#include "next_symbols.h" +#include "first_set.h" #include "rule_transitions.h" #include "grammar.h" #include @@ -35,7 +35,11 @@ namespace tree_sitter { } void visit(const Seq *rule) { - value = apply(rule->left, grammar); + if (rule_can_be_blank(rule->left)) { + value = set_union(apply(rule->left, grammar), apply(rule->right, grammar)); + } else { + value = apply(rule->left, grammar); + } } public: @@ -46,37 +50,14 @@ namespace tree_sitter { } }; - template - set next_symbols(const rules::rule_ptr &rule, const Grammar &grammar) { - set result; - for (auto pair : rule_transitions(rule)) { - auto symbol = dynamic_pointer_cast(pair.first); - if (symbol && (grammar.has_definition(*symbol) == !isTerminal)) - result.insert(*symbol); - } - return result; - } - - set next_terminals(const rules::rule_ptr &rule, const Grammar &grammar) { + set first_set(const rules::rule_ptr &rule, const Grammar &grammar) { return FirstSetVisitor::apply(rule, grammar); } - set next_non_terminals(const rules::rule_ptr &rule, const Grammar &grammar) { - return next_symbols(rule, grammar); - } - - set next_terminals(const ParseItem &item, const Grammar &grammar) { - return next_terminals(item.rule, grammar); - } - - set next_non_terminals(const ParseItem &item, const Grammar &grammar) { - return next_non_terminals(item.rule, grammar); - } - - set next_terminals(const ParseItemSet &item_set, const Grammar &grammar) { + set first_set(const ParseItemSet &item_set, const Grammar &grammar) { set result; for (auto item : item_set) - for (rules::Symbol symbol : next_terminals(item, grammar)) + for (rules::Symbol symbol : first_set(item.rule, grammar)) result.insert(symbol); return result; } diff --git a/src/compiler/build_tables/first_set.h b/src/compiler/build_tables/first_set.h new file mode 100644 index 00000000..4e2a2858 --- /dev/null +++ b/src/compiler/build_tables/first_set.h @@ -0,0 +1,17 @@ +#ifndef __tree_sitter__first_set__ +#define __tree_sitter__first_set__ + +#include "item.h" +#include "symbol.h" +#include + +namespace tree_sitter { + class Grammar; + + namespace build_tables { + std::set first_set(const rules::rule_ptr &rule, const Grammar &grammar); + std::set first_set(const ParseItemSet &item_set, const Grammar &grammar); + } +} + +#endif diff --git a/src/compiler/build_tables/follow_sets.cpp b/src/compiler/build_tables/follow_sets.cpp new file mode 100644 index 00000000..4e65041c --- /dev/null +++ b/src/compiler/build_tables/follow_sets.cpp @@ -0,0 +1,29 @@ +#include "follow_sets.h" +#include "rule_transitions.h" +#include "grammar.h" + +using std::unordered_map; +using std::set; +using std::dynamic_pointer_cast; +using tree_sitter::rules::Symbol; + +namespace tree_sitter { + class Grammar; + + namespace build_tables { + unordered_map> follow_sets(const ParseItem &item, const Grammar &grammar) { + unordered_map> result; + + for (auto pair : rule_transitions(item.rule)) { + auto symbol = dynamic_pointer_cast(pair.first); + if (symbol && grammar.has_definition(*symbol)) { + set following_terminals; + following_terminals.insert(rules::Symbol("__END__")); + result.insert({ *symbol, following_terminals }); + } + } + + return result; + } + } +} diff --git a/src/compiler/build_tables/follow_sets.h b/src/compiler/build_tables/follow_sets.h new file mode 100644 index 00000000..d670bdf8 --- /dev/null +++ b/src/compiler/build_tables/follow_sets.h @@ -0,0 +1,17 @@ +#ifndef __tree_sitter__follow_sets__ +#define __tree_sitter__follow_sets__ + +#include "item.h" +#include "symbol.h" +#include +#include + +namespace tree_sitter { + class Grammar; + + namespace build_tables { + std::unordered_map> follow_sets(const ParseItem &item, const Grammar &grammar); + } +} + +#endif diff --git a/src/compiler/build_tables/item.cpp b/src/compiler/build_tables/item.cpp index c83f04df..d063502a 100644 --- a/src/compiler/build_tables/item.cpp +++ b/src/compiler/build_tables/item.cpp @@ -12,10 +12,7 @@ namespace tree_sitter { rule(rule) {}; bool Item::is_done() const { - for (auto pair : rule_transitions(rule)) - if (*pair.first == rules::Blank()) - return true; - return false; + return rule_can_be_blank(rule); } ostream& operator<<(ostream &stream, const Item &item) { @@ -39,10 +36,10 @@ namespace tree_sitter { return rule_names_eq && rules_eq; } - ParseItem::ParseItem(const std::string &rule_name, const rules::rule_ptr rule, int consumed_sym_count) : + ParseItem::ParseItem(const std::string &rule_name, const rules::rule_ptr rule, int consumed_sym_count, const std::string &lookahead_sym_name) : Item(rule_name, rule), consumed_sym_count(consumed_sym_count), - lookahead_sym_name("") {} + lookahead_sym_name(lookahead_sym_name) {} bool ParseItem::operator==(const ParseItem &other) const { bool rule_names_eq = other.rule_name == rule_name; diff --git a/src/compiler/build_tables/item.h b/src/compiler/build_tables/item.h index 841df11f..ffb763bf 100644 --- a/src/compiler/build_tables/item.h +++ b/src/compiler/build_tables/item.h @@ -28,7 +28,7 @@ namespace tree_sitter { class ParseItem : public Item { public: - ParseItem(const std::string &rule_name, const rules::rule_ptr rule, int consumed_sym_count); + ParseItem(const std::string &rule_name, const rules::rule_ptr rule, int consumed_sym_count, const std::string &lookahead_sym_name); bool operator==(const ParseItem &other) const; const int consumed_sym_count; diff --git a/src/compiler/build_tables/item_set_closure.cpp b/src/compiler/build_tables/item_set_closure.cpp index 190246a1..83c9275b 100644 --- a/src/compiler/build_tables/item_set_closure.cpp +++ b/src/compiler/build_tables/item_set_closure.cpp @@ -1,9 +1,10 @@ #include "item_set_closure.h" -#include "./next_symbols.h" +#include "./follow_sets.h" #include "grammar.h" #include "item.h" #include +using std::set; using std::vector; namespace tree_sitter { @@ -12,16 +13,16 @@ namespace tree_sitter { return (std::find(items.begin(), items.end(), item) != items.end()); } - ParseItem parse_item_at_beginning_of_rule(const rules::Symbol &symbol, const Grammar &grammar) { - return ParseItem(symbol.name, grammar.rule(symbol.name), 0); - } - static void add_item(ParseItemSet &item_set, const ParseItem &item, const Grammar &grammar) { if (!contains(item_set, item)) { item_set.insert(item); - for (rules::Symbol rule : next_non_terminals(item, grammar)) { - auto next_item = parse_item_at_beginning_of_rule(rule, grammar); - add_item(item_set, next_item, grammar); + for (auto pair : follow_sets(item, grammar)) { + auto non_terminal = pair.first; + auto terminals = pair.second; + for (rules::Symbol terminal : terminals) { + auto next_item = ParseItem(non_terminal.name, grammar.rule(non_terminal.name), 0, terminal.name); + add_item(item_set, next_item, grammar); + } } } } diff --git a/src/compiler/build_tables/item_set_transitions.cpp b/src/compiler/build_tables/item_set_transitions.cpp index bd874042..6507785d 100644 --- a/src/compiler/build_tables/item_set_transitions.cpp +++ b/src/compiler/build_tables/item_set_transitions.cpp @@ -26,7 +26,7 @@ namespace tree_sitter { transition_map result; for (ParseItem item : item_set) { for (auto transition : rule_transitions(item.rule)) { - auto new_item = ParseItem(item.rule_name, transition.second, item.consumed_sym_count + 1); + auto new_item = ParseItem(item.rule_name, transition.second, item.consumed_sym_count + 1, item.lookahead_sym_name); auto rule = dynamic_pointer_cast(transition.first); if (rule.get()) { auto new_item_set = make_shared(item_set_closure(ParseItemSet({ new_item }), grammar)); diff --git a/src/compiler/build_tables/next_symbols.h b/src/compiler/build_tables/next_symbols.h deleted file mode 100644 index e94537f5..00000000 --- a/src/compiler/build_tables/next_symbols.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __tree_sitter__first_terminal__ -#define __tree_sitter__first_terminal__ - -#include "item.h" -#include "symbol.h" -#include - -namespace tree_sitter { - class Grammar; - - namespace build_tables { - std::set next_terminals(const rules::rule_ptr &rule, const Grammar &grammar); - std::set next_terminals(const ParseItemSet &item_set, const Grammar &grammar); - std::set next_terminals(const ParseItem &item, const Grammar &grammar); - std::set next_non_terminals(const ParseItem &item, const Grammar &grammar); - } -} - -#endif diff --git a/src/compiler/build_tables/perform.cpp b/src/compiler/build_tables/perform.cpp index b02532a0..dbcc5120 100644 --- a/src/compiler/build_tables/perform.cpp +++ b/src/compiler/build_tables/perform.cpp @@ -1,7 +1,7 @@ #include "./perform.h" #include "item.h" #include "item_set_closure.h" -#include "next_symbols.h" +#include "first_set.h" #include "item_set_transitions.h" #include "rules.h" #include "grammar.h" @@ -84,7 +84,7 @@ namespace tree_sitter { LexItemSet lex_item_set_for_parse_item_set(const ParseItemSet &parse_item_set) { LexItemSet result; - for (rules::Symbol symbol : next_terminals(parse_item_set, grammar)) + for (rules::Symbol symbol : first_set(parse_item_set, grammar)) result.insert(LexItem(symbol.name, lex_grammar.rule(symbol.name))); return result; } @@ -110,7 +110,7 @@ namespace tree_sitter { lex_grammar(lex_grammar) {}; pair build() { - auto item = ParseItem(ParseTable::START, rules::sym(grammar.start_rule_name), 0); + auto item = ParseItem(ParseTable::START, rules::sym(grammar.start_rule_name), 0, ParseTable::END_OF_INPUT); ParseItemSet item_set = item_set_closure(ParseItemSet({ item }), grammar); add_parse_state(item_set); return pair(parse_table, lex_table); diff --git a/src/compiler/build_tables/rule_transitions.cpp b/src/compiler/build_tables/rule_transitions.cpp index 8834c929..ece1fd9f 100644 --- a/src/compiler/build_tables/rule_transitions.cpp +++ b/src/compiler/build_tables/rule_transitions.cpp @@ -5,6 +5,10 @@ using namespace tree_sitter::rules; namespace tree_sitter { namespace build_tables { + bool is_blank(const rule_ptr &rule) { + return typeid(*rule) == typeid(Blank); + } + class TransitionsVisitor : public rules::Visitor { public: transition_map value; @@ -30,7 +34,7 @@ namespace tree_sitter { void visit(const Seq *rule) { value = rule_transitions(rule->left).map([&](const rule_ptr left_rule) -> rule_ptr { - if (typeid(*left_rule) == typeid(Blank)) + if (is_blank(left_rule)) return rule->right; else return seq({ left_rule, rule->right }); @@ -55,6 +59,13 @@ namespace tree_sitter { } }; + bool rule_can_be_blank(const rule_ptr &rule) { + for (auto pair : rule_transitions(rule)) + if (is_blank(pair.first)) + return true; + return false; + } + transition_map rule_transitions(const rule_ptr &rule) { TransitionsVisitor visitor; rule->accept(visitor); diff --git a/src/compiler/build_tables/rule_transitions.h b/src/compiler/build_tables/rule_transitions.h index da627dd2..19db0ac3 100644 --- a/src/compiler/build_tables/rule_transitions.h +++ b/src/compiler/build_tables/rule_transitions.h @@ -6,6 +6,7 @@ namespace tree_sitter { namespace build_tables { + bool rule_can_be_blank(const rules::rule_ptr &rule); transition_map rule_transitions(const rules::rule_ptr &rule); } } diff --git a/src/compiler/rules/rule.h b/src/compiler/rules/rule.h index fb90ed04..00014f07 100644 --- a/src/compiler/rules/rule.h +++ b/src/compiler/rules/rule.h @@ -28,7 +28,7 @@ namespace tree_sitter { namespace std { template<> struct hash { - size_t operator()(const tree_sitter::rules::Rule &rule) { + size_t operator()(const tree_sitter::rules::Rule &rule) const { return rule.hash_code(); } }; diff --git a/tree_sitter.xcodeproj/project.pbxproj b/tree_sitter.xcodeproj/project.pbxproj index f901d9e3..fa440216 100644 --- a/tree_sitter.xcodeproj/project.pbxproj +++ b/tree_sitter.xcodeproj/project.pbxproj @@ -17,8 +17,9 @@ 1225CC6418765693000D4723 /* prepare_grammar_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1225CC6318765693000D4723 /* prepare_grammar_spec.cpp */; }; 1251209B1830145300C9B56A /* rule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1251209A1830145300C9B56A /* rule.cpp */; }; 125120A4183083BD00C9B56A /* arithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 125120A3183083BD00C9B56A /* arithmetic.cpp */; }; + 12AB465F188BD03E00DE79DF /* follow_sets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12AB465D188BD03E00DE79DF /* follow_sets.cpp */; }; 12BC470518822B27005AC502 /* parse_config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12BC470318822A17005AC502 /* parse_config.cpp */; }; - 12BC470718830BC5005AC502 /* next_symbols_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12BC470618830BC5005AC502 /* next_symbols_spec.cpp */; }; + 12BC470718830BC5005AC502 /* first_set_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12BC470618830BC5005AC502 /* first_set_spec.cpp */; }; 12D136A4183678A2005F3369 /* repeat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12D136A2183678A2005F3369 /* repeat.cpp */; }; 12EDCF8A187B498C005A7A07 /* tree_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12EDCF89187B498C005A7A07 /* tree_spec.cpp */; }; 12EDCF8D187C6282005A7A07 /* document.c in Sources */ = {isa = PBXBuildFile; fileRef = 12EDCF8C187C6282005A7A07 /* document.c */; }; @@ -34,7 +35,7 @@ 12EDCFBD188205BF005A7A07 /* perform_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12EDCFB7188205BA005A7A07 /* perform_spec.cpp */; }; 12EDCFC018820880005A7A07 /* item_set_closure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12EDCFBE18820880005A7A07 /* item_set_closure.cpp */; }; 12EDCFC318820A70005A7A07 /* item_set_transitions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12EDCFC118820A70005A7A07 /* item_set_transitions.cpp */; }; - 12EDCFC61882153D005A7A07 /* next_symbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12EDCFC41882153D005A7A07 /* next_symbols.cpp */; }; + 12EDCFC61882153D005A7A07 /* first_set.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12EDCFC41882153D005A7A07 /* first_set.cpp */; }; 12F9A64E182DD5FD00FAF50C /* spec_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12F9A64C182DD5FD00FAF50C /* spec_helper.cpp */; }; 12F9A651182DD6BC00FAF50C /* grammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12F9A64F182DD6BC00FAF50C /* grammar.cpp */; }; 12FD4061185E68470041A84E /* c_code.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12FD405F185E68470041A84E /* c_code.cpp */; }; @@ -94,8 +95,10 @@ 1251209A1830145300C9B56A /* rule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rule.cpp; sourceTree = ""; }; 125120A218307FFD00C9B56A /* arithmetic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arithmetic.h; path = spec/fixtures/grammars/arithmetic.h; sourceTree = SOURCE_ROOT; }; 125120A3183083BD00C9B56A /* arithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = arithmetic.cpp; path = spec/fixtures/grammars/arithmetic.cpp; sourceTree = SOURCE_ROOT; }; + 12AB465D188BD03E00DE79DF /* follow_sets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = follow_sets.cpp; sourceTree = ""; }; + 12AB465E188BD03E00DE79DF /* follow_sets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = follow_sets.h; sourceTree = ""; }; 12BC470318822A17005AC502 /* parse_config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_config.cpp; sourceTree = ""; }; - 12BC470618830BC5005AC502 /* next_symbols_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = next_symbols_spec.cpp; sourceTree = ""; }; + 12BC470618830BC5005AC502 /* first_set_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = first_set_spec.cpp; sourceTree = ""; }; 12C344421822F27700B07BE3 /* transition_map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = transition_map.h; path = ../build_tables/transition_map.h; sourceTree = ""; }; 12D1369E18342088005F3369 /* todo.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = todo.md; sourceTree = ""; }; 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; }; @@ -130,8 +133,8 @@ 12EDCFBF18820880005A7A07 /* item_set_closure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = item_set_closure.h; sourceTree = ""; }; 12EDCFC118820A70005A7A07 /* item_set_transitions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = item_set_transitions.cpp; sourceTree = ""; }; 12EDCFC218820A70005A7A07 /* item_set_transitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = item_set_transitions.h; sourceTree = ""; }; - 12EDCFC41882153D005A7A07 /* next_symbols.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = next_symbols.cpp; sourceTree = ""; }; - 12EDCFC51882153D005A7A07 /* next_symbols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = next_symbols.h; sourceTree = ""; }; + 12EDCFC41882153D005A7A07 /* first_set.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = first_set.cpp; sourceTree = ""; }; + 12EDCFC51882153D005A7A07 /* first_set.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = first_set.h; sourceTree = ""; }; 12F9A64C182DD5FD00FAF50C /* spec_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = spec_helper.cpp; path = spec/spec_helper.cpp; sourceTree = SOURCE_ROOT; }; 12F9A64D182DD5FD00FAF50C /* spec_helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spec_helper.h; path = spec/spec_helper.h; sourceTree = SOURCE_ROOT; }; 12F9A64F182DD6BC00FAF50C /* grammar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = grammar.cpp; path = src/compiler/grammar.cpp; sourceTree = SOURCE_ROOT; }; @@ -204,14 +207,16 @@ 12130618182C84B700FCF928 /* build_tables */ = { isa = PBXGroup; children = ( + 12EDCFC41882153D005A7A07 /* first_set.cpp */, + 12EDCFC51882153D005A7A07 /* first_set.h */, + 12AB465D188BD03E00DE79DF /* follow_sets.cpp */, + 12AB465E188BD03E00DE79DF /* follow_sets.h */, 12EDCFA218820137005A7A07 /* item.cpp */, 12EDCFA318820137005A7A07 /* item.h */, 12EDCFBE18820880005A7A07 /* item_set_closure.cpp */, 12EDCFBF18820880005A7A07 /* item_set_closure.h */, 12EDCFC118820A70005A7A07 /* item_set_transitions.cpp */, 12EDCFC218820A70005A7A07 /* item_set_transitions.h */, - 12EDCFC41882153D005A7A07 /* next_symbols.cpp */, - 12EDCFC51882153D005A7A07 /* next_symbols.h */, 12EDCFA418820137005A7A07 /* perform.cpp */, 12EDCFA518820137005A7A07 /* perform.h */, 12EDCFA618820137005A7A07 /* rule_transitions.cpp */, @@ -226,7 +231,7 @@ children = ( 12EDCFB6188205BA005A7A07 /* rule_transitions_spec.cpp */, 12EDCFB7188205BA005A7A07 /* perform_spec.cpp */, - 12BC470618830BC5005AC502 /* next_symbols_spec.cpp */, + 12BC470618830BC5005AC502 /* first_set_spec.cpp */, ); name = build_tables; path = compiler/build_tables; @@ -470,8 +475,9 @@ 12130617182C3D2900FCF928 /* string.cpp in Sources */, 12EDCFC018820880005A7A07 /* item_set_closure.cpp in Sources */, 12EDCFBD188205BF005A7A07 /* perform_spec.cpp in Sources */, - 12EDCFC61882153D005A7A07 /* next_symbols.cpp in Sources */, + 12EDCFC61882153D005A7A07 /* first_set.cpp in Sources */, 12130611182C3A1100FCF928 /* blank.cpp in Sources */, + 12AB465F188BD03E00DE79DF /* follow_sets.cpp in Sources */, 1213060E182C398300FCF928 /* choice.cpp in Sources */, 12F9A64E182DD5FD00FAF50C /* spec_helper.cpp in Sources */, 12EDCFB018820392005A7A07 /* item.cpp in Sources */, @@ -495,7 +501,7 @@ 12EDCFBC188205BF005A7A07 /* rule_transitions_spec.cpp in Sources */, 12130605182C348F00FCF928 /* character.cpp in Sources */, 12EDCFB418820519005A7A07 /* compile.cpp in Sources */, - 12BC470718830BC5005AC502 /* next_symbols_spec.cpp in Sources */, + 12BC470718830BC5005AC502 /* first_set_spec.cpp in Sources */, 1213060B182C389100FCF928 /* symbol.cpp in Sources */, 1251209B1830145300C9B56A /* rule.cpp in Sources */, 27A343CA69E17E0F9EBEDF1C /* pattern.cpp in Sources */,