Split up item set transition functions
This commit is contained in:
parent
7490a7ac94
commit
a8588cd4d3
7 changed files with 67 additions and 58 deletions
|
|
@ -2,10 +2,11 @@
|
|||
#include "rule_can_be_blank.h"
|
||||
#include "grammar.h"
|
||||
|
||||
using std::set;
|
||||
using namespace tree_sitter::rules;
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::set;
|
||||
using namespace rules;
|
||||
|
||||
namespace build_tables {
|
||||
class FirstSetVisitor : Visitor {
|
||||
set<Symbol> value;
|
||||
|
|
|
|||
|
|
@ -4,24 +4,25 @@
|
|||
#include "rule_can_be_blank.h"
|
||||
#include "grammar.h"
|
||||
|
||||
using std::map;
|
||||
using std::set;
|
||||
using tree_sitter::rules::Symbol;
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::set;
|
||||
using std::map;
|
||||
using rules::Symbol;
|
||||
using rules::rule_ptr;
|
||||
|
||||
class Grammar;
|
||||
|
||||
namespace build_tables {
|
||||
map<Symbol, set<Symbol>> follow_sets(const ParseItem &item, const Grammar &grammar) {
|
||||
map<Symbol, set<Symbol>> result;
|
||||
|
||||
for (auto pair : sym_transitions(item.rule)) {
|
||||
auto symbol = pair.first;
|
||||
for (auto &pair : sym_transitions(item.rule)) {
|
||||
Symbol symbol = pair.first;
|
||||
rule_ptr next_rule = pair.second;
|
||||
if (grammar.has_definition(symbol)) {
|
||||
auto following_non_terminals = first_set(pair.second, grammar);
|
||||
if (rule_can_be_blank(pair.second)) {
|
||||
set<Symbol> following_non_terminals = first_set(next_rule, grammar);
|
||||
if (rule_can_be_blank(next_rule))
|
||||
following_non_terminals.insert(item.lookahead_sym);
|
||||
}
|
||||
result.insert({ symbol, following_non_terminals });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
#include "grammar.h"
|
||||
#include "rule_can_be_blank.h"
|
||||
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::ostream;
|
||||
using std::vector;
|
||||
using tree_sitter::rules::Symbol;
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::ostream;
|
||||
using std::vector;
|
||||
using rules::Symbol;
|
||||
|
||||
namespace build_tables {
|
||||
Item::Item(const Symbol &lhs, const rules::rule_ptr rule) :
|
||||
lhs(lhs),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
#include "item.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::set;
|
||||
using rules::Symbol;
|
||||
|
||||
namespace build_tables {
|
||||
static bool contains(ParseItemSet items, ParseItem item) {
|
||||
return (std::find(items.begin(), items.end(), item) != items.end());
|
||||
|
|
@ -13,10 +16,10 @@ namespace tree_sitter {
|
|||
if (!contains(item_set, item)) {
|
||||
item_set.insert(item);
|
||||
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, grammar.rule(non_terminal), {}, terminal);
|
||||
Symbol non_terminal = pair.first;
|
||||
set<Symbol> terminals = pair.second;
|
||||
for (auto &terminal : terminals) {
|
||||
ParseItem next_item(non_terminal, grammar.rule(non_terminal), {}, terminal);
|
||||
add_item(item_set, next_item, grammar);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,56 +3,60 @@
|
|||
#include "rule_transitions.h"
|
||||
#include "merge_transitions.h"
|
||||
|
||||
using std::map;
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::map;
|
||||
using std::set;
|
||||
using rules::CharacterSet;
|
||||
using rules::Symbol;
|
||||
|
||||
namespace build_tables {
|
||||
template<typename T>
|
||||
static std::set<T> merge_sets(const std::set<T> &left, const std::set<T> &right) {
|
||||
std::set<T> result = left;
|
||||
result.insert(right.begin(), right.end());
|
||||
map<CharacterSet, LexItemSet> char_transitions(const LexItem &item) {
|
||||
map<CharacterSet, LexItemSet> result;
|
||||
for (auto &transition : char_transitions(item.rule)) {
|
||||
LexItem next_item(item.lhs, transition.second);
|
||||
result.insert({ transition.first, LexItemSet({ next_item }) });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
map<Symbol, ParseItemSet> sym_transitions(const ParseItem &item, const Grammar &grammar) {
|
||||
map<Symbol, ParseItemSet> result;
|
||||
for (auto transition : sym_transitions(item.rule)) {
|
||||
Symbol rule = transition.first;
|
||||
auto consumed_symbols = item.consumed_symbols;
|
||||
consumed_symbols.push_back(rule.is_auxiliary);
|
||||
ParseItem new_item(item.lhs, transition.second, consumed_symbols, item.lookahead_sym);
|
||||
result.insert({ rule, item_set_closure(ParseItemSet({ new_item }), grammar) });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static set<T> merge_sets(const set<T> &left, const set<T> &right) {
|
||||
set<T> result = left;
|
||||
result.insert(right.begin(), right.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
map<CharacterSet, LexItemSet> char_transitions(const LexItemSet &item_set, const Grammar &grammar) {
|
||||
map<CharacterSet, LexItemSet> result;
|
||||
for (const LexItem &item : item_set) {
|
||||
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.insert({ rule, LexItemSet(new_item_set) });
|
||||
}
|
||||
|
||||
map<CharacterSet, LexItemSet> item_transitions = char_transitions(item);
|
||||
result = merge_char_transitions<LexItemSet>(result, item_transitions, [](LexItemSet left, LexItemSet right) {
|
||||
return merge_sets(left, right);
|
||||
});
|
||||
}
|
||||
|
||||
return 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) {
|
||||
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);
|
||||
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.insert({ rule, ParseItemSet(new_item_set) });
|
||||
}
|
||||
|
||||
result = merge_sym_transitions<ParseItemSet>(result, item_transitions, [](ParseItemSet left, ParseItemSet right) {
|
||||
map<Symbol, ParseItemSet> sym_transitions(const ParseItemSet &item_set, const Grammar &grammar) {
|
||||
map<Symbol, ParseItemSet> result;
|
||||
for (const ParseItem &item : item_set) {
|
||||
map<Symbol, ParseItemSet> item_transitions = sym_transitions(item, grammar);
|
||||
result = merge_sym_transitions<ParseItemSet>(result, item_transitions, [&](ParseItemSet left, ParseItemSet right) {
|
||||
return merge_sets(left, right);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
#include "rules.h"
|
||||
#include "grammar.h"
|
||||
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::map;
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::map;
|
||||
|
||||
namespace build_tables {
|
||||
static int NOT_FOUND = -1;
|
||||
static rules::Symbol START("start", true);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
#include "rule_can_be_blank.h"
|
||||
#include "merge_transitions.h"
|
||||
|
||||
using namespace tree_sitter::rules;
|
||||
using std::map;
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::map;
|
||||
using namespace rules;
|
||||
|
||||
namespace build_tables {
|
||||
bool is_blank(const rule_ptr &rule) {
|
||||
return typeid(*rule) == typeid(Blank);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue