Avoid creating redundant auxiliary repeat rules
This commit is contained in:
parent
9ef52ce2fb
commit
e8db35af6b
3 changed files with 2227 additions and 2263 deletions
|
|
@ -67,6 +67,28 @@ describe("expand_repeats", []() {
|
|||
})));
|
||||
});
|
||||
|
||||
it("does not create redundant auxiliary rules", [&]() {
|
||||
SyntaxGrammar grammar({
|
||||
{ "rule0", choice({
|
||||
seq({ i_token(1), repeat(i_token(3)) }),
|
||||
seq({ i_token(2), repeat(i_token(3)) }) }) },
|
||||
}, {}, set<Symbol>());
|
||||
|
||||
auto match = expand_repeats(grammar);
|
||||
|
||||
AssertThat(match.rules, Equals(rule_list({
|
||||
{ "rule0", choice({
|
||||
seq({ i_token(1), choice({ i_aux_sym(0), blank() }) }),
|
||||
seq({ i_token(2), choice({ i_aux_sym(0), blank() }) }) }) },
|
||||
})));
|
||||
|
||||
AssertThat(match.aux_rules, Equals(rule_list({
|
||||
{ "rule0_repeat0", seq({
|
||||
i_token(3),
|
||||
choice({ i_aux_sym(0), blank() }) }) },
|
||||
})));
|
||||
});
|
||||
|
||||
it("can replace multiple repeats in the same rule", [&]() {
|
||||
SyntaxGrammar grammar({
|
||||
{ "rule0", seq({
|
||||
|
|
|
|||
4448
spec/fixtures/parsers/golang.c
vendored
4448
spec/fixtures/parsers/golang.c
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -28,18 +28,28 @@ using rules::Symbol;
|
|||
|
||||
class ExpandRepeats : public rules::IdentityRuleFn {
|
||||
string rule_name;
|
||||
vector<pair<const rule_ptr, Symbol>> existing_repeats;
|
||||
|
||||
rule_ptr expand_repeat(const Repeat *rule) {
|
||||
for (auto pair : existing_repeats) {
|
||||
if (pair.first->operator==(*rule))
|
||||
return pair.second.copy();
|
||||
}
|
||||
|
||||
rule_ptr apply_to(const Repeat *rule) {
|
||||
rule_ptr inner_rule = apply(rule->content);
|
||||
size_t index = aux_rules.size();
|
||||
string helper_rule_name = rule_name + string("_repeat") + to_string(index);
|
||||
rule_ptr repeat_symbol =
|
||||
make_shared<Symbol>(offset + index, rules::SymbolOptionAuxiliary);
|
||||
Symbol repeat_symbol(offset + index, rules::SymbolOptionAuxiliary);
|
||||
existing_repeats.push_back({ rule->copy(), repeat_symbol });
|
||||
aux_rules.push_back(
|
||||
{ helper_rule_name,
|
||||
Seq::build({ inner_rule, Choice::build({ repeat_symbol,
|
||||
Seq::build({ inner_rule, Choice::build({ repeat_symbol.copy(),
|
||||
make_shared<Blank>() }) }) });
|
||||
return Choice::build({ repeat_symbol, make_shared<Blank>() });
|
||||
return repeat_symbol.copy();
|
||||
}
|
||||
|
||||
rule_ptr apply_to(const Repeat *rule) {
|
||||
return Choice::build({ expand_repeat(rule), make_shared<Blank>() });
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue