🔥 get_metadata function

This commit is contained in:
Max Brunsfeld 2015-10-30 16:22:25 -07:00
parent 73b3280fbb
commit c8be143f65
9 changed files with 26 additions and 214 deletions

View file

@ -8,7 +8,6 @@
#include "compiler/parse_table.h"
#include "compiler/build_tables/parse_conflict_manager.h"
#include "compiler/build_tables/parse_item.h"
#include "compiler/build_tables/get_metadata.h"
#include "compiler/build_tables/item_set_closure.h"
#include "compiler/lexical_grammar.h"
#include "compiler/syntax_grammar.h"

View file

@ -1,67 +0,0 @@
#include "compiler/build_tables/get_metadata.h"
#include <utility>
#include "compiler/rules/visitor.h"
#include "compiler/rules/seq.h"
#include "compiler/rules/repeat.h"
#include "compiler/rules/choice.h"
#include "compiler/build_tables/rule_can_be_blank.h"
namespace tree_sitter {
namespace build_tables {
using std::pair;
MetadataRange get_metadata(const rule_ptr &rule, rules::MetadataKey key) {
class GetMetadata : public rules::RuleFn<pair<MetadataRange, bool>> {
rules::MetadataKey metadata_key;
public:
explicit GetMetadata(rules::MetadataKey key) : metadata_key(key) {}
protected:
pair<MetadataRange, bool> apply_to(const rules::Metadata *rule) {
pair<MetadataRange, bool> result = apply(rule->rule);
if (result.second) {
return result;
} else {
int value = rule->value_for(metadata_key);
return { { value, value }, value != 0 };
}
}
pair<MetadataRange, bool> apply_to(const rules::Choice *rule) {
pair<MetadataRange, bool> result(MetadataRange(0, 0), false);
for (const auto &element : rule->elements)
merge_result(&result, apply(element));
return result;
}
pair<MetadataRange, bool> apply_to(const rules::Seq *rule) {
pair<MetadataRange, bool> result = apply(rule->left);
if (rule_can_be_blank(rule->left))
merge_result(&result, apply(rule->right));
return result;
}
pair<MetadataRange, bool> apply_to(const rules::Repeat *rule) {
return apply(rule->content);
}
private:
void merge_result(pair<MetadataRange, bool> *left,
const pair<MetadataRange, bool> &right) {
if (right.second) {
if (!left->second || right.first.min < left->first.min)
left->first.min = right.first.min;
if (!left->second || right.first.max > left->first.max)
left->first.max = right.first.max;
left->second = true;
}
}
};
return GetMetadata(key).apply(rule).first;
}
} // namespace build_tables
} // namespace tree_sitter

View file

@ -1,27 +0,0 @@
#ifndef COMPILER_BUILD_TABLES_GET_METADATA_H_
#define COMPILER_BUILD_TABLES_GET_METADATA_H_
#include "compiler/rules/metadata.h"
#include "tree_sitter/compiler.h"
namespace tree_sitter {
namespace build_tables {
struct MetadataRange {
MetadataRange() : min(0), max(0) {}
MetadataRange(int min, int max) : min(min), max(max) {}
bool operator==(const MetadataRange &other) const {
return min == other.min && max == other.max;
}
int min;
int max;
};
MetadataRange get_metadata(const rule_ptr &, rules::MetadataKey);
} // namespace build_tables
} // namespace tree_sitter
#endif // COMPILER_BUILD_TABLES_GET_METADATA_H_

View file

@ -1,8 +1,12 @@
#include "compiler/build_tables/lex_item.h"
#include <unordered_set>
#include "compiler/build_tables/get_metadata.h"
#include "compiler/build_tables/lex_item_transitions.h"
#include "compiler/build_tables/rule_can_be_blank.h"
#include "compiler/rules/choice.h"
#include "compiler/rules/metadata.h"
#include "compiler/rules/seq.h"
#include "compiler/rules/symbol.h"
#include "compiler/rules/visitor.h"
namespace tree_sitter {
namespace build_tables {
@ -22,7 +26,25 @@ bool LexItem::operator==(const LexItem &other) const {
}
bool LexItem::is_token_start() const {
return get_metadata(rule, rules::START_TOKEN).max > 0;
class IsTokenStart : public rules::RuleFn<bool> {
bool apply_to(const rules::Seq *rule) {
return apply(rule->left) ||
(rule_can_be_blank(rule->left) && apply(rule->right));
}
bool apply_to(const rules::Metadata *rule) {
return (rule->value_for(rules::START_TOKEN) > 0) || apply(rule->rule);
}
bool apply_to(const rules::Choice *rule) {
for (const rule_ptr &element : rule->elements)
if (apply(element))
return true;
return false;
}
};
return IsTokenStart().apply(rule);
}
size_t LexItem::Hash::operator()(const LexItem &item) const {

View file

@ -77,7 +77,8 @@ class LexItemTransitions : public rules::RuleFn<void> {
merge_transition(transitions, *rule,
LexItemSet({
LexItem(item_lhs, rules::Blank::build()),
}), PrecedenceRange());
}),
PrecedenceRange());
}
void apply_to(const rules::Choice *rule) {