Store rule metadata as a map, not a single number
Need to store more than just boolean values
This commit is contained in:
parent
610a8e4a29
commit
1da9f1fdfd
12 changed files with 120 additions and 88 deletions
|
|
@ -15,6 +15,7 @@
|
|||
namespace tree_sitter {
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::map;
|
||||
using std::unordered_map;
|
||||
using std::make_shared;
|
||||
using rules::Symbol;
|
||||
|
|
@ -50,7 +51,7 @@ namespace tree_sitter {
|
|||
|
||||
void add_token_start(const LexItemSet &item_set, LexStateId state_id) {
|
||||
for (auto &item : item_set)
|
||||
if (item.has_metadata(rules::START_TOKEN))
|
||||
if (item.get_metadata(rules::START_TOKEN))
|
||||
lex_table.state(state_id).is_token_start = true;
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ namespace tree_sitter {
|
|||
rules::rule_ptr after_separators(rules::rule_ptr rule) {
|
||||
return rules::Seq::Build({
|
||||
make_shared<rules::Repeat>(CharacterSet({ ' ', '\t', '\n', '\r' }).copy()),
|
||||
make_shared<rules::Metadata>(rule, rules::START_TOKEN)
|
||||
make_shared<rules::Metadata>(rule, map<rules::MetadataKey, int>({ {rules::START_TOKEN, 1} }))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "check_metadata.h"
|
||||
#include "get_metadata.h"
|
||||
#include "compiler/rules/seq.h"
|
||||
#include "compiler/rules/choice.h"
|
||||
#include "compiler/rules/repeat.h"
|
||||
|
|
@ -7,10 +7,11 @@
|
|||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
class HasMetadata : public rules::RuleFn<bool> {
|
||||
rules::MetadataValue metadata_value;
|
||||
class GetMetadata : public rules::RuleFn<int> {
|
||||
rules::MetadataKey metadata_key;
|
||||
public:
|
||||
HasMetadata(rules::MetadataValue value) : metadata_value(value) {}
|
||||
GetMetadata(rules::MetadataKey key) :
|
||||
metadata_key(key) {}
|
||||
|
||||
void visit(const rules::Choice *rule) {
|
||||
value = apply(rule->left) || apply(rule->right);
|
||||
|
|
@ -21,19 +22,21 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
void visit(const rules::Seq *rule) {
|
||||
bool result = apply(rule->left);
|
||||
if (rule_can_be_blank(rule->left))
|
||||
result = result || apply(rule->right);
|
||||
int result = apply(rule->left);
|
||||
if (rule_can_be_blank(rule->left) && result == 0)
|
||||
result = apply(rule->right);
|
||||
value = result;
|
||||
}
|
||||
|
||||
void visit(const rules::Metadata *rule) {
|
||||
value = rule->value & metadata_value;
|
||||
auto pair = rule->value.find(metadata_key);
|
||||
if (pair != rule->value.end())
|
||||
value = pair->second;
|
||||
}
|
||||
};
|
||||
|
||||
bool check_metadata(const rules::rule_ptr &rule, rules::MetadataValue value) {
|
||||
return HasMetadata(value).apply(rule);
|
||||
int get_metadata(const rules::rule_ptr &rule, rules::MetadataKey key) {
|
||||
return GetMetadata(key).apply(rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
bool check_metadata(const rules::rule_ptr &rule, rules::MetadataValue value);
|
||||
int get_metadata(const rules::rule_ptr &rule, rules::MetadataKey key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include "compiler/build_tables/item.h"
|
||||
#include "compiler/build_tables/rule_can_be_blank.h"
|
||||
#include "compiler/build_tables/check_metadata.h"
|
||||
#include "compiler/build_tables/get_metadata.h"
|
||||
#include "tree_sitter/compiler.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
|
|
@ -20,8 +20,8 @@ namespace tree_sitter {
|
|||
return rule_can_be_blank(rule);
|
||||
}
|
||||
|
||||
bool Item::has_metadata(rules::MetadataValue value) const {
|
||||
return check_metadata(rule, value);
|
||||
int Item::get_metadata(rules::MetadataKey key) const {
|
||||
return build_tables::get_metadata(rule, key);
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream &stream, const LexItem &item) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace tree_sitter {
|
|||
public:
|
||||
Item(const rules::Symbol &lhs, rules::rule_ptr rule);
|
||||
bool is_done() const;
|
||||
bool has_metadata(rules::MetadataValue) const;
|
||||
int get_metadata(rules::MetadataKey) const;
|
||||
|
||||
rules::Symbol lhs;
|
||||
rules::rule_ptr rule;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace tree_sitter {
|
|||
Symbol non_terminal = pair.first;
|
||||
set<Symbol> terminals = pair.second;
|
||||
for (auto &terminal : terminals) {
|
||||
ParseItem next_item(non_terminal, grammar.rule(non_terminal), {}, terminal);
|
||||
ParseItem next_item(non_terminal, grammar.rule(non_terminal), 0, terminal);
|
||||
add_item(item_set, next_item, grammar);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@
|
|||
namespace tree_sitter {
|
||||
using std::hash;
|
||||
using std::make_shared;
|
||||
using std::map;
|
||||
|
||||
namespace rules {
|
||||
Metadata::Metadata(rule_ptr rule, MetadataValue value) : rule(rule), value(value) {}
|
||||
Metadata::Metadata(rule_ptr rule, map<MetadataKey, int> values) : rule(rule), value(values) {}
|
||||
|
||||
bool Metadata::operator==(const Rule &rule) const {
|
||||
auto other = dynamic_cast<const Metadata *>(&rule);
|
||||
|
|
@ -16,7 +17,12 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
size_t Metadata::hash_code() const {
|
||||
return hash<int>()(value);
|
||||
size_t result = hash<size_t>()(value.size());
|
||||
for (auto &pair : value) {
|
||||
result ^= hash<int>()(pair.first);
|
||||
result ^= hash<int>()(pair.second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
rule_ptr Metadata::copy() const {
|
||||
|
|
|
|||
|
|
@ -2,18 +2,19 @@
|
|||
#define COMPILER_RULES_METADATA_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "compiler/rules/rule.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
typedef enum {
|
||||
NONE = 0,
|
||||
START_TOKEN = 1,
|
||||
} MetadataValue;
|
||||
START_TOKEN,
|
||||
PRECEDENCE
|
||||
} MetadataKey;
|
||||
|
||||
class Metadata : public Rule {
|
||||
public:
|
||||
Metadata(rule_ptr rule, MetadataValue value);
|
||||
Metadata(rule_ptr rule, std::map<MetadataKey, int> value);
|
||||
|
||||
bool operator==(const Rule& other) const;
|
||||
size_t hash_code() const;
|
||||
|
|
@ -22,7 +23,7 @@ namespace tree_sitter {
|
|||
void accept(Visitor *visitor) const;
|
||||
|
||||
const rule_ptr rule;
|
||||
const MetadataValue value;
|
||||
const std::map<MetadataKey, int> value;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue