Extract public compiler API into its own header file
This commit is contained in:
parent
0b4e1c8d0d
commit
9e2dc14182
53 changed files with 466 additions and 409 deletions
|
|
@ -1,7 +1,5 @@
|
|||
#include "spec_helper.h"
|
||||
#include "build_tables/first_set.h"
|
||||
#include "grammar.h"
|
||||
#include "rules.h"
|
||||
|
||||
using std::set;
|
||||
using namespace build_tables;
|
||||
|
|
@ -10,7 +8,7 @@ using namespace rules;
|
|||
START_TEST
|
||||
|
||||
describe("computing FIRST sets", []() {
|
||||
const Grammar null_grammar({{ "something", blank() }});
|
||||
const Grammar null_grammar("", {{ "something", blank() }});
|
||||
|
||||
describe("for a sequence AB", [&]() {
|
||||
it("ignores B when A cannot be blank", [&]() {
|
||||
|
|
@ -42,7 +40,7 @@ describe("computing FIRST sets", []() {
|
|||
sym("A") }),
|
||||
sym("A") });
|
||||
|
||||
Grammar grammar({
|
||||
Grammar grammar("A", {
|
||||
{ "A", choice({
|
||||
seq({
|
||||
sym("y"),
|
||||
|
|
@ -57,7 +55,7 @@ describe("computing FIRST sets", []() {
|
|||
});
|
||||
|
||||
it("includes FIRST(B) when A is a non-terminal and its expansion can be blank", [&]() {
|
||||
Grammar grammar({{ "A", choice({ sym("x"), blank() }) }});
|
||||
Grammar grammar("A", {{ "A", choice({ sym("x"), blank() }) }});
|
||||
|
||||
auto rule = seq({
|
||||
sym("A"),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#include "spec_helper.h"
|
||||
#include "build_tables/item_set_closure.h"
|
||||
#include "build_tables/item_set_transitions.h"
|
||||
#include "grammar.h"
|
||||
#include "rules.h"
|
||||
|
||||
using namespace build_tables;
|
||||
using namespace rules;
|
||||
|
|
@ -10,7 +8,7 @@ using namespace rules;
|
|||
START_TEST
|
||||
|
||||
describe("computing closures of item sets", []() {
|
||||
Grammar grammar({
|
||||
Grammar grammar("E", {
|
||||
{ "E", choice({
|
||||
seq({
|
||||
sym("T"),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ static set<Symbol> keys(const map<Symbol, parse_actions> &map) {
|
|||
START_TEST
|
||||
|
||||
describe("building parse and lex tables", []() {
|
||||
Grammar grammar({
|
||||
Grammar grammar("expression", {
|
||||
{ "expression", choice({
|
||||
seq({
|
||||
sym("term"),
|
||||
|
|
@ -36,7 +36,7 @@ describe("building parse and lex tables", []() {
|
|||
}) }) }
|
||||
});
|
||||
|
||||
Grammar lex_grammar({
|
||||
Grammar lex_grammar("", {
|
||||
{ "plus", str("+") },
|
||||
{ "variable", pattern("\\w+") },
|
||||
{ "number", pattern("\\d+") },
|
||||
|
|
@ -72,9 +72,9 @@ describe("building parse and lex tables", []() {
|
|||
})));
|
||||
|
||||
AssertThat(lex_state(0).expected_inputs(), Equals(set<CharacterSet>({
|
||||
CharacterSet({ '(' }, true),
|
||||
CharacterSet({ {'0', '9'} }, true),
|
||||
CharacterSet({ {'a', 'z'}, {'A', 'Z'} }, true),
|
||||
CharacterSet({ '(' }),
|
||||
CharacterSet({ CharacterRange('0', '9') }),
|
||||
CharacterSet({ {'a', 'z'}, {'A', 'Z'} }),
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ describe("rule transitions", []() {
|
|||
|
||||
it("handles characters", [&]() {
|
||||
AssertThat(
|
||||
char_transitions(character('1')),
|
||||
char_transitions(character({ '1' })),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ '1' }), blank() }
|
||||
})));
|
||||
|
|
@ -100,7 +100,7 @@ describe("rule transitions", []() {
|
|||
AssertThat(
|
||||
char_transitions(str("bad")),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ 'b' }, true), seq({ character('a'), character('d') }) }
|
||||
{ CharacterSet({ 'b' }), seq({ character({ 'a' }), character({ 'd' }) }) }
|
||||
})));
|
||||
});
|
||||
|
||||
|
|
@ -124,9 +124,9 @@ describe("rule transitions", []() {
|
|||
character({ { 'm', 'z' } }),
|
||||
sym("y") }) })),
|
||||
Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ {'a','l'} }, true), sym("x") },
|
||||
{ CharacterSet({ {'m','s'} }, true), choice({ sym("x"), sym("y") }) },
|
||||
{ CharacterSet({ {'t','z'} }, true), sym("y") },
|
||||
{ CharacterSet({ {'a','l'} }), sym("x") },
|
||||
{ CharacterSet({ {'m','s'} }), choice({ sym("x"), sym("y") }) },
|
||||
{ CharacterSet({ {'t','z'} }), sym("y") },
|
||||
})));
|
||||
});
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ describe("rule transitions", []() {
|
|||
{
|
||||
CharacterSet({ 'a' }),
|
||||
seq({
|
||||
character('b'),
|
||||
character({ 'b' }),
|
||||
choice({
|
||||
rule,
|
||||
blank()
|
||||
|
|
@ -166,17 +166,17 @@ describe("rule transitions", []() {
|
|||
repeat(character({ '"' }, false)),
|
||||
blank(),
|
||||
}),
|
||||
character('"'),
|
||||
character({ '"' }),
|
||||
});
|
||||
|
||||
AssertThat(char_transitions(rule), Equals(rule_map<CharacterSet>({
|
||||
{ CharacterSet({ '"' }, false), seq({
|
||||
{ CharacterSet({ '"' }).complement(), seq({
|
||||
choice({
|
||||
repeat(character({ '"' }, false)),
|
||||
blank(),
|
||||
}),
|
||||
character('"'), }) },
|
||||
{ CharacterSet({ '"' }, true), blank() },
|
||||
character({ '"' }), }) },
|
||||
{ CharacterSet({ '"' }), blank() },
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "spec_helper.h"
|
||||
#include "compile.h"
|
||||
#include "../fixtures/grammars/test_grammars.h"
|
||||
#include <fstream>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,19 +9,19 @@ using prepare_grammar::perform;
|
|||
describe("preparing a grammar", []() {
|
||||
describe("extracting tokens", []() {
|
||||
it("moves sub-rules that don't contain symbols into a separate 'lexical' grammar", [&]() {
|
||||
pair<Grammar, Grammar> result = perform(Grammar({
|
||||
pair<Grammar, Grammar> result = perform(Grammar("rule1", {
|
||||
{ "rule1", seq({
|
||||
character('a'),
|
||||
character('b'),
|
||||
character({ 'a' }),
|
||||
character({ 'b' }),
|
||||
seq({
|
||||
sym("rule2"),
|
||||
sym("rule3") }),
|
||||
seq({
|
||||
character('a'),
|
||||
character('b') }) }) }
|
||||
character({ 'a' }),
|
||||
character({ 'b' }) }) }) }
|
||||
}));
|
||||
|
||||
AssertThat(result.first, Equals(Grammar({
|
||||
AssertThat(result.first, Equals(Grammar("rule1", {
|
||||
{ "rule1", seq({
|
||||
aux_sym("token1"),
|
||||
seq({
|
||||
|
|
@ -32,27 +32,27 @@ describe("preparing a grammar", []() {
|
|||
|
||||
AssertThat(result.second, Equals(Grammar("", map<const string, const rule_ptr>(), {
|
||||
{ "token1", rules::seq({
|
||||
rules::character('a'),
|
||||
rules::character('b') }) },
|
||||
rules::character({ 'a' }),
|
||||
rules::character({ 'b' }) }) },
|
||||
})));
|
||||
});
|
||||
|
||||
it("moves entire rules into the lexical grammar when possible, preserving their names", [&]() {
|
||||
auto result = perform(Grammar({
|
||||
auto result = perform(Grammar("rule1", {
|
||||
{ "rule1", sym("rule2") },
|
||||
{ "rule2", seq({
|
||||
character('a'),
|
||||
character('b') }) }
|
||||
character({ 'a' }),
|
||||
character({ 'b' }) }) }
|
||||
}));
|
||||
|
||||
AssertThat(result.first, Equals(Grammar({
|
||||
AssertThat(result.first, Equals(Grammar("rule1", {
|
||||
{ "rule1", sym("rule2") }
|
||||
})));
|
||||
|
||||
AssertThat(result.second, Equals(Grammar("", {
|
||||
{ "rule2", seq({
|
||||
character('a'),
|
||||
character('b') }) },
|
||||
character({ 'a' }),
|
||||
character({ 'b' }) }) },
|
||||
})));
|
||||
});
|
||||
|
||||
|
|
@ -60,8 +60,8 @@ describe("preparing a grammar", []() {
|
|||
auto result = perform(Grammar("rule1", map<const string, const rule_ptr>(), {
|
||||
{ "rule1", sym("rule2") },
|
||||
{ "rule2", seq({
|
||||
character('a'),
|
||||
character('b') }) }
|
||||
character({ 'a' }),
|
||||
character({ 'b' }) }) }
|
||||
}));
|
||||
|
||||
AssertThat(result.first, Equals(Grammar("rule1", map<const string, const rule_ptr>(), {
|
||||
|
|
@ -70,13 +70,13 @@ describe("preparing a grammar", []() {
|
|||
|
||||
AssertThat(result.second, Equals(Grammar("", map<const string, const rule_ptr>(), {
|
||||
{ "rule2", seq({
|
||||
character('a'),
|
||||
character('b') }) },
|
||||
character({ 'a' }),
|
||||
character({ 'b' }) }) },
|
||||
})));
|
||||
});
|
||||
|
||||
it("does not extract blanks into tokens", [&]() {
|
||||
pair<Grammar, Grammar> result = perform(Grammar({
|
||||
pair<Grammar, Grammar> result = perform(Grammar("rule1", {
|
||||
{ "rule1", choice({ sym("rule2"), blank() }) },
|
||||
}));
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ describe("preparing a grammar", []() {
|
|||
|
||||
describe("expanding repeats", []() {
|
||||
it("replaces repeat rules with pairs of recursive rules", [&]() {
|
||||
Grammar result = perform(Grammar({
|
||||
Grammar result = perform(Grammar("rule1", {
|
||||
{ "rule1", seq({
|
||||
sym("x"),
|
||||
repeat(seq({ sym("a"), sym("b") })),
|
||||
|
|
@ -116,7 +116,7 @@ describe("preparing a grammar", []() {
|
|||
});
|
||||
|
||||
it("does not replace repeat rules that can be moved into the lexical grammar", [&]() {
|
||||
pair<Grammar, Grammar> result = perform(Grammar({
|
||||
pair<Grammar, Grammar> result = perform(Grammar("rule1", {
|
||||
{ "rule1", seq({
|
||||
sym("x"),
|
||||
repeat(seq({ str("a"), str("b") })),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "spec_helper.h"
|
||||
#include "rules.h"
|
||||
#include "pattern.h"
|
||||
#include "character_set.h"
|
||||
|
||||
using namespace rules;
|
||||
|
||||
|
|
@ -11,9 +12,9 @@ describe("parsing pattern rules", []() {
|
|||
AssertThat(
|
||||
rule.to_rule_tree(),
|
||||
EqualsPointer(seq({
|
||||
character('a'),
|
||||
character('b'),
|
||||
character('c')
|
||||
character({ 'a' }),
|
||||
character({ 'b' }),
|
||||
character({ 'c' })
|
||||
})));
|
||||
});
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ describe("parsing pattern rules", []() {
|
|||
rule.to_rule_tree(),
|
||||
EqualsPointer(seq({
|
||||
character({ {'a', 'z'}, {'A', 'Z'} }),
|
||||
character('-'),
|
||||
character({ '-' }),
|
||||
character({ {'0', '9'} })
|
||||
})));
|
||||
});
|
||||
|
|
@ -34,16 +35,16 @@ describe("parsing pattern rules", []() {
|
|||
rule.to_rule_tree(),
|
||||
EqualsPointer(choice({
|
||||
seq({
|
||||
character('a'),
|
||||
character('b'),
|
||||
character({ 'a' }),
|
||||
character({ 'b' }),
|
||||
}),
|
||||
seq({
|
||||
character('c'),
|
||||
character('d')
|
||||
character({ 'c' }),
|
||||
character({ 'd' })
|
||||
}),
|
||||
seq({
|
||||
character('e'),
|
||||
character('f')
|
||||
character({ 'e' }),
|
||||
character({ 'f' })
|
||||
})
|
||||
})));
|
||||
});
|
||||
|
|
@ -73,7 +74,7 @@ describe("parsing pattern rules", []() {
|
|||
Pattern rule("\\\\");
|
||||
AssertThat(
|
||||
rule.to_rule_tree(),
|
||||
EqualsPointer(character('\\')));
|
||||
EqualsPointer(character({ '\\' })));
|
||||
});
|
||||
|
||||
it("parses character groups in sequences", []() {
|
||||
|
|
@ -81,12 +82,12 @@ describe("parsing pattern rules", []() {
|
|||
AssertThat(
|
||||
rule.to_rule_tree(),
|
||||
EqualsPointer(seq({
|
||||
character('"'),
|
||||
character({ '"' }),
|
||||
repeat(choice({
|
||||
character({ '"' }, false),
|
||||
seq({ character('\\'), character('"') })
|
||||
seq({ character({ '\\' }), character({ '"' }) })
|
||||
})),
|
||||
character('"')
|
||||
character({ '"' })
|
||||
})));
|
||||
});
|
||||
|
||||
|
|
@ -96,11 +97,11 @@ describe("parsing pattern rules", []() {
|
|||
rule.to_rule_tree(),
|
||||
EqualsPointer(seq({
|
||||
choice({
|
||||
character('a'),
|
||||
character('b'),
|
||||
character({ 'a' }),
|
||||
character({ 'b' }),
|
||||
}),
|
||||
character('c'),
|
||||
character('d')
|
||||
character({ 'c' }),
|
||||
character({ 'd' })
|
||||
})));
|
||||
});
|
||||
|
||||
|
|
@ -109,9 +110,9 @@ describe("parsing pattern rules", []() {
|
|||
AssertThat(
|
||||
rule.to_rule_tree(),
|
||||
EqualsPointer(seq({
|
||||
character('a'),
|
||||
character('('),
|
||||
character('b')
|
||||
character({ 'a' }),
|
||||
character({ '(' }),
|
||||
character({ 'b' })
|
||||
})));
|
||||
});
|
||||
|
||||
|
|
@ -122,12 +123,12 @@ describe("parsing pattern rules", []() {
|
|||
EqualsPointer(
|
||||
seq({
|
||||
repeat(seq({
|
||||
character('a'),
|
||||
character('b')
|
||||
character({ 'a' }),
|
||||
character({ 'b' })
|
||||
})),
|
||||
repeat(seq({
|
||||
character('c'),
|
||||
character('d')
|
||||
character({ 'c' }),
|
||||
character({ 'd' })
|
||||
})),
|
||||
})
|
||||
));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "spec_helper.h"
|
||||
#include "rule.h"
|
||||
|
||||
using namespace rules;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue