2014-01-19 01:49:56 -08:00
|
|
|
#include "first_set.h"
|
2014-02-17 12:53:57 -08:00
|
|
|
#include "tree_sitter/compiler.h"
|
2014-02-19 13:36:38 -08:00
|
|
|
#include "prepared_grammar.h"
|
2014-02-11 13:21:45 -08:00
|
|
|
#include "rule_can_be_blank.h"
|
2014-02-16 22:13:08 -08:00
|
|
|
#include "rules/visitor.h"
|
|
|
|
|
#include "rules/seq.h"
|
|
|
|
|
#include "rules/choice.h"
|
2014-01-11 16:48:40 -08:00
|
|
|
|
|
|
|
|
namespace tree_sitter {
|
2014-02-12 22:56:44 -08:00
|
|
|
using std::set;
|
|
|
|
|
using namespace rules;
|
|
|
|
|
|
2014-01-11 16:48:40 -08:00
|
|
|
namespace build_tables {
|
2014-02-23 18:04:51 -08:00
|
|
|
class FirstSet : public RuleFn<set<Symbol>> {
|
2014-02-19 13:36:38 -08:00
|
|
|
const PreparedGrammar grammar;
|
2014-02-23 18:04:51 -08:00
|
|
|
public:
|
|
|
|
|
FirstSet(const PreparedGrammar &grammar) : grammar(grammar) {}
|
2014-01-13 12:57:48 -08:00
|
|
|
|
|
|
|
|
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)) {
|
2014-02-23 18:04:51 -08:00
|
|
|
value = apply(grammar.rule(*rule));
|
2014-01-13 12:57:48 -08:00
|
|
|
} else {
|
|
|
|
|
value = set<Symbol>({ *rule });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Choice *rule) {
|
2014-02-23 18:04:51 -08:00
|
|
|
value = set_union(apply(rule->left), apply(rule->right));
|
2014-01-13 12:57:48 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Seq *rule) {
|
2014-02-23 18:04:51 -08:00
|
|
|
auto result = apply(rule->left);
|
2014-02-15 15:43:32 -08:00
|
|
|
if (rule_can_be_blank(rule->left, grammar)) {
|
2014-02-23 18:04:51 -08:00
|
|
|
result = set_union(result, apply(rule->right));
|
2014-01-19 01:49:56 -08:00
|
|
|
}
|
2014-02-23 18:04:51 -08:00
|
|
|
value = result;
|
2014-01-13 12:57:48 -08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
set<Symbol> first_set(const rule_ptr &rule, const PreparedGrammar &grammar) {
|
2014-02-23 18:04:51 -08:00
|
|
|
return FirstSet(grammar).apply(rule);
|
2014-01-13 12:57:48 -08:00
|
|
|
}
|
2014-01-11 16:48:40 -08:00
|
|
|
}
|
|
|
|
|
}
|