From 849f2ee19579b67900d0bb5ccd30683dee631180 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 7 Nov 2013 08:22:56 -0800 Subject: [PATCH] Add character rule class --- spec/rules_spec.cpp | 69 +++++++++++++++++++++++++++++---------------- src/rules.cpp | 28 ++++++++++++++---- src/rules.h | 11 ++++++++ 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/spec/rules_spec.cpp b/spec/rules_spec.cpp index c878c060..dbd5c84a 100644 --- a/spec/rules_spec.cpp +++ b/spec/rules_spec.cpp @@ -5,60 +5,79 @@ using namespace std; using namespace igloo; using namespace tree_sitter; -using namespace tree_sitter::rules; + +EqualsContainerConstraint< + TransitionMap, + bool (*)(const TransitionMap::pair_type &, const TransitionMap::pair_type &) +> +EqualsTransitionMap(const TransitionMap &expected) { + return EqualsContainer(expected, TransitionMap::elements_equal); +} Describe(Rules) { Describe(transitions) { - Symbol symbol1 = Symbol(1); - Symbol symbol2 = Symbol(2); - Symbol symbol3 = Symbol(3); - Symbol symbol4 = Symbol(3); + rules::Symbol symbol1 = rules::Symbol(1); + rules::Symbol symbol2 = rules::Symbol(2); + rules::Symbol symbol3 = rules::Symbol(3); + rules::Symbol symbol4 = rules::Symbol(3); It(handles_symbols) { AssertThat( symbol1.transitions(), - EqualsContainer(TransitionMap( + EqualsTransitionMap(TransitionMap( { symbol1.copy() }, - { new Blank() } - ), TransitionMap::elements_equal)); + { new rules::Blank() } + ))); + } + + It(handles_characters) { + rules::Char char1 = rules::Char('a'); + AssertThat( + char1.transitions(), + EqualsTransitionMap(TransitionMap( + { char1.copy() }, + { new rules::Blank() } + ))); } It(handles_choices) { AssertThat( - Choice(symbol1, symbol2).transitions(), - EqualsContainer(TransitionMap( + rules::Choice(symbol1, symbol2).transitions(), + EqualsTransitionMap(TransitionMap( { symbol1.copy(), symbol2.copy() }, - { new Blank(), new Blank() } - ), TransitionMap::elements_equal)); + { new rules::Blank(), new rules::Blank() } + ))); } It(handles_sequences) { AssertThat( - Seq(symbol1, symbol2).transitions(), - EqualsContainer(TransitionMap( + rules::Seq(symbol1, symbol2).transitions(), + EqualsTransitionMap(TransitionMap( { symbol1.copy() }, { symbol2.copy() } - ), TransitionMap::elements_equal)); + ))); } It(handles_long_sequences) { AssertThat( - Seq(Seq(symbol1, symbol2), Seq(symbol3, symbol4)).transitions(), - EqualsContainer(TransitionMap( + rules::Seq( + rules::Seq(symbol1, symbol2), + rules::Seq(symbol3, symbol4)).transitions(), + EqualsTransitionMap(TransitionMap( { symbol1.copy() }, - { new Seq(symbol2, Seq(symbol3, symbol4)) } - ), TransitionMap::elements_equal)); + { new rules::Seq(symbol2, rules::Seq(symbol3, symbol4)) } + ))); } It(handles_choices_with_common_starting_symbols) { AssertThat( - Choice( - Seq(symbol1, symbol2), - Seq(symbol1, symbol3)).transitions(), - EqualsContainer(TransitionMap( + rules::Choice( + rules::Seq(symbol1, symbol2), + rules::Seq(symbol1, symbol3)).transitions(), + EqualsTransitionMap(TransitionMap( { symbol1.copy() }, - { new Choice(symbol2, symbol3) } - ), TransitionMap::elements_equal)); + { new rules::Choice(symbol2, symbol3) } + ))); } }; }; diff --git a/src/rules.cpp b/src/rules.cpp index 8079678b..f3cd192c 100644 --- a/src/rules.cpp +++ b/src/rules.cpp @@ -6,9 +6,11 @@ using namespace std; namespace tree_sitter { namespace rules { + // Constructors Blank::Blank() {} Symbol::Symbol(int id) : id(id) {}; + Char::Char(char value) : value(value) {}; Seq::Seq(const Rule &left, const Rule &right) : left(left.copy()), right(right.copy()) {}; Seq::Seq(const Rule *left, const Rule *right) : left(left), right(right) {}; Seq::Seq(shared_ptr left, shared_ptr right) : left(left), right(right) {}; @@ -24,6 +26,10 @@ namespace tree_sitter { TransitionMap Symbol::transitions() const { return TransitionMap({ copy() }, { new Blank() }); } + + TransitionMap Char::transitions() const { + return TransitionMap({ copy() }, { new Blank() }); + } TransitionMap Choice::transitions() const { auto result = left->transitions(); @@ -35,11 +41,10 @@ namespace tree_sitter { TransitionMap Seq::transitions() const { return left->transitions().map([&](rule_ptr left_rule) -> rule_ptr { - if (typeid(*left_rule) == typeid(Blank)) { + if (typeid(*left_rule) == typeid(Blank)) return right; - } else { + else return rule_ptr(new Seq(left_rule, right)); - } }); } @@ -53,6 +58,11 @@ namespace tree_sitter { return (other != NULL) && (other->id == id); } + bool Char::operator==(const Rule &rule) const { + const Char *other = dynamic_cast(&rule); + return (other != NULL) && (other->value == value); + } + bool Choice::operator==(const Rule &rule) const { const Choice *other = dynamic_cast(&rule); return (other != NULL) && (*other->left == *left) && (*other->right == *right); @@ -71,7 +81,11 @@ namespace tree_sitter { Symbol * Symbol::copy() const { return new Symbol(id); } - + + Char * Char::copy() const { + return new Char(value); + } + Choice * Choice::copy() const { return new Choice(left, right); } @@ -86,7 +100,11 @@ namespace tree_sitter { } string Symbol::to_string() const { - return string(std::to_string(id)); + return std::to_string(id); + } + + string Char::to_string() const { + return std::to_string(value); } string Choice::to_string() const { diff --git a/src/rules.h b/src/rules.h index f5f2a2e4..26a4bc75 100644 --- a/src/rules.h +++ b/src/rules.h @@ -36,6 +36,17 @@ namespace tree_sitter { private: int id; }; + + class Char : public Rule { + public: + Char(char value); + TransitionMap transitions() const; + Char * copy() const; + bool operator==(const Rule& other) const; + std::string to_string() const; + private: + char value; + }; class Choice : public Rule { public: