Extract public compiler API into its own header file

This commit is contained in:
Max Brunsfeld 2014-02-16 22:13:08 -08:00
parent 0b4e1c8d0d
commit 9e2dc14182
53 changed files with 466 additions and 409 deletions

View file

@ -1,4 +1,5 @@
#include "rules.h"
#include "blank.h"
#include "visitor.h"
namespace tree_sitter {
namespace rules {

View file

@ -0,0 +1,44 @@
#include "compiler.h"
namespace tree_sitter {
using std::string;
namespace rules {
static const char MAX_CHAR = '\xff';
CharacterRange::CharacterRange(char value) : min(value), max(value) {}
CharacterRange::CharacterRange(char min, char max) : min(min), max(max) {}
bool CharacterRange::operator==(const CharacterRange &other) const {
return min == other.min && max == other.max;
}
bool CharacterRange::operator<(const CharacterRange &other) const {
if (min < other.min) return true;
if (min > other.min) return false;
if (max < other.max) return true;
return false;
}
string escape_character(char input) {
switch (input) {
case '\0':
return "<EOF>";
case MAX_CHAR:
return "<MAX>";
default:
return string() + input;
}
}
string CharacterRange::to_string() const {
if (min == 0 && max == MAX_CHAR)
return "<ANY>";
if (min == max)
return escape_character(min);
else
return string() + escape_character(min) + "-" + escape_character(max);
}
}
}

View file

@ -1,42 +1,16 @@
#include "rules.h"
#include "character_set.h"
#include "visitor.h"
using std::string;
using std::hash;
using std::set;
using std::pair;
using std::initializer_list;
namespace tree_sitter {
namespace rules {
const char MAX_CHAR = '\xff';
CharacterRange::CharacterRange(char value) : min(value), max(value) {}
CharacterRange::CharacterRange(char min, char max) :
min(min),
max(max)
{}
bool CharacterRange::operator==(const CharacterRange &other) const {
return min == other.min && max == other.max;
}
static const char MAX_CHAR = '\xff';
bool CharacterRange::operator<(const CharacterRange &other) const {
if (min < other.min) return true;
if (min > other.min) return false;
if (max < other.max) return true;
return false;
}
string escape_character(char input) {
switch (input) {
case '\0':
return "<EOF>";
case MAX_CHAR:
return "<MAX>";
default:
return string() + input;
}
}
int max_int(const CharacterRange &range) {
return range.max == MAX_CHAR ? 255 : (int)range.max;
}
@ -45,19 +19,9 @@ namespace tree_sitter {
return (int)range.min;
}
string CharacterRange::to_string() const {
if (min == 0 && max == MAX_CHAR)
return "<ANY>";
if (min == max)
return escape_character(min);
else
return string() + escape_character(min) + "-" + escape_character(max);
}
CharacterSet::CharacterSet() : ranges({}) {}
CharacterSet::CharacterSet(const set<CharacterRange> &ranges) : ranges(ranges) {}
CharacterSet::CharacterSet(const set<CharacterRange> &ranges, bool sign) :
ranges(sign ? ranges : CharacterSet(ranges).complement().ranges) {}
CharacterSet::CharacterSet(const initializer_list<CharacterRange> &ranges) : ranges(ranges) {}
bool CharacterSet::operator==(const Rule &rule) const {
const CharacterSet *other = dynamic_cast<const CharacterSet *>(&rule);
@ -89,7 +53,7 @@ namespace tree_sitter {
}
CharacterSet CharacterSet::complement() const {
CharacterSet result({ {0, MAX_CHAR} }, true);
CharacterSet result({ {0, MAX_CHAR} });
result.remove_set(*this);
return result;
}

View file

@ -1,31 +1,10 @@
#ifndef __tree_sitter__character_set__
#define __tree_sitter__character_set__
#include "compiler.h"
#include "rule.h"
#include <set>
namespace tree_sitter {
namespace rules {
struct CharacterRange {
char min;
char max;
CharacterRange(char);
CharacterRange(char, char);
bool operator==(const CharacterRange &) const;
bool operator<(const CharacterRange &) const;
std::string to_string() const;
};
}
}
namespace std {
template<>
struct hash<tree_sitter::rules::CharacterRange> {
size_t operator()(const tree_sitter::rules::CharacterRange &range) const {
return (hash<char>()(range.min) ^ hash<char>()(range.max));
}
};
}
#include <initializer_list>
namespace tree_sitter {
namespace rules {
@ -33,15 +12,7 @@ namespace tree_sitter {
public:
CharacterSet();
CharacterSet(const std::set<CharacterRange> &ranges);
CharacterSet(const std::set<CharacterRange> &ranges, bool);
CharacterSet complement() const;
CharacterSet intersect(const CharacterSet &) const;
std::pair<CharacterSet, bool> most_compact_representation() const;
bool is_empty() const;
void add_set(const CharacterSet &other);
CharacterSet remove_set(const CharacterSet &other);
CharacterSet(const std::initializer_list<CharacterRange> &ranges);
bool operator==(const Rule& other) const;
bool operator<(const CharacterSet &) const;
@ -50,6 +21,13 @@ namespace tree_sitter {
std::string to_string() const;
void accept(Visitor &visitor) const;
void add_set(const CharacterSet &other);
CharacterSet remove_set(const CharacterSet &other);
CharacterSet complement() const;
CharacterSet intersect(const CharacterSet &) const;
std::pair<CharacterSet, bool> most_compact_representation() const;
bool is_empty() const;
std::set<CharacterRange> ranges;
};
}

View file

@ -1,11 +1,21 @@
#include "rules.h"
using std::string;
#include "choice.h"
#include "visitor.h"
namespace tree_sitter {
using std::string;
using std::make_shared;
using std::vector;
namespace rules {
Choice::Choice(rule_ptr left, rule_ptr right) : left(left), right(right) {};
rule_ptr Choice::Build(const vector<rule_ptr> &rules) {
rule_ptr result;
for (auto rule : rules)
result = result.get() ? make_shared<Choice>(result, rule) : rule;
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);

View file

@ -2,12 +2,14 @@
#define __tree_sitter__choice__
#include "rule.h"
#include <vector>
namespace tree_sitter {
namespace rules {
class Choice : public Rule {
public:
Choice(rule_ptr left, rule_ptr right);
static rule_ptr Build(const std::vector<rule_ptr> &rules);
bool operator==(const Rule& other) const;
size_t hash_code() const;

View file

@ -1,11 +1,18 @@
#include "rules.h"
using std::string;
using std::hash;
using std::set;
#include "pattern.h"
#include "visitor.h"
#include "choice.h"
#include "seq.h"
#include "repeat.h"
#include "character_set.h"
#include <set>
namespace tree_sitter {
namespace rules {
using std::string;
using std::hash;
using std::make_shared;
using std::set;
class PatternParser {
public:
PatternParser(const string &input) :
@ -17,7 +24,7 @@ namespace tree_sitter {
auto result = term();
while (has_more_input() && peek() == '|') {
next();
result = choice({ result, term() });
result = make_shared<Choice>(result, term());
}
return result;
}
@ -26,7 +33,7 @@ namespace tree_sitter {
rule_ptr term() {
rule_ptr result = factor();
while (has_more_input() && (peek() != '|') && (peek() != ')'))
result = seq({ result, factor() });
result = Seq::Build({ result, factor() });
return result;
}
@ -34,7 +41,7 @@ namespace tree_sitter {
rule_ptr result = atom();
if (has_more_input() && (peek() == '+')) {
next();
result = repeat(result);
result = make_shared<Repeat>(result);
}
return result;
}
@ -92,7 +99,7 @@ namespace tree_sitter {
next();
if (peek() == '-') {
next();
value = CharacterSet({ {first_char, peek()} }, true);
value = CharacterSet({ CharacterRange(first_char, peek()) });
next();
} else {
value = CharacterSet({ first_char });
@ -108,9 +115,9 @@ namespace tree_sitter {
case ')':
return CharacterSet({ value });
case 'w':
return CharacterSet({{'a', 'z'}, {'A', 'Z'}}, true);
return CharacterSet({{'a', 'z'}, {'A', 'Z'}});
case 'd':
return CharacterSet({{'0', '9'}}, true);
return CharacterSet({CharacterRange('0', '9')});
default:
error("unrecognized escape sequence");
return CharacterSet();

View file

@ -1,4 +1,5 @@
#include "rules.h"
#include "repeat.h"
#include "visitor.h"
using std::string;

View file

@ -1,34 +1,38 @@
#include "rules.h"
using std::make_shared;
using std::string;
using std::set;
using std::vector;
#include "compiler.h"
#include "rule.h"
#include "blank.h"
#include "symbol.h"
#include "choice.h"
#include "seq.h"
#include "string.h"
#include "pattern.h"
#include "character_set.h"
#include "repeat.h"
namespace tree_sitter {
using std::make_shared;
using std::string;
using std::set;
using std::vector;
namespace rules {
rule_ptr blank() {
return make_shared<Blank>();
}
rule_ptr character(char value) {
set<CharacterRange> ranges = { value };
return make_shared<CharacterSet>(ranges);
}
rule_ptr character(const set<CharacterRange> &ranges) {
return make_shared<CharacterSet>(ranges);
}
rule_ptr character(const set<CharacterRange> &ranges, bool sign) {
return make_shared<CharacterSet>(ranges, sign);
if (sign)
return character(ranges);
else
return CharacterSet(ranges).complement().copy();
}
rule_ptr choice(const vector<rule_ptr> &rules) {
rule_ptr result;
for (auto rule : rules)
result = result.get() ? make_shared<Choice>(result, rule) : rule;
return result;
return Choice::Build(rules);
}
rule_ptr pattern(const string &value) {
@ -40,12 +44,7 @@ namespace tree_sitter {
}
rule_ptr seq(const vector<rule_ptr> &rules) {
rule_ptr result = blank();
for (auto rule : rules)
result = (typeid(*result) != typeid(Blank)) ?
make_shared<Seq>(result, rule) :
rule;
return result;
return Seq::Build(rules);
}
rule_ptr str(const string &value) {

View file

@ -1,33 +0,0 @@
#ifndef __TreeSitter__rules__
#define __TreeSitter__rules__
#include "rule.h"
#include "blank.h"
#include "symbol.h"
#include "choice.h"
#include "seq.h"
#include "string.h"
#include "pattern.h"
#include "character_set.h"
#include "repeat.h"
#include "visitor.h"
#include <vector>
namespace tree_sitter {
namespace rules {
rule_ptr blank();
rule_ptr character(char value);
rule_ptr character(const std::set<CharacterRange> &matches);
rule_ptr character(const std::set<CharacterRange> &matches, bool);
rule_ptr choice(const std::vector<rule_ptr> &rules);
rule_ptr pattern(const std::string &value);
rule_ptr repeat(const rule_ptr content);
rule_ptr seq(const std::vector<rule_ptr> &rules);
rule_ptr str(const std::string &value);
rule_ptr sym(const std::string &name);
rule_ptr aux_sym(const std::string &name);
}
}
#endif

View file

@ -1,11 +1,22 @@
#include "rules.h"
using std::string;
#include "seq.h"
#include "visitor.h"
#include "blank.h"
namespace tree_sitter {
using std::make_shared;
using std::string;
using std::vector;
namespace rules {
Seq::Seq(rule_ptr left, rule_ptr right) : left(left), right(right) {};
rule_ptr Seq::Build(const std::vector<rule_ptr> &rules) {
rule_ptr result = make_shared<Blank>();
for (auto &rule : rules)
result = (typeid(*result) != typeid(Blank)) ? make_shared<Seq>(result, rule) : rule;
return result;
}
bool Seq::operator==(const Rule &rule) const {
const Seq *other = dynamic_cast<const Seq *>(&rule);
return other && (*other->left == *left) && (*other->right == *right);

View file

@ -2,12 +2,14 @@
#define __tree_sitter__seq__
#include "rule.h"
#include <vector>
namespace tree_sitter {
namespace rules {
class Seq : public Rule {
public:
Seq(rule_ptr left, rule_ptr right);
static rule_ptr Build(const std::vector<rule_ptr> &rules);
bool operator==(const Rule& other) const;
size_t hash_code() const;

View file

@ -1,4 +1,5 @@
#include "rules.h"
#include "string.h"
#include "visitor.h"
using std::string;
using std::hash;

View file

@ -1,4 +1,5 @@
#include "rules.h"
#include "symbol.h"
#include "visitor.h"
using std::string;
using std::hash;

View file

@ -1,4 +1,13 @@
#include "visitor.h"
#include "rule.h"
#include "blank.h"
#include "symbol.h"
#include "choice.h"
#include "seq.h"
#include "string.h"
#include "pattern.h"
#include "character_set.h"
#include "repeat.h"
namespace tree_sitter {
namespace rules {

View file

@ -1,10 +1,18 @@
#ifndef __tree_sitter__rule_visitor__
#define __tree_sitter__rule_visitor__
#include "rules.h"
namespace tree_sitter {
namespace rules {
class Rule;
class Blank;
class Symbol;
class CharacterSet;
class Choice;
class Repeat;
class Seq;
class String;
class Pattern;
class Visitor {
public:
virtual void default_visit(const Rule *rule);