From 9c09bc6c4a1dab425d5a355a42058a9bb63123f1 Mon Sep 17 00:00:00 2001 From: Franck Dary <franck.dary@lis-lab.fr> Date: Wed, 8 Jan 2020 15:00:51 +0100 Subject: [PATCH] Defined the Strategy class --- common/include/util.hpp | 2 +- common/src/util.cpp | 6 ++-- reading_machine/include/ReadingMachine.hpp | 3 +- reading_machine/include/Strategy.hpp | 19 ++++++++++++ reading_machine/src/ReadingMachine.cpp | 34 +++++++++++---------- reading_machine/src/Strategy.cpp | 35 +++++++++++++++++++++- 6 files changed, 79 insertions(+), 20 deletions(-) diff --git a/common/include/util.hpp b/common/include/util.hpp index 4afb1c6..2d00f79 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 d6362cc..1542c89 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 339e25a..dc4be73 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 bd42d4f..60dbfa9 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 9528bb8..cc484eb 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 4beb7af..2d5e9ae 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}; +} -- GitLab