diff --git a/common/include/util.hpp b/common/include/util.hpp
index 694316ccc90513adaa7cba8ee738ac088bc649b4..4afb1c679d44166ef22f9e3398123253c9faaebd 100644
--- a/common/include/util.hpp
+++ b/common/include/util.hpp
@@ -18,6 +18,7 @@
 #include <vector>
 #include <array>
 #include <unordered_map>
+#include <regex>
 #include <experimental/source_location>
 #include <boost/flyweight.hpp>
 #include "fmt/core.h"
@@ -76,6 +77,8 @@ 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);
+
 };
 
 template <>
diff --git a/common/src/util.cpp b/common/src/util.cpp
index 8214980eb1466ae9326c8047fbf934dcd67d2464..5c02379e7e1f64696d6bf77e0bc784733f610aa6 100644
--- a/common/src/util.cpp
+++ b/common/src/util.cpp
@@ -114,5 +114,17 @@ std::string int2HumanStr(int number)
   return result;
 }
 
+bool doIfNameMatch(const std::regex & reg, const std::string & name, const std::function<void(const std::smatch &)> & f)
+{
+  std::smatch sm;
+  std::regex_match(name, sm, reg);
+  if (sm.empty())
+    return false;
+
+  f(sm);
+
+  return true;
+};
+
 };
 
diff --git a/dev/src/dev.cpp b/dev/src/dev.cpp
index 788880972f51cc66345a4a8ab22d390ddd3cd5ce..d33d37063d2761c0500755bc76b70a4687ac3aab 100644
--- a/dev/src/dev.cpp
+++ b/dev/src/dev.cpp
@@ -4,13 +4,11 @@
 #include "BaseConfig.hpp"
 #include "SubConfig.hpp"
 #include "TransitionSet.hpp"
+#include "ReadingMachine.hpp"
 
 int main(int argc, char * argv[])
 {
-  TransitionSet ts(argv[1]);
-
-  return 0;
-
+  /*
   BaseConfig goldConfig(argv[3], argv[1], argv[2]);
 
   SubConfig config(goldConfig);
@@ -24,6 +22,9 @@ int main(int argc, char * argv[])
 
   fmt::print(stderr, "ok\n");
   std::scanf("%*c");
+  */
+
+  ReadingMachine machine(argv[1]);
 
   return 0;
 }
diff --git a/reading_machine/include/Classifier.hpp b/reading_machine/include/Classifier.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..24cc9aa825dba2fd3db4fc2a391b1d5e12104a4d
--- /dev/null
+++ b/reading_machine/include/Classifier.hpp
@@ -0,0 +1,19 @@
+#ifndef CLASSIFIER__H
+#define CLASSIFIER__H
+
+#include <string>
+#include "TransitionSet.hpp"
+
+class Classifier
+{
+  private :
+
+  std::string name;
+  std::unique_ptr<TransitionSet> transitionSet;
+
+  public :
+
+  Classifier(const std::string & name, const std::string & topology, const std::string & tsFile);
+};
+
+#endif
diff --git a/reading_machine/include/ReadingMachine.hpp b/reading_machine/include/ReadingMachine.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a37a0c8eae3c6dad996ec3bc221ca806c792b5b
--- /dev/null
+++ b/reading_machine/include/ReadingMachine.hpp
@@ -0,0 +1,19 @@
+#ifndef READING_MACHINE__H
+#define READING_MACHINE__H
+
+#include <memory>
+#include "Classifier.hpp"
+
+class ReadingMachine
+{
+  private :
+
+  std::string name;
+  std::unique_ptr<Classifier> classifier;
+
+  public :
+
+  ReadingMachine(const std::string & filename);
+};
+
+#endif
diff --git a/reading_machine/src/Classifier.cpp b/reading_machine/src/Classifier.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..29791a5033ae5cfc15c1339d4ae3ffb732b71c51
--- /dev/null
+++ b/reading_machine/src/Classifier.cpp
@@ -0,0 +1,8 @@
+#include "Classifier.hpp"
+
+Classifier::Classifier(const std::string & name, const std::string & topology, const std::string & tsFile)
+{
+  this->name = name;
+  this->transitionSet.reset(new TransitionSet(tsFile));
+}
+
diff --git a/reading_machine/src/ReadingMachine.cpp b/reading_machine/src/ReadingMachine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9160a890b454c52b4b7773218bcc1e0a3dca5ccf
--- /dev/null
+++ b/reading_machine/src/ReadingMachine.cpp
@@ -0,0 +1,31 @@
+#include "ReadingMachine.hpp"
+#include "util.hpp"
+
+ReadingMachine::ReadingMachine(const std::string & filename)
+{
+  std::regex nameRegex("Name : (.+)[\n]");
+  std::regex classifierRegex("Classifier : (.+) (.+) (.+)[\n]");
+
+  std::FILE * file = std::fopen(filename.c_str(), "r");
+
+  char buffer[1024];
+  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(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()));}
+  }
+
+  std::fclose(file);
+}
+
diff --git a/reading_machine/src/Transition.cpp b/reading_machine/src/Transition.cpp
index e6466051aad7873241b9db69fa1572086aa5c8b7..b0ced3642a286fc2960cf222af0ad96a208df809 100644
--- a/reading_machine/src/Transition.cpp
+++ b/reading_machine/src/Transition.cpp
@@ -7,22 +7,10 @@ Transition::Transition(const std::string & name)
 
   std::regex writeRegex("WRITE ([bs])\\.(.+) (.+) (.+)");
 
-  auto doIfNameMatch = [name](auto & reg, auto init)
-  {
-    std::smatch sm;
-    std::regex_match(name, sm, reg);
-    if (sm.empty())
-      return false;
-
-    init(sm);
-
-    return true;
-  };
-
   try
   {
 
-  if (doIfNameMatch(writeRegex, [this](auto sm){initWrite(sm[3], sm[1], sm[2], sm[4]);}))
+  if (util::doIfNameMatch(writeRegex, name, [this](auto sm){initWrite(sm[3], sm[1], sm[2], sm[4]);}))
     return;
 
   throw std::invalid_argument("no match");
diff --git a/reading_machine/src/TransitionSet.cpp b/reading_machine/src/TransitionSet.cpp
index fbee4f566adc2a63fdb97b85e897ddfe617be689..1bf42b13096c1d51f54bcaffffadbd7b42941060 100644
--- a/reading_machine/src/TransitionSet.cpp
+++ b/reading_machine/src/TransitionSet.cpp
@@ -3,6 +3,8 @@
 TransitionSet::TransitionSet(const std::string & filename)
 {
   FILE * file = std::fopen(filename.c_str(), "r");
+  if (!file)
+    util::myThrow(fmt::format("cannot open file '{}'", filename));
 
   char readBuffer[1024];