This commit is contained in:
Max Brunsfeld 2013-12-28 10:40:45 -08:00
parent 29a9b4643d
commit ccd806a0da
4 changed files with 11 additions and 3 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 = CharMatchTypeClass };
result.value.character = value;
return result;
}
CharMatch CharMatchRange(char min, char max) {
CharMatch result = { .type = CharMatchTypeRange };
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);
}
}

View file

@ -0,0 +1,52 @@
#ifndef __TreeSitter__char_match__
#define __TreeSitter__char_match__
#include <unordered_map>
#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);
}
namespace std {
template<>
struct hash<tree_sitter::CharMatch> {
size_t operator()(const tree_sitter::CharMatch &match) const {
return (
hash<int>()(match.type) ^
hash<char>()(match.value.range.min_character) ^
hash<char>()(match.value.range.max_character));
}
};
}
#endif

View file

@ -0,0 +1,103 @@
#ifndef __TreeSitter__TransitionSet__
#define __TreeSitter__TransitionSet__
#include <vector>
#include <functional>
#include <initializer_list>
#include "rule.h"
namespace tree_sitter {
template<typename TKey, typename TValue>
class transition_map {
typedef std::shared_ptr<const TKey> TKeyPtr;
typedef std::shared_ptr<const TValue> TValuePtr;
typedef std::pair<const TKeyPtr, TValuePtr> pair_type;
typedef std::vector<pair_type> contents_type;
public:
transition_map() : contents(contents_type()) {};
transition_map(std::initializer_list<pair_type> pairs) : contents(pairs) {};
bool operator==(const transition_map<TKey, TValue> &other) const {
if (size() != other.size()) return false;
for (int i = 0; i < size(); i++) {
auto left = contents[i];
auto right = other.contents[i];
if (!(*left.first == *right.first) ||
!(*left.second == *right.second)) return false;
}
return true;
}
void add(TKeyPtr key, TValuePtr value) {
contents.push_back(pair_type(key, value));
}
void merge(const transition_map<TKey, TValue> &other, std::function<TValuePtr(TValuePtr, TValuePtr)> merge_fn) {
for (pair_type other_pair : other) {
if (pair_type *current_pair = pair_for_key(*other_pair.first))
current_pair->second = merge_fn(current_pair->second, other_pair.second);
else
add(other_pair.first, other_pair.second);
}
}
transition_map<TKey, TValue> where(std::function<bool(TKeyPtr)> filter_fn) {
transition_map<TKey, TValue> result;
for (pair_type pair : *this)
if (filter_fn(pair.first))
result.add(pair.first, pair.second);
return result;
}
template<typename NewV>
transition_map<TKey, NewV> map(std::function<const std::shared_ptr<const NewV>(TValuePtr)> map_fn) {
transition_map<TKey, NewV> result;
for (pair_type pair : *this) {
auto new_value = map_fn(pair.second);
result.add(pair.first, new_value);
}
return result;
}
#pragma mark - Container
typedef typename contents_type::const_iterator const_iterator;
typedef typename contents_type::iterator iterator;
iterator begin() { return contents.begin(); }
iterator end() { return contents.end(); }
const_iterator begin() const { return contents.begin(); }
const_iterator end() const { return contents.end(); }
size_t size() const { return contents.size(); }
private:
pair_type * pair_for_key(const TKey &key) {
for (int i = 0; i < contents.size(); i++) {
pair_type *pair = &contents[i];
if (*pair->first == key) return pair;
}
return NULL;
}
contents_type contents;
};
template<typename K, typename V>
std::ostream& operator<<(std::ostream &stream, const transition_map<K, V> &map) {
stream << std::string("[");
bool started = false;
for (auto pair : map) {
if (started) stream << std::string(", ");
stream << pair.first->to_string() << std::string(" => ");
stream << *pair.second;
started = true;
}
stream << std::string("]");
return stream;
}
}
#endif