- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# 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).second);
    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