Refactor rule visitors

This commit is contained in:
Max Brunsfeld 2014-04-09 13:14:46 -07:00
parent bd5ec68c96
commit a5816a9624
9 changed files with 126 additions and 113 deletions

View file

@ -24,32 +24,35 @@ namespace tree_sitter {
public:
explicit FirstSet(const PreparedGrammar &grammar) : grammar(grammar) {}
void visit(const Symbol *rule) {
set<Symbol> apply_to(const Symbol *rule) {
if (visited_symbols.find(*rule) == visited_symbols.end()) {
visited_symbols.insert(*rule);
if (grammar.has_definition(*rule)) {
value = apply(grammar.rule(*rule));
return apply(grammar.rule(*rule));
} else {
value = set<Symbol>({ *rule });
return set<Symbol>({ *rule });
}
} else {
return set<Symbol>();
}
}
void visit(const rules::Metadata *rule) {
value = apply(rule->rule);
set<Symbol> apply_to(const rules::Metadata *rule) {
return apply(rule->rule);
}
void visit(const rules::Choice *rule) {
value = set_union(apply(rule->left), apply(rule->right));
set<Symbol> apply_to(const rules::Choice *rule) {
return set_union(apply(rule->left), apply(rule->right));
}
void visit(const rules::Seq *rule) {
set<Symbol> apply_to(const rules::Seq *rule) {
auto result = apply(rule->left);
if (rule_can_be_blank(rule->left, grammar)) {
result = set_union(result, apply(rule->right));
return set_union(result, apply(rule->right));
} else {
return result;
}
value = result;
}
};

View file

@ -13,25 +13,27 @@ namespace tree_sitter {
GetMetadata(rules::MetadataKey key) :
metadata_key(key) {}
void visit(const rules::Choice *rule) {
value = apply(rule->left) || apply(rule->right);
int apply_to(const rules::Choice *rule) {
return apply(rule->left) || apply(rule->right);
}
void visit(const rules::Repeat *rule) {
value = apply(rule->content);
int apply_to(const rules::Repeat *rule) {
return apply(rule->content);
}
void visit(const rules::Seq *rule) {
int apply_to(const rules::Seq *rule) {
int result = apply(rule->left);
if (rule_can_be_blank(rule->left) && result == 0)
result = apply(rule->right);
value = result;
return result;
}
void visit(const rules::Metadata *rule) {
int apply_to(const rules::Metadata *rule) {
auto pair = rule->value.find(metadata_key);
if (pair != rule->value.end())
value = pair->second;
return pair->second;
else
return 0;
}
};

View file

@ -15,28 +15,24 @@ namespace tree_sitter {
namespace build_tables {
class CanBeBlank : public rules::RuleFn<bool> {
protected:
void default_visit(const rules::Rule *) {
value = false;
bool apply_to(const rules::Blank *) {
return true;
}
void visit(const rules::Blank *) {
value = true;
bool apply_to(const rules::Repeat *rule) {
return true;
}
void visit(const rules::Repeat *rule) {
value = true;
bool apply_to(const rules::Choice *rule) {
return apply(rule->left) || apply(rule->right);
}
void visit(const rules::Choice *rule) {
value = apply(rule->left) || apply(rule->right);
bool apply_to(const rules::Seq *rule) {
return apply(rule->left) && apply(rule->right);
}
void visit(const rules::Seq *rule) {
value = apply(rule->left) && apply(rule->right);
}
void visit(const rules::Metadata *rule) {
value = apply(rule->rule);
bool apply_to(const rules::Metadata *rule) {
return apply(rule->rule);
}
};
@ -46,12 +42,15 @@ namespace tree_sitter {
using CanBeBlank::visit;
public:
using CanBeBlank::apply_to;
explicit CanBeBlankRecursive(const PreparedGrammar &grammar) : grammar(grammar) {}
void visit(const rules::Symbol *rule) {
bool apply_to(const rules::Symbol *rule) {
if (visited_symbols.find(*rule) == visited_symbols.end()) {
visited_symbols.insert(*rule);
value = grammar.has_definition(*rule) && apply(grammar.rule(*rule));
return grammar.has_definition(*rule) && apply(grammar.rule(*rule));
} else {
return false;
}
}
};

View file

@ -22,7 +22,8 @@ namespace tree_sitter {
namespace build_tables {
template<typename T>
map<T, rule_ptr> merge_transitions(const map<T, rule_ptr> &left, const map<T, rule_ptr> &right);
map<T, rule_ptr>
merge_transitions(const map<T, rule_ptr> &left, const map<T, rule_ptr> &right);
template<>
map<CharacterSet, rule_ptr>
@ -51,28 +52,29 @@ namespace tree_sitter {
template<typename T>
class RuleTransitions : public rules::RuleFn<map<T, rule_ptr>> {
void visit_atom(const rules::Rule *rule) {
map<T, rule_ptr> apply_to_atom(const rules::Rule *rule) {
auto atom = dynamic_cast<const T *>(rule);
if (atom)
this->value = map<T, rule_ptr>({{ *atom, make_shared<rules::Blank>() }});
return map<T, rule_ptr>({{ *atom, make_shared<rules::Blank>() }});
else
return map<T, rule_ptr>();
}
void visit(const CharacterSet *rule) {
visit_atom(rule);
map<T, rule_ptr> apply_to(const CharacterSet *rule) {
return apply_to_atom(rule);
}
void visit(const Symbol *rule) {
visit_atom(rule);
map<T, rule_ptr> apply_to(const Symbol *rule) {
return apply_to_atom(rule);
}
void visit(const rules::Choice *rule) {
map<T, rule_ptr> apply_to(const rules::Choice *rule) {
auto left_transitions = this->apply(rule->left);
auto right_transitions = this->apply(rule->right);
this->value = merge_transitions<T>(left_transitions,
right_transitions);
return merge_transitions<T>(left_transitions, right_transitions);
}
void visit(const rules::Seq *rule) {
map<T, rule_ptr> apply_to(const rules::Seq *rule) {
auto result = map_transitions(this->apply(rule->left), [&](const rule_ptr left_rule) {
return rules::Seq::Build({ left_rule, rule->right });
});
@ -80,31 +82,31 @@ namespace tree_sitter {
auto right_transitions = this->apply(rule->right);
result = merge_transitions<T>(result, right_transitions);
}
this->value = result;
return result;
}
void visit(const rules::Repeat *rule) {
this->value = map_transitions(this->apply(rule->content), [&](const rule_ptr &value) {
map<T, rule_ptr> apply_to(const rules::Repeat *rule) {
return map_transitions(this->apply(rule->content), [&](const rule_ptr &value) {
return rules::Seq::Build({ value, rule->copy() });
});
}
void visit(const rules::Metadata *rule) {
this->value = this->apply(rule->rule);
map<T, rule_ptr> apply_to(const rules::Metadata *rule) {
return this->apply(rule->rule);
}
void visit(const rules::String *rule) {
map<T, rule_ptr> apply_to(const rules::String *rule) {
rule_ptr result = make_shared<rules::Blank>();
for (char val : rule->value)
result = rules::Seq::Build({
result,
make_shared<CharacterSet>(set<rules::CharacterRange>({ val }))
});
this->value = this->apply(result);
return this->apply(result);
}
void visit(const rules::Pattern *rule) {
this->value = this->apply(rule->to_rule_tree());
map<T, rule_ptr> apply_to(const rules::Pattern *rule) {
return this->apply(rule->to_rule_tree());
}
};

View file

@ -18,12 +18,12 @@ namespace tree_sitter {
class TokenName : public rules::RuleFn<string> {
protected:
virtual void visit(const rules::Pattern *rule) {
value = "/" + util::escape_string(rule->value) + "/";
string apply_to(const rules::Pattern *rule) {
return "/" + util::escape_string(rule->value) + "/";
}
virtual void visit(const rules::String *rule) {
value = "'" + util::escape_string(rule->value) + "'";
string apply_to(const rules::String *rule) {
return "'" + util::escape_string(rule->value) + "'";
}
};

View file

@ -31,11 +31,11 @@ namespace tree_sitter {
make_shared<Blank>() });
}
void visit(const Repeat *rule) {
rule_ptr apply_to(const Repeat *rule) {
rule_ptr inner_rule = apply(rule->content);
string helper_rule_name = string("repeat_helper") + to_string(aux_rules.size() + 1);
aux_rules.push_back({ helper_rule_name, make_repeat_helper(helper_rule_name, inner_rule) });
value = make_shared<Symbol>(helper_rule_name, rules::SymbolTypeAuxiliary);
return make_shared<Symbol>(helper_rule_name, rules::SymbolTypeAuxiliary);
}
public:

View file

@ -22,16 +22,12 @@ namespace tree_sitter {
namespace prepare_grammar {
class IsToken : public rules::RuleFn<bool> {
void default_visit(const rules::Rule *rule) {
value = false;
bool apply_to(const rules::String *rule) {
return true;
}
void visit(const rules::String *rule) {
value = true;
}
void visit(const rules::Pattern *rule) {
value = true;
bool apply_to(const rules::Pattern *rule) {
return true;
}
};
@ -45,12 +41,12 @@ namespace tree_sitter {
return name;
}
void default_visit(const rules::Rule *rule) {
rule_ptr default_apply(const rules::Rule *rule) {
auto result = rule->copy();
if (IsToken().apply(result)) {
value = make_shared<rules::Symbol>(add_token(result), rules::SymbolTypeAuxiliary);
return make_shared<rules::Symbol>(add_token(result), rules::SymbolTypeAuxiliary);
} else {
value = result;
return result;
}
}

View file

@ -12,35 +12,24 @@
namespace tree_sitter {
namespace rules {
void Visitor::default_visit(const Rule *rule) {}
void Visitor::visit(const Blank *rule) { default_visit(rule); }
void Visitor::visit(const CharacterSet *rule) { default_visit(rule); }
void Visitor::visit(const Choice *rule) { default_visit(rule); }
void Visitor::visit(const Metadata *rule) { default_visit(rule); }
void Visitor::visit(const Pattern *rule) { default_visit(rule); }
void Visitor::visit(const Repeat *rule) { default_visit(rule); }
void Visitor::visit(const Seq *rule) { default_visit(rule); }
void Visitor::visit(const String *rule) { default_visit(rule); }
void Visitor::visit(const Symbol *rule) { default_visit(rule); }
void IdentityRuleFn::default_visit(const Rule *rule) {
value = rule->copy();
rule_ptr IdentityRuleFn::default_apply(const Rule *rule) {
return rule->copy();
}
void IdentityRuleFn::visit(const Choice *rule) {
value = Choice::Build({ apply(rule->left), apply(rule->right) });
rule_ptr IdentityRuleFn::apply_to(const Choice *rule) {
return Choice::Build({ apply(rule->left), apply(rule->right) });
}
void IdentityRuleFn::visit(const Seq *rule) {
value = Seq::Build({ apply(rule->left), apply(rule->right) });
rule_ptr IdentityRuleFn::apply_to(const Seq *rule) {
return Seq::Build({ apply(rule->left), apply(rule->right) });
}
void IdentityRuleFn::visit(const Repeat *rule) {
value = std::make_shared<Repeat>(apply(rule->content));
rule_ptr IdentityRuleFn::apply_to(const Repeat *rule) {
return std::make_shared<Repeat>(apply(rule->content));
}
void IdentityRuleFn::visit(const Metadata *rule) {
value = std::make_shared<Metadata>(apply(rule->rule), rule->value);
rule_ptr IdentityRuleFn::apply_to(const Metadata *rule) {
return std::make_shared<Metadata>(apply(rule->rule), rule->value);
}
}
}

View file

@ -17,36 +17,58 @@ namespace tree_sitter {
class Visitor {
public:
virtual void default_visit(const Rule *rule);
virtual void visit(const Blank *rule);
virtual void visit(const CharacterSet *rule);
virtual void visit(const Choice *rule);
virtual void visit(const Metadata *rule);
virtual void visit(const Pattern *rule);
virtual void visit(const Repeat *rule);
virtual void visit(const Seq *rule);
virtual void visit(const String *rule);
virtual void visit(const Symbol *rule);
virtual void visit(const Blank *rule) = 0;
virtual void visit(const CharacterSet *rule) = 0;
virtual void visit(const Choice *rule) = 0;
virtual void visit(const Metadata *rule) = 0;
virtual void visit(const Pattern *rule) = 0;
virtual void visit(const Repeat *rule) = 0;
virtual void visit(const Seq *rule) = 0;
virtual void visit(const String *rule) = 0;
virtual void visit(const Symbol *rule) = 0;
};
template<typename T>
class RuleFn : public Visitor {
protected:
T value;
class RuleFn : private Visitor {
public:
T apply(const rule_ptr &rule) {
value = T();
value_ = T();
rule->accept(this);
return value;
return value_;
}
protected:
virtual T default_apply(const Rule *rule) { return T(); }
virtual T apply_to(const Blank *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const CharacterSet *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const Choice *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const Metadata *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const Pattern *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const Repeat *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const Seq *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const String *rule) { return default_apply((const Rule *)rule); }
virtual T apply_to(const Symbol *rule) { return default_apply((const Rule *)rule); }
void visit(const Blank *rule) { value_ = apply_to(rule); }
void visit(const CharacterSet *rule) { value_ = apply_to(rule); }
void visit(const Choice *rule) { value_ = apply_to(rule); }
void visit(const Metadata *rule) { value_ = apply_to(rule); }
void visit(const Pattern *rule) { value_ = apply_to(rule); }
void visit(const Repeat *rule) { value_ = apply_to(rule); }
void visit(const Seq *rule) { value_ = apply_to(rule); }
void visit(const String *rule) { value_ = apply_to(rule); }
void visit(const Symbol *rule) { value_ = apply_to(rule); }
private:
T value_;
};
class IdentityRuleFn : public RuleFn<rule_ptr> {
virtual void default_visit(const Rule *rule);
virtual void visit(const Choice *rule);
virtual void visit(const Metadata *rule);
virtual void visit(const Seq *rule);
virtual void visit(const Repeat *rule);
virtual rule_ptr default_apply(const Rule *rule);
virtual rule_ptr apply_to(const Choice *rule);
virtual rule_ptr apply_to(const Metadata *rule);
virtual rule_ptr apply_to(const Seq *rule);
virtual rule_ptr apply_to(const Repeat *rule);
};
}
}