Select Git revision
comp_gabdual_long.pyx
TransitionMachine.cpp 4.40 KiB
#include "TransitionMachine.hpp"
#include "File.hpp"
#include "util.hpp"
#include <cstring>
TransitionMachine::TransitionMachine(bool trainMode)
{
std::string filename = ProgramParameters::tmFilename;
auto badFormatAndAbort = [&filename](const std::string & errInfo)
{
fprintf(stderr, "ERROR (%s) : file %s bad format. Aborting.\n", errInfo.c_str(), filename.c_str());
exit(1);
};
this->trainMode = trainMode;
File file(filename, "r");
FILE * fd = file.getDescriptor();
char buffer[1024];
char buffer2[1024];
char buffer3[1024];
// Reading the name
if(fscanf(fd, "Name : %[^\n]\n", buffer) != 1)
badFormatAndAbort(ERRINFO);
name = buffer;
// Reading dicts
if(fscanf(fd, "Dicts : %[^\n]\n", buffer) != 1)
badFormatAndAbort(ERRINFO);
if (ProgramParameters::dicts.empty())
ProgramParameters::dicts = ProgramParameters::expPath + buffer;
Dict::readDicts(ProgramParameters::expPath, ProgramParameters::dicts, trainMode);
// Reading %CLASSIFIERS
if(fscanf(fd, "%%%s\n", buffer) != 1 || buffer != std::string("CLASSIFIERS"))
badFormatAndAbort(ERRINFO);
while(fscanf(fd, "%%%s\n", buffer) != 1)
{
// Reading a classifier
if(fscanf(fd, "%s %s\n", buffer, buffer2) != 2)
badFormatAndAbort(ERRINFO);
str2classifier.emplace(buffer, std::unique_ptr<Classifier>(new Classifier(buffer2, trainMode)));
classifiers.emplace_back(str2classifier[buffer].get());
}
// Reading %STATES
if(buffer != std::string("STATES"))
badFormatAndAbort(ERRINFO);
currentState = nullptr;
initialState = nullptr;
while(fscanf(fd, "%%%s\n", buffer) != 1)
{
// Reading a state
if(fscanf(fd, "%s %s\n", buffer, buffer2) != 2)
badFormatAndAbort(ERRINFO);
if(str2classifier.count(buffer2) == 0)
badFormatAndAbort(ERRINFO + std::string(" unknown classifier \'") + buffer2 + std::string("\'"));
Classifier * classifier = str2classifier[buffer2].get();
str2state.emplace(buffer, std::unique_ptr<State>(new State(buffer, classifier)));
if(!currentState) // Initial state = first state in the file
{
currentState = str2state[buffer].get();
initialState = currentState;
}
}
// Reading %TRANSITIONS
if(buffer != std::string("TRANSITIONS"))
badFormatAndAbort(ERRINFO);
// Reading all transitions
int mvt;
while(fscanf(fd, "%s %s %d %[^\n]\n", buffer, buffer2, &mvt, buffer3) == 4)
{
std::string src(buffer);
std::string dest(buffer2);
std::string prefix(buffer3);
if(str2state.count(src) == 0)
badFormatAndAbort(ERRINFO + std::string(" unknown state \'") + src + std::string("\'"));
if(str2state.count(dest) == 0)
badFormatAndAbort(ERRINFO + std::string(" unknown state \'") + dest + std::string("\'"));
State * srcState = str2state[src].get();
State * destState = str2state[dest].get();
srcState->transitions.emplace_back(destState, prefix, mvt);
}
}
TransitionMachine::State::State(const std::string & name, Classifier * classifier)
{
this->name = name;
this->classifier = classifier;
}
TransitionMachine::Transition::Transition(State * dest, const std::string & prefix, int mvt)
{
this->dest = dest;
this->actionPrefix = prefix;
this->headMvt = mvt;
}
TransitionMachine::State * TransitionMachine::getCurrentState()
{
return currentState;
}
TransitionMachine::Transition * TransitionMachine::getTransition(const std::string & action)
{
int longestPrefix = -1;
for (unsigned int i = 0; i < currentState->transitions.size(); i++)
{
auto & transition = currentState->transitions[i];
unsigned int currentMaxLength = longestPrefix >= 0 ? currentState->transitions[longestPrefix].actionPrefix.size() : 0;
if(transition.actionPrefix == "*" || !strncmp(action.c_str(), transition.actionPrefix.c_str(), transition.actionPrefix.size()))
if (transition.actionPrefix.size() > currentMaxLength)
longestPrefix = i;
}
if (longestPrefix != -1)
return ¤tState->transitions[longestPrefix];
fprintf(stderr, "ERROR (%s) : no corresponding transition for action \'%s\' and state \'%s\'. Aborting.\n", ERRINFO, action.c_str(), currentState->name.c_str());
exit(1);
return nullptr;
}
void TransitionMachine::takeTransition(Transition * transition)
{
currentState = transition->dest;
}
std::vector<Classifier*> & TransitionMachine::getClassifiers()
{
return classifiers;
}
void TransitionMachine::reset()
{
currentState = initialState;
}