tree-sitter/spec/compiler/build_tables/first_set_spec.cc

102 lines
2.9 KiB
C++
Raw Normal View History

2014-06-23 18:50:03 -07:00
#include "compiler/compiler_spec_helper.h"
2014-03-09 22:05:05 -07:00
#include "compiler/prepared_grammar.h"
#include "compiler/build_tables/first_set.h"
#include "compiler/rules/metadata.h"
using std::set;
using namespace build_tables;
using namespace rules;
START_TEST
describe("computing FIRST sets", []() {
const SyntaxGrammar null_grammar;
2014-02-13 18:52:17 -08:00
describe("for a sequence AB", [&]() {
it("ignores B when A cannot be blank", [&]() {
auto rule = seq({ i_token(0), i_token(1) });
2014-03-09 19:49:35 -07:00
AssertThat(first_set(rule, null_grammar), Equals(set<Symbol>({
Symbol(0, SymbolOptionToken),
})));
});
2014-02-13 18:52:17 -08:00
it("includes FIRST(B) when A can be blank", [&]() {
auto rule = seq({
choice({
i_token(0),
2014-02-13 18:52:17 -08:00
blank() }),
i_token(1) });
2014-03-09 19:49:35 -07:00
AssertThat(first_set(rule, null_grammar), Equals(set<Symbol>({
Symbol(0, SymbolOptionToken),
Symbol(1, SymbolOptionToken)
2014-02-13 18:52:17 -08:00
})));
});
2014-03-09 19:49:35 -07:00
2014-02-13 18:52:17 -08:00
it("includes FIRST(A's right hand side) when A is a non-terminal", [&]() {
auto rule = choice({
seq({
i_token(0),
i_token(1) }),
i_sym(0) });
2014-04-25 22:17:23 -07:00
SyntaxGrammar grammar({
{ "rule0", seq({
i_token(2),
i_token(3),
i_token(4) }) }
}, {}, {});
2014-04-25 22:17:23 -07:00
AssertThat(first_set(rule, grammar), Equals(set<Symbol>({
Symbol(0, SymbolOptionToken),
Symbol(2, SymbolOptionToken),
2014-02-13 18:52:17 -08:00
})));
});
2014-03-09 19:49:35 -07:00
2014-02-13 18:52:17 -08:00
it("includes FIRST(B) when A is a non-terminal and its expansion can be blank", [&]() {
auto rule = seq({
i_sym(0),
i_token(1) });
2014-04-25 22:17:23 -07:00
SyntaxGrammar grammar({
{ "rule0", choice({
i_token(0),
blank() }) }
}, {}, {});
2014-03-09 19:49:35 -07:00
AssertThat(first_set(rule, grammar), Equals(set<Symbol>({
Symbol(0, SymbolOptionToken),
Symbol(1, SymbolOptionToken),
})));
});
});
2014-03-28 13:51:32 -07:00
describe("when there are left-recursive rules", [&]() {
it("terminates", [&]() {
SyntaxGrammar grammar({
{ "rule0", choice({
seq({ i_sym(0), i_token(10) }),
i_token(11),
}) },
}, {}, {});
2014-04-25 22:17:23 -07:00
auto rule = i_sym(0);
2014-03-28 13:51:32 -07:00
AssertThat(first_set(rule, grammar), Equals(set<Symbol>({
Symbol(11, SymbolOptionToken)
})));
});
});
2014-04-04 13:10:55 -07:00
it("ignores metadata rules", [&]() {
auto rule = make_shared<Metadata>(i_token(3), map<rules::MetadataKey, int>());
2014-04-04 13:10:55 -07:00
AssertThat(first_set(rule, null_grammar), Equals(set<Symbol>({
Symbol(3, SymbolOptionToken),
})));
});
});
END_TEST