Vaucanson 1.4
|
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