#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_THROW(g.generate(), std::runtime_error); try { g.generate(); } catch (std::runtime_error& e) { ASSERT_EQ(std::string("shift-reduce"), e.what()); } } { 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); } */ }