Make ParseTableBuilder a private class
This commit is contained in:
parent
73d8cb3722
commit
84a7afbca5
4 changed files with 63 additions and 67 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ typedef std::unordered_set<ParseAction> 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<string, actions>({
|
||||
|
|
|
|||
|
|
@ -1,67 +1,77 @@
|
|||
#include "parse_table_builder.h"
|
||||
#include <unordered_map>
|
||||
#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<const ItemSet, size_t>())
|
||||
{};
|
||||
|
||||
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<const ItemSet, size_t> 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<const rules::Symbol>(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<const rules::Symbol>(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<const ItemSet, size_t>())
|
||||
{};
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,13 @@
|
|||
#ifndef __TreeSitter__parse_table_builder__
|
||||
#define __TreeSitter__parse_table_builder__
|
||||
|
||||
#include <unordered_map>
|
||||
#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<const ItemSet, size_t> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue