tree-sitter/test/compiler/build_tables/parse_item_set_builder_test.cc

133 lines
3.8 KiB
C++
Raw Normal View History

#include "test_helper.h"
#include "compiler/syntax_grammar.h"
2016-11-14 10:25:26 -08:00
#include "compiler/lexical_grammar.h"
#include "compiler/build_tables/parse_item_set_builder.h"
#include "compiler/build_tables/lookahead_set.h"
using namespace build_tables;
using namespace rules;
START_TEST
describe("ParseItemSetBuilder", []() {
vector<LexicalVariable> lexical_variables;
2016-11-14 10:25:26 -08:00
for (size_t i = 0; i < 20; i++) {
lexical_variables.push_back({
2016-11-14 10:25:26 -08:00
"token_" + to_string(i),
VariableTypeNamed,
Blank{},
false
2016-11-14 10:25:26 -08:00
});
}
LexicalGrammar lexical_grammar{lexical_variables, {}};
it("adds items at the beginnings of referenced rules", [&]() {
SyntaxGrammar grammar{{
2017-03-01 22:15:26 -08:00
SyntaxVariable{"rule0", VariableTypeNamed, {
Production({
{Symbol::non_terminal(1), 0, AssociativityNone},
{Symbol::terminal(11), 0, AssociativityNone},
}),
2017-03-01 22:15:26 -08:00
}},
SyntaxVariable{"rule1", VariableTypeNamed, {
Production({
{Symbol::terminal(12), 0, AssociativityNone},
{Symbol::terminal(13), 0, AssociativityNone},
}),
Production({
{Symbol::non_terminal(2), 0, AssociativityNone},
})
2017-03-01 22:15:26 -08:00
}},
SyntaxVariable{"rule2", VariableTypeNamed, {
Production({
{Symbol::terminal(14), 0, AssociativityNone},
{Symbol::terminal(15), 0, AssociativityNone},
})
2017-03-01 22:15:26 -08:00
}},
}, {}, {}, {}};
2014-03-09 19:49:35 -07:00
auto production = [&](int variable_index, int production_index) -> const Production & {
return grammar.variables[variable_index].productions[production_index];
};
ParseItemSet item_set({
{
ParseItem(Symbol::non_terminal(0), production(0, 0), 0),
LookaheadSet({ Symbol::terminal(10) }),
}
});
2016-11-14 10:25:26 -08:00
ParseItemSetBuilder item_set_builder(grammar, lexical_grammar);
item_set_builder.apply_transitive_closure(&item_set);
2014-03-28 13:51:32 -07:00
2014-08-06 13:00:35 -07:00
AssertThat(item_set, Equals(ParseItemSet({
{
ParseItem(Symbol::non_terminal(0), production(0, 0), 0),
LookaheadSet({ Symbol::terminal(10) })
2016-11-30 09:34:47 -08:00
},
{
ParseItem(Symbol::non_terminal(1), production(1, 0), 0),
LookaheadSet({ Symbol::terminal(11) })
},
{
ParseItem(Symbol::non_terminal(1), production(1, 1), 0),
LookaheadSet({ Symbol::terminal(11) })
},
{
ParseItem(Symbol::non_terminal(2), production(2, 0), 0),
LookaheadSet({ Symbol::terminal(11) })
},
2014-08-06 13:00:35 -07:00
})));
});
it("handles rules with empty productions", [&]() {
SyntaxGrammar grammar{{
2017-03-01 22:15:26 -08:00
SyntaxVariable{"rule0", VariableTypeNamed, {
Production({
{Symbol::non_terminal(1), 0, AssociativityNone},
{Symbol::terminal(11), 0, AssociativityNone},
}),
2017-03-01 22:15:26 -08:00
}},
SyntaxVariable{"rule1", VariableTypeNamed, {
Production({
{Symbol::terminal(12), 0, AssociativityNone},
{Symbol::terminal(13), 0, AssociativityNone},
}),
Production({})
2017-03-01 22:15:26 -08:00
}},
}, {}, {}, {}};
auto production = [&](int variable_index, int production_index) -> const Production & {
return grammar.variables[variable_index].productions[production_index];
};
ParseItemSet item_set({
{
ParseItem(Symbol::non_terminal(0), production(0, 0), 0),
LookaheadSet({ Symbol::terminal(10) }),
}
});
2016-11-14 10:25:26 -08:00
ParseItemSetBuilder item_set_builder(grammar, lexical_grammar);
item_set_builder.apply_transitive_closure(&item_set);
AssertThat(item_set, Equals(ParseItemSet({
{
ParseItem(Symbol::non_terminal(0), production(0, 0), 0),
LookaheadSet({ Symbol::terminal(10) })
},
{
ParseItem(Symbol::non_terminal(1), production(1, 0), 0),
LookaheadSet({ Symbol::terminal(11) })
},
{
ParseItem(Symbol::non_terminal(1), production(1, 1), 0),
LookaheadSet({ Symbol::terminal(11) })
},
})));
});
});
2014-06-23 18:50:03 -07:00
END_TEST