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 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 <vaucanson/automata/concept/handlers.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025 # include <vaucanson/automata/concept/automata_base.hh>
00026 
00027 namespace vcsn {
00028 
00029   namespace tools {
00030 
00031     /*---------.
00032     | fsm_load |
00033     `---------*/
00034     enum data_e
00035     {
00036       final,
00037       transition
00038     };
00039 
00040     struct line_data
00041     {
00042         data_e       type;
00043         unsigned int from;
00044         unsigned int to;
00045         char         letter;
00046         float        weight;
00047     };
00048 
00049     std::pair<std::string, std::string>
00050     next_token(std::string line)
00051     {
00052       std::string token;
00053       std::string::iterator i = line.begin();
00054       while ((i != line.end()) && ((*i == '\t')
00055                                    || (*i == ' ') || (*i == '\0')))
00056         ++i;
00057       for (;i != line.end();++i)
00058       {
00059         if ((*i == '\t') || (*i == ' ')
00060             || (*i == '\n') || (*i == '\0'))
00061           break;
00062         else
00063           token.push_back(*i);
00064       }
00065       if (i != line.end())
00066       {
00067         ++i;
00068         return std::make_pair(token,
00069                               std::string(line,
00070                                           (unsigned)(i - line.begin()),
00071                                           (unsigned)(line.end() - i + 1)));
00072       }
00073       else
00074         return std::make_pair(token, std::string());
00075     }
00076 
00077     template <typename St, typename AutoType_>
00078     void fsm_load(St& in, AutoType_& a)
00079     {
00080       AUTOMATON_TYPES(AutoType_);
00081       AUTOMATON_FREEMONOID_TYPES(AutoType_);
00082       // read everything and build the alphabet.
00083       alphabet_t                alpha;
00084       unsigned                  nb = 0;
00085       std::vector<line_data>    stock;
00086       std::string               line;
00087       std::pair<std::string,    std::string> tmp;
00088       std::vector<std::string>  tokens;
00089 
00090       while (!in.eof())
00091       {
00092         tokens.clear();
00093         ++nb;
00094         stock.resize(nb);
00095         getline(in, line);
00096         while (true)
00097         {
00098           tmp = next_token(line);
00099           line = tmp.second;
00100           if (tmp.first.length() != 0)
00101             tokens.push_back(tmp.first);
00102           if (line.length() == 0)
00103             break;
00104         }
00105         if (tokens.size() == 0)
00106         {
00107           nb--;
00108           stock.resize(nb);
00109           break;
00110         }
00111         if (tokens.size() == 1)
00112         {
00113           stock[nb-1].type = final;
00114           stock[nb-1].from = atoi(tokens[0].c_str());
00115           stock[nb-1].weight = 0.;
00116         }
00117         else if (tokens.size() == 2)
00118         {
00119           stock[nb-1].type = final;
00120           stock[nb-1].from = atoi(tokens[0].c_str());
00121           stock[nb-1].weight = atof(tokens[1].c_str());
00122         }
00123         else if (tokens.size() == 4)
00124         {
00125           stock[nb-1].type   = transition;
00126           stock[nb-1].from   = atoi(tokens[0].c_str());
00127           stock[nb-1].to     = atoi(tokens[1].c_str());
00128           stock[nb-1].letter = tokens[2][0];
00129           stock[nb-1].weight = atof(tokens[3].c_str());
00130           alpha.insert(stock[nb-1].letter);
00131         }
00132       }
00133       // construct the automaton.
00134       monoid_t    monoid(alpha);
00135       semiring_t   semiring;
00136       series_set_t        series(semiring, monoid);
00137       automata_set_t aset(series);
00138       automaton_t automaton(aset);
00139       std::map<int, hstate_t> to_h;
00140 
00141       for_all_const_(std::vector<line_data>, i, stock)
00142       {
00143         if (i->type == transition)
00144         {
00145           if (to_h.find(i->from) == to_h.end())
00146             to_h[i->from] = automaton.add_state();
00147           if (to_h.find(i->to) == to_h.end())
00148             to_h[i->to] = automaton.add_state();
00149           if (i == stock.begin())
00150             automaton.set_initial(to_h[i->from]);
00151           // FIXME: please be generic w.r.t spontaneous transition.
00152           if (i->letter == '1')
00153             automaton.add_spontaneous(to_h[i->from],
00154                                       to_h[i->to]);
00155           else
00156             automaton.add_letter_transition(to_h[i->from],
00157                                             to_h[i->to],
00158                                             letter_t(i->letter));
00159         }
00160         else if (i->type == final)
00161         {
00162           if (to_h.find(i->from) == to_h.end())
00163             to_h[i->from] = automaton.add_state();
00164           automaton.set_final(to_h[i->from]);
00165         }
00166       }
00167       a = automaton;
00168     }
00169 
00170   } // tools
00171 
00172 } // vcsn
00173 
00174 #endif // ! VCSN_TOOLS_FSM_LOAD_HXX

Generated on Wed Jun 13 17:00:21 2007 for Vaucanson by  doxygen 1.5.1