2014-01-11 15:14:17 -08:00
|
|
|
#include "rule_transitions.h"
|
2013-12-18 20:58:05 -08:00
|
|
|
#include "rules.h"
|
|
|
|
|
|
2013-12-28 23:26:20 -08:00
|
|
|
using namespace tree_sitter::rules;
|
|
|
|
|
|
2013-12-18 20:58:05 -08:00
|
|
|
namespace tree_sitter {
|
2014-01-11 15:14:17 -08:00
|
|
|
namespace build_tables {
|
2014-01-19 01:49:56 -08:00
|
|
|
bool is_blank(const rule_ptr &rule) {
|
|
|
|
|
return typeid(*rule) == typeid(Blank);
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-28 23:26:20 -08:00
|
|
|
class TransitionsVisitor : public rules::Visitor {
|
2013-12-18 20:58:05 -08:00
|
|
|
public:
|
2013-12-20 21:59:31 -08:00
|
|
|
transition_map<Rule, Rule> value;
|
2013-12-18 20:58:05 -08:00
|
|
|
|
2014-02-03 13:05:51 -08:00
|
|
|
void visit(const CharacterSet *rule) {
|
2014-01-02 13:04:41 -08:00
|
|
|
value = transition_map<Rule, Rule>({{ rule->copy(), blank() }});
|
2013-12-18 20:58:05 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Symbol *rule) {
|
2014-01-02 13:04:41 -08:00
|
|
|
value = transition_map<Rule, Rule>({{ rule->copy(), blank() }});
|
2013-12-18 20:58:05 -08:00
|
|
|
}
|
2014-01-03 22:42:05 -08:00
|
|
|
|
2013-12-18 20:58:05 -08:00
|
|
|
void visit(const Choice *rule) {
|
2014-01-11 15:14:17 -08:00
|
|
|
value = rule_transitions(rule->left);
|
|
|
|
|
value.merge(rule_transitions(rule->right), [&](rule_ptr left, rule_ptr right) -> rule_ptr {
|
2013-12-18 20:58:05 -08:00
|
|
|
return choice({ left, right });
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Seq *rule) {
|
2014-01-11 15:14:17 -08:00
|
|
|
value = rule_transitions(rule->left).map<Rule>([&](const rule_ptr left_rule) -> rule_ptr {
|
2014-01-19 01:49:56 -08:00
|
|
|
if (is_blank(left_rule))
|
2013-12-18 20:58:05 -08:00
|
|
|
return rule->right;
|
|
|
|
|
else
|
|
|
|
|
return seq({ left_rule, rule->right });
|
|
|
|
|
});
|
2014-01-23 23:56:37 -08:00
|
|
|
if (rule_can_be_blank(rule->left)) {
|
|
|
|
|
value.merge(rule_transitions(rule->right), [&](rule_ptr left, rule_ptr right) -> rule_ptr {
|
|
|
|
|
return choice({ left, right });
|
|
|
|
|
});
|
|
|
|
|
}
|
2013-12-18 20:58:05 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Repeat *rule) {
|
2014-01-11 15:14:17 -08:00
|
|
|
value = rule_transitions(rule->content).map<Rule>([&](const rule_ptr &value) -> rule_ptr {
|
2014-01-03 22:42:05 -08:00
|
|
|
return seq({ value, choice({ rule->copy(), blank() }) });
|
2013-12-18 20:58:05 -08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const String *rule) {
|
|
|
|
|
rule_ptr result = character(rule->value[0]);
|
|
|
|
|
for (int i = 1; i < rule->value.length(); i++)
|
|
|
|
|
result = seq({ result, character(rule->value[i]) });
|
2014-01-11 15:14:17 -08:00
|
|
|
value = rule_transitions(result);
|
2013-12-18 20:58:05 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Pattern *rule) {
|
2014-01-11 15:14:17 -08:00
|
|
|
value = rule_transitions(rule->to_rule_tree());
|
2013-12-18 20:58:05 -08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-01-11 15:14:17 -08:00
|
|
|
transition_map<Rule, Rule> rule_transitions(const rule_ptr &rule) {
|
2013-12-18 20:58:05 -08:00
|
|
|
TransitionsVisitor visitor;
|
|
|
|
|
rule->accept(visitor);
|
|
|
|
|
return visitor.value;
|
|
|
|
|
}
|
2014-01-23 23:56:37 -08:00
|
|
|
|
|
|
|
|
class EpsilonVisitor : public rules::Visitor {
|
|
|
|
|
public:
|
|
|
|
|
bool value;
|
|
|
|
|
|
|
|
|
|
void default_visit(const Rule *) {
|
|
|
|
|
value = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Blank *) {
|
|
|
|
|
value = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Choice *rule) {
|
|
|
|
|
value = rule_can_be_blank(rule->left) || rule_can_be_blank(rule->right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Seq *rule) {
|
|
|
|
|
value = rule_can_be_blank(rule->left) && rule_can_be_blank(rule->right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void visit(const Repeat *rule) {
|
|
|
|
|
value = rule_can_be_blank(rule->content);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool rule_can_be_blank(const rule_ptr &rule) {
|
|
|
|
|
EpsilonVisitor visitor;
|
|
|
|
|
rule->accept(visitor);
|
|
|
|
|
return visitor.value;
|
|
|
|
|
}
|
2013-12-18 20:58:05 -08:00
|
|
|
}
|
|
|
|
|
}
|