Represent rule metadata as a struct, not a map
This commit is contained in:
parent
cac4f5d5bc
commit
6cf4ccb840
17 changed files with 158 additions and 108 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include "compiler/rules/metadata.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <climits>
|
||||
#include "compiler/rules/visitor.h"
|
||||
#include "compiler/rules/blank.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
|
@ -13,47 +14,80 @@ using std::map;
|
|||
using std::pair;
|
||||
using util::hash_combine;
|
||||
|
||||
Metadata::Metadata(rule_ptr rule, map<MetadataKey, int> values)
|
||||
: rule(rule), value(values) {}
|
||||
MetadataParams::MetadataParams() :
|
||||
precedence{0},
|
||||
associativity{AssociativityNone},
|
||||
has_precedence{false},
|
||||
has_associativity{false},
|
||||
is_token{false},
|
||||
is_string{false},
|
||||
is_active{false},
|
||||
is_main_token{false} {}
|
||||
|
||||
rule_ptr Metadata::build(rule_ptr rule, map<MetadataKey, int> values) {
|
||||
return std::make_shared<Metadata>(rule, values);
|
||||
bool MetadataParams::operator==(const MetadataParams &other) const {
|
||||
return
|
||||
precedence == other.precedence &&
|
||||
associativity == other.associativity &&
|
||||
has_precedence == other.has_precedence &&
|
||||
has_associativity == other.has_associativity &&
|
||||
is_token == other.is_token &&
|
||||
is_string == other.is_string &&
|
||||
is_active == other.is_active &&
|
||||
is_main_token == other.is_main_token;
|
||||
}
|
||||
|
||||
Metadata::Metadata(rule_ptr rule, MetadataParams params)
|
||||
: rule(rule), params(params) {}
|
||||
|
||||
rule_ptr Metadata::build(rule_ptr rule, MetadataParams params) {
|
||||
return std::make_shared<Metadata>(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr Metadata::main_token(rule_ptr rule) {
|
||||
MetadataParams params;
|
||||
params.has_precedence = true;
|
||||
params.precedence = 0;
|
||||
params.is_main_token = true;
|
||||
return Metadata::build(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr Metadata::separator(rule_ptr rule) {
|
||||
MetadataParams params;
|
||||
params.has_precedence = true;
|
||||
params.precedence = INT_MIN;
|
||||
params.is_active = true;
|
||||
return Metadata::build(rule, params);
|
||||
}
|
||||
|
||||
bool Metadata::operator==(const Rule &rule) const {
|
||||
auto other = rule.as<Metadata>();
|
||||
return other && other->value == value && other->rule->operator==(*this->rule);
|
||||
return other && other->params == params && other->rule->operator==(*this->rule);
|
||||
}
|
||||
|
||||
size_t Metadata::hash_code() const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, value.size());
|
||||
for (auto &pair : value) {
|
||||
hash_combine<int>(&result, pair.first);
|
||||
hash_combine(&result, pair.second);
|
||||
}
|
||||
hash_combine(&result, params.precedence);
|
||||
hash_combine<int>(&result, params.associativity);
|
||||
hash_combine(&result, params.has_precedence);
|
||||
hash_combine(&result, params.has_associativity);
|
||||
hash_combine(&result, params.is_token);
|
||||
hash_combine(&result, params.is_string);
|
||||
hash_combine(&result, params.is_active);
|
||||
hash_combine(&result, params.is_main_token);
|
||||
return result;
|
||||
}
|
||||
|
||||
rule_ptr Metadata::copy() const {
|
||||
return make_shared<Metadata>(rule->copy(), value);
|
||||
}
|
||||
|
||||
pair<int, bool> Metadata::value_for(MetadataKey key) const {
|
||||
auto entry = value.find(key);
|
||||
if (entry == value.end())
|
||||
return { 0, false };
|
||||
else
|
||||
return { entry->second, true };
|
||||
return make_shared<Metadata>(rule->copy(), params);
|
||||
}
|
||||
|
||||
std::string Metadata::to_string() const {
|
||||
auto precedence = value_for(rules::PRECEDENCE);
|
||||
if (precedence.second && value_for(rules::IS_ACTIVE).second)
|
||||
return "(metadata prec:" + std::to_string(precedence.first) + " " +
|
||||
if (params.has_precedence) {
|
||||
return "(metadata prec:" + std::to_string(params.precedence) + " " +
|
||||
rule->to_string() + ")";
|
||||
else
|
||||
} else {
|
||||
return "(metadata " + rule->to_string() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
void Metadata::accept(Visitor *visitor) const {
|
||||
|
|
|
|||
|
|
@ -14,29 +14,35 @@ enum Associativity {
|
|||
AssociativityRight,
|
||||
};
|
||||
|
||||
enum MetadataKey {
|
||||
MAIN_TOKEN,
|
||||
PRECEDENCE,
|
||||
ASSOCIATIVITY,
|
||||
IS_TOKEN,
|
||||
IS_STRING,
|
||||
IS_ACTIVE,
|
||||
struct MetadataParams {
|
||||
int precedence;
|
||||
Associativity associativity;
|
||||
bool has_precedence;
|
||||
bool has_associativity;
|
||||
bool is_token;
|
||||
bool is_string;
|
||||
bool is_active;
|
||||
bool is_main_token;
|
||||
|
||||
MetadataParams();
|
||||
bool operator==(const MetadataParams &) const;
|
||||
};
|
||||
|
||||
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);
|
||||
Metadata(rule_ptr rule, MetadataParams);
|
||||
static rule_ptr build(rule_ptr rule, MetadataParams);
|
||||
static rule_ptr main_token(rule_ptr rule);
|
||||
static rule_ptr separator(rule_ptr rule);
|
||||
|
||||
bool operator==(const Rule &other) const;
|
||||
size_t hash_code() const;
|
||||
rule_ptr copy() const;
|
||||
std::string to_string() const;
|
||||
void accept(Visitor *visitor) const;
|
||||
std::pair<int, bool> value_for(MetadataKey key) const;
|
||||
|
||||
const rule_ptr rule;
|
||||
const std::map<MetadataKey, int> value;
|
||||
MetadataParams params;
|
||||
};
|
||||
|
||||
} // namespace rules
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ using std::string;
|
|||
using std::set;
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using rules::MetadataParams;
|
||||
|
||||
static rule_ptr metadata(rule_ptr rule, map<rules::MetadataKey, int> values) {
|
||||
return std::make_shared<rules::Metadata>(rule, values);
|
||||
static rule_ptr metadata(rule_ptr rule, MetadataParams params) {
|
||||
return std::make_shared<rules::Metadata>(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr blank() {
|
||||
|
|
@ -60,29 +61,48 @@ rule_ptr str(const string &value) {
|
|||
}
|
||||
|
||||
rule_ptr prec_left(const rule_ptr &rule) {
|
||||
return metadata(rule, { { rules::ASSOCIATIVITY, rules::AssociativityLeft } });
|
||||
MetadataParams params;
|
||||
params.has_associativity = true;
|
||||
params.associativity = rules::AssociativityLeft;
|
||||
return metadata(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr prec_left(int precedence, const rule_ptr &rule) {
|
||||
return metadata(rule, { { rules::PRECEDENCE, precedence },
|
||||
{ rules::ASSOCIATIVITY, rules::AssociativityLeft } });
|
||||
MetadataParams params;
|
||||
params.has_associativity = true;
|
||||
params.associativity = rules::AssociativityLeft;
|
||||
params.has_precedence = true;
|
||||
params.precedence = precedence;
|
||||
return metadata(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr prec_right(const rule_ptr &rule) {
|
||||
return metadata(rule, { { rules::ASSOCIATIVITY, rules::AssociativityRight } });
|
||||
MetadataParams params;
|
||||
params.has_associativity = true;
|
||||
params.associativity = rules::AssociativityRight;
|
||||
return metadata(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr prec_right(int precedence, const rule_ptr &rule) {
|
||||
return metadata(rule, { { rules::PRECEDENCE, precedence },
|
||||
{ rules::ASSOCIATIVITY, rules::AssociativityRight } });
|
||||
MetadataParams params;
|
||||
params.has_associativity = true;
|
||||
params.associativity = rules::AssociativityRight;
|
||||
params.has_precedence = true;
|
||||
params.precedence = precedence;
|
||||
return metadata(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr prec(int precedence, const rule_ptr &rule) {
|
||||
return metadata(rule, { { rules::PRECEDENCE, precedence } });
|
||||
MetadataParams params;
|
||||
params.has_precedence = true;
|
||||
params.precedence = precedence;
|
||||
return metadata(rule, params);
|
||||
}
|
||||
|
||||
rule_ptr token(const rule_ptr &rule) {
|
||||
return metadata(rule, { { rules::IS_TOKEN, 1 } });
|
||||
MetadataParams params;
|
||||
params.is_token = true;
|
||||
return metadata(rule, params);
|
||||
}
|
||||
|
||||
} // namespace tree_sitter
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ rule_ptr IdentityRuleFn::apply_to(const Repeat *rule) {
|
|||
}
|
||||
|
||||
rule_ptr IdentityRuleFn::apply_to(const Metadata *rule) {
|
||||
return std::make_shared<Metadata>(apply(rule->rule), rule->value);
|
||||
return Metadata::build(apply(rule->rule), rule->params);
|
||||
}
|
||||
|
||||
} // namespace rules
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue