diff --git a/spec/compiler/generate_parsers.cpp b/spec/compiler/generate_parsers.cpp index 787c4d67..2c5fb8ff 100644 --- a/spec/compiler/generate_parsers.cpp +++ b/spec/compiler/generate_parsers.cpp @@ -13,7 +13,7 @@ Describe(code_generation) { It(works_for_the_arithmetic_grammar) { Grammar grammar = test_grammars::arithmetic(); - ParseTable table = ParseTableBuilder::build_table(grammar); + ParseTable table = build_tables(grammar); std::ofstream parser_file(test_parser_dir + "/arithmetic.c"); parser_file << code_gen::c_code(grammar, table); } diff --git a/spec/compiler/lr/parse_table_builder_spec.cpp b/spec/compiler/lr/parse_table_builder_spec.cpp index 1b470797..d23c51cc 100644 --- a/spec/compiler/lr/parse_table_builder_spec.cpp +++ b/spec/compiler/lr/parse_table_builder_spec.cpp @@ -8,7 +8,7 @@ typedef std::unordered_set actions; Describe(ParseTableBuilder_test) { Grammar grammar = test_grammars::arithmetic(); - ParseTable table = ParseTableBuilder::build_table(grammar); + ParseTable table = build_tables(grammar); It(has_the_right_starting_state) { AssertThat(table.actions_for(0), Equals(unordered_map({ diff --git a/src/compiler/lr/parse_table_builder.cpp b/src/compiler/lr/parse_table_builder.cpp index 6c5fe815..6494439a 100644 --- a/src/compiler/lr/parse_table_builder.cpp +++ b/src/compiler/lr/parse_table_builder.cpp @@ -1,67 +1,77 @@ #include "parse_table_builder.h" +#include #include "item_set.h" #include "rules.h" +#include "item_set.h" +#include "grammar.h" using namespace std; namespace tree_sitter { namespace lr { static int NOT_FOUND = -1; - - ParseTable ParseTableBuilder::build_table(const tree_sitter::Grammar &grammar) { - auto builder = ParseTableBuilder(grammar); - builder.build(); - return builder.table; - } - - ParseTableBuilder::ParseTableBuilder(const Grammar &grammar) : - grammar(grammar), - table(ParseTable(grammar.rule_names())), - state_indices(unordered_map()) - {}; - void ParseTableBuilder::build() { - auto item = Item(ParseTable::START, rules::sym(grammar.start_rule_name), 0); - auto item_set = ItemSet(item, grammar); - add_item_set(item_set); - } - - size_t ParseTableBuilder::add_item_set(const ItemSet &item_set) { - auto state_index = state_index_for_item_set(item_set); - if (state_index == NOT_FOUND) { - state_index = table.add_state(); - state_indices[item_set] = state_index; - - add_shift_actions(item_set, state_index); - add_reduce_actions(item_set, state_index); + class ParseTableBuilder { + const Grammar grammar; + std::unordered_map state_indices; + ParseTable table; + + long state_index_for_item_set(const ItemSet &item_set) const { + auto entry = state_indices.find(item_set); + return (entry == state_indices.end()) ? NOT_FOUND : entry->second; } - return state_index; - } - - void ParseTableBuilder::add_shift_actions(const ItemSet &item_set, size_t state_index) { - for (auto transition : item_set.sym_transitions(grammar)) { - rules::sym_ptr symbol = static_pointer_cast(transition.first); - size_t new_state_index = add_item_set(*transition.second); - table.add_action(state_index, symbol->name, ParseAction::Shift(new_state_index)); + + void add_shift_actions(const ItemSet &item_set, size_t state_index) { + for (auto transition : item_set.sym_transitions(grammar)) { + rules::sym_ptr symbol = static_pointer_cast(transition.first); + size_t new_state_index = add_item_set(*transition.second); + table.add_action(state_index, symbol->name, ParseAction::Shift(new_state_index)); + } } - } - - void ParseTableBuilder::add_reduce_actions(const ItemSet &item_set, size_t state_index) { - for (Item item : item_set) { - if (item.is_done()) { - if (item.rule_name == ParseTable::START) { - table.add_action(state_index, ParseTable::END_OF_INPUT, ParseAction::Accept()); - } else { - for (string rule_name : table.symbol_names) - table.add_action(state_index, rule_name, ParseAction::Reduce(item.rule_name, item.consumed_sym_count)); + + void add_reduce_actions(const ItemSet &item_set, size_t state_index) { + for (Item item : item_set) { + if (item.is_done()) { + if (item.rule_name == ParseTable::START) { + table.add_action(state_index, ParseTable::END_OF_INPUT, ParseAction::Accept()); + } else { + for (string rule_name : table.symbol_names) + table.add_action(state_index, rule_name, ParseAction::Reduce(item.rule_name, item.consumed_sym_count)); + } } } } - } + + size_t add_item_set(const ItemSet &item_set) { + auto state_index = state_index_for_item_set(item_set); + if (state_index == NOT_FOUND) { + state_index = table.add_state(); + state_indices[item_set] = state_index; + + add_shift_actions(item_set, state_index); + add_reduce_actions(item_set, state_index); + } + return state_index; + } + + public: + + ParseTableBuilder(const Grammar &grammar) : + grammar(grammar), + table(ParseTable(grammar.rule_names())), + state_indices(unordered_map()) + {}; + + ParseTable build() { + auto item = Item(ParseTable::START, rules::sym(grammar.start_rule_name), 0); + auto item_set = ItemSet(item, grammar); + add_item_set(item_set); + return table; + } + }; - long ParseTableBuilder::state_index_for_item_set(const ItemSet &item_set) const { - auto entry = state_indices.find(item_set); - return (entry == state_indices.end()) ? NOT_FOUND : entry->second; + ParseTable build_tables(const tree_sitter::Grammar &grammar) { + return ParseTableBuilder(grammar).build(); } } } \ No newline at end of file diff --git a/src/compiler/lr/parse_table_builder.h b/src/compiler/lr/parse_table_builder.h index 9a58752d..9392838e 100644 --- a/src/compiler/lr/parse_table_builder.h +++ b/src/compiler/lr/parse_table_builder.h @@ -1,27 +1,13 @@ #ifndef __TreeSitter__parse_table_builder__ #define __TreeSitter__parse_table_builder__ -#include -#include "grammar.h" -#include "item_set.h" #include "parse_table.h" namespace tree_sitter { + class Grammar; + namespace lr { - class ParseTableBuilder { - const Grammar grammar; - ParseTable table; - std::unordered_map state_indices; - - long state_index_for_item_set(const ItemSet &item_set) const; - void add_shift_actions(const ItemSet &item_set, size_t state_index); - void add_reduce_actions(const ItemSet &item_set, size_t state_index); - size_t add_item_set(const ItemSet &item_set); - public: - ParseTableBuilder(const Grammar &grammar); - static ParseTable build_table(const Grammar &grammar); - void build(); - }; + ParseTable build_tables(const Grammar &grammar); } }