tree-sitter/src/compiler/build_tables/first_set.cc

73 lines
2.5 KiB
C++
Raw Normal View History

2014-03-09 21:37:21 -07:00
#include "compiler/build_tables/first_set.h"
#include "tree_sitter/compiler.h"
2014-03-09 21:37:21 -07:00
#include "compiler/prepared_grammar.h"
#include "compiler/build_tables/rule_can_be_blank.h"
#include "compiler/rules/metadata.h"
2014-03-09 21:37:21 -07:00
#include "compiler/rules/visitor.h"
#include "compiler/rules/seq.h"
#include "compiler/rules/choice.h"
#include "compiler/rules/symbol.h"
namespace tree_sitter {
2014-02-12 22:56:44 -08:00
using std::set;
using rules::Symbol;
2014-02-12 22:56:44 -08:00
namespace build_tables {
class FirstSet : public rules::RuleFn<set<Symbol>> {
const PreparedGrammar *grammar;
set<Symbol> visited_symbols;
2014-04-28 21:46:43 -07:00
2014-02-23 18:04:51 -08:00
public:
explicit FirstSet(const PreparedGrammar *grammar) : grammar(grammar) {}
2014-03-09 19:49:35 -07:00
set<Symbol> apply_to(const Symbol *rule) {
auto insertion_result = visited_symbols.insert(*rule);
if (insertion_result.second) {
return (rule->is_token()) ?
set<Symbol>({ *rule }) :
apply(grammar->rule(*rule));
2014-04-09 13:14:46 -07:00
} else {
return set<Symbol>();
2014-01-13 12:57:48 -08:00
}
}
2014-04-04 13:10:55 -07:00
set<Symbol> apply_to(const rules::Metadata *rule) {
2014-04-09 13:14:46 -07:00
return apply(rule->rule);
}
2014-03-09 19:49:35 -07:00
set<Symbol> apply_to(const rules::Choice *rule) {
set<Symbol> result;
for (const auto &el : rule->elements) {
auto &&next_syms = apply(el);
result.insert(next_syms.begin(), next_syms.end());
}
return result;
2014-01-13 12:57:48 -08:00
}
2014-03-09 19:49:35 -07:00
set<Symbol> apply_to(const rules::Seq *rule) {
auto &&result = apply(rule->left);
if (rule_can_be_blank(rule->left, *grammar)) {
auto &&right_symbols = apply(rule->right);
result.insert(right_symbols.begin(), right_symbols.end());
}
return result;
2014-01-13 12:57:48 -08:00
}
};
2014-03-09 19:49:35 -07:00
set<Symbol> first_set(const rules::rule_ptr &rule, const PreparedGrammar &grammar) {
return FirstSet(&grammar).apply(rule);
2014-01-13 12:57:48 -08:00
}
2014-03-09 19:49:35 -07:00
set<Symbol> first_set(const ParseItemSet &item_set, const PreparedGrammar &grammar) {
set<Symbol> result;
2014-02-26 19:03:43 -08:00
for (auto &item : item_set) {
auto &&rule_set = first_set(item.rule, grammar);
result.insert(rule_set.begin(), rule_set.end());
2014-02-26 19:03:43 -08:00
if (rule_can_be_blank(item.rule, grammar))
result.insert(item.lookahead_sym);
}
return result;
}
}
2014-04-28 21:46:43 -07:00
}