Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
printer.hxx
Go to the documentation of this file.
1 #ifndef VCSN_CORE_RAT_PRINTER_HXX
2 # define VCSN_CORE_RAT_PRINTER_HXX
3 
4 # include <vcsn/misc/escape.hh>
5 # include <vcsn/misc/indent.hh>
6 # include <vcsn/misc/memory.hh> // address
7 # include <vcsn/misc/raise.hh>
8 
9 namespace vcsn
10 {
11  namespace rat
12  {
13 
14  inline
15  std::ostream&
16  operator<<(std::ostream& o, type_t t)
17  {
18  switch (t)
19  {
20 # define CASE(T) case type_t::T: o << #T; break
21  CASE(zero);
22  CASE(one);
23  CASE(atom);
24  CASE(sum);
25  CASE(prod);
26  CASE(ldiv);
28  CASE(shuffle);
29  CASE(star);
31  CASE(lweight);
32  CASE(rweight);
34 # undef CASE
35  }
36  return o;
37  }
38 
39  template <typename RatExpSet>
40  inline
42  std::ostream& out,
43  const bool debug)
44  : out_(out)
45  , ctx_(rs.context())
46  , identities_(rs.identities())
47  , debug_(debug)
48  {}
49 
50 
51 # define DEFINE \
52  template <typename RatExpSet> \
53  inline \
54  auto \
55  printer<RatExpSet>
56 
57  DEFINE::operator()(const node_t& v)
58  -> std::ostream&
59  {
60  static bool print = !! getenv("VCSN_PRINT");
61  static bool debug = !! getenv("VCSN_DEBUG");
62  if (print)
63  out_ << '<' << v.type() << "@0x" << address(v) << '>' << vcsn::incendl;
64  if (debug && format_ == "latex")
65  out_ << (identities_ == identities_t::series
66  ? "{\\color{red}{" : "{\\color{blue}{");
67  v.accept(*this);
68  if (debug && format_ == "latex")
69  out_ << "}}";
70  if (print)
71  out_ << vcsn::decendl << "</" << v.type() << '>';
72  return out_;
73  }
74 
75  DEFINE::format(symbol format)
76  -> void
77  {
78  format_ = format;
79  if (format_ == "latex")
80  {
81  lgroup_ = "{";
82  rgroup_ = "}";
83  langle_ = " \\left\\langle ";
84  rangle_ = " \\right\\rangle ";
85  lparen_ = "\\left(";
86  rparen_ = "\\right)";
87  star_ = "^{*}";
88  complement_ = "^{c}";
89  transposition_ = "^{T}";
90  conjunction_ = " \\& ";
91  shuffle_ = " \\between ";
92  product_ = " \\, ";
93  sum_ = (identities_ == identities_t::series
94  ? " \\oplus " : " + ");
95  zero_ = "\\emptyset";
96  one_ = "\\varepsilon";
97  lmul_ = "\\,";
98  rmul_ = "\\,";
99  ldiv_ = " \\backslash ";
100  }
101  else if (format_ == "text")
102  {
103  lgroup_ = "";
104  rgroup_ = "";
105  langle_ = "<";
106  rangle_ = ">";
107  lparen_ = "(";
108  rparen_ = ")";
109  star_ = "*";
110  complement_ = "{c}";
111  transposition_ = "{T}";
112  conjunction_ = "&";
113  shuffle_ = ":";
114  product_ = "";
115  sum_ = "+";
116  zero_ = "\\z";
117  one_ = "\\e";
118  lmul_ = "";
119  rmul_ = "";
120  ldiv_ = "{\\}";
121  }
122  else
123  raise("invalid output format for ratexp: ", str_escape(format));
124  }
125 
126  DEFINE::precedence_(const node_t& v) const
127  -> precedence_t
128  {
129  if (is_word_(v))
130  return precedence_t::word;
131  else
132  switch (v.type())
133  {
134 # define CASE(Type) \
135  case exp::type_t::Type: \
136  return precedence_t::Type;
137  CASE(atom);
138  CASE(complement);
139  CASE(conjunction);
140  CASE(ldiv);
141  CASE(lweight);
142  CASE(one);
143  CASE(prod);
144  CASE(rweight);
145  CASE(shuffle);
146  CASE(star);
147  CASE(sum);
149  CASE(zero);
150 # undef CASE
151  }
152  abort(); // Unreachable.
153  }
154 
155 # define VISIT(Type) \
156  DEFINE::visit(const Type ## _t& v) \
157  -> void
158 
160  {
161  out_ << langle_;
162  ctx_.weightset()->print(v.weight(), out_, format_);
163  out_ << rangle_ << lmul_;
164  print_child_(*v.sub(), v);
165  }
166 
168  {
169  print_child_(*v.sub(), v);
170  out_ << rmul_ << langle_;
171  ctx_.weightset()->print(v.weight(), out_, format_);
172  out_ << rangle_;
173  }
174 
176  {
177  (void) v;
178  out_ << zero_;
179  }
180 
182  {
183  (void) v;
184  out_ << one_;
185  }
186 
188  {
189  ctx_.labelset()->print(v.value(), out_, format_);
190  }
191 
192  DEFINE::print_child_(const node_t& child, const node_t& parent)
193  -> void
194  {
195  static bool force = !! getenv("VCSN_PARENS");
196  bool parent_has_precedence = precedence_(child) <= precedence_(parent);
197  bool needs_parens =
198  (force
199  || (parent_has_precedence
200  && ! (parent.is_unary() && child.is_unary())));
201  if (needs_parens)
202  out_ << lparen_;
203  else if (parent.is_unary())
204  out_ << lgroup_;
205  operator()(child);
206  if (needs_parens)
207  out_ << rparen_;
208  else if (parent.is_unary())
209  out_ << rgroup_;
210  }
211 
212  template <typename RatExpSet>
213  template <type_t Type>
214  inline
215  auto
216  printer<RatExpSet>::print_(const unary_t<Type>& v, const char* op)
217  -> void
218  {
219  print_child_(*v.sub(), v);
220  out_ << op;
221  }
222 
223  template <typename RatExpSet>
224  template <type_t Type>
225  inline
226  auto
228  -> void
229  {
230  bool first = true;
231  for (auto i: n)
232  {
233  if (! first)
234  out_ << op;
235  print_child_(*i, n);
236  first = false;
237  }
238  }
239 
240 # undef VISIT
241 # undef DEFINE
242 
243  } // namespace rat
244 } // namespace vcsn
245 
246 #endif // !VCSN_CORE_RAT_PRINTER_HXX
precedence_t
The possible node precedence levels, increasing.
Definition: printer.hh:89
An inner node with multiple children.
Definition: fwd.hh:123
std::ostream & operator<<(std::ostream &o, type_t t)
Definition: printer.hxx:16
Indentation relative functions.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
Definition: indent.cc:54
typename super_t::template unary_t< Type > unary_t
Definition: printer.hh:31
boost::flyweight< std::string, boost::flyweights::no_tracking > symbol
An internalized string.
Definition: symbol.hh:24
automaton shuffle_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Variadic bridge helper.
Definition: product.hh:549
std::ostream & str_escape(std::ostream &os, const std::string &str)
Output a string, escaping special characters.
Definition: escape.cc:43
typename super_t::template variadic_t< Type > variadic_t
Definition: printer.hh:33
void print_(const unary_t< Type > &n, const char *op)
Print a unary node.
int address(const void *t)
Name pointers, to make them easier to read.
Definition: memory.hh:23
#define VISIT(Type)
Definition: printer.hxx:155
std::ostream & print(const ValueSet &vs, const typename ValueSet::value_t &v, std::ostream &o, const std::string &format)
Applies to (ValueSet, Value, ostream, string): for expansionset, polynomialset, ratexpset, and weightset.
Definition: print.hh:51
type_t
The possible types of ratexps.
Definition: fwd.hh:31
typename super_t::node_t node_t
Definition: printer.hh:28
Trivial identities plus series identities.
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
Definition: indent.cc:59
An inner node implementing a weight.
Definition: fwd.hh:145
#define CASE(T)
printer(const ratexpset_t &rs, std::ostream &out, const bool debug=!!getenv("VCSN_PARENS"))
Definition: printer.hxx:41
RatExpSet ratexpset_t
Definition: printer.hh:23
identities
A ratexpset can implement several different sets of identities on expressions.
Definition: identities.hh:17
automaton product_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Definition: product.hh:478