Improve prepare_grammar specs
This commit is contained in:
parent
fd0d77ef8b
commit
c3b65d22bf
5 changed files with 193 additions and 218 deletions
107
spec/compiler/prepare_grammar_spec.cpp
Normal file
107
spec/compiler/prepare_grammar_spec.cpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#include "spec_helper.h"
|
||||
#include "prepare_grammar/perform.h"
|
||||
|
||||
START_TEST
|
||||
|
||||
using namespace rules;
|
||||
using prepare_grammar::perform;
|
||||
|
||||
describe("preparing a grammar", []() {
|
||||
it("moves sub-rules that don't contain symbols into a separate 'lexical' grammar", [&]() {
|
||||
pair<Grammar, Grammar> result = perform(Grammar({
|
||||
{ "rule1", seq({
|
||||
character('a'),
|
||||
character('b'),
|
||||
seq({
|
||||
sym("rule2"),
|
||||
sym("rule3") }),
|
||||
seq({
|
||||
character('a'),
|
||||
character('b') }) }) }
|
||||
}));
|
||||
|
||||
AssertThat(result.first, Equals(Grammar({
|
||||
{ "rule1", seq({
|
||||
aux_sym("token1"),
|
||||
seq({
|
||||
sym("rule2"),
|
||||
sym("rule3") }),
|
||||
aux_sym("token1") }) }
|
||||
})));
|
||||
|
||||
AssertThat(result.second, Equals(Grammar("", {}, {
|
||||
{ "token1", rules::seq({
|
||||
rules::character('a'),
|
||||
rules::character('b') }) },
|
||||
})));
|
||||
});
|
||||
|
||||
it("moves entire rules into the lexical grammar when possible, preserving their names", [&]() {
|
||||
auto result = perform(Grammar({
|
||||
{ "rule1", sym("rule2") },
|
||||
{ "rule2", seq({
|
||||
character('a'),
|
||||
character('b') }) }
|
||||
}));
|
||||
|
||||
AssertThat(result.first, Equals(Grammar({
|
||||
{ "rule1", sym("rule2") }
|
||||
})));
|
||||
|
||||
AssertThat(result.second, Equals(Grammar("", {
|
||||
{ "rule2", seq({
|
||||
character('a'),
|
||||
character('b') }) },
|
||||
})));
|
||||
});
|
||||
|
||||
it("replaces repeat rules with pairs of recursive rules", [&]() {
|
||||
Grammar result = perform(Grammar({
|
||||
{ "rule1", seq({
|
||||
sym("x"),
|
||||
repeat(seq({ sym("a"), sym("b") })),
|
||||
sym("y")
|
||||
}) },
|
||||
})).first;
|
||||
|
||||
AssertThat(result, Equals(Grammar("rule1", {
|
||||
{ "rule1", seq({
|
||||
sym("x"),
|
||||
aux_sym("repeat_helper1"),
|
||||
sym("y")
|
||||
}) },
|
||||
}, {
|
||||
{ "repeat_helper1", seq({
|
||||
seq({ sym("a"), sym("b") }),
|
||||
choice({
|
||||
aux_sym("repeat_helper1") ,
|
||||
blank()
|
||||
}),
|
||||
}) }
|
||||
})));
|
||||
});
|
||||
|
||||
it("does not replace repeat rules that can be moved into the lexical grammar", [&]() {
|
||||
pair<Grammar, Grammar> result = perform(Grammar({
|
||||
{ "rule1", seq({
|
||||
sym("x"),
|
||||
repeat(seq({ str("a"), str("b") })),
|
||||
sym("y")
|
||||
}) },
|
||||
}));
|
||||
|
||||
AssertThat(result.first, Equals(Grammar("rule1", {
|
||||
{ "rule1", seq({
|
||||
sym("x"),
|
||||
aux_sym("token1"),
|
||||
sym("y")
|
||||
}) },
|
||||
})));
|
||||
|
||||
AssertThat(result.second, Equals(Grammar("", {}, {
|
||||
{ "token1", repeat(seq({ str("a"), str("b") })) },
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
||||
END_TEST
|
||||
Loading…
Add table
Add a link
Reference in a new issue