diff --git a/common/include/util.hpp b/common/include/util.hpp index 4afb1c679d44166ef22f9e3398123253c9faaebd..2d00f799e4777cc2898c66f06774afa08cc47b00 100644 --- a/common/include/util.hpp +++ b/common/include/util.hpp @@ -77,7 +77,7 @@ bool isEmpty(const boost::flyweight<T> & s) return isEmpty(s.get()); } -bool doIfNameMatch(const std::regex & reg, const std::string & name, const std::function<void(const std::smatch &)> & f); +bool doIfNameMatch(const std::regex & reg, std::string_view name, const std::function<void(const std::smatch &)> & f); }; diff --git a/common/src/util.cpp b/common/src/util.cpp index d6362cc6441c4614efde9b0d39796fed11faa79b..1542c89046a8cea68ae122753f98f87fe3eda2e8 100644 --- a/common/src/util.cpp +++ b/common/src/util.cpp @@ -111,10 +111,12 @@ std::string util::int2HumanStr(int number) return result; } -bool util::doIfNameMatch(const std::regex & reg, const std::string & name, const std::function<void(const std::smatch &)> & f) +bool util::doIfNameMatch(const std::regex & reg, std::string_view name, const std::function<void(const std::smatch &)> & f) { std::smatch sm; - std::regex_match(name, sm, reg); + std::string sname(name); + std::regex_match(sname, sm, reg); + if (sm.empty()) return false; diff --git a/reading_machine/include/ReadingMachine.hpp b/reading_machine/include/ReadingMachine.hpp index 339e25a95f888bbf6fb3c93d312a6997c485bac7..dc4be73e0b6710f6606a7ed406acc7d5a7c90aab 100644 --- a/reading_machine/include/ReadingMachine.hpp +++ b/reading_machine/include/ReadingMachine.hpp @@ -3,14 +3,15 @@ #include <memory> #include "Classifier.hpp" +#include "Strategy.hpp" class ReadingMachine { private : std::string name; - std::function<std::pair<std::string, int>(const Config & config)> strategy; std::unique_ptr<Classifier> classifier; + std::unique_ptr<Strategy> strategy; public : diff --git a/reading_machine/include/Strategy.hpp b/reading_machine/include/Strategy.hpp index bd42d4f20149202a3d05550c9a6bde02f78acf5a..60dbfa90d424d42dd866c33f02a7a40435826d75 100644 --- a/reading_machine/include/Strategy.hpp +++ b/reading_machine/include/Strategy.hpp @@ -3,4 +3,23 @@ #include "Config.hpp" +class Strategy +{ + private : + + enum Type + { + Incremental, + Sequential + }; + + Type type; + std::map<std::pair<std::string, std::string>, std::string> edges; + + public : + + Strategy(const std::vector<std::string_view> & lines); + std::pair<std::string, int> getMovement(const Config & c, const std::string & transition); +}; + #endif diff --git a/reading_machine/src/ReadingMachine.cpp b/reading_machine/src/ReadingMachine.cpp index 9528bb8bd5e89a8ac449989df98bdf7d587746f4..cc484eb3c84459b7748985b24cb2b6e609a90a4c 100644 --- a/reading_machine/src/ReadingMachine.cpp +++ b/reading_machine/src/ReadingMachine.cpp @@ -1,32 +1,36 @@ #include "ReadingMachine.hpp" #include "util.hpp" -#include "Strategy.hpp" ReadingMachine::ReadingMachine(const std::string & filename) { - std::regex nameRegex("Name : (.+)[\n]"); - std::regex strategyRegex("Strategy : (.+)[\n]"); - std::regex classifierRegex("Classifier : (.+) (.+) (.+)[\n]"); - std::FILE * file = std::fopen(filename.c_str(), "r"); char buffer[1024]; + std::string fileContent; while (!std::feof(file)) { if (buffer != std::fgets(buffer, 1024, file)) break; - try - { - if (util::doIfNameMatch(nameRegex, buffer, [this](auto sm){name = sm[1];})) - continue; - if (util::doIfNameMatch(strategyRegex, buffer, [this](auto sm){})) - continue; - if (util::doIfNameMatch(classifierRegex, buffer, [this](auto sm){classifier.reset(new Classifier(sm[1], sm[2], sm[3]));})) - continue; - } catch(std::exception & e) {util::myThrow(fmt::format("during reading of '{}' : {}", filename, e.what()));} + fileContent += buffer; } - std::fclose(file); + + auto lines = util::split(fileContent, '\n'); + + try + { + unsigned int curLine = 0; + if (!util::doIfNameMatch(std::regex("Name : (.+)"), lines[curLine++], [this](auto sm){name = sm[1];})) + util::myThrow("No name specified"); + + while (util::doIfNameMatch(std::regex("Classifier : (.+) (.+) (.+)"), lines[curLine++], [this](auto sm){classifier.reset(new Classifier(sm[1], sm[2], sm[3]));})); + if (!classifier.get()) + util::myThrow("No Classifier specified"); + + std::vector<std::string_view> restOfFile(lines.begin()+curLine-1, lines.end()); + strategy.reset(new Strategy(restOfFile)); + + } catch(std::exception & e) {util::myThrow(fmt::format("during reading of '{}' : {}", filename, e.what()));} } diff --git a/reading_machine/src/Strategy.cpp b/reading_machine/src/Strategy.cpp index 4beb7af4ea29f9e99adf41b18cf6344d65bd5fb0..2d5e9ae9af696cfc936dbcb5c19d46ed5961c213 100644 --- a/reading_machine/src/Strategy.cpp +++ b/reading_machine/src/Strategy.cpp @@ -1,3 +1,36 @@ #include "Strategy.hpp" -#include "util.hpp" + +Strategy::Strategy(const std::vector<std::string_view> & lines) +{ + if (!util::doIfNameMatch(std::regex("Strategy : ((incremental)|(sequential))"), lines[0], [this](auto sm) + {type = sm[1] == "sequential" ? Type::Sequential : Type::Incremental;})) + util::myThrow(fmt::format("Invalid strategy identifier '{}'", lines[0])); + + for (unsigned int i = 1; i < lines.size(); i++) + { + auto splited = util::split(lines[i], ' '); + if (splited.size() == 2) + edges[std::pair<std::string,std::string>(splited[0], "")] = splited[1]; + else if (splited.size() == 3) + edges[std::pair<std::string,std::string>(splited[0], splited[1])] = splited[2]; + else + util::myThrow(fmt::format("Invalid strategy line '{}'", lines[i])); + } +} + +std::pair<std::string, int> Strategy::getMovement(const Config & c, const std::string & transition) +{ + auto foundSpecific = edges.find(std::make_pair(c.getState(), transition)); + auto foundGeneric = edges.find(std::make_pair(c.getState(), "")); + + if (foundSpecific != edges.end()) + return {foundSpecific->second, 1}; + + if (foundGeneric != edges.end()) + return {foundGeneric->second, 1}; + + util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition)); + + return {"", 0}; +}