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

# 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