Refactor avoidance of redundant repeat rules
This commit is contained in:
parent
a0d9da9d5c
commit
160fca6579
7 changed files with 42 additions and 17 deletions
22
spec/compiler/rules/repeat_spec.cc
Normal file
22
spec/compiler/rules/repeat_spec.cc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "compiler/compiler_spec_helper.h"
|
||||
#include "compiler/rules/repeat.h"
|
||||
#include "compiler/rules/symbol.h"
|
||||
|
||||
using namespace rules;
|
||||
|
||||
START_TEST
|
||||
|
||||
describe("Repeat", []() {
|
||||
describe("constructing repeats", [&]() {
|
||||
it("doesn't create redundant repeats", [&]() {
|
||||
auto sym = make_shared<Symbol>(1);
|
||||
auto repeat = Repeat::build(sym);
|
||||
auto outer_repeat = Repeat::build(repeat);
|
||||
|
||||
AssertThat(repeat, !Equals(sym));
|
||||
AssertThat(outer_repeat, Equals(repeat));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
END_TEST
|
||||
|
|
@ -128,18 +128,9 @@ class LexTableBuilder {
|
|||
|
||||
rules::rule_ptr separator_rule() const {
|
||||
vector<rules::rule_ptr> separators;
|
||||
for (const auto &rule : lex_grammar.separators) {
|
||||
|
||||
// TODO - remove this hack. right now, nested repeats cause
|
||||
// item sets which are equivalent to appear unequal.
|
||||
auto repeat = dynamic_pointer_cast<const rules::Repeat>(rule);
|
||||
if (repeat.get())
|
||||
separators.push_back(repeat->content);
|
||||
else
|
||||
separators.push_back(rule);
|
||||
}
|
||||
|
||||
return rules::repeat(rules::choice(separators));
|
||||
for (const auto &rule : lex_grammar.separators)
|
||||
separators.push_back(rules::repeat(rule));
|
||||
return rules::choice(separators);
|
||||
}
|
||||
|
||||
set<int> precedence_values_for_item_set(const LexItemSet &item_set) const {
|
||||
|
|
|
|||
|
|
@ -78,11 +78,11 @@ class PatternParser {
|
|||
switch (peek()) {
|
||||
case '*':
|
||||
next();
|
||||
result = make_shared<Repeat>(result);
|
||||
result = Repeat::build(result);
|
||||
break;
|
||||
case '+':
|
||||
next();
|
||||
result = make_shared<Seq>(result, make_shared<Repeat>(result));
|
||||
result = make_shared<Seq>(result, Repeat::build(result));
|
||||
break;
|
||||
case '?':
|
||||
next();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,25 @@
|
|||
#include "compiler/rules/repeat.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "compiler/rules/visitor.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::make_shared;
|
||||
using std::string;
|
||||
|
||||
Repeat::Repeat(const rule_ptr content) : content(content) {}
|
||||
|
||||
rule_ptr Repeat::build(const rule_ptr &rule) {
|
||||
auto inner_repeat = dynamic_pointer_cast<Repeat>(rule);
|
||||
if (inner_repeat.get())
|
||||
return inner_repeat;
|
||||
else
|
||||
return make_shared<Repeat>(rule);
|
||||
}
|
||||
|
||||
bool Repeat::operator==(const Rule &rule) const {
|
||||
const Repeat *other = dynamic_cast<const Repeat *>(&rule);
|
||||
return other && (*other->content == *content);
|
||||
|
|
@ -16,7 +27,7 @@ bool Repeat::operator==(const Rule &rule) const {
|
|||
|
||||
size_t Repeat::hash_code() const { return content->hash_code(); }
|
||||
|
||||
rule_ptr Repeat::copy() const { return std::make_shared<Repeat>(*this); }
|
||||
rule_ptr Repeat::copy() const { return make_shared<Repeat>(*this); }
|
||||
|
||||
string Repeat::to_string() const {
|
||||
return string("(repeat ") + content->to_string() + ")";
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace rules {
|
|||
class Repeat : public Rule {
|
||||
public:
|
||||
explicit Repeat(rule_ptr content);
|
||||
static rule_ptr build(const rule_ptr &rule);
|
||||
|
||||
bool operator==(const Rule &other) const;
|
||||
size_t hash_code() const;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ rule_ptr blank() { return make_shared<Blank>(); }
|
|||
rule_ptr choice(const vector<rule_ptr> &rules) { return Choice::build(rules); }
|
||||
|
||||
rule_ptr repeat(const rule_ptr &content) {
|
||||
return std::make_shared<Repeat>(content);
|
||||
return Repeat::build(content);
|
||||
}
|
||||
|
||||
rule_ptr seq(const vector<rule_ptr> &rules) { return Seq::build(rules); }
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ rule_ptr IdentityRuleFn::apply_to(const Seq *rule) {
|
|||
}
|
||||
|
||||
rule_ptr IdentityRuleFn::apply_to(const Repeat *rule) {
|
||||
return std::make_shared<Repeat>(apply(rule->content));
|
||||
return Repeat::build(apply(rule->content));
|
||||
}
|
||||
|
||||
rule_ptr IdentityRuleFn::apply_to(const Metadata *rule) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue