From a5816a96243e89d2f14cab1ca2684369a3097941 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 9 Apr 2014 13:14:46 -0700 Subject: [PATCH] Refactor rule visitors --- src/compiler/build_tables/first_set.cc | 23 ++++--- src/compiler/build_tables/get_metadata.cc | 18 +++--- .../build_tables/rule_can_be_blank.cc | 31 +++++----- src/compiler/build_tables/rule_transitions.cc | 44 ++++++------- src/compiler/name_symbols/name_symbols.cc | 8 +-- .../prepare_grammar/expand_repeats.cc | 4 +- .../prepare_grammar/extract_tokens.cc | 18 +++--- src/compiler/rules/visitor.cc | 31 +++------- src/compiler/rules/visitor.h | 62 +++++++++++++------ 9 files changed, 126 insertions(+), 113 deletions(-) diff --git a/src/compiler/build_tables/first_set.cc b/src/compiler/build_tables/first_set.cc index 1593bfaa..3befcb26 100644 --- a/src/compiler/build_tables/first_set.cc +++ b/src/compiler/build_tables/first_set.cc @@ -24,32 +24,35 @@ namespace tree_sitter { public: explicit FirstSet(const PreparedGrammar &grammar) : grammar(grammar) {} - void visit(const Symbol *rule) { + set 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({ *rule }); + return set({ *rule }); } + } else { + return set(); } } - void visit(const rules::Metadata *rule) { - value = apply(rule->rule); + set 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 apply_to(const rules::Choice *rule) { + return set_union(apply(rule->left), apply(rule->right)); } - void visit(const rules::Seq *rule) { + set 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; } }; diff --git a/src/compiler/build_tables/get_metadata.cc b/src/compiler/build_tables/get_metadata.cc index 4c45231d..02cd5fdf 100644 --- a/src/compiler/build_tables/get_metadata.cc +++ b/src/compiler/build_tables/get_metadata.cc @@ -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; } }; diff --git a/src/compiler/build_tables/rule_can_be_blank.cc b/src/compiler/build_tables/rule_can_be_blank.cc index 2b836dc2..b5f02172 100644 --- a/src/compiler/build_tables/rule_can_be_blank.cc +++ b/src/compiler/build_tables/rule_can_be_blank.cc @@ -15,28 +15,24 @@ namespace tree_sitter { namespace build_tables { class CanBeBlank : public rules::RuleFn { 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; } } }; diff --git a/src/compiler/build_tables/rule_transitions.cc b/src/compiler/build_tables/rule_transitions.cc index f2670bde..71cf287b 100644 --- a/src/compiler/build_tables/rule_transitions.cc +++ b/src/compiler/build_tables/rule_transitions.cc @@ -22,7 +22,8 @@ namespace tree_sitter { namespace build_tables { template - map merge_transitions(const map &left, const map &right); + map + merge_transitions(const map &left, const map &right); template<> map @@ -51,28 +52,29 @@ namespace tree_sitter { template class RuleTransitions : public rules::RuleFn> { - void visit_atom(const rules::Rule *rule) { + map apply_to_atom(const rules::Rule *rule) { auto atom = dynamic_cast(rule); if (atom) - this->value = map({{ *atom, make_shared() }}); + return map({{ *atom, make_shared() }}); + else + return map(); } - void visit(const CharacterSet *rule) { - visit_atom(rule); + map apply_to(const CharacterSet *rule) { + return apply_to_atom(rule); } - void visit(const Symbol *rule) { - visit_atom(rule); + map apply_to(const Symbol *rule) { + return apply_to_atom(rule); } - void visit(const rules::Choice *rule) { + map apply_to(const rules::Choice *rule) { auto left_transitions = this->apply(rule->left); auto right_transitions = this->apply(rule->right); - this->value = merge_transitions(left_transitions, - right_transitions); + return merge_transitions(left_transitions, right_transitions); } - void visit(const rules::Seq *rule) { + map 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(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 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 apply_to(const rules::Metadata *rule) { + return this->apply(rule->rule); } - - void visit(const rules::String *rule) { + + map apply_to(const rules::String *rule) { rule_ptr result = make_shared(); for (char val : rule->value) result = rules::Seq::Build({ result, make_shared(set({ 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 apply_to(const rules::Pattern *rule) { + return this->apply(rule->to_rule_tree()); } }; diff --git a/src/compiler/name_symbols/name_symbols.cc b/src/compiler/name_symbols/name_symbols.cc index 3dbd363e..1ea4a320 100644 --- a/src/compiler/name_symbols/name_symbols.cc +++ b/src/compiler/name_symbols/name_symbols.cc @@ -18,12 +18,12 @@ namespace tree_sitter { class TokenName : public rules::RuleFn { 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) + "'"; } }; diff --git a/src/compiler/prepare_grammar/expand_repeats.cc b/src/compiler/prepare_grammar/expand_repeats.cc index a660656d..998fb49c 100644 --- a/src/compiler/prepare_grammar/expand_repeats.cc +++ b/src/compiler/prepare_grammar/expand_repeats.cc @@ -31,11 +31,11 @@ namespace tree_sitter { make_shared() }); } - 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(helper_rule_name, rules::SymbolTypeAuxiliary); + return make_shared(helper_rule_name, rules::SymbolTypeAuxiliary); } public: diff --git a/src/compiler/prepare_grammar/extract_tokens.cc b/src/compiler/prepare_grammar/extract_tokens.cc index a1899e8f..a85be0fe 100644 --- a/src/compiler/prepare_grammar/extract_tokens.cc +++ b/src/compiler/prepare_grammar/extract_tokens.cc @@ -22,16 +22,12 @@ namespace tree_sitter { namespace prepare_grammar { class IsToken : public rules::RuleFn { - 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(add_token(result), rules::SymbolTypeAuxiliary); + return make_shared(add_token(result), rules::SymbolTypeAuxiliary); } else { - value = result; + return result; } } diff --git a/src/compiler/rules/visitor.cc b/src/compiler/rules/visitor.cc index f3620cac..53dadcb3 100644 --- a/src/compiler/rules/visitor.cc +++ b/src/compiler/rules/visitor.cc @@ -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(apply(rule->content)); + rule_ptr IdentityRuleFn::apply_to(const Repeat *rule) { + return std::make_shared(apply(rule->content)); } - void IdentityRuleFn::visit(const Metadata *rule) { - value = std::make_shared(apply(rule->rule), rule->value); + rule_ptr IdentityRuleFn::apply_to(const Metadata *rule) { + return std::make_shared(apply(rule->rule), rule->value); } } } \ No newline at end of file diff --git a/src/compiler/rules/visitor.h b/src/compiler/rules/visitor.h index 371654fe..768ecdbd 100644 --- a/src/compiler/rules/visitor.h +++ b/src/compiler/rules/visitor.h @@ -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 - 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 { - 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); }; } }