Vaucanson  1.4.1
fsm_load.hxx
1 // fsm_load.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2001, 2002, 2004, 2005, 2006, 2008 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_TOOLS_FSM_LOAD_HXX
18 # define VCSN_TOOLS_FSM_LOAD_HXX
19 
20 # include <vaucanson/tools/fsm_load.hh>
21 # include <map>
22 # include <set>
23 # include <string>
24 # include <vaucanson/automata/concept/handlers.hh>
25 # include <vaucanson/misc/usual_macros.hh>
26 # include <vaucanson/automata/concept/automata_base.hh>
27 
28 namespace vcsn {
29 
30  namespace tools {
31 
32  /*---------.
33  | fsm_load |
34  `---------*/
35  enum data_e
36  {
37  final,
38  transition
39  };
40 
41  struct line_data
42  {
43  data_e type;
44  unsigned int from;
45  unsigned int to;
46  std::string letter;
47  float weight;
48  };
49 
50  std::pair<std::string, std::string>
51  next_token(std::string line)
52  {
53  std::string token;
54  std::string::iterator i = line.begin();
55  while ((i != line.end()) && ((*i == '\t')
56  || (*i == ' ') || (*i == '\0')))
57  ++i;
58  for (;i != line.end();++i)
59  {
60  if ((*i == '\t') || (*i == ' ')
61  || (*i == '\n') || (*i == '\0'))
62  break;
63  else
64  token.push_back(*i);
65  }
66  if (i != line.end())
67  {
68  ++i;
69  return std::make_pair(token,
70  std::string(line,
71  (unsigned)(i - line.begin()),
72  (unsigned)(line.end() - i + 1)));
73  }
74  else
75  return std::make_pair(token, std::string());
76  }
77 
78  template <typename St, typename AutoType_>
79  void fsm_load(St& in, AutoType_& a)
80  {
81  AUTOMATON_TYPES(AutoType_);
82  AUTOMATON_FREEMONOID_TYPES(AutoType_);
83  // read everything and build the alphabet.
84  alphabet_t alpha;
85  unsigned nb = 0;
86  std::vector<line_data> stock;
87  std::string line;
88  std::pair<std::string, std::string> tmp;
89  std::vector<std::string> tokens;
90 
91  while (!in.eof())
92  {
93  tokens.clear();
94  ++nb;
95  stock.resize(nb);
96  getline(in, line);
97  while (true)
98  {
99  tmp = next_token(line);
100  line = tmp.second;
101  if (tmp.first.length() != 0)
102  tokens.push_back(tmp.first);
103  if (line.length() == 0)
104  break;
105  }
106  if (tokens.size() == 0)
107  {
108  nb--;
109  stock.resize(nb);
110  break;
111  }
112  if (tokens.size() == 1)
113  {
114  stock[nb-1].type = final;
115  stock[nb-1].from = atoi(tokens[0].c_str());
116  stock[nb-1].weight = 0.;
117  }
118  else if (tokens.size() == 2)
119  {
120  stock[nb-1].type = final;
121  stock[nb-1].from = atoi(tokens[0].c_str());
122  stock[nb-1].weight = atof(tokens[1].c_str());
123  }
124  else if (tokens.size() == 4)
125  {
126  stock[nb-1].type = transition;
127  stock[nb-1].from = atoi(tokens[0].c_str());
128  stock[nb-1].to = atoi(tokens[1].c_str());
129  stock[nb-1].letter = tokens[2][0];
130  stock[nb-1].weight = atof(tokens[3].c_str());
131  alpha.insert(stock[nb-1].letter);
132  }
133  }
134  // construct the automaton.
135  monoid_t monoid(alpha);
136  semiring_t semiring;
137  series_set_t series(semiring, monoid);
138  automata_set_t aset(series);
139  automaton_t automaton(aset);
140  std::map<int, hstate_t> to_h;
141 
142  for_all_const_(std::vector<line_data>, i, stock)
143  {
144  if (i->type == transition)
145  {
146  if (to_h.find(i->from) == to_h.end())
147  to_h[i->from] = automaton.add_state();
148  if (to_h.find(i->to) == to_h.end())
149  to_h[i->to] = automaton.add_state();
150  if (i == stock.begin())
151  automaton.set_initial(to_h[i->from]);
152  // FIXME: please be generic w.r.t spontaneous transition.
153  if (i->letter == "1")
154  automaton.add_spontaneous(to_h[i->from],
155  to_h[i->to]);
156  else
157  automaton.add_letter_transition(to_h[i->from],
158  to_h[i->to],
159  vcsn::algebra::letter_traits<letter_t>::literal_to_letter(i->letter).second);
160  }
161  else if (i->type == final)
162  {
163  if (to_h.find(i->from) == to_h.end())
164  to_h[i->from] = automaton.add_state();
165  automaton.set_final(to_h[i->from]);
166  }
167  }
168  a = automaton;
169  }
170 
171  } // tools
172 
173 } // vcsn
174 
175 #endif // ! VCSN_TOOLS_FSM_LOAD_HXX