Switch specs to use bandit instead of igloo

This commit is contained in:
Max Brunsfeld 2013-12-28 15:09:52 -08:00
parent ccd806a0da
commit d027aa5af6
14 changed files with 138 additions and 118 deletions

6
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "externals/igloo"]
path = externals/igloo
url = https://github.com/joakimkarlsson/igloo
[submodule "externals/bandit"]
path = externals/bandit
url = https://github.com/joakimkarlsson/bandit.git

View file

@ -120,7 +120,7 @@
12D136A0183570F5005F3369 /* pattern_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pattern_spec.cpp; path = spec/compiler/rules/pattern_spec.cpp; sourceTree = SOURCE_ROOT; };
12D136A2183678A2005F3369 /* repeat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = repeat.cpp; sourceTree = "<group>"; };
12D136A3183678A2005F3369 /* repeat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = repeat.h; sourceTree = "<group>"; };
12E71794181D02A80051A649 /* specs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = specs; path = compiler_specs; sourceTree = BUILT_PRODUCTS_DIR; };
12E71794181D02A80051A649 /* compiler_specs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = compiler_specs; sourceTree = BUILT_PRODUCTS_DIR; };
12E71852181D081C0051A649 /* rules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rules.h; path = src/compiler/rules/rules.h; sourceTree = SOURCE_ROOT; };
12F9A64C182DD5FD00FAF50C /* spec_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = spec_helper.cpp; path = spec/compiler/spec_helper.cpp; sourceTree = SOURCE_ROOT; };
12F9A64D182DD5FD00FAF50C /* spec_helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spec_helper.h; path = spec/compiler/spec_helper.h; sourceTree = SOURCE_ROOT; };
@ -135,8 +135,8 @@
12FD40DA185FEF0D0041A84E /* arithmetic_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = arithmetic_spec.cpp; sourceTree = "<group>"; };
12FD40DC185FF12C0041A84E /* parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = parser.c; sourceTree = "<group>"; };
12FD40DE1860064C0041A84E /* tree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tree.c; sourceTree = "<group>"; };
12FD40E0186245FE0041A84E /* transitions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transitions.cpp; sourceTree = "<group>"; };
12FD40E1186245FE0041A84E /* transitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transitions.h; sourceTree = "<group>"; };
12FD40E0186245FE0041A84E /* transitions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = transitions.cpp; path = ../rules/transitions.cpp; sourceTree = "<group>"; };
12FD40E1186245FE0041A84E /* transitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = transitions.h; path = ../rules/transitions.h; sourceTree = "<group>"; };
12FD40E41862B3530041A84E /* visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = visitor.h; sourceTree = "<group>"; };
12FD40E618639B910041A84E /* visitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = visitor.cpp; sourceTree = "<group>"; };
12FD40E818641FB70041A84E /* rules.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rules.cpp; sourceTree = "<group>"; };
@ -191,8 +191,6 @@
12130616182C3D2900FCF928 /* string.h */,
12130609182C389100FCF928 /* symbol.cpp */,
1213060A182C389100FCF928 /* symbol.h */,
12FD40E0186245FE0041A84E /* transitions.cpp */,
12FD40E1186245FE0041A84E /* transitions.h */,
);
path = rules;
sourceTree = "<group>";
@ -200,6 +198,8 @@
12130618182C84B700FCF928 /* lr */ = {
isa = PBXGroup;
children = (
12FD40E0186245FE0041A84E /* transitions.cpp */,
12FD40E1186245FE0041A84E /* transitions.h */,
12130619182C84DF00FCF928 /* item.cpp */,
1213061A182C84DF00FCF928 /* item.h */,
12130620182C85D300FCF928 /* item_set.cpp */,
@ -247,11 +247,11 @@
12E716F9181D010E0051A649 = {
isa = PBXGroup;
children = (
12D1369E18342088005F3369 /* todo.md */,
12FD40D3185FED630041A84E /* include */,
12E71701181D01890051A649 /* src */,
12E71796181D02A80051A649 /* spec */,
12E71795181D02A80051A649 /* Products */,
12FD40D3185FED630041A84E /* include */,
12E71796181D02A80051A649 /* spec */,
12E71701181D01890051A649 /* src */,
12D1369E18342088005F3369 /* todo.md */,
);
sourceTree = "<group>";
};
@ -267,7 +267,7 @@
12E71795181D02A80051A649 /* Products */ = {
isa = PBXGroup;
children = (
12E71794181D02A80051A649 /* specs */,
12E71794181D02A80051A649 /* compiler_specs */,
12FD40D1185EEB5E0041A84E /* runtime_specs */,
);
name = Products;
@ -387,7 +387,7 @@
);
name = compiler_specs;
productName = Specs;
productReference = 12E71794181D02A80051A649 /* specs */;
productReference = 12E71794181D02A80051A649 /* compiler_specs */;
productType = "com.apple.product-type.tool";
};
12FD40B1185EEB5E0041A84E /* runtime_specs */ = {
@ -571,6 +571,7 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
externals/igloo,
externals/bandit,
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
ONLY_ACTIVE_ARCH = YES;
@ -610,6 +611,7 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
externals/igloo,
externals/bandit,
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -654,6 +656,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
externals/igloo,
include,
externals/bandit,
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
ONLY_ACTIVE_ARCH = YES;
@ -694,6 +697,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
externals/igloo,
include,
externals/bandit,
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = runtime_specs;

1
externals/bandit vendored Submodule

@ -0,0 +1 @@
Subproject commit 22201682be9a322e1ce271a09384bc7ca168b37f

1
externals/igloo vendored

@ -1 +0,0 @@
Subproject commit d8c6aa24de88740c6f1783281249eb18f858deaf

View file

@ -4,17 +4,17 @@
#include "c_code.h"
#include <fstream>
using namespace std;
using namespace tree_sitter::lr;
using namespace tree_sitter;
START_TEST
Describe(code_generation) {
describe("code_generation", []() {
string test_parser_dir = src_dir() + "/spec/fixtures/parsers";
It(works_for_the_arithmetic_grammar) {
it("works for the arithmetic grammar", [&]() {
Grammar grammar = test_grammars::arithmetic();
pair<ParseTable, LexTable> tables = build_tables(grammar);
std::ofstream parser_file(test_parser_dir + "/arithmetic.c");
parser_file << code_gen::c_code(grammar, tables.first, tables.second);
}
};
auto tables = lr::build_tables(grammar);
string code = code_gen::c_code(grammar, tables.first, tables.second);
std::ofstream(test_parser_dir + "/arithmetic.c") << code;
});
});
END_TEST

View file

@ -8,10 +8,12 @@ static item_set_ptr item_set(const std::initializer_list<Item> &items) {
return item_set_ptr(new ItemSet(items));
}
Describe(item_sets) {
START_TEST
describe("item sets", []() {
Grammar grammar = test_grammars::arithmetic();
It(computes_the_closure_of_an_item_set_under_symbol_expansion) {
it("computes the closure of an item set under symbol expansion", [&]() {
Item item = Item::at_beginning_of_rule("expression", grammar);
ItemSet set = ItemSet(item, grammar);
@ -25,9 +27,9 @@ Describe(item_sets) {
Item("number", grammar.rule("number"), 0),
Item("left_paren", grammar.rule("left_paren"), 0),
})));
}
});
It(computes_transitions) {
it("computes transitions", [&]() {
Item item = Item::at_beginning_of_rule("factor", grammar);
ItemSet set = ItemSet(item, grammar);
@ -38,9 +40,9 @@ Describe(item_sets) {
{ sym("number"), item_set({ Item("factor", blank(), 1) }) },
{ sym("left_paren"), std::make_shared<ItemSet>(Item("factor", seq({ sym("expression"), sym("right_paren") }), 1), grammar) },
})));
}
});
It(computes_character_transitions) {
it("computes character transitions", [&]() {
Item item = Item::at_beginning_of_rule("factor", grammar);
ItemSet set = ItemSet(item, grammar);
@ -51,14 +53,16 @@ Describe(item_sets) {
{ character(CharClassDigit), item_set({ Item("number", choice({ repeat(character(CharClassDigit)), blank() }), 1) }) },
{ character('('), item_set({ Item("left_paren", blank(), 1) }) }
})));
}
});
It(can_be_hashed) {
it("can be hashed", [&]() {
ItemSet set1 = ItemSet(Item::at_beginning_of_rule("factor", grammar), grammar);
ItemSet set2 = ItemSet(Item::at_beginning_of_rule("factor", grammar), grammar);
AssertThat(std::hash<const ItemSet>()(set1), Equals(std::hash<const ItemSet>()(set2)));
ItemSet set3 = ItemSet(Item::at_beginning_of_rule("term", grammar), grammar);
AssertThat(std::hash<const ItemSet>()(set1), !Equals(std::hash<const ItemSet>()(set3)));
}
};
});
});
END_TEST

View file

@ -1,15 +1,18 @@
#include "spec_helper.h"
#include "../../fixtures/grammars/arithmetic.h"
using namespace tree_sitter::lr;
Describe(items) {
Describe(transitions) {
Grammar grammar = test_grammars::arithmetic();
It(finds_the_item_at_the_start_of_a_rule) {
START_TEST
describe("items", []() {
Grammar grammar = test_grammars::arithmetic();
describe("transitions", [&]() {
it("finds the item at the start of a rule", [&]() {
Item item = Item::at_beginning_of_rule("expression", grammar);
AssertThat(item, Equals(Item("expression", grammar.rule("expression"), 0)));
}
};
};
});
});
});
END_TEST

View file

@ -1,28 +1,27 @@
#include "spec_helper.h"
#include "parse_table.h"
#include "lex_table.h"
#include "table_builder.h"
#include <functional>
using namespace tree_sitter::lr;
typedef std::unordered_set<ParseAction> parse_actions;
typedef std::unordered_set<LexAction> lex_actions;
Describe(TableBuilderSpec) {
START_TEST
describe("building parse and lex tables", []() {
Grammar grammar = test_grammars::arithmetic();
ParseTable table = build_tables(grammar).first;
LexTable lex_table = build_tables(grammar).second;
ParseState parse_state(size_t index) {
function<ParseState(size_t)> parse_state = [&](size_t index) {
return table.states[index];
}
};
LexState lex_state(size_t parse_state_index) {
function<LexState(size_t)> lex_state = [&](size_t parse_state_index) {
size_t index = table.states[parse_state_index].lex_state_index;
return lex_table.states[index];
}
};
It(has_the_right_starting_state) {
it("has the right starting state", [&]() {
AssertThat(parse_state(0).actions, Equals(unordered_map<string, parse_actions>({
{ "expression", parse_actions({ ParseAction::Shift(1) }) },
{ "term", parse_actions({ ParseAction::Shift(2) }) },
@ -37,15 +36,15 @@ Describe(TableBuilderSpec) {
{ CharMatchClass(CharClassDigit), lex_actions({ LexAction::Advance(4) }) },
{ CharMatchSpecific('('), lex_actions({ LexAction::Advance(11) }) }
})));
}
});
It(accepts_when_the_start_symbol_is_reduced) {
it("accepts when the start symbol is reduced", [&]() {
AssertThat(parse_state(1).actions, Equals(unordered_map<string, parse_actions>({
{ ParseTable::END_OF_INPUT, parse_actions({ ParseAction::Accept() }) }
})));
}
});
It(has_the_right_next_states) {
it("has the right next states", [&]() {
AssertThat(parse_state(2).actions, Equals(unordered_map<string, parse_actions>({
{ "plus", parse_actions({ ParseAction::Shift(3) }) },
})));
@ -57,5 +56,7 @@ Describe(TableBuilderSpec) {
{ "number", parse_actions({ ParseAction::Shift(8) }) },
{ "term", parse_actions({ ParseAction::Shift(4) }) },
})));
}
};
});
});
END_TEST

View file

@ -4,8 +4,10 @@
using namespace tree_sitter::rules;
Describe(pattern_rules) {
It(parses_simple_strings) {
START_TEST
describe("parsing pattern rules", []() {
it("parses simple strings", [&]() {
Pattern rule("abc");
AssertThat(
rule.to_rule_tree()->to_string(),
@ -14,9 +16,9 @@ Describe(pattern_rules) {
character('b'),
character('c')
})->to_string()));
};
});
It(parses_character_classes) {
it("parses character classes", []() {
Pattern rule("\\w-\\d");
AssertThat(
rule.to_rule_tree()->to_string(),
@ -25,9 +27,9 @@ Describe(pattern_rules) {
character('-'),
character(CharClassDigit)
})->to_string()));
};
});
It(parses_choices) {
it("parses choices", []() {
Pattern rule("ab|cd|ef");
AssertThat(
rule.to_rule_tree()->to_string(),
@ -45,9 +47,9 @@ Describe(pattern_rules) {
character('f')
})
})->to_string()));
};
});
It(parses_choices_in_sequences) {
it("parses choices in sequences", []() {
Pattern rule("(a|b)cd");
AssertThat(
rule.to_rule_tree()->to_string(),
@ -59,9 +61,9 @@ Describe(pattern_rules) {
character('c'),
character('d')
})->to_string()));
};
});
It(parses_special_characters_when_they_are_escaped) {
it("parses special characters when they are escaped", []() {
Pattern rule("a\\(b");
AssertThat(
rule.to_rule_tree()->to_string(),
@ -70,9 +72,9 @@ Describe(pattern_rules) {
character('('),
character('b')
})->to_string()));
}
});
It(parses_repeating_rules) {
it("parses repeating rules", []() {
Pattern rule("(ab)+(cd)+");
AssertThat(
rule.to_rule_tree()->to_string(),
@ -88,5 +90,7 @@ Describe(pattern_rules) {
})),
})->to_string()
));
}
};
});
});
END_TEST

View file

@ -1,15 +1,15 @@
#include "spec_helper.h"
#include "rules.h"
#include "transitions.h"
#include "transition_map.h"
Describe(Rules) {
Describe(construction) {
START_TEST
describe("Rules", []() {
describe("construction", []() {
rules::rule_ptr symbol1 = rules::sym("1");
rules::rule_ptr symbol2 = rules::sym("2");
rules::rule_ptr symbol3 = rules::sym("3");
It(constructs_binary_trees) {
it("constructs binary trees", [&]() {
AssertThat(
rules::seq({ symbol1, symbol2, symbol3 })->to_string(),
Equals(std::string("(seq (seq (sym '1') (sym '2')) (sym '3'))")));
@ -17,59 +17,59 @@ Describe(Rules) {
AssertThat(
rules::choice({ symbol1, symbol2, symbol3 })->to_string(),
Equals(std::string("(choice (choice (sym '1') (sym '2')) (sym '3'))")));
}
};
});
});
Describe(transitions) {
describe("transitions", []() {
rules::rule_ptr symbol1 = rules::sym("1");
rules::rule_ptr symbol2 = rules::sym("2");
rules::rule_ptr symbol3 = rules::sym("3");
rules::rule_ptr symbol4 = rules::sym("3");
rules::rule_ptr char1 = rules::character('a');
It(handles_symbols) {
it("handles symbols", [&]() {
AssertThat(
rules::transitions(symbol1),
Equals(transition_map<rules::Rule, rules::Rule>({
{ symbol1, rules::blank() }
})));
}
});
It(handles_characters) {
it("handles characters", [&]() {
AssertThat(
rules::transitions(char1),
Equals(transition_map<rules::Rule, rules::Rule>({
{ char1, rules::blank() }
})));
}
});
It(handles_character_classes) {
it("handles character classes", [&]() {
auto rule = rules::character(CharClassDigit);
AssertThat(
rules::transitions(rule),
Equals(transition_map<rules::Rule, rules::Rule>({
{ rule, rules::blank() }
})));
}
});
It(handles_choices) {
it("handles choices", [&]() {
AssertThat(
rules::transitions(rules::choice({ symbol1, symbol2 })),
Equals(transition_map<rules::Rule, rules::Rule>({
{ symbol1, rules::blank() },
{ symbol2, rules::blank() }
})));
}
});
It(handles_sequences) {
it("handles sequences", [&]() {
AssertThat(
rules::transitions(rules::seq({ symbol1, symbol2 })),
Equals(transition_map<rules::Rule, rules::Rule>({
{ symbol1, symbol2 }
})));
}
});
It(handles_long_sequences) {
it("handles_long_sequences", [&]() {
AssertThat(
rules::transitions(rules::seq({
symbol1,
@ -80,9 +80,9 @@ Describe(Rules) {
Equals(transition_map<rules::Rule, rules::Rule>({
{ symbol1, rules::seq({ symbol2, symbol3, symbol4 }) }
})));
}
});
It(handles_choices_with_common_starting_symbols) {
it("handles choices with common starting symbols", [&]() {
AssertThat(
rules::transitions(
rules::choice({
@ -91,9 +91,9 @@ Describe(Rules) {
Equals(transition_map<rules::Rule, rules::Rule>({
{ symbol1, rules::choice({ symbol2, symbol3 }) }
})));
}
});
It(handles_strings) {
it("handles strings", [&]() {
AssertThat(
rules::transitions(rules::str("bad")),
Equals(transition_map<rules::Rule, rules::Rule>({
@ -102,18 +102,18 @@ Describe(Rules) {
rules::seq({ rules::character('a'), rules::character('d') })
}
})));
}
});
It(handles_patterns) {
it("handles patterns", [&]() {
AssertThat(
rules::transitions(rules::pattern("a|b")),
Equals(transition_map<rules::Rule, rules::Rule>({
{ rules::character('a'), rules::blank() },
{ rules::character('b'), rules::blank() }
})));
}
});
It(handles_repeats) {
it("handles repeats", [&]() {
rules::rule_ptr repeat = rules::repeat(rules::str("ab"));
AssertThat(
rules::transitions(repeat),
@ -140,6 +140,8 @@ Describe(Rules) {
rules::blank()
})
}})));
}
};
};
});
});
});
END_TEST

View file

@ -1,6 +1,5 @@
#include "spec_helper.h"
namespace tree_sitter {
namespace lr {
template<typename TKey, typename TValue>

View file

@ -1,22 +1,22 @@
#ifndef TreeSitter_SpecHelper_h
#define TreeSitter_SpecHelper_h
#include "igloo/igloo_alt.h"
#include "bandit/bandit.h"
#include "transition_map.h"
#include "rules.h"
#include "item.h"
#include "item_set.h"
#include "grammar.h"
#include "parse_table.h"
#include "table_builder.h"
#include "../fixtures/grammars/arithmetic.h"
using namespace tree_sitter;
using namespace std;
using namespace igloo;
using namespace bandit;
#define START_TEST go_bandit([]() {
#define END_TEST });
namespace tree_sitter {
namespace lr {

View file

@ -1,6 +1,7 @@
#include <igloo/igloo_alt.h>
#include "spec_helper.h"
int main(int argc, char *argv[])
{
return igloo::TestRunner::RunAllTests(argc, argv);
char *args[] = {nullptr, (char *)"--no-color"};
return bandit::run(2, args);
}

View file

@ -1,10 +1,12 @@
#include <igloo/igloo_alt.h>
#include "spec_helper.h"
#include "../fixtures/parsers/arithmetic.c"
using namespace igloo;
START_TEST
Describe(arithmetic) {
It(parses_numbers) {
describe("arithmetic", []() {
it("parses_numbers", [&]() {
ts_parse_arithmetic("5");
};
};
});
});
END_TEST