Move rule transitions to visitor class
This commit is contained in:
parent
84a7afbca5
commit
b1bbeae2a1
29 changed files with 205 additions and 125 deletions
|
|
@ -53,6 +53,7 @@
|
|||
12FD40DB185FEF0D0041A84E /* arithmetic_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12FD40DA185FEF0D0041A84E /* arithmetic_spec.cpp */; };
|
||||
12FD40DD185FF12C0041A84E /* parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 12FD40DC185FF12C0041A84E /* parser.c */; };
|
||||
12FD40DF1860064C0041A84E /* tree.c in Sources */ = {isa = PBXBuildFile; fileRef = 12FD40DE1860064C0041A84E /* tree.c */; };
|
||||
12FD40E2186245FE0041A84E /* transitions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12FD40E0186245FE0041A84E /* transitions.cpp */; };
|
||||
27A343CA69E17E0F9EBEDF1C /* pattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27A340F3EEB184C040521323 /* pattern.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
|
@ -129,6 +130,9 @@
|
|||
12FD40DA185FEF0D0041A84E /* arithmetic_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = arithmetic_spec.cpp; sourceTree = "<group>"; };
|
||||
12FD40DC185FF12C0041A84E /* parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = parser.c; sourceTree = "<group>"; };
|
||||
12FD40DE1860064C0041A84E /* tree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tree.c; sourceTree = "<group>"; };
|
||||
12FD40E0186245FE0041A84E /* transitions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transitions.cpp; sourceTree = "<group>"; };
|
||||
12FD40E1186245FE0041A84E /* transitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transitions.h; sourceTree = "<group>"; };
|
||||
12FD40E41862B3530041A84E /* rule_visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rule_visitor.h; sourceTree = "<group>"; };
|
||||
27A340F3EEB184C040521323 /* pattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pattern.cpp; sourceTree = "<group>"; };
|
||||
27A3438C4FA59A3882E8493B /* pattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pattern.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
|
@ -175,6 +179,9 @@
|
|||
1213060A182C389100FCF928 /* symbol.h */,
|
||||
12F8BE8C183C79B2006CCF99 /* char_class.cpp */,
|
||||
12F8BE8D183C79B2006CCF99 /* char_class.h */,
|
||||
12FD40E0186245FE0041A84E /* transitions.cpp */,
|
||||
12FD40E1186245FE0041A84E /* transitions.h */,
|
||||
12FD40E41862B3530041A84E /* rule_visitor.h */,
|
||||
);
|
||||
path = rules;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -416,6 +423,7 @@
|
|||
1213061B182C84DF00FCF928 /* item.cpp in Sources */,
|
||||
12FD40D9185FEEDF0041A84E /* pattern_spec.cpp in Sources */,
|
||||
12130617182C3D2900FCF928 /* string.cpp in Sources */,
|
||||
12FD40E2186245FE0041A84E /* transitions.cpp in Sources */,
|
||||
12F8BE8E183C79B2006CCF99 /* char_class.cpp in Sources */,
|
||||
12130611182C3A1100FCF928 /* blank.cpp in Sources */,
|
||||
1213060E182C398300FCF928 /* choice.cpp in Sources */,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "spec_helper.h"
|
||||
#include "rules.h"
|
||||
#include "transitions.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
Describe(Rules) {
|
||||
|
|
@ -28,7 +29,7 @@ Describe(Rules) {
|
|||
|
||||
It(handles_symbols) {
|
||||
AssertThat(
|
||||
symbol1->transitions(),
|
||||
rules::transitions(symbol1),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ symbol1, rules::blank() }
|
||||
})));
|
||||
|
|
@ -36,7 +37,7 @@ Describe(Rules) {
|
|||
|
||||
It(handles_characters) {
|
||||
AssertThat(
|
||||
char1->transitions(),
|
||||
rules::transitions(char1),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ char1, rules::blank() }
|
||||
})));
|
||||
|
|
@ -45,7 +46,7 @@ Describe(Rules) {
|
|||
It(handles_character_classes) {
|
||||
auto rule = rules::char_class(rules::CharClassTypeDigit);
|
||||
AssertThat(
|
||||
rule->transitions(),
|
||||
rules::transitions(rule),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ rule, rules::blank() }
|
||||
})));
|
||||
|
|
@ -53,7 +54,7 @@ Describe(Rules) {
|
|||
|
||||
It(handles_choices) {
|
||||
AssertThat(
|
||||
rules::choice({ symbol1, symbol2 })->transitions(),
|
||||
rules::transitions(rules::choice({ symbol1, symbol2 })),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ symbol1, rules::blank() },
|
||||
{ symbol2, rules::blank() }
|
||||
|
|
@ -62,7 +63,7 @@ Describe(Rules) {
|
|||
|
||||
It(handles_sequences) {
|
||||
AssertThat(
|
||||
rules::seq({ symbol1, symbol2 })->transitions(),
|
||||
rules::transitions(rules::seq({ symbol1, symbol2 })),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ symbol1, symbol2 }
|
||||
})));
|
||||
|
|
@ -70,12 +71,12 @@ Describe(Rules) {
|
|||
|
||||
It(handles_long_sequences) {
|
||||
AssertThat(
|
||||
rules::seq({
|
||||
rules::transitions(rules::seq({
|
||||
symbol1,
|
||||
symbol2,
|
||||
symbol3,
|
||||
symbol4
|
||||
})->transitions(),
|
||||
})),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ symbol1, rules::seq({ symbol2, symbol3, symbol4 }) }
|
||||
})));
|
||||
|
|
@ -83,9 +84,10 @@ Describe(Rules) {
|
|||
|
||||
It(handles_choices_with_common_starting_symbols) {
|
||||
AssertThat(
|
||||
rules::choice({
|
||||
rules::seq({ symbol1, symbol2 }),
|
||||
rules::seq({ symbol1, symbol3 }) })->transitions(),
|
||||
rules::transitions(
|
||||
rules::choice({
|
||||
rules::seq({ symbol1, symbol2 }),
|
||||
rules::seq({ symbol1, symbol3 }) })),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ symbol1, rules::choice({ symbol2, symbol3 }) }
|
||||
})));
|
||||
|
|
@ -93,7 +95,7 @@ Describe(Rules) {
|
|||
|
||||
It(handles_strings) {
|
||||
AssertThat(
|
||||
rules::str("bad")->transitions(),
|
||||
rules::transitions(rules::str("bad")),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{
|
||||
rules::character('b'),
|
||||
|
|
@ -104,7 +106,7 @@ Describe(Rules) {
|
|||
|
||||
It(handles_patterns) {
|
||||
AssertThat(
|
||||
rules::pattern("a|b")->transitions(),
|
||||
rules::transitions(rules::pattern("a|b")),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{ rules::character('a'), rules::blank() },
|
||||
{ rules::character('b'), rules::blank() }
|
||||
|
|
@ -114,7 +116,7 @@ Describe(Rules) {
|
|||
It(handles_repeats) {
|
||||
rules::rule_ptr repeat = rules::repeat(rules::str("ab"));
|
||||
AssertThat(
|
||||
repeat->transitions(),
|
||||
rules::transitions(repeat),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{
|
||||
rules::character('a'),
|
||||
|
|
@ -129,7 +131,7 @@ Describe(Rules) {
|
|||
|
||||
repeat = rules::repeat(rules::str("a"));
|
||||
AssertThat(
|
||||
repeat->transitions(),
|
||||
rules::transitions(repeat),
|
||||
EqualsTransitionMap(TransitionMap<rules::Rule>({
|
||||
{
|
||||
rules::character('a'),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "item.h"
|
||||
#include "grammar.h"
|
||||
#include "transitions.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -17,14 +18,14 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
TransitionMap<Item> Item::transitions() const {
|
||||
return rule->transitions().map<Item>([&](rules::rule_ptr to_rule) {
|
||||
return rules::transitions(rule).map<Item>([&](rules::rule_ptr to_rule) {
|
||||
return std::make_shared<Item>(rule_name, to_rule, consumed_sym_count + 1);
|
||||
});
|
||||
};
|
||||
|
||||
vector<rules::sym_ptr> Item::next_symbols() const {
|
||||
vector<rules::sym_ptr> result;
|
||||
for (auto pair : rule->transitions()) {
|
||||
for (auto pair : rules::transitions(rule)) {
|
||||
shared_ptr<const rules::Symbol> sym = dynamic_pointer_cast<const rules::Symbol>(pair.first);
|
||||
if (sym) result.push_back(sym);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <string>
|
||||
#include "rule.h"
|
||||
#include "symbol.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
#include "blank.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
Blank::Blank() {}
|
||||
|
||||
blank_ptr blank() {
|
||||
rule_ptr blank() {
|
||||
return std::make_shared<Blank>();
|
||||
}
|
||||
|
||||
TransitionMap<Rule> Blank::transitions() const {
|
||||
return TransitionMap<Rule>();
|
||||
}
|
||||
|
||||
bool Blank::operator==(const Rule &rule) const {
|
||||
return dynamic_cast<const Blank *>(&rule) != nullptr;
|
||||
}
|
||||
|
|
@ -20,5 +16,9 @@ namespace tree_sitter {
|
|||
std::string Blank::to_string() const {
|
||||
return "blank";
|
||||
}
|
||||
|
||||
void Blank::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,13 +8,12 @@ namespace tree_sitter {
|
|||
class Blank : public Rule {
|
||||
public:
|
||||
Blank();
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<const Blank> blank_ptr;
|
||||
blank_ptr blank();
|
||||
rule_ptr blank();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "char.h"
|
||||
#include "blank.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -12,10 +11,6 @@ namespace tree_sitter {
|
|||
return std::make_shared<Char>(value);
|
||||
}
|
||||
|
||||
TransitionMap<Rule> Char::transitions() const {
|
||||
return TransitionMap<Rule>({{ character(value), blank() }});
|
||||
}
|
||||
|
||||
bool Char::operator==(const Rule &rule) const {
|
||||
const Char *other = dynamic_cast<const Char *>(&rule);
|
||||
return other && (other->value == value);
|
||||
|
|
@ -24,5 +19,9 @@ namespace tree_sitter {
|
|||
string Char::to_string() const {
|
||||
return std::string("'") + value + "'";
|
||||
}
|
||||
|
||||
void Char::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ namespace tree_sitter {
|
|||
class Char : public Rule {
|
||||
public:
|
||||
Char(char value);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
private:
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
|
||||
const char value;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "char_class.h"
|
||||
#include "blank.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -12,10 +11,6 @@ namespace tree_sitter {
|
|||
return std::make_shared<CharClass>(type);
|
||||
}
|
||||
|
||||
TransitionMap<Rule> CharClass::transitions() const {
|
||||
return TransitionMap<Rule>({{ char_class(value), blank() }});
|
||||
}
|
||||
|
||||
bool CharClass::operator==(const Rule &rule) const {
|
||||
const CharClass *other = dynamic_cast<const CharClass *>(&rule);
|
||||
return other && (other->value == value);
|
||||
|
|
@ -29,5 +24,9 @@ namespace tree_sitter {
|
|||
return "<word>";
|
||||
}
|
||||
}
|
||||
|
||||
void CharClass::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ namespace tree_sitter {
|
|||
class CharClass : public Rule {
|
||||
public:
|
||||
CharClass(CharClassType type);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
private:
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
|
||||
const CharClassType value;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "choice.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
|
|
@ -12,14 +12,6 @@ namespace tree_sitter {
|
|||
return result;
|
||||
}
|
||||
|
||||
TransitionMap<Rule> Choice::transitions() const {
|
||||
auto result = left->transitions();
|
||||
result.merge(right->transitions(), [&](rule_ptr left, rule_ptr right) -> rule_ptr {
|
||||
return choice({ left, right });
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Choice::operator==(const Rule &rule) const {
|
||||
const Choice *other = dynamic_cast<const Choice *>(&rule);
|
||||
return other && (*other->left == *left) && (*other->right == *right);
|
||||
|
|
@ -28,5 +20,9 @@ namespace tree_sitter {
|
|||
std::string Choice::to_string() const {
|
||||
return std::string("(choice ") + left->to_string() + " " + right->to_string() + ")";
|
||||
}
|
||||
|
||||
void Choice::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,10 +8,10 @@ namespace tree_sitter {
|
|||
class Choice : public Rule {
|
||||
public:
|
||||
Choice(rule_ptr left, rule_ptr right);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
private:
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
|
||||
const rule_ptr left;
|
||||
const rule_ptr right;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#include "choice.h"
|
||||
#include "seq.h"
|
||||
#include "Pattern.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -108,16 +106,8 @@ namespace tree_sitter {
|
|||
pattern_ptr pattern(const std::string &value) {
|
||||
return std::make_shared<Pattern>(value);
|
||||
}
|
||||
|
||||
TransitionMap<Rule> Pattern::transitions() const {
|
||||
return to_rule_tree()->transitions();
|
||||
}
|
||||
|
||||
rule_ptr Pattern::to_rule_tree() const {
|
||||
return PatternParser(value).rule();
|
||||
}
|
||||
|
||||
bool Pattern::operator ==(tree_sitter::rules::Rule const &other) const {
|
||||
bool Pattern::operator==(tree_sitter::rules::Rule const &other) const {
|
||||
auto pattern = dynamic_cast<const Pattern *>(&other);
|
||||
return pattern && (pattern->value == value);
|
||||
}
|
||||
|
|
@ -125,5 +115,13 @@ namespace tree_sitter {
|
|||
std::string Pattern::to_string() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
void Pattern::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
rule_ptr Pattern::to_rule_tree() const {
|
||||
return PatternParser(value).rule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,13 @@
|
|||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
class Pattern : public Rule {
|
||||
const std::string value;
|
||||
public:
|
||||
Pattern(const std::string &string);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
rule_ptr to_rule_tree() const;
|
||||
private:
|
||||
const std::string value;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<const Pattern> pattern_ptr;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
#include "blank.h"
|
||||
#include "seq.h"
|
||||
#include "choice.h"
|
||||
#include "repeat.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
|
|
@ -12,12 +9,6 @@ namespace tree_sitter {
|
|||
return std::make_shared<Repeat>(content);
|
||||
}
|
||||
|
||||
TransitionMap<Rule> Repeat::transitions() const {
|
||||
return content->transitions().map<Rule>([&](const rule_ptr &value) -> rule_ptr {
|
||||
return seq({ value, choice({ repeat(content), blank() }) });
|
||||
});
|
||||
}
|
||||
|
||||
bool Repeat::operator==(const Rule &rule) const {
|
||||
const Repeat *other = dynamic_cast<const Repeat *>(&rule);
|
||||
return other && (*other->content == *content);
|
||||
|
|
@ -26,5 +17,9 @@ namespace tree_sitter {
|
|||
std::string Repeat::to_string() const {
|
||||
return std::string("(repeat ") + content->to_string() + ")";
|
||||
}
|
||||
|
||||
void Repeat::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ namespace tree_sitter {
|
|||
class Repeat : public Rule {
|
||||
public:
|
||||
Repeat(rule_ptr content);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
private:
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
|
||||
const rule_ptr content;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@
|
|||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
size_t Rule::hash_code() const {
|
||||
return std::hash<std::string>()(to_string());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const Rule &rule)
|
||||
{
|
||||
stream << rule.to_string();
|
||||
|
|
|
|||
|
|
@ -4,21 +4,17 @@
|
|||
#include <string>
|
||||
|
||||
namespace tree_sitter {
|
||||
template<class value> class TransitionMap;
|
||||
|
||||
namespace rules {
|
||||
class Rule;
|
||||
typedef std::shared_ptr<const Rule> rule_ptr;
|
||||
class RuleVisitor;
|
||||
|
||||
class Rule {
|
||||
public:
|
||||
virtual TransitionMap<Rule> transitions() const = 0;
|
||||
virtual bool operator==(const Rule& other) const = 0;
|
||||
virtual std::string to_string() const = 0;
|
||||
virtual size_t hash_code() const;
|
||||
virtual void accept(RuleVisitor &visitor) const = 0;
|
||||
};
|
||||
|
||||
|
||||
typedef std::shared_ptr<const Rule> rule_ptr;
|
||||
std::ostream& operator<<(std::ostream& stream, const Rule &rule);
|
||||
std::ostream& operator<<(std::ostream& stream, const rule_ptr &rule);
|
||||
}
|
||||
|
|
@ -28,7 +24,7 @@ namespace std {
|
|||
template<>
|
||||
struct hash<tree_sitter::rules::Rule> {
|
||||
size_t operator()(const tree_sitter::rules::Rule &rule) {
|
||||
return rule.hash_code();
|
||||
return std::hash<std::string>()(rule.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
23
src/compiler/rules/rule_visitor.h
Normal file
23
src/compiler/rules/rule_visitor.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef __tree_sitter__rule_visitor__
|
||||
#define __tree_sitter__rule_visitor__
|
||||
|
||||
#include "rules.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
class RuleVisitor {
|
||||
public:
|
||||
virtual void visit(const Blank *rule) = 0;
|
||||
virtual void visit(const Symbol *rule) = 0;
|
||||
virtual void visit(const Char *rule) = 0;
|
||||
virtual void visit(const CharClass *rule) = 0;
|
||||
virtual void visit(const Choice *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 Pattern *rule) = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -11,5 +11,6 @@
|
|||
#include "char.h"
|
||||
#include "char_class.h"
|
||||
#include "repeat.h"
|
||||
#include "rule_visitor.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "seq.h"
|
||||
#include "blank.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
|
|
@ -15,15 +14,6 @@ namespace tree_sitter {
|
|||
return result;
|
||||
}
|
||||
|
||||
TransitionMap<Rule> Seq::transitions() const {
|
||||
return left->transitions().map<Rule>([&](rule_ptr left_rule) -> rule_ptr {
|
||||
if (typeid(*left_rule) == typeid(Blank))
|
||||
return right;
|
||||
else
|
||||
return seq({ left_rule, right });
|
||||
});
|
||||
}
|
||||
|
||||
bool Seq::operator==(const Rule &rule) const {
|
||||
const Seq *other = dynamic_cast<const Seq *>(&rule);
|
||||
return other && (*other->left == *left) && (*other->right == *right);
|
||||
|
|
@ -32,5 +22,9 @@ namespace tree_sitter {
|
|||
std::string Seq::to_string() const {
|
||||
return std::string("(seq ") + left->to_string() + " " + right->to_string() + ")";
|
||||
}
|
||||
|
||||
void Seq::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ namespace tree_sitter {
|
|||
class Seq : public Rule {
|
||||
public:
|
||||
Seq(rule_ptr left, rule_ptr right);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
private:
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
|
||||
const rule_ptr left;
|
||||
const rule_ptr right;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "string.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
#include "char.h"
|
||||
#include "seq.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
|
@ -11,13 +9,6 @@ namespace tree_sitter {
|
|||
return std::make_shared<String>(value);
|
||||
}
|
||||
|
||||
TransitionMap<Rule> String::transitions() const {
|
||||
rule_ptr result = character(value[0]);
|
||||
for (int i = 1; i < value.length(); i++)
|
||||
result = seq({ result, character(value[i]) });
|
||||
return result->transitions();
|
||||
}
|
||||
|
||||
bool String::operator==(const Rule &rule) const {
|
||||
const String *other = dynamic_cast<const String *>(&rule);
|
||||
return (other != NULL) && (other->value == value);
|
||||
|
|
@ -26,6 +17,9 @@ namespace tree_sitter {
|
|||
std::string String::to_string() const {
|
||||
return std::string("(string '") + value + "')";
|
||||
}
|
||||
|
||||
|
||||
void String::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,10 +8,10 @@ namespace tree_sitter {
|
|||
class String : public Rule {
|
||||
public:
|
||||
String(std::string value);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
private:
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
|
||||
const std::string value;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "symbol.h"
|
||||
#include "blank.h"
|
||||
#include "rules.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
|
|
@ -10,10 +9,6 @@ namespace tree_sitter {
|
|||
return std::make_shared<Symbol>(name);
|
||||
}
|
||||
|
||||
TransitionMap<Rule> Symbol::transitions() const {
|
||||
return TransitionMap<Rule>({{ sym(name) , blank() }});
|
||||
}
|
||||
|
||||
bool Symbol::operator==(const Rule &rule) const {
|
||||
const Symbol *other = dynamic_cast<const Symbol *>(&rule);
|
||||
return other && (other->name == name);
|
||||
|
|
@ -22,5 +17,9 @@ namespace tree_sitter {
|
|||
std::string Symbol::to_string() const {
|
||||
return std::string("(sym '") + name + "')";
|
||||
}
|
||||
|
||||
void Symbol::accept(RuleVisitor &visitor) const {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,10 @@ namespace tree_sitter {
|
|||
class Symbol : public Rule {
|
||||
public:
|
||||
Symbol(const std::string &name);
|
||||
TransitionMap<Rule> transitions() const;
|
||||
bool operator==(const Rule& other) const;
|
||||
std::string to_string() const;
|
||||
void accept(RuleVisitor &visitor) const;
|
||||
|
||||
const std::string name;
|
||||
};
|
||||
|
||||
|
|
|
|||
66
src/compiler/rules/transitions.cpp
Normal file
66
src/compiler/rules/transitions.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include "transitions.h"
|
||||
#include "rules.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
class TransitionsVisitor : public RuleVisitor {
|
||||
public:
|
||||
TransitionMap<Rule> value;
|
||||
|
||||
void visit(const Blank *rule) {
|
||||
value = TransitionMap<Rule>();
|
||||
}
|
||||
|
||||
void visit(const CharClass *rule) {
|
||||
value = TransitionMap<Rule>({{ char_class(rule->value), blank() }});
|
||||
}
|
||||
|
||||
void visit(const Char *rule) {
|
||||
value = TransitionMap<Rule>({{ character(rule->value), blank() }});
|
||||
}
|
||||
|
||||
void visit(const Symbol *rule) {
|
||||
value = TransitionMap<Rule>({{ sym(rule->name), blank() }});
|
||||
}
|
||||
|
||||
void visit(const Choice *rule) {
|
||||
value = transitions(rule->left);
|
||||
value.merge(transitions(rule->right), [&](rule_ptr left, rule_ptr right) -> rule_ptr {
|
||||
return choice({ left, right });
|
||||
});
|
||||
}
|
||||
|
||||
void visit(const Seq *rule) {
|
||||
value = transitions(rule->left).map<Rule>([&](rule_ptr left_rule) -> rule_ptr {
|
||||
if (typeid(*left_rule) == typeid(Blank))
|
||||
return rule->right;
|
||||
else
|
||||
return seq({ left_rule, rule->right });
|
||||
});
|
||||
}
|
||||
|
||||
void visit(const Repeat *rule) {
|
||||
value = transitions(rule->content).map<Rule>([&](const rule_ptr &value) -> rule_ptr {
|
||||
return seq({ value, choice({ repeat(rule->content), blank() }) });
|
||||
});
|
||||
}
|
||||
|
||||
void visit(const String *rule) {
|
||||
rule_ptr result = character(rule->value[0]);
|
||||
for (int i = 1; i < rule->value.length(); i++)
|
||||
result = seq({ result, character(rule->value[i]) });
|
||||
value = transitions(result);
|
||||
}
|
||||
|
||||
void visit(const Pattern *rule) {
|
||||
value = transitions(rule->to_rule_tree());
|
||||
}
|
||||
};
|
||||
|
||||
TransitionMap<Rule> transitions(const rule_ptr &rule) {
|
||||
TransitionsVisitor visitor;
|
||||
rule->accept(visitor);
|
||||
return visitor.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
src/compiler/rules/transitions.h
Normal file
13
src/compiler/rules/transitions.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef __tree_sitter__transitions__
|
||||
#define __tree_sitter__transitions__
|
||||
|
||||
#include "rule.h"
|
||||
#include "transition_map.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
TransitionMap<Rule> transitions(const rule_ptr &rule);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
#include <vector>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include "rules.h"
|
||||
#include "rule.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
template<typename MappedType>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue