summaryrefslogtreecommitdiff
path: root/code/core/regex.cpp
blob: ef98209277507fea45b17f9325d8be2b7d53b5bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// file access
#include <fcntl.h>
#include <errno.h>
#include <list>
#include <boost/xpressive/xpressive_static.hpp>
#include <boost/xpressive/regex_actions.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/foreach.hpp>

#include "interface.h"

#include "log.h"
#include "simulate.h"
#include "tracepoints.h"
#include "global.h"
#include "neuron.h"
#include "synapse.h"
#include "spike.h"

#include "regex.h"

// pollute seperate namespace with regex expressions
namespace tracepoints {

  using namespace boost::xpressive;

  /* parser result variables */
  std::set<int> intSet;
  std::set<std::string> stringSet;
  double targetTimeOffset = 0.0;
  std::string filename;
  bool ioDirection; // tue -> write; false -> read
  bool ioBinary;

  /* parser callback implementations */
  struct push_impl
  {
    typedef void result_type;     // Result type, needed for tr1::result_of
    
    template<typename Set, class Value>
    void operator()(Set &s, Value const &val) const { s.insert(val); }
  };
  function<push_impl>::type const push = {{}};

  /* I/O interface launcher */
  template<class T>
  struct start_interface_impl
  {
    typedef void result_type;     // Result type, needed for tr1::result_of
    
    void operator() () const {
      // open src/dst file
      int fd = open(filename.c_str, write ? (O_WRONLY | O_APPEND | O_CREAT) : (O_RDONLY | O_NONBLOCK));
      if (fd == -1) DIE("could not open file");

      // execute task
      if (ioDirection) { // write
	if (boost::is_same<T, SpikeMUX>::value) {
	  // create a persistent interface to write out spikes as they occur
	  s.spikeOIfList.push_back(new OutputInterface<SpikeMUX>(fd, ioBinary, stringSet, intSet));
	}else{
	  // create a temporary interface to write out any state
	  OutputInterface<T> oif(fd, ioBinary, stringSet, intSet);
	  oif.pushClass();
	  close(fd);
	}
      }else{ // read
	// create long living input interface (terminates itself when EOF is discovered)
	FileInputEvent<T>::createInputStream(new InputInterface<T>(fd, ioBinary, stringSet, intSet));
      }
      
      // clean up vars for next command
      ioBinary = false;
      stringSet.empty();
      intSet.empty();
    }
  };

  function<start_interface_impl<Global> >::type const start_interface_global = {{}};
  function<start_interface_impl<Neuron> >::type const start_interface_neuron = {{}};
  function<start_interface_impl<Synapse> >::type const start_interface_synapse = {{}};
  function<start_interface_impl<Spike> >::type const start_interface_spike = {{}};

  /* regex pattern definitions */

  // character sets
  cregex Delim = as_xpr(';');
  cregex VarNameChar = alnum | as_xpr('_');

  // basic elements
  cregex Time = (+_d >> !('.' >> +_d))[ ref(targetOffseTime)=as<double>(_) ];

  cregex Index = (+_d)[ push(as<int>(_)) ];

  cregex Element = (+varnamechar)[ push(as<std::string>(_)) ];

  cregex Filename = (+varnamechar)[ ref(filename)=<std::string>(_) ];

  cregex IODirWrite = as_xpr('>') [ ref(ioDirection)=true ];
  cregex IODirRead = as_xpr('>') [ ref(ioDirection)=false ];
  cregex IODirection = IODirWrite | IODirRead;

  cregex IOBinaryTrue = as_xpr('#') [ ref(ioBinary)=true ];
  cregex IOBinary = !IOBinaryTrue;

  cregex IOCmd = IOBinary >> IODirection >> Filename;

  // lists
  cregex ObjectListInner = *space >> (s1= index) >> *space;
  cregex ObjectList = *space >> '(' >> object_list_inner >> *( delim >> object_list_inner ) >> ')';

  cregex ElementListInner = *space >> (s1= element) >> *space;
  cregex ElementList = *space >> '{' >> element_list_inner >> *( delim >> element_list_inner ) >> '}';

  // trace commands
  cregex TraceCmdTail = *space >> !ElementList >> *space >> !ObjectList >> *space >> IOCmd;

  cregex TraceGlobal  = (icase( "global" )  >> TraceCmdTail [ start_interface_global() ];
  cregex TraceNeuron  = (icase( "neuron" )  >> TraceCmdTail [ start_interface_neuron() ];
  cregex TraceSynapse = (icase( "synapse" ) >> TraceCmdTail [ start_interface_synapse() ];
  cregex TraceSpike   = (icase( "spike" )   >> TraceCmdTail [ start_interface_spike() ];

  // whole line
  // target format  what
  //  cregex channel = *space >> +delim >> *space >> ( neuron | synapse | global | spikes );
  //  cregex traceline = time  >> *channel >> *( delim | space );
  cregex traceLine = !icase("proceed") >> +space >> time;
  cregex line = *space >> *(inputElem | outputElem | traceElem) >> *( delim | space ));

  bool parseRequest(char *str) {
    return regex_match(str, line);
  }
  
};
contact: Jan Huwald // Impressum