diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f66065b..9ef8861 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,6 +22,7 @@ add_executable(Parsodus-test lr0_shift-red.cpp lr1_only.cpp + lr0_only.cpp ) target_link_libraries(Parsodus-test # Parsodus-backends diff --git a/tests/lr0_only.cpp b/tests/lr0_only.cpp new file mode 100644 index 0000000..cb80991 --- /dev/null +++ b/tests/lr0_only.cpp @@ -0,0 +1,120 @@ +/* + * Parsodus - A language agnostic parser generator + * Copyright © 2016-2017 Thomas Avé, Robin Jadoul, Kobe Wullaert + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "Parsodus/lrtables/generator.h" +#include "Parsodus/lrtables/LR0Itemset.h" +#include "Parsodus/util/symbols.h" +#include "gtest/gtest.h" + +#include + +TEST(lr0, only) { + using namespace pds; + using namespace pds::lr; + + Grammar grammar; + grammar.start = "s"; + grammar.variables = {"s","l",}; + grammar.terminals = {"X", "LBRACE", "RBRACE", "COMMA"}; + + for (const std::pair>& p : std::vector>>({ + {"s", {"LBRACE", "l", "RBRACE"}}, + {"s", {"X"}}, + {"l", {"s"}}, + {"l", {"l", "COMMA" ,"s"}}, + })) { + + grammar.rules.emplace_back(std::make_shared(p.first, p.second)); + } + + { + Generator g(grammar); + LRTable table; + ASSERT_NO_THROW(table = g.generate()); + std::vector>> act = { + { + {"LBRACE", {Action::SHIFT, 1}}, + {"X", {Action::SHIFT, 2}} + }, { + {"LBRACE", {Action::SHIFT, 1}}, + {"X", {Action::SHIFT, 2}}, + + }, { + {util::EOF_PLACEHOLDER, {Action::REDUCE, 1}}, + {"COMMA", {Action::REDUCE, 1}}, + {"LBRACE", {Action::REDUCE, 1}}, + {"RBRACE", {Action::REDUCE, 1}}, + {"X", {Action::REDUCE, 1}} + }, { + {util::EOF_PLACEHOLDER, {Action::ACCEPT, 0}} + }, { + {"COMMA", {Action::SHIFT, 6}}, + {"RBRACE", {Action::SHIFT, 7}} + }, { + {util::EOF_PLACEHOLDER, {Action::REDUCE, 2}}, + {"COMMA", {Action::REDUCE, 2}}, + {"LBRACE", {Action::REDUCE, 2}}, + {"RBRACE", {Action::REDUCE, 2}}, + {"X", {Action::REDUCE, 2}}, + }, { + {"LBRACE", {Action::SHIFT, 1}}, + {"X", {Action::SHIFT, 2}} + }, { + {util::EOF_PLACEHOLDER, {Action::REDUCE, 0}}, + {"COMMA", {Action::REDUCE, 0}}, + {"LBRACE", {Action::REDUCE, 0}}, + {"RBRACE", {Action::REDUCE, 0}}, + {"X", {Action::REDUCE, 0}} + }, { + {util::EOF_PLACEHOLDER, {Action::REDUCE, 3}}, + {"COMMA", {Action::REDUCE, 3}}, + {"LBRACE", {Action::REDUCE, 3}}, + {"RBRACE", {Action::REDUCE, 3}}, + {"X", {Action::REDUCE, 3}} + }}; + ASSERT_EQ(act.size(), table.act.size()); + for (std::size_t i = 0; i < act.size(); i++) { + EXPECT_EQ(act[i], table.act[i]); + } + + std::vector> got = { + { {"s", 3}}, + {{"l", 4}, {"s", 5}}, + {}, + {}, + {}, + {}, + {{"s", 8}}, + {}, + {} + }; + ASSERT_EQ(got.size(), table.goto_.size()); + for (std::size_t i = 0; i < got.size(); i++) { + EXPECT_EQ(got[i], table.goto_[i]); + } + } + +} + + +