Store choice rules using vectors, not pairs
This commit is contained in:
parent
c9e0d4bdf0
commit
29bbff655c
9 changed files with 9273 additions and 8919 deletions
|
|
@ -1,29 +1,37 @@
|
|||
#include "compiler/rules/choice.h"
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "compiler/rules/visitor.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::string;
|
||||
using std::make_shared;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
using std::dynamic_pointer_cast;
|
||||
|
||||
namespace rules {
|
||||
Choice::Choice(rule_ptr left, rule_ptr right) : left(left), right(right) {}
|
||||
Choice::Choice(const vector<rule_ptr> &elements) : elements(elements) {}
|
||||
|
||||
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;
|
||||
rule_ptr Choice::Build(const vector<rule_ptr> &elements) {
|
||||
return make_shared<Choice>(elements);
|
||||
}
|
||||
|
||||
bool Choice::operator==(const Rule &rule) const {
|
||||
const Choice *other = dynamic_cast<const Choice *>(&rule);
|
||||
return other && (*other->left == *left) && (*other->right == *right);
|
||||
if (!other) return false;
|
||||
size_t size = elements.size();
|
||||
if (size != other->elements.size()) return false;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
if (!elements[i]->operator==(*other->elements[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Choice::hash_code() const {
|
||||
return left->hash_code() ^ right->hash_code();
|
||||
size_t result = std::hash<size_t>()(elements.size());
|
||||
for (const auto &element : elements)
|
||||
result ^= element->hash_code();
|
||||
return result;
|
||||
}
|
||||
|
||||
rule_ptr Choice::copy() const {
|
||||
|
|
@ -31,7 +39,10 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
string Choice::to_string() const {
|
||||
return string("#<choice ") + left->to_string() + " " + right->to_string() + ">";
|
||||
string result = "#<choice";
|
||||
for (const auto &element : elements)
|
||||
result += " " + element->to_string();
|
||||
return result + ">";
|
||||
}
|
||||
|
||||
void Choice::accept(Visitor *visitor) const {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace tree_sitter {
|
|||
namespace rules {
|
||||
class Choice : public Rule {
|
||||
public:
|
||||
Choice(rule_ptr left, rule_ptr right);
|
||||
Choice(const std::vector<rule_ptr> &elements);
|
||||
static rule_ptr Build(const std::vector<rule_ptr> &rules);
|
||||
|
||||
bool operator==(const Rule& other) const;
|
||||
|
|
@ -18,8 +18,7 @@ namespace tree_sitter {
|
|||
std::string to_string() const;
|
||||
void accept(Visitor *visitor) const;
|
||||
|
||||
const rule_ptr left;
|
||||
const rule_ptr right;
|
||||
const std::vector<rule_ptr> elements;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace tree_sitter {
|
|||
using std::hash;
|
||||
using std::make_shared;
|
||||
using std::set;
|
||||
using std::vector;
|
||||
|
||||
class PatternParser {
|
||||
public:
|
||||
|
|
@ -24,12 +25,12 @@ namespace tree_sitter {
|
|||
position(0) {}
|
||||
|
||||
rule_ptr rule() {
|
||||
auto result = term();
|
||||
vector<rule_ptr> choices = { term() };
|
||||
while (has_more_input() && peek() == '|') {
|
||||
next();
|
||||
result = make_shared<Choice>(result, term());
|
||||
choices.push_back(term());
|
||||
}
|
||||
return result;
|
||||
return (choices.size() > 1) ? Choice::Build(choices) : choices.front();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -54,7 +55,7 @@ namespace tree_sitter {
|
|||
break;
|
||||
case '?':
|
||||
next();
|
||||
result = make_shared<Choice>(result, make_shared<Blank>());
|
||||
result = Choice::Build({ result, make_shared<Blank>() });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,18 @@
|
|||
#include "compiler/rules/repeat.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
using std::vector;
|
||||
|
||||
namespace rules {
|
||||
rule_ptr IdentityRuleFn::default_apply(const Rule *rule) {
|
||||
return rule->copy();
|
||||
}
|
||||
|
||||
rule_ptr IdentityRuleFn::apply_to(const Choice *rule) {
|
||||
return Choice::Build({ apply(rule->left), apply(rule->right) });
|
||||
vector<rule_ptr> rules;
|
||||
for (const auto &el : rule->elements)
|
||||
rules.push_back(apply(el));
|
||||
return Choice::Build(rules);
|
||||
}
|
||||
|
||||
rule_ptr IdentityRuleFn::apply_to(const Seq *rule) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue