Extract public compiler API into its own header file

This commit is contained in:
Max Brunsfeld 2014-02-16 22:13:08 -08:00
parent 0b4e1c8d0d
commit 9e2dc14182
53 changed files with 466 additions and 409 deletions

View file

@ -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"),

View file

@ -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"),

View file

@ -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'} }),
})));
});
});

View file

@ -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() },
})));
});
});

View file

@ -1,5 +1,4 @@
#include "spec_helper.h"
#include "compile.h"
#include "../fixtures/grammars/test_grammars.h"
#include <fstream>

View file

@ -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") })),

View file

@ -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' })
})),
})
));

View file

@ -1,4 +1,5 @@
#include "spec_helper.h"
#include "rule.h"
using namespace rules;