2014-01-03 01:02:24 -08:00
|
|
|
#include "spec_helper.h"
|
2014-02-19 13:36:38 -08:00
|
|
|
#include "prepared_grammar.h"
|
2014-01-28 18:44:14 -08:00
|
|
|
#include "prepare_grammar/perform.h"
|
2014-02-19 13:05:54 -08:00
|
|
|
#include "rules/symbol.h"
|
2014-01-03 01:02:24 -08:00
|
|
|
|
|
|
|
|
START_TEST
|
|
|
|
|
|
2014-01-11 17:08:32 -08:00
|
|
|
using namespace rules;
|
2014-01-28 18:44:14 -08:00
|
|
|
using prepare_grammar::perform;
|
2014-01-03 01:02:24 -08:00
|
|
|
|
|
|
|
|
describe("preparing a grammar", []() {
|
2014-02-13 13:09:00 -08:00
|
|
|
describe("extracting tokens", []() {
|
|
|
|
|
it("moves sub-rules that don't contain symbols into a separate 'lexical' grammar", [&]() {
|
2014-02-19 13:36:38 -08:00
|
|
|
pair<PreparedGrammar, PreparedGrammar> result = perform(Grammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", seq({
|
2014-02-16 22:13:08 -08:00
|
|
|
character({ 'a' }),
|
|
|
|
|
character({ 'b' }),
|
2014-02-13 13:09:00 -08:00
|
|
|
seq({
|
|
|
|
|
sym("rule2"),
|
|
|
|
|
sym("rule3") }),
|
|
|
|
|
seq({
|
2014-02-16 22:13:08 -08:00
|
|
|
character({ 'a' }),
|
|
|
|
|
character({ 'b' }) }) }) }
|
2014-02-13 13:09:00 -08:00
|
|
|
}));
|
|
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.first, Equals(PreparedGrammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", seq({
|
2014-02-19 13:05:54 -08:00
|
|
|
make_shared<Symbol>("token1", SymbolTypeAuxiliary),
|
2014-02-13 13:09:00 -08:00
|
|
|
seq({
|
|
|
|
|
sym("rule2"),
|
|
|
|
|
sym("rule3") }),
|
2014-02-19 13:05:54 -08:00
|
|
|
make_shared<Symbol>("token1", SymbolTypeAuxiliary) }) }
|
2014-02-19 13:36:38 -08:00
|
|
|
}, {})));
|
2014-02-13 13:09:00 -08:00
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.second, Equals(PreparedGrammar("", {}, {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "token1", rules::seq({
|
2014-02-16 22:13:08 -08:00
|
|
|
rules::character({ 'a' }),
|
|
|
|
|
rules::character({ 'b' }) }) },
|
2014-02-13 13:09:00 -08:00
|
|
|
})));
|
|
|
|
|
});
|
2014-01-03 01:02:24 -08:00
|
|
|
|
2014-02-13 13:09:00 -08:00
|
|
|
it("moves entire rules into the lexical grammar when possible, preserving their names", [&]() {
|
2014-02-16 22:13:08 -08:00
|
|
|
auto result = perform(Grammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", sym("rule2") },
|
|
|
|
|
{ "rule2", seq({
|
2014-02-16 22:13:08 -08:00
|
|
|
character({ 'a' }),
|
|
|
|
|
character({ 'b' }) }) }
|
2014-02-13 13:09:00 -08:00
|
|
|
}));
|
|
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.first, Equals(PreparedGrammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", sym("rule2") }
|
2014-02-19 13:36:38 -08:00
|
|
|
}, {})));
|
2014-02-13 13:09:00 -08:00
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.second, Equals(PreparedGrammar("", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule2", seq({
|
2014-02-16 22:13:08 -08:00
|
|
|
character({ 'a' }),
|
|
|
|
|
character({ 'b' }) }) },
|
2014-02-19 13:36:38 -08:00
|
|
|
}, {})));
|
2014-02-13 13:09:00 -08:00
|
|
|
});
|
2014-01-28 12:52:29 -08:00
|
|
|
|
2014-02-13 13:09:00 -08:00
|
|
|
it("does not extract blanks into tokens", [&]() {
|
2014-02-19 13:36:38 -08:00
|
|
|
pair<PreparedGrammar, PreparedGrammar> result = perform(Grammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", choice({ sym("rule2"), blank() }) },
|
|
|
|
|
}));
|
|
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.first, Equals(PreparedGrammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", choice({ sym("rule2"), blank() }) },
|
2014-02-19 13:36:38 -08:00
|
|
|
}, {})));
|
2014-02-13 13:09:00 -08:00
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.second, Equals(PreparedGrammar("", {}, {})));
|
2014-02-13 13:09:00 -08:00
|
|
|
});
|
2014-01-28 12:52:29 -08:00
|
|
|
});
|
2014-02-13 13:09:00 -08:00
|
|
|
|
|
|
|
|
describe("expanding repeats", []() {
|
|
|
|
|
it("replaces repeat rules with pairs of recursive rules", [&]() {
|
2014-02-19 13:36:38 -08:00
|
|
|
PreparedGrammar result = perform(Grammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", seq({
|
|
|
|
|
sym("x"),
|
|
|
|
|
repeat(seq({ sym("a"), sym("b") })),
|
|
|
|
|
sym("y")
|
|
|
|
|
}) },
|
|
|
|
|
})).first;
|
|
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result, Equals(PreparedGrammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", seq({
|
|
|
|
|
sym("x"),
|
2014-02-19 13:05:54 -08:00
|
|
|
make_shared<Symbol>("repeat_helper1", SymbolTypeAuxiliary),
|
2014-02-13 13:09:00 -08:00
|
|
|
sym("y")
|
|
|
|
|
}) },
|
|
|
|
|
}, {
|
2014-02-15 15:43:32 -08:00
|
|
|
{ "repeat_helper1", choice({
|
|
|
|
|
seq({
|
|
|
|
|
seq({ sym("a"), sym("b") }),
|
2014-02-19 13:05:54 -08:00
|
|
|
make_shared<Symbol>("repeat_helper1", SymbolTypeAuxiliary),
|
2014-02-13 13:09:00 -08:00
|
|
|
}),
|
2014-02-15 15:43:32 -08:00
|
|
|
blank(),
|
2014-02-13 13:09:00 -08:00
|
|
|
}) }
|
|
|
|
|
})));
|
|
|
|
|
});
|
2014-02-12 18:31:57 -08:00
|
|
|
|
2014-02-13 13:09:00 -08:00
|
|
|
it("does not replace repeat rules that can be moved into the lexical grammar", [&]() {
|
2014-02-19 13:36:38 -08:00
|
|
|
pair<PreparedGrammar, PreparedGrammar> result = perform(Grammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", seq({
|
|
|
|
|
sym("x"),
|
|
|
|
|
repeat(seq({ str("a"), str("b") })),
|
|
|
|
|
sym("y")
|
|
|
|
|
}) },
|
|
|
|
|
}));
|
|
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.first, Equals(PreparedGrammar("rule1", {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "rule1", seq({
|
|
|
|
|
sym("x"),
|
2014-02-19 13:05:54 -08:00
|
|
|
make_shared<Symbol>("token1", SymbolTypeAuxiliary),
|
2014-02-13 13:09:00 -08:00
|
|
|
sym("y")
|
|
|
|
|
}) },
|
2014-02-19 13:36:38 -08:00
|
|
|
}, {})));
|
2014-02-13 13:09:00 -08:00
|
|
|
|
2014-02-19 13:36:38 -08:00
|
|
|
AssertThat(result.second, Equals(PreparedGrammar("", {}, {
|
2014-02-13 13:09:00 -08:00
|
|
|
{ "token1", repeat(seq({ str("a"), str("b") })) },
|
|
|
|
|
})));
|
|
|
|
|
});
|
2014-02-12 18:31:57 -08:00
|
|
|
});
|
2014-01-03 01:02:24 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
END_TEST
|