fsm_load.hxx

00001 // fsm_load.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2004, 2005, 2006, 2008 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_TOOLS_FSM_LOAD_HXX
00018 # define VCSN_TOOLS_FSM_LOAD_HXX
00019 
00020 # include <vaucanson/tools/fsm_load.hh>
00021 # include <map>
00022 # include <set>
00023 # include <string>
00024 # include <vaucanson/automata/concept/handlers.hh>
00025 # include <vaucanson/misc/usual_macros.hh>
00026 # include <vaucanson/automata/concept/automata_base.hh>
00027 
00028 namespace vcsn {
00029 
00030   namespace tools {
00031 
00032     /*---------.
00033     | fsm_load |
00034     `---------*/
00035     enum data_e
00036     {
00037       final,
00038       transition
00039     };
00040 
00041     struct line_data
00042     {
00043         data_e          type;
00044         unsigned int    from;
00045         unsigned int    to;
00046         std::string     letter;
00047         float           weight;
00048     };
00049 
00050     std::pair<std::string, std::string>
00051     next_token(std::string line)
00052     {
00053       std::string token;
00054       std::string::iterator i = line.begin();
00055       while ((i != line.end()) && ((*i == '\t')
00056                                    || (*i == ' ') || (*i == '\0')))
00057         ++i;
00058       for (;i != line.end();++i)
00059       {
00060         if ((*i == '\t') || (*i == ' ')
00061             || (*i == '\n') || (*i == '\0'))
00062           break;
00063         else
00064           token.push_back(*i);
00065       }
00066       if (i != line.end())
00067       {
00068         ++i;
00069         return std::make_pair(token,
00070                               std::string(line,
00071                                           (unsigned)(i - line.begin()),
00072                                           (unsigned)(line.end() - i + 1)));
00073       }
00074       else
00075         return std::make_pair(token, std::string());
00076     }
00077 
00078     template <typename St, typename AutoType_>
00079     void fsm_load(St& in, AutoType_& a)
00080     {
00081       AUTOMATON_TYPES(AutoType_);
00082       AUTOMATON_FREEMONOID_TYPES(AutoType_);
00083       // read everything and build the alphabet.
00084       alphabet_t                alpha;
00085       unsigned                  nb = 0;
00086       std::vector<line_data>    stock;
00087       std::string               line;
00088       std::pair<std::string,    std::string> tmp;
00089       std::vector<std::string>  tokens;
00090 
00091       while (!in.eof())
00092       {
00093         tokens.clear();
00094         ++nb;
00095         stock.resize(nb);
00096         getline(in, line);
00097         while (true)
00098         {
00099           tmp = next_token(line);
00100           line = tmp.second;
00101           if (tmp.first.length() != 0)
00102             tokens.push_back(tmp.first);
00103           if (line.length() == 0)
00104             break;
00105         }
00106         if (tokens.size() == 0)
00107         {
00108           nb--;
00109           stock.resize(nb);
00110           break;
00111         }
00112         if (tokens.size() == 1)
00113         {
00114           stock[nb-1].type = final;
00115           stock[nb-1].from = atoi(tokens[0].c_str());
00116           stock[nb-1].weight = 0.;
00117         }
00118         else if (tokens.size() == 2)
00119         {
00120           stock[nb-1].type = final;
00121           stock[nb-1].from = atoi(tokens[0].c_str());
00122           stock[nb-1].weight = atof(tokens[1].c_str());
00123         }
00124         else if (tokens.size() == 4)
00125         {
00126           stock[nb-1].type   = transition;
00127           stock[nb-1].from   = atoi(tokens[0].c_str());
00128           stock[nb-1].to     = atoi(tokens[1].c_str());
00129           stock[nb-1].letter = tokens[2][0];
00130           stock[nb-1].weight = atof(tokens[3].c_str());
00131           alpha.insert(stock[nb-1].letter);
00132         }
00133       }
00134       // construct the automaton.
00135       monoid_t    monoid(alpha);
00136       semiring_t   semiring;
00137       series_set_t        series(semiring, monoid);
00138       automata_set_t aset(series);
00139       automaton_t automaton(aset);
00140       std::map<int, hstate_t> to_h;
00141 
00142       for_all_const_(std::vector<line_data>, i, stock)
00143       {
00144         if (i->type == transition)
00145         {
00146           if (to_h.find(i->from) == to_h.end())
00147             to_h[i->from] = automaton.add_state();
00148           if (to_h.find(i->to) == to_h.end())
00149             to_h[i->to] = automaton.add_state();
00150           if (i == stock.begin())
00151             automaton.set_initial(to_h[i->from]);
00152           // FIXME: please be generic w.r.t spontaneous transition.
00153           if (i->letter == "1")
00154             automaton.add_spontaneous(to_h[i->from],
00155                                       to_h[i->to]);
00156           else
00157             automaton.add_letter_transition(to_h[i->from],
00158                                             to_h[i->to],
00159                                             vcsn::algebra::letter_traits<letter_t>::literal_to_letter(i->letter));
00160         }
00161         else if (i->type == final)
00162         {
00163           if (to_h.find(i->from) == to_h.end())
00164             to_h[i->from] = automaton.add_state();
00165           automaton.set_final(to_h[i->from]);
00166         }
00167       }
00168       a = automaton;
00169     }
00170 
00171   } // tools
00172 
00173 } // vcsn
00174 
00175 #endif // ! VCSN_TOOLS_FSM_LOAD_HXX

Generated on Thu Oct 9 20:22:35 2008 for Vaucanson by  doxygen 1.5.1