#include "bnf.h" #include "cpp.h" #include "lexer.h" #include "grammer.h" #include "minicc.h" #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include #include #include #include #include #include #include #include class Test: public ::testing::Test { protected: Test(){} ~Test() override {} }; TEST_F(Test, BNF) { std::string LexTop{"preprocessing-token"}; BNF LexBNF{ {"preprocessing-token", {{"identifier"}, {"preprocessing-op-or-punc"}, {"pp-number"}}}, {"identifier", {{"identifier-nondigit"}, {"identifier", "identifier-nondigit"}, {"identifier", "digit"}}}, {"digit", {{"0"}, {"1"}, {"2"}, {"3"}, {"4"}, {"5"}, {"6"}, {"7"}, {"8"}, {"9"} }}, {"identifier-nondigit", {{"a"}, {"b"}, {"c"}, {"d"}, {"e"}, {"f"}, {"g"}, {"h"}, {"i"}, {"j"}, {"k"}, {"l"}, {"m"}, {"n"}, {"o"}, {"p"}, {"q"}, {"r"}, {"s"}, {"t"}, {"u"}, {"v"}, {"w"}, {"x"}, {"y"}, {"z"}, {"A"}, {"B"}, {"C"}, {"D"}, {"E"}, {"F"}, {"G"}, {"H"}, {"I"}, {"J"}, {"K"}, {"L"}, {"M"}, {"N"}, {"O"}, {"P"}, {"Q"}, {"R"}, {"S"}, {"T"}, {"U"}, {"V"}, {"W"}, {"X"}, {"Y"}, {"Z"}, {"_"}}}, {"preprocessing-op-or-punc", {{";"}, {"="}}}, {"pp-number", {{"digit"}, {"pp-number", "digit"}}} }; std::string Top{"program"}; BNF bnf{ {"program", {{"statement-list"}}}, {"statement-list", { {"statement"}, {"statement-list", "statement"}, }}, {"statement", {{"assignment", ";"}}}, {"assignment", {{"identifier", "=", "identifier"}, {"identifier", "=", "pp-number"}}} }; // implicit? //std::set Terminals{"identifier", "=", ";"}; std::string Code{"a = bc ; c = 123 ; esd = Ff ; 1 = XYZ ;"}; std::vector tokens_reference{ {"identifier", "a", { 1, 1} }, {"preprocessing-op-or-punc", "=", { 1, 3}}, {"identifier", "bc", { 1, 5}}, {"preprocessing-op-or-punc", ";", { 1, 8}}, {"identifier", "c", { 1, 10}}, {"preprocessing-op-or-punc", "=", { 1, 12}}, {"pp-number", "123", { 1, 14}}, {"preprocessing-op-or-punc", ";", { 1, 18}}, {"identifier", "esd", { 1, 20}}, {"preprocessing-op-or-punc", "=", { 1, 24}}, {"identifier", "Ff", { 1, 26}}, {"preprocessing-op-or-punc", ";", { 1, 29}}, {"pp-number", "1", { 1, 31}}, {"preprocessing-op-or-punc", "=", { 1, 33}}, {"identifier", "XYZ", { 1, 35}}, {"preprocessing-op-or-punc", ";", { 1, 38}}, }; Lex::Lexer lexer(LexBNF, LexTop); auto tokens = lexer.Lex(Code); ASSERT_EQ(tokens, tokens_reference); #if 1 std::cout << "=== Tokens =================================" << std::endl; for (const auto& i: tokens) { std::cout << i.type << ": " << i.value << std::endl; } #endif CPP::PreprocessorTokensToTokens(tokens); Gram::Compiler compiler(bnf, Top); auto Tree = compiler.compile(tokens); compiler.DumpTree(); } int main(int argc, char* argv[]) { ::testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); }