Vaucanson  1.4.1
dot_format.hxx
1 // dot_format.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_TOOLS_DOT_FORMAT_HXX
18 # define VCSN_TOOLS_DOT_FORMAT_HXX
19 
20 # include <sstream>
21 # include <map>
22 
23 # include <vaucanson/tools/dot_format.hh>
24 # include <vaucanson/automata/concept/handlers.hh>
25 # include <vaucanson/misc/usual_macros.hh>
26 
27 namespace vcsn
28 {
29  namespace tools
30  {
31  void
32  name_escaper(std::ostream& out, const std::string& name)
33  {
34  for (std::string::const_iterator i = name.begin(); i != name.end(); ++i)
35  {
36  if (*i == '"')
37  out << "\\";
38  out << *i;
39  }
40  }
41 
42  inline dot::dot(const std::string& name)
43  {
44  std::ostringstream os;
45  name_escaper(os, name);
46  name_ = std::string("\"") + os.str();
47  }
48 
49  template<typename Saver, typename Conv>
50  void dot::operator()(std::ostream& out, const Saver& s,
51  const Conv& conv) const
52  {
53  typedef typename Saver::automaton_t auto_t;
54  typedef typename auto_t::hstate_t hstate_t;
55 
56  const auto_t& a = s.automaton();
57  unsigned count = 0;
58  std::map<hstate_t, unsigned> state_map;
59 
60  out << "digraph vcsn {" << std::endl
61  << "label=\"" << name_.c_str() + 1 << ' ' << a << "\";" << std::endl
62  << "node [shape=circle];" << std::endl;
63 
64  for (typename auto_t::state_iterator i = a.states().begin();
65  i != a.states().end();
66  ++i)
67  {
68  unsigned c = state_map[*i] = count++;
69  if (a.is_initial(*i))
70  {
71  out << name_ << count
72  << "\" [style=invis,label=\"\",width=.01,height=.01];"
73  << std::endl
74  << name_ << count << "\" -> " << name_ << c
75  << "\" [label=\"" << conv(a.structure(), a.get_initial(*i))
76  << "\"];" << std::endl;
77  ++count;
78  }
79  if (a.is_final(*i))
80  {
81  out << name_ << count
82  << "\" [style=invis,label=\"\",width=.01,height=.01];"
83  << std::endl
84  << name_ << c << "\" -> " << name_ << count
85  << "\" [label=\""<< conv(a.structure(), a.get_final(*i))
86  <<"\"];" << std::endl;
87  ++count;
88  }
89  out << name_ << c << "\" [label=\"" << *i << "\"];" << std::endl;
90  }
91  for (typename auto_t::transition_iterator i = a.transitions().begin();
92  i != a.transitions().end();
93  ++i)
94  {
95  out << name_ << state_map[a.src_of(*i)]
96  << "\" -> "
97  << name_ << state_map[a.dst_of(*i)];
98  out << "\" [label=\"" << conv(a.structure(), a.series_of(*i))
99  << "\"];" << std::endl;
100  }
101  out << "}" << std::endl;
102  }
103 
104  inline transducer_dot::transducer_dot(const std::string& name)
105  {
106  std::ostringstream os;
107  name_escaper(os, name);
108  name_ = std::string("\"") + os.str();
109  }
110 
111  template<typename Saver, typename Conv>
112  void transducer_dot::operator()(std::ostream& out, const Saver& s,
113  const Conv& conv) const
114  {
115  typedef typename Saver::automaton_t auto_t;
116  AUTOMATON_TYPES(auto_t);
117  const auto_t& a = s.automaton();
118  unsigned count = 0;
119  std::map<hstate_t, unsigned> state_map;
120 
121  out << "digraph vcsn {" << std::endl
122  << "label=\"" << name_.c_str() + 1 << ' ' << a << "\";" << std::endl
123  << "node [shape=circle];" << std::endl;
124 
125  for (typename auto_t::state_iterator i = a.states().begin();
126  i != a.states().end();
127  ++i)
128  {
129  unsigned c = state_map[*i] = count++;
130  if (a.is_initial(*i))
131  {
132  out << name_ << count
133  << "\" [style=invis,label=\"\",width=.01,height=.01];"
134  << std::endl
135  << name_ << count << "\" -> " << name_ << c << '"';
136  std::ostringstream o;
137  series_set_elt_t ss = a.get_initial(*i);
138  if (ss.supp().begin() == ss.supp().end())
139  o << ss;
140  for_all_const_(series_set_elt_t::support_t, s, ss.supp())
141  {
142  monoid_elt_t x(a.structure().series().monoid(), *s);
143  o << conv(a.structure(), x) << "|" << ss.get(x) << " ";
144  }
145  out << "[label=\"" << o.str() << "\"];"
146  << std::endl;
147  ++count;
148  }
149  if (a.is_final(*i))
150  {
151  out << name_ << count
152  << "\" [style=invis,label=\"\",width=.01,height=.01];"
153  << std::endl
154  << name_ << c << "\" -> " << name_ << count << '"';
155  std::ostringstream o;
156  series_set_elt_t ss = a.get_final(*i);
157  if (ss.supp().begin() == ss.supp().end())
158  o << ss;
159  for_all_const_(series_set_elt_t::support_t, s, ss.supp())
160  {
161  monoid_elt_t x(a.structure().series().monoid(), *s);
162  o << conv(a.structure(), x) << "|" << ss.get(x) << " ";
163  }
164  out << "[label=\"" << o.str() << "\"];"
165  << std::endl;
166  ++count;
167  }
168  out << name_ << c << "\" [label=\"" << *i << "\"];" << std::endl;
169  }
170  for (typename auto_t::transition_iterator i = a.transitions().begin();
171  i != a.transitions().end();
172  ++i)
173  {
174  out << name_ << state_map[a.src_of(*i)]
175  << "\" -> "
176  << name_ << state_map[a.dst_of(*i)] << '"';
177  std::ostringstream o;
178  series_set_elt_t ss = a.series_of(*i);
179  if (ss.supp().begin() == ss.supp().end())
180  o << ss;
181  for_all_const_(series_set_elt_t::support_t, s, ss.supp())
182  {
183  monoid_elt_t x(a.structure().series().monoid(), *s);
184  o << conv(a.structure(), x) << "|" << ss.get(x) << " ";
185  }
186  out << "[label=\"" << o.str() << "\"];"
187  << std::endl;
188  }
189  out << "}" << std::endl;
190  }
191 
192  } // ! tools
193 
194 } // ! vcsn
195 
196 #endif // ! VCSN_TOOLS_DOT_FORMAT_HXX