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

56 lines
1.8 KiB
C++
Raw Normal View History

#include "first_set.h"
#include "compiler.h"
#include "rule_can_be_blank.h"
#include "rules/visitor.h"
#include "rules/seq.h"
#include "rules/choice.h"
namespace tree_sitter {
2014-02-12 22:56:44 -08:00
using std::set;
using namespace rules;
namespace build_tables {
2014-01-13 12:57:48 -08:00
class FirstSetVisitor : Visitor {
set<Symbol> value;
const Grammar grammar;
FirstSetVisitor(const Grammar &grammar) : grammar(grammar) {}
set<Symbol> set_union(const set<Symbol> &left, const set<Symbol> &right) {
set<Symbol> result = left;
result.insert(right.begin(), right.end());
return result;
}
void visit(const Symbol *rule) {
if (grammar.has_definition(*rule)) {
value = apply(grammar.rule(*rule), grammar);
2014-01-13 12:57:48 -08:00
} else {
value = set<Symbol>({ *rule });
}
}
void visit(const Choice *rule) {
value = set_union(apply(rule->left, grammar), apply(rule->right, grammar));
}
void visit(const Seq *rule) {
2014-02-13 18:52:17 -08:00
value = apply(rule->left, grammar);
2014-02-15 15:43:32 -08:00
if (rule_can_be_blank(rule->left, grammar)) {
2014-02-13 18:52:17 -08:00
value = set_union(value, apply(rule->right, grammar));
}
2014-01-13 12:57:48 -08:00
}
public:
static set<Symbol> apply(const rule_ptr rule, const Grammar &grammar) {
FirstSetVisitor visitor(grammar);
rule->accept(visitor);
return visitor.value;
}
};
2014-02-12 23:06:26 -08:00
set<Symbol> first_set(const rule_ptr &rule, const Grammar &grammar) {
2014-01-13 12:57:48 -08:00
return FirstSetVisitor::apply(rule, grammar);
}
}
}