Refactor classes representing individual characters & character classes

This commit is contained in:
Max Brunsfeld 2013-12-21 23:53:26 -08:00
parent 8dec6c90f4
commit 9667b3fd6c
17 changed files with 167 additions and 120 deletions

View file

@ -0,0 +1,62 @@
#include "char_match.h"
using std::string;
namespace tree_sitter {
CharMatch CharMatchSpecific(char value) {
CharMatch result = { .type = CharMatchTypeSpecific };
result.value.character = value;
return result;
}
CharMatch CharMatchClass(CharClass value) {
CharMatch result = { .type = CharMatchTypeSpecific };
result.value.character = value;
return result;
}
CharMatch CharMatchRange(char min, char max) {
CharMatch result = { .type = CharMatchTypeSpecific };
result.value.range.min_character = min;
result.value.range.max_character = max;
return result;
}
string CharMatchToString(CharMatch match) {
switch (match.type) {
case CharMatchTypeClass:
switch (match.value.character_class) {
case CharClassDigit:
return "<digit>";
case CharClassWord:
return "<word>";
}
case CharMatchTypeSpecific:
return string("'") + string(&match.value.character) + "'";
case CharMatchTypeRange:
return (
string("'") +
string(&match.value.range.min_character) + "-" +
string(&match.value.range.max_character) + "'");
}
}
bool operator==(const CharMatch &left, const CharMatch &right) {
if (left.type != right.type)
return false;
switch (left.type) {
case CharMatchTypeClass:
return (left.value.character_class == right.value.character_class);
case CharMatchTypeSpecific:
return (left.value.character == right.value.character);
case CharMatchTypeRange:
return (
left.value.range.min_character == right.value.range.min_character &&
left.value.range.max_character == right.value.range.max_character);
}
}
std::ostream& operator<<(std::ostream& stream, const CharMatch &match) {
return stream << CharMatchToString(match);
}
}

39
src/compiler/char_match.h Normal file
View file

@ -0,0 +1,39 @@
#ifndef __TreeSitter__char_match__
#define __TreeSitter__char_match__
#include <string>
namespace tree_sitter {
typedef enum {
CharMatchTypeSpecific,
CharMatchTypeClass,
CharMatchTypeRange,
} CharMatchType;
typedef enum {
CharClassWord,
CharClassDigit
} CharClass;
struct CharMatch {
CharMatchType type;
union {
CharClass character_class;
char character;
struct {
char min_character;
char max_character;
} range;
} value;
};
CharMatch CharMatchSpecific(char);
CharMatch CharMatchClass(CharClass);
CharMatch CharMatchRange(char, char);
std::string CharMatchToString(CharMatch);
bool operator==(const CharMatch &, const CharMatch &);
std::ostream& operator<<(std::ostream& stream, const CharMatch &rule);
}
#endif

View file

@ -1,23 +0,0 @@
#include "rules.h"
#include "transition_map.h"
using std::string;
namespace tree_sitter {
namespace rules {
Char::Char(char value) : value(value) {};
bool Char::operator==(const Rule &rule) const {
const Char *other = dynamic_cast<const Char *>(&rule);
return other && (other->value == value);
}
string Char::to_string() const {
return string("'") + value + "'";
}
void Char::accept(Visitor &visitor) const {
visitor.visit(this);
}
}
}

View file

@ -1,28 +0,0 @@
#include "rules.h"
#include "transition_map.h"
using std::string;
namespace tree_sitter {
namespace rules {
CharClass::CharClass(CharClassType value) : value(value) {};
bool CharClass::operator==(const Rule &rule) const {
const CharClass *other = dynamic_cast<const CharClass *>(&rule);
return other && (other->value == value);
}
string CharClass::to_string() const {
switch (value) {
case CharClassTypeDigit:
return "<digit>";
case CharClassTypeWord:
return "<word>";
}
}
void CharClass::accept(Visitor &visitor) const {
visitor.visit(this);
}
}
}

View file

@ -1,25 +0,0 @@
#ifndef __tree_sitter__char_class__
#define __tree_sitter__char_class__
#include "rule.h"
namespace tree_sitter {
namespace rules {
typedef enum {
CharClassTypeWord,
CharClassTypeDigit
} CharClassType;
class CharClass : public Rule {
public:
CharClass(CharClassType type);
bool operator==(const Rule& other) const;
std::string to_string() const;
void accept(Visitor &visitor) const;
const CharClassType value;
};
}
}
#endif

View file

@ -0,0 +1,25 @@
#include "rules.h"
#include "transition_map.h"
using std::string;
namespace tree_sitter {
namespace rules {
Character::Character(char value) : value(CharMatchSpecific(value)) {};
Character::Character(CharClass value) : value(CharMatchClass(value)) {};
Character::Character(char min, char max) : value(CharMatchRange(min, max)) {};
bool Character::operator==(const Rule &rule) const {
const Character *other = dynamic_cast<const Character *>(&rule);
return other && (other->value == value);
}
string Character::to_string() const {
return CharMatchToString(value);
}
void Character::accept(Visitor &visitor) const {
visitor.visit(this);
}
}
}

View file

@ -2,17 +2,20 @@
#define __tree_sitter__char__
#include "rule.h"
#include "char_match.h"
namespace tree_sitter {
namespace rules {
class Char : public Rule {
class Character : public Rule {
public:
Char(char value);
Character(char character);
Character(CharClass character_class);
Character(char min_character, char max_character);
bool operator==(const Rule& other) const;
std::string to_string() const;
void accept(Visitor &visitor) const;
const char value;
const CharMatch value;
};
}
}

View file

@ -71,9 +71,9 @@ namespace tree_sitter {
case ')':
return character(value);
case 'w':
return char_class(CharClassTypeWord);
return character(CharClassWord);
case 'd':
return char_class(CharClassTypeDigit);
return character(CharClassDigit);
default:
error("unrecognized escape sequence");
return rule_ptr();

View file

@ -11,13 +11,13 @@ namespace tree_sitter {
}
rule_ptr character(char value) {
return make_shared<Char>(value);
return make_shared<Character>(value);
}
rule_ptr char_class(CharClassType type) {
return make_shared<CharClass>(type);
rule_ptr character(CharClass value) {
return make_shared<Character>(value);
}
rule_ptr choice(const initializer_list<rule_ptr> &rules) {
rule_ptr result;
for (auto rule : rules)

View file

@ -8,8 +8,7 @@
#include "seq.h"
#include "string.h"
#include "pattern.h"
#include "char.h"
#include "char_class.h"
#include "character.h"
#include "repeat.h"
#include "visitor.h"
@ -17,7 +16,8 @@ namespace tree_sitter {
namespace rules {
rule_ptr blank();
rule_ptr character(char value);
rule_ptr char_class(CharClassType value);
rule_ptr character(char min, char max);
rule_ptr character(CharClass value);
rule_ptr choice(const std::initializer_list<rule_ptr> &rules);
rule_ptr pattern(const std::string &value);
rule_ptr repeat(const rule_ptr content);

View file

@ -11,12 +11,8 @@ namespace tree_sitter {
value = transition_map<Rule, Rule>();
}
void visit(const CharClass *rule) {
value = transition_map<Rule, Rule>({{ char_class(rule->value), blank() }});
}
void visit(const Char *rule) {
value = transition_map<Rule, Rule>({{ character(rule->value), blank() }});
void visit(const Character *rule) {
value = transition_map<Rule, Rule>({{ std::make_shared<Character>(*rule), blank() }});
}
void visit(const Symbol *rule) {

View file

@ -4,8 +4,7 @@ namespace tree_sitter {
namespace rules {
void Visitor::visit(const Blank *rule) {}
void Visitor::visit(const Symbol *rule) {}
void Visitor::visit(const Char *rule) {}
void Visitor::visit(const CharClass *rule) {}
void Visitor::visit(const Character *rule) {}
void Visitor::visit(const Choice *rule) {}
void Visitor::visit(const Repeat *rule) {}
void Visitor::visit(const Seq *rule) {}

View file

@ -9,8 +9,7 @@ namespace tree_sitter {
public:
virtual void visit(const Blank *rule);
virtual void visit(const Symbol *rule);
virtual void visit(const Char *rule);
virtual void visit(const CharClass *rule);
virtual void visit(const Character *rule);
virtual void visit(const Choice *rule);
virtual void visit(const Repeat *rule);
virtual void visit(const Seq *rule);