tree-sitter/test/compiler/prepare_grammar/intern_symbols_test.cc
Max Brunsfeld 6e72c2943d Avoid missing field initializer warnings w/o default field syntax
The default field syntax aint working on windows
2018-06-14 11:12:04 -07:00

91 lines
2.7 KiB
C++

#include "test_helper.h"
#include "compiler/prepare_grammar/intern_symbols.h"
#include "compiler/grammar.h"
#include "compiler/rule.h"
#include "helpers/stream_methods.h"
START_TEST
using namespace rules;
using prepare_grammar::intern_symbols;
describe("intern_symbols", []() {
it("replaces named symbols with numerically-indexed symbols", [&]() {
InputGrammar grammar;
grammar.variables = {
{"x", VariableTypeNamed, Rule::choice({ NamedSymbol{"y"}, NamedSymbol{"_z"} })},
{"y", VariableTypeNamed, NamedSymbol{"_z"}},
{"_z", VariableTypeNamed, String{"stuff"}}
};
auto result = intern_symbols(grammar);
AssertThat(result.second, Equals(CompileError::none()));
AssertThat(result.first.variables, Equals(vector<Variable>{
{"x", VariableTypeNamed, Rule::choice({ Symbol::non_terminal(1), Symbol::non_terminal(2) })},
{"y", VariableTypeNamed, Symbol::non_terminal(2)},
{"_z", VariableTypeHidden, String{"stuff"}},
}));
});
describe("when there are symbols that reference undefined rules", [&]() {
it("returns an error", []() {
InputGrammar grammar;
grammar.variables = {
{"x", VariableTypeNamed, NamedSymbol{"y"}},
};
auto result = intern_symbols(grammar);
AssertThat(result.second.message, Equals("Undefined rule 'y'"));
});
});
it("translates the grammar's optional 'extra_tokens' to numerical symbols", [&]() {
InputGrammar grammar;
grammar.variables = {
{"x", VariableTypeNamed, Rule::choice({ NamedSymbol{"y"}, NamedSymbol{"z"} })},
{"y", VariableTypeNamed, NamedSymbol{"z"}},
{"z", VariableTypeNamed, String{"stuff"}}
};
grammar.extra_tokens = {
NamedSymbol{"z"}
};
auto result = intern_symbols(grammar);
AssertThat(result.second, Equals(CompileError::none()));
AssertThat(result.first.extra_tokens.size(), Equals<size_t>(1));
AssertThat(result.first.extra_tokens, Equals(vector<Rule>({ Symbol::non_terminal(2) })));
});
it("records any rule names that match external token names", [&]() {
InputGrammar grammar;
grammar.variables = {
{"x", VariableTypeNamed, Rule::choice({ NamedSymbol{"y"}, NamedSymbol{"z"} })},
{"y", VariableTypeNamed, NamedSymbol{"z"}},
{"z", VariableTypeNamed, String{"stuff"}},
};
grammar.external_tokens = {
NamedSymbol{"w"},
NamedSymbol{"z"},
};
auto result = intern_symbols(grammar);
AssertThat(result.first.external_tokens, Equals(vector<Variable>{
Variable{
"w",
VariableTypeNamed,
Symbol::external(0),
},
Variable{
"z",
VariableTypeNamed,
Symbol::non_terminal(2),
},
}))
});
});
END_TEST