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