tree-sitter/spec/compiler/build_tables/perform_spec.cpp

111 lines
3.1 KiB
C++
Raw Normal View History

2013-12-27 17:31:08 -08:00
#include "spec_helper.h"
#include <functional>
2014-01-11 15:14:17 -08:00
#include "build_tables/perform.h"
2013-12-27 17:31:08 -08:00
2014-01-11 17:08:32 -08:00
using build_tables::perform;
using namespace rules;
2014-01-08 18:35:16 -08:00
typedef unordered_set<ParseAction> parse_actions;
typedef unordered_set<LexAction> lex_actions;
2013-12-27 17:31:08 -08:00
2014-01-23 13:10:37 -08:00
static unordered_set<string> keys(const unordered_map<string, parse_actions> &map) {
unordered_set<string> result;
for (auto pair : map) {
result.insert(pair.first);
}
return result;
}
static unordered_set<CharMatch> keys(const unordered_map<CharMatch, lex_actions> &map) {
unordered_set<CharMatch> result;
for (auto pair : map) {
result.insert(pair.first);
}
return result;
}
START_TEST
describe("building parse and lex tables", []() {
Grammar grammar({
{ "expression", choice({
seq({
sym("term"),
2014-01-08 18:35:16 -08:00
sym("plus"),
sym("term") }),
sym("term") }) },
{ "term", choice({
sym("variable"),
sym("number"),
seq({
2014-01-08 18:35:16 -08:00
sym("left-paren"),
sym("expression"),
2014-01-08 18:35:16 -08:00
sym("right-paren")
}) }) }
});
Grammar lex_grammar({
2014-01-08 18:35:16 -08:00
{ "plus", str("+") },
{ "variable", pattern("\\w+") },
{ "number", pattern("\\d+") },
{ "left-paren", str("(") },
{ "right-paren", str(")") }
});
ParseTable table;
LexTable lex_table;
before_each([&]() {
pair<ParseTable, LexTable> tables = perform(grammar, lex_grammar);
table = tables.first;
lex_table = tables.second;
});
2013-12-27 17:31:08 -08:00
function<ParseState(size_t)> parse_state = [&](size_t index) {
2013-12-27 17:31:08 -08:00
return table.states[index];
};
2013-12-27 17:31:08 -08:00
function<LexState(size_t)> lex_state = [&](size_t parse_state_index) {
long index = table.states[parse_state_index].lex_state_index;
2013-12-27 17:31:08 -08:00
return lex_table.states[index];
};
2013-12-27 17:31:08 -08:00
it("has the right starting state", [&]() {
2014-01-23 13:10:37 -08:00
AssertThat(keys(parse_state(0).actions), Equals(unordered_set<string>({
"expression",
"term",
"number",
"variable",
"left-paren",
2013-12-27 17:31:08 -08:00
})));
2014-01-23 13:10:37 -08:00
AssertThat(keys(lex_state(0).actions), Equals(unordered_set<CharMatch>({
CharMatchSpecific('('),
CharMatchClass(CharClassDigit),
CharMatchClass(CharClassWord),
2013-12-27 17:31:08 -08:00
})));
2014-01-08 18:35:16 -08:00
AssertThat(lex_state(0).expected_inputs(), Equals(unordered_set<CharMatch>({
CharMatchSpecific('('),
CharMatchClass(CharClassDigit),
CharMatchClass(CharClassWord),
})));
});
2013-12-27 17:31:08 -08:00
it("accepts when the start symbol is reduced", [&]() {
2013-12-27 17:31:08 -08:00
AssertThat(parse_state(1).actions, Equals(unordered_map<string, parse_actions>({
{ "__END__", parse_actions({ ParseAction::Accept() }) }
2013-12-27 17:31:08 -08:00
})));
});
2013-12-27 17:31:08 -08:00
it("has the right next states", [&]() {
2013-12-27 17:31:08 -08:00
AssertThat(parse_state(2).actions, Equals(unordered_map<string, parse_actions>({
2014-01-08 18:35:16 -08:00
{ "plus", parse_actions({ ParseAction::Shift(3) }) },
2014-01-22 23:04:11 -08:00
{ "__END__", parse_actions({ ParseAction::Reduce("expression", 1) }) },
2013-12-27 17:31:08 -08:00
})));
});
});
END_TEST