From f3d374794b54b51894bd8687e6e8300c3e1f5027 Mon Sep 17 00:00:00 2001 From: Franck Dary <franck.dary@lis-lab.fr> Date: Mon, 23 Sep 2019 11:45:33 +0200 Subject: [PATCH] Fixed some bugs in parser oracle --- transition_machine/include/ActionSet.hpp | 6 +++ transition_machine/src/ActionSet.cpp | 48 +++++++++++++++++------- transition_machine/src/Classifier.cpp | 5 +-- transition_machine/src/Oracle.cpp | 32 ++++++++++++---- 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/transition_machine/include/ActionSet.hpp b/transition_machine/include/ActionSet.hpp index 17471a3..1d1c842 100644 --- a/transition_machine/include/ActionSet.hpp +++ b/transition_machine/include/ActionSet.hpp @@ -32,6 +32,8 @@ class ActionSet /// /// If it is the case, the default action is the first element of the vector actions.\n When getAction is called with an unknown name, the default action is returned.\n If an ActionSet is dynamic, it cannot have a default action. bool hasDefaultAction; + /// @brief Index of the default action, if it has one. + int defaultActionIndex; public : @@ -64,6 +66,10 @@ class ActionSet /// /// @return A pointer to the Action. Action * getAction(const std::string & name); + /// @brief Get a pointer to the default Action object. + /// + /// @return A pointer to the default Action. + Action * getDefaultAction(); /// @brief Get the number of actions contained in this set. /// /// @return The number of actions in this set. diff --git a/transition_machine/src/ActionSet.cpp b/transition_machine/src/ActionSet.cpp index 2a0b527..934562b 100644 --- a/transition_machine/src/ActionSet.cpp +++ b/transition_machine/src/ActionSet.cpp @@ -14,17 +14,31 @@ ActionSet::ActionSet(const std::string & filename, bool isDynamic) char buffer[1024]; - if(fscanf(fd, "Default : %[^\n]\n", buffer) == 1) + while (true) { - str2index[buffer] = actions.size(); - actions.emplace_back(buffer); - hasDefaultAction = true; - } - - while(fscanf(fd, "%[^\n]\n", buffer) == 1) - { - str2index[buffer] = actions.size(); - actions.emplace_back(buffer); + if (fscanf(fd, "Default : %[^\n]\n", buffer) == 1) + { + if (hasDefaultAction) + { + fprintf(stderr, "ERROR (%s) : \'%s\' has more than 1 default action. Aborting.\n", ERRINFO, filename.c_str()); + exit(1); + } + + str2index[buffer] = actions.size(); + actions.emplace_back(buffer); + hasDefaultAction = true; + defaultActionIndex = actions.size()-1; + continue; + } + + if (fscanf(fd, "%[^\n]\n", buffer) == 1) + { + str2index[buffer] = actions.size(); + actions.emplace_back(buffer); + continue; + } + + break; } this->name = getFilenameFromPath(filename); @@ -52,9 +66,6 @@ int ActionSet::getActionIndex(const std::string & name) if(!isDynamic) { - if(hasDefaultAction) - return 0; - fprintf(stderr, "ERROR (%s) : unknown action \'%s\'. Aborting.\n", ERRINFO, name.c_str()); printForDebug(stderr); @@ -86,6 +97,17 @@ Action * ActionSet::getAction(const std::string & name) return &actions[getActionIndex(name)]; } +Action * ActionSet::getDefaultAction() +{ + if (!hasDefaultAction) + { + fprintf(stderr, "ERROR (%s) : requested default action in ActionSet \'%s\'. Aborting.\n", ERRINFO, name.c_str()); + exit(1); + } + + return &actions[defaultActionIndex]; +} + unsigned int ActionSet::size() { return actions.size(); diff --git a/transition_machine/src/Classifier.cpp b/transition_machine/src/Classifier.cpp index 337291a..f68f1cc 100644 --- a/transition_machine/src/Classifier.cpp +++ b/transition_machine/src/Classifier.cpp @@ -279,15 +279,14 @@ std::vector<std::string> Classifier::getZeroCostActions(Config & config) result.emplace_back(a.name); if (result.empty() && as->hasDefaultAction) - result.emplace_back(as->getActionName(0)); + result.emplace_back(as->getDefaultAction()->name); return result; } std::string Classifier::getDefaultAction() const { - if (as->hasDefaultAction) - return as->getActionName(0); + return as->getDefaultAction()->name; return std::string(); } diff --git a/transition_machine/src/Oracle.cpp b/transition_machine/src/Oracle.cpp index a20e397..8ba8eb2 100644 --- a/transition_machine/src/Oracle.cpp +++ b/transition_machine/src/Oracle.cpp @@ -584,6 +584,8 @@ void Oracle::createDatabase() }, [](Config & c, Oracle *, const std::string & action) { + bool hasId = c.hasTape("ID"); + auto & labels = c.getTape("LABEL"); auto & govs = c.getTape("GOV"); auto & eos = c.getTape(ProgramParameters::sequenceDelimiterTape); @@ -592,8 +594,10 @@ void Oracle::createDatabase() int stackHead = c.stackEmpty() ? 0 : c.stackTop(); int stackGov = 0; bool stackNoGov = false; - try {stackGov = stackHead + std::stoi(govs.getRef(stackHead-head));} - catch (std::exception &){stackNoGov = true;} + try + { + stackGov = stackHead + std::stoi(govs.getRef(stackHead-head)); + } catch (std::exception &){stackNoGov = true;} int headGov = 0; bool headNoGov = false; try {headGov = head + std::stoi(govs.getRef(0));} @@ -671,7 +675,7 @@ void Oracle::createDatabase() { if (stackNoGov) return 0; - if (stackGov == 0) + if (stackGov == stackHead) cost++; for (int i = head; i <= sentenceEnd; i++) @@ -683,14 +687,17 @@ void Oracle::createDatabase() cost++; } - return eos.getRef(stackHead-head) != ProgramParameters::sequenceDelimiter ? cost : cost+1; + if (eos.getRef(stackHead-head) != ProgramParameters::sequenceDelimiter) + return cost; + + return cost+1; } else if (parts[0] == "LEFT") { if (stackNoGov) return 0; - if (stackGov == 0) + if (stackGov == stackHead) cost++; if (eos.getRef(stackHead-head) == ProgramParameters::sequenceDelimiter) @@ -708,7 +715,13 @@ void Oracle::createDatabase() if (stackGov != head) cost++; - return parts.size() == 1 || labels.getRef(stackHead-head) == parts[1] ? cost : cost+1; + if (parts.size() == 1) + return cost; + + if (labels.getRef(stackHead-head) == parts[1]) + return cost; + + return cost+1; } else if (parts[0] == "RIGHT") { @@ -733,7 +746,12 @@ void Oracle::createDatabase() if (headGov == i) cost++; - return parts.size() == 1 || labels.getRef(0) == parts[1] ? cost : cost+1; + if (parts.size() == 1) + return cost; + if (labels.getRef(0) == parts[1]) + return cost; + + return cost+1; } else if (parts[0] == "EOS") { -- GitLab