From bfba9c855b45fce27846bcdcc9950bb98159559e Mon Sep 17 00:00:00 2001 From: Franck Dary <franck.dary@lis-lab.fr> Date: Thu, 9 Jan 2020 15:26:00 +0100 Subject: [PATCH] Finished Strategy --- reading_machine/include/Config.hpp | 1 + reading_machine/include/Strategy.hpp | 11 ++++ reading_machine/src/Config.cpp | 8 +++ reading_machine/src/Strategy.cpp | 83 +++++++++++++++++++++++++--- 4 files changed, 96 insertions(+), 7 deletions(-) diff --git a/reading_machine/include/Config.hpp b/reading_machine/include/Config.hpp index 464286f..697418c 100644 --- a/reading_machine/include/Config.hpp +++ b/reading_machine/include/Config.hpp @@ -93,6 +93,7 @@ class Config bool hasStack(int relativeIndex) const; String getState() const; void setState(const std::string state); + bool stateIsDone() const; }; diff --git a/reading_machine/include/Strategy.hpp b/reading_machine/include/Strategy.hpp index 60dbfa9..e1bc580 100644 --- a/reading_machine/include/Strategy.hpp +++ b/reading_machine/include/Strategy.hpp @@ -5,6 +5,10 @@ class Strategy { + public : + + static inline std::pair<std::string, int> endMovement{"", 0}; + private : enum Type @@ -15,6 +19,13 @@ class Strategy Type type; std::map<std::pair<std::string, std::string>, std::string> edges; + std::map<std::string, bool> isDone; + std::vector<std::string> defaultCycle; + + private : + + std::pair<std::string, int> getMovementSequential(const Config & c, const std::string & transition); + std::pair<std::string, int> getMovementIncremental(const Config & c, const std::string & transition); public : diff --git a/reading_machine/src/Config.cpp b/reading_machine/src/Config.cpp index 919ab25..a8d8134 100644 --- a/reading_machine/src/Config.cpp +++ b/reading_machine/src/Config.cpp @@ -340,3 +340,11 @@ void Config::setState(const std::string state) this->state = state; } +bool Config::stateIsDone() const +{ + if (!rawInput.empty()) + return rawInputOnlySeparatorsLeft(); + + return !has(0, wordIndex+1, 0); +} + diff --git a/reading_machine/src/Strategy.cpp b/reading_machine/src/Strategy.cpp index 2d5e9ae..afb1e3f 100644 --- a/reading_machine/src/Strategy.cpp +++ b/reading_machine/src/Strategy.cpp @@ -9,28 +9,97 @@ Strategy::Strategy(const std::vector<std::string_view> & lines) for (unsigned int i = 1; i < lines.size(); i++) { auto splited = util::split(lines[i], ' '); + std::pair<std::string, std::string> key; + std::string value; + if (splited.size() == 2) - edges[std::pair<std::string,std::string>(splited[0], "")] = splited[1]; + { + key = std::pair<std::string,std::string>(splited[0], ""); + value = splited[1]; + defaultCycle.emplace_back(value); + } else if (splited.size() == 3) - edges[std::pair<std::string,std::string>(splited[0], splited[1])] = splited[2]; + { + key = std::pair<std::string,std::string>(splited[0], splited[1]); + value = splited[1]; + } else util::myThrow(fmt::format("Invalid strategy line '{}'", lines[i])); + + if (edges.count(key)) + util::myThrow(fmt::format("Edge {} {} defined twice", key.first, key.second)); + edges[key] = value; + isDone[key.first] = false; } + + if (edges.empty()) + util::myThrow("Strategy is empty"); + defaultCycle.pop_back(); + std::reverse(defaultCycle.begin(), defaultCycle.end()); + + for (auto & s : defaultCycle) + fmt::print("{}\n", s); } std::pair<std::string, int> Strategy::getMovement(const Config & c, const std::string & transition) +{ + if (c.stateIsDone()) + isDone[c.getState()] = true; + + while (defaultCycle.size() && isDone[defaultCycle.back()]) + defaultCycle.pop_back(); + + if (type == Type::Sequential) + return getMovementSequential(c, transition); + + return getMovementIncremental(c, transition); +} + +std::pair<std::string, int> Strategy::getMovementSequential(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(), "")); + + std::string target; + + if (foundSpecific != edges.end()) + target = foundSpecific->second; + else if (foundGeneric != edges.end()) + target = foundGeneric->second; + + if (target.empty()) + util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition)); + + if (!c.stateIsDone()) + return {c.getState(), (c.getState() == target) && edges.size() > 1 ? 0 : 1}; + + if (!isDone[target]) + return {target, -c.getWordIndex()}; + + return endMovement; +} + +std::pair<std::string, int> Strategy::getMovementIncremental(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(), "")); + std::string target; + if (foundSpecific != edges.end()) - return {foundSpecific->second, 1}; + target = foundSpecific->second; + else if (foundGeneric != edges.end()) + target = foundGeneric->second; + + if (target.empty()) + util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition)); - if (foundGeneric != edges.end()) - return {foundGeneric->second, 1}; + if (!isDone[target]) + return {target, target == defaultCycle.back() ? 1 : 0}; - util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition)); + if (defaultCycle.empty()) + return endMovement; - return {"", 0}; + return {defaultCycle.back(), 1}; } -- GitLab