Add helper for dynamic-casting to rule subclasses
This commit is contained in:
parent
db9966b57c
commit
5c67f58a4b
14 changed files with 47 additions and 28 deletions
|
|
@ -18,7 +18,6 @@
|
|||
namespace tree_sitter {
|
||||
namespace prepare_grammar {
|
||||
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::make_shared;
|
||||
using std::make_tuple;
|
||||
using std::map;
|
||||
|
|
@ -122,8 +121,8 @@ tuple<InitialSyntaxGrammar, LexicalGrammar, const GrammarError *> extract_tokens
|
|||
*/
|
||||
size_t i = 0;
|
||||
for (const Variable &variable : processed_variables) {
|
||||
auto symbol = dynamic_pointer_cast<const Symbol>(variable.rule);
|
||||
if (symbol.get() && symbol->is_token && !symbol->is_built_in() &&
|
||||
auto symbol = variable.rule->as<Symbol>();
|
||||
if (symbol && symbol->is_token && !symbol->is_built_in() &&
|
||||
extractor.token_usage_counts[symbol->index] == 1) {
|
||||
lexical_grammar.variables[symbol->index].type = variable.type;
|
||||
lexical_grammar.variables[symbol->index].name = variable.name;
|
||||
|
|
@ -160,8 +159,8 @@ tuple<InitialSyntaxGrammar, LexicalGrammar, const GrammarError *> extract_tokens
|
|||
continue;
|
||||
}
|
||||
|
||||
auto symbol = dynamic_pointer_cast<const Symbol>(rule);
|
||||
if (!symbol.get())
|
||||
auto symbol = rule->as<Symbol>();
|
||||
if (!symbol)
|
||||
return make_tuple(syntax_grammar, lexical_grammar,
|
||||
ubiq_token_err(rule->to_string()));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "compiler/rule.h"
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
namespace tree_sitter {
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ class Rule {
|
|||
virtual std::string to_string() const = 0;
|
||||
virtual void accept(rules::Visitor *visitor) const = 0;
|
||||
virtual ~Rule();
|
||||
|
||||
template<typename T>
|
||||
const T * as() const {
|
||||
return dynamic_cast<const T *>(this);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tree_sitter
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ rule_ptr Blank::build() {
|
|||
}
|
||||
|
||||
bool Blank::operator==(const Rule &rule) const {
|
||||
return dynamic_cast<const Blank *>(&rule) != nullptr;
|
||||
return rule.as<Blank>() != nullptr;
|
||||
}
|
||||
|
||||
size_t Blank::hash_code() const {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ CharacterSet::CharacterSet()
|
|||
: includes_all(false), included_chars({}), excluded_chars({}) {}
|
||||
|
||||
bool CharacterSet::operator==(const Rule &rule) const {
|
||||
const CharacterSet *other = dynamic_cast<const CharacterSet *>(&rule);
|
||||
const CharacterSet *other = rule.as<CharacterSet>();
|
||||
return other && (includes_all == other->includes_all) &&
|
||||
(included_chars == other->included_chars) &&
|
||||
(excluded_chars == other->excluded_chars);
|
||||
|
|
|
|||
|
|
@ -10,18 +10,17 @@ using std::string;
|
|||
using std::make_shared;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
using std::dynamic_pointer_cast;
|
||||
|
||||
Choice::Choice(const vector<rule_ptr> &elements) : elements(elements) {}
|
||||
|
||||
void add_choice_element(vector<rule_ptr> *vec, const rule_ptr new_rule) {
|
||||
auto choice = dynamic_pointer_cast<const Choice>(new_rule);
|
||||
if (choice.get()) {
|
||||
auto choice = new_rule->as<Choice>();
|
||||
if (choice) {
|
||||
for (auto &child : choice->elements)
|
||||
add_choice_element(vec, child);
|
||||
} else {
|
||||
for (auto &el : *vec)
|
||||
if (el->operator==(*new_rule))
|
||||
for (auto &element : *vec)
|
||||
if (element->operator==(*new_rule))
|
||||
return;
|
||||
vec->push_back(new_rule);
|
||||
}
|
||||
|
|
@ -38,7 +37,7 @@ rule_ptr Choice::build(const vector<rule_ptr> &inputs) {
|
|||
}
|
||||
|
||||
bool Choice::operator==(const Rule &rule) const {
|
||||
const Choice *other = dynamic_cast<const Choice *>(&rule);
|
||||
const Choice *other = rule.as<Choice>();
|
||||
if (!other)
|
||||
return false;
|
||||
size_t size = elements.size();
|
||||
|
|
|
|||
|
|
@ -13,8 +13,12 @@ using std::map;
|
|||
Metadata::Metadata(rule_ptr rule, map<MetadataKey, int> values)
|
||||
: rule(rule), value(values) {}
|
||||
|
||||
rule_ptr Metadata::build(rule_ptr rule, map<MetadataKey, int> values) {
|
||||
return std::make_shared<Metadata>(rule, values);
|
||||
}
|
||||
|
||||
bool Metadata::operator==(const Rule &rule) const {
|
||||
auto other = dynamic_cast<const Metadata *>(&rule);
|
||||
auto other = rule.as<Metadata>();
|
||||
return other && other->value == value && other->rule->operator==(*this->rule);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ enum MetadataKey {
|
|||
class Metadata : public Rule {
|
||||
public:
|
||||
Metadata(rule_ptr rule, std::map<MetadataKey, int> value);
|
||||
static rule_ptr build(rule_ptr rule, std::map<MetadataKey, int> value);
|
||||
|
||||
bool operator==(const Rule &other) const;
|
||||
size_t hash_code() const;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ using std::hash;
|
|||
NamedSymbol::NamedSymbol(const std::string &name) : name(name) {}
|
||||
|
||||
bool NamedSymbol::operator==(const Rule &rule) const {
|
||||
auto other = dynamic_cast<const NamedSymbol *>(&rule);
|
||||
auto other = rule.as<NamedSymbol>();
|
||||
return other && other->name == name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ using std::hash;
|
|||
Pattern::Pattern(const string &string) : value(string) {}
|
||||
|
||||
bool Pattern::operator==(tree_sitter::Rule const &other) const {
|
||||
auto pattern = dynamic_cast<const Pattern *>(&other);
|
||||
auto pattern = other.as<Pattern>();
|
||||
return pattern && (pattern->value == value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,22 +6,21 @@
|
|||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::make_shared;
|
||||
using std::string;
|
||||
|
||||
Repeat::Repeat(const rule_ptr content) : content(content) {}
|
||||
|
||||
rule_ptr Repeat::build(const rule_ptr &rule) {
|
||||
auto inner_repeat = dynamic_pointer_cast<Repeat>(rule);
|
||||
if (inner_repeat.get())
|
||||
return inner_repeat;
|
||||
auto inner_repeat = rule->as<Repeat>();
|
||||
if (inner_repeat)
|
||||
return rule;
|
||||
else
|
||||
return make_shared<Repeat>(rule);
|
||||
}
|
||||
|
||||
bool Repeat::operator==(const Rule &rule) const {
|
||||
const Repeat *other = dynamic_cast<const Repeat *>(&rule);
|
||||
auto other = rule.as<Repeat>();
|
||||
return other && (*other->content == *content);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include "compiler/rules/visitor.h"
|
||||
#include "compiler/rules/blank.h"
|
||||
#include "compiler/rules/metadata.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
|
@ -14,14 +15,25 @@ Seq::Seq(rule_ptr left, rule_ptr right) : left(left), right(right) {}
|
|||
|
||||
rule_ptr Seq::build(const std::vector<rule_ptr> &rules) {
|
||||
rule_ptr result = make_shared<Blank>();
|
||||
for (auto &rule : rules)
|
||||
result = (typeid(*result) != typeid(Blank)) ? make_shared<Seq>(result, rule)
|
||||
: rule;
|
||||
for (auto &rule : rules) {
|
||||
auto blank = rule->as<Blank>();
|
||||
if (blank)
|
||||
continue;
|
||||
|
||||
auto metadata = rule->as<Metadata>();
|
||||
if (metadata && metadata->rule->as<Blank>())
|
||||
continue;
|
||||
|
||||
if (result->as<Blank>())
|
||||
result = rule;
|
||||
else
|
||||
result = make_shared<Seq>(result, rule);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Seq::operator==(const Rule &rule) const {
|
||||
const Seq *other = dynamic_cast<const Seq *>(&rule);
|
||||
const Seq *other = rule.as<Seq>();
|
||||
return other && (*other->left == *left) && (*other->right == *right);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ using std::hash;
|
|||
String::String(string value) : value(value) {}
|
||||
|
||||
bool String::operator==(const Rule &rule) const {
|
||||
const String *other = dynamic_cast<const String *>(&rule);
|
||||
auto other = rule.as<String>();
|
||||
return other && (other->value == value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ bool Symbol::operator==(const Symbol &other) const {
|
|||
}
|
||||
|
||||
bool Symbol::operator==(const Rule &rule) const {
|
||||
const Symbol *other = dynamic_cast<const Symbol *>(&rule);
|
||||
auto other = rule.as<Symbol>();
|
||||
return other && this->operator==(*other);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue