/* * 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 #include #include #include #include #include "Parsodus/grammar.h" #include "Parsodus/lrtables/generator.h" #include "Parsodus/lrtables/SLR1Itemset.h" #include "gtest/gtest.h" #define ACCEPT_STATE 0 #define ERROR_STATE 0 TEST(lr0, test0) { pds::Grammar grammar; grammar.start = "S"; grammar.variables = {"S","A","E"}; grammar.terminals = {";", "id", ":=", "+"}; std::shared_ptr rule(new pds::Rule()); rule->head = "S"; rule->tail = {"S",";","A"}; grammar.rules.push_back(std::make_shared(*rule)); rule->head = "S"; rule->tail = {"A"}; grammar.rules.push_back(std::make_shared(*rule)); rule->head = "A"; rule->tail = {"E"}; grammar.rules.push_back(std::make_shared(*rule)); rule->head = "A"; rule->tail = {"id",":=","E"}; grammar.rules.push_back(std::make_shared(*rule)); rule->head = "E"; rule->tail = {"E","+","id"}; grammar.rules.push_back(std::make_shared(*rule)); rule->head = "E"; rule->tail = {"id"}; grammar.rules.push_back(std::make_shared(*rule)); { pds::lr::Generator g(grammar); ASSERT_NO_THROW(g.generate()); } // auto tbl = g.generate(); // LRTable // EXPECT_THROW(throw "shift-reduce", std::exception); /* std::vector >> act { { {"id", std::make_pair(pds::lr::Action::SHIFT,4) } }, { {";", std::make_pair(pds::lr::Action::SHIFT,5) }, {"$", std::make_pair(pds::lr::Action::SHIFT, ACCEPT_STATE)} }, { {"id", std::make_pair(pds::lr::Action::REDUCE,3) }, {";", std::make_pair(pds::lr::Action::REDUCE,3) }, {"+", std::make_pair(pds::lr::Action::REDUCE,3) }, {":=", std::make_pair(pds::lr::Action::REDUCE,3) }, {"$", std::make_pair(pds::lr::Action::REDUCE, 3)} }, { {"id", std::make_pair(pds::lr::Action::REDUCE,4) }, {";", std::make_pair(pds::lr::Action::REDUCE,4) }, {"+", std::make_pair(pds::lr::Action::ERROR, ERROR_STATE) }, {":=", std::make_pair(pds::lr::Action::REDUCE,4) }, {"$", std::make_pair(pds::lr::Action::REDUCE,4)} }, { {"id", std::make_pair(pds::lr::Action::REDUCE,7) }, {";", std::make_pair(pds::lr::Action::REDUCE,7) }, {"+", std::make_pair(pds::lr::Action::REDUCE,7) }, {":=", std::make_pair(pds::lr::Action::ERROR, ERROR_STATE) }, {"$", std::make_pair(pds::lr::Action::REDUCE, 7)} }, { {"id", std::make_pair(pds::lr::Action::SHIFT,4) } }, { {"id", std::make_pair(pds::lr::Action::SHIFT,9) } }, { {"id", std::make_pair(pds::lr::Action::SHIFT, 11) } }, { {"id", std::make_pair(pds::lr::Action::REDUCE,2) }, {";", std::make_pair(pds::lr::Action::REDUCE,2) }, {"+", std::make_pair(pds::lr::Action::REDUCE,2) }, {":=", std::make_pair(pds::lr::Action::REDUCE,2) }, {"$", std::make_pair(pds::lr::Action::REDUCE, 2)} }, { {"id", std::make_pair(pds::lr::Action::REDUCE,6) }, {";", std::make_pair(pds::lr::Action::REDUCE,6) }, {"+", std::make_pair(pds::lr::Action::REDUCE,6) }, {":=", std::make_pair(pds::lr::Action::REDUCE,6) }, {"$", std::make_pair(pds::lr::Action::REDUCE, 6)} }, { {"id", std::make_pair(pds::lr::Action::REDUCE,5) }, {";", std::make_pair(pds::lr::Action::REDUCE,5) }, {"+", std::make_pair(pds::lr::Action::ERROR, ERROR_STATE) }, {":=", std::make_pair(pds::lr::Action::REDUCE,5) }, {"$", std::make_pair(pds::lr::Action::REDUCE,5)} }, { {"id", std::make_pair(pds::lr::Action::REDUCE,7) }, {";", std::make_pair(pds::lr::Action::REDUCE,7) }, {"+", std::make_pair(pds::lr::Action::REDUCE, 7) }, {":=", std::make_pair(pds::lr::Action::REDUCE,7) }, {"$", std::make_pair(pds::lr::Action::REDUCE,7)} }, }; std::vector> goto_ = { { {"S",1}, {"A",2}, {"E",3} }, // state_num:1 { {"A",8}, {"E",3} }, // state_num:5 { {"E",10} }, // state_num:7 }; // Action: enum {ERROR,SHIFT,REDUCE,ACCEPT} ASSERT_EQ(goto_.size(),tbl.goto_.size()); ASSERT_EQ(act.size(),tbl.act.size()); for(std::size_t i = 0; i < goto_.size(); i++) { EXPECT_EQ(goto_[i].first,tbl.goto_[i].first); EXPECT_EQ(goto_[i].second.first,tbl.goto_[i].second.first); EXPECT_EQ(goto_[i].second.second,tbl.goto_[i].second.second); } for(std::size_t i = 0; i < act.size(); i++) { EXPECT_EQ(act[i].first,tbl.act[i].first); EXPECT_EQ(act[i].second.first,tbl.act[i].second.first); EXPECT_EQ(act[i].second.second,tbl.act[i].second.second); } */ }