Vcsn  2.1
Be Rational
printer.hxx
Go to the documentation of this file.
1 #include <vcsn/misc/escape.hh>
2 #include <vcsn/misc/indent.hh>
3 #include <vcsn/misc/memory.hh> // address
4 #include <vcsn/misc/raise.hh>
5 
6 namespace vcsn
7 {
8  namespace rat
9  {
10 
11  inline
12  std::ostream&
13  operator<<(std::ostream& o, type_t t)
14  {
15  switch (t)
16  {
17 #define CASE(T) case type_t::T: o << #T; break
18  CASE(atom);
22  CASE(ldiv);
23  CASE(lweight);
24  CASE(one);
25  CASE(prod);
26  CASE(rweight);
27  CASE(shuffle);
28  CASE(star);
29  CASE(sum);
31  CASE(tuple);
32  CASE(zero);
33 #undef CASE
34  }
35  return o;
36  }
37 
38  template <typename ExpSet>
39  inline
41  std::ostream& out)
42  : out_(out)
43  , rs_(rs)
44  {}
45 
46 
47 #define DEFINE \
48  template <typename ExpSet> \
49  inline \
50  auto \
51  printer<ExpSet>
52 
53  DEFINE::operator()(const node_t& v)
54  -> std::ostream&
55  {
56  static bool print = !! getenv("VCSN_PRINT");
57  if (print)
58  out_ << '<' << v.type() << "@0x" << address(v) << '>' << vcsn::incendl;
59  if (debug_ && fmt_ == format::latex)
60  out_ << (rs_.identities().is_distributive()
61  ? "{\\color{red}{" : "{\\color{blue}{");
62  v.accept(*this);
63  if (debug_ && fmt_ == format::latex)
64  out_ << "}}";
65  if (print)
66  out_ << vcsn::decendl << "</" << v.type() << '>';
67  return out_;
68  }
69 
70  DEFINE::format(class format fmt)
71  -> void
72  {
73  fmt_ = fmt;
74  if (fmt_ == format::latex)
75  {
76  lgroup_ = "{";
77  rgroup_ = "}";
78  langle_ = " \\left\\langle ";
79  rangle_ = " \\right\\rangle ";
80  lparen_ = "\\left(";
81  rparen_ = "\\right)";
82  star_ = "^{*}";
83  complement_ = "^{c}";
84  transposition_ = "^{T}";
85  conjunction_ = " \\& ";
86  infiltration_ = " \\uparrow ";
87  shuffle_ = " \\between ";
88  product_ = " \\, ";
89  sum_ = (rs_.identities().is_distributive() ? " \\oplus "
90  : " + ");
91  zero_ = "\\emptyset";
92  one_ = "\\varepsilon";
93  lmul_ = "\\,";
94  rmul_ = "\\,";
95  ldiv_ = " \\backslash ";
96  tuple_left = " \\left. ";
97  tuple_middle = " \\middle| ";
98  tuple_right = " \\right. ";
99  }
100  else if (fmt_ == format::text)
101  {
102  lgroup_ = "";
103  rgroup_ = "";
104  langle_ = "<";
105  rangle_ = ">";
106  lparen_ = "(";
107  rparen_ = ")";
108  star_ = "*";
109  complement_ = "{c}";
110  transposition_ = "{T}";
111  conjunction_ = "&";
112  infiltration_ = "&:";
113  shuffle_ = ":";
114  product_ = "";
115  sum_ = "+";
116  zero_ = "\\z";
117  one_ = "\\e";
118  lmul_ = "";
119  rmul_ = "";
120  ldiv_ = "{\\}";
121  tuple_left = "";
122  tuple_middle = "|";
123  tuple_right = "";
124  }
125  }
126 
127  DEFINE::precedence_(const node_t& v) const
128  -> precedence_t
129  {
130  if (is_word_(v))
131  return precedence_t::word;
132  else
133  switch (v.type())
134  {
135 #define CASE(Type) \
136  case exp::type_t::Type: \
137  return precedence_t::Type
138  CASE(atom);
139  CASE(complement);
140  CASE(conjunction);
142  CASE(ldiv);
143  CASE(lweight);
144  CASE(one);
145  CASE(prod);
146  CASE(rweight);
147  CASE(shuffle);
148  CASE(star);
149  CASE(sum);
151  CASE(tuple);
152  CASE(zero);
153 #undef CASE
154  }
155  abort(); // Unreachable.
156  }
157 
158 #define VISIT(Type) \
159  DEFINE::visit(const Type ## _t& v) \
160  -> void
161 
162  VISIT(lweight)
163  {
164  out_ << langle_;
165  rs_.weightset()->print(v.weight(), out_, fmt_.for_weights());
166  out_ << rangle_ << lmul_;
167  print_child_(*v.sub(), v);
168  }
169 
170  VISIT(rweight)
171  {
172  print_child_(*v.sub(), v);
173  out_ << rmul_ << langle_;
174  rs_.weightset()->print(v.weight(), out_, fmt_.for_weights());
175  out_ << rangle_;
176  }
177 
178  VISIT(zero)
179  {
180  (void) v;
181  out_ << zero_;
182  }
183 
184  VISIT(one)
185  {
186  (void) v;
187  out_ << one_;
188  }
189 
190  VISIT(atom)
191  {
192  rs_.labelset()->print(v.value(), out_, fmt_.for_labels());
193  }
194 
195  DEFINE::print_child(const node_t& child, precedence_t parent)
196  -> void
197  {
198  static bool force = !! getenv("VCSN_PARENS");
199  bool parent_has_precedence = precedence_(child) <= parent;
200  bool needs_parens =
201  (force
202  || (parent_has_precedence
203  && ! (parent == precedence_t::unary && child.is_unary())
204  && ! is_braced_(child)));
205  if (needs_parens)
206  out_ << lparen_;
207  else if (parent == precedence_t::unary)
208  out_ << lgroup_;
209  operator()(child);
210  if (needs_parens)
211  out_ << rparen_;
212  else if (parent == precedence_t::unary)
213  out_ << rgroup_;
214  }
215 
216  DEFINE::print_child_(const node_t& child, const node_t& parent)
217  -> void
218  {
219  print_child(child, precedence_(parent));
220  }
221 
222  template <typename ExpSet>
223  template <type_t Type>
224  inline
225  auto
226  printer<ExpSet>::print_(const unary_t<Type>& v, const char* op)
227  -> void
228  {
229  print_child_(*v.sub(), v);
230  out_ << op;
231  }
232 
233  template <typename ExpSet>
234  template <type_t Type>
235  inline
236  auto
237  printer<ExpSet>::print_(const variadic_t<Type>& n, const char* op)
238  -> void
239  {
240  bool first = true;
241  for (const auto& i: n)
242  {
243  if (! first)
244  out_ << op;
245  print_child_(*i, n);
246  first = false;
247  }
248  }
249 
250 #undef VISIT
251 #undef DEFINE
252 
253  } // namespace rat
254 } // namespace vcsn
typename super_t::template unary_t< Type > unary_t
Definition: printer.hh:75
automaton conjunction_(const std::vector< automaton > &as, bool lazy, vcsn::detail::index_sequence< I...>)
Bridge helper.
Definition: conjunction.hh:598
type_t
The possible types of expressions.
Definition: fwd.hh:39
automaton infiltration_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Variadic bridge helper.
Definition: conjunction.hh:739
int address(const void *t)
Name pointers, to make them easier to read.
Definition: memory.hh:22
void print_(const unary_t< Type > &n, const char *op)
Print a unary node.
typename super_t::template variadic_t< Type > variadic_t
Definition: printer.hh:77
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
Definition: indent.cc:54
automaton shuffle_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Variadic bridge helper.
Definition: conjunction.hh:650
typename super_t::node_t node_t
Actual node, without indirection.
Definition: printer.hh:70
weight_node< type_t::rweight, Context > rweight
Definition: fwd.hh:177
#define CASE(T)
std::ostream & operator<<(std::ostream &o, type_t t)
Definition: printer.hxx:13
An input/output format.
Definition: format.hh:11
std::ostream & print(const Aut &aut, std::ostream &out, const std::string &format)
Definition: print.hh:77
Implementation of nodes of tuple of rational expressions.
Definition: expression.hh:182
precedence_t
The possible node precedence levels, increasing.
Definition: printer.hh:34
ExpSet expressionset_t
Definition: printer.hh:61
#define VISIT(Type)
Definition: printer.hxx:158
printer(const expressionset_t &rs, std::ostream &out)
A printer.
Definition: printer.hxx:40
auto rs
Definition: lift.hh:151
constant< type_t::zero, Context > zero
Definition: fwd.hh:108
weight_node< type_t::lweight, Context > lweight
Definition: fwd.hh:174
An inner node implementing a weight.
Definition: expression.hh:264
Indentation relative functions.
constant< type_t::one, Context > one
Definition: fwd.hh:111
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 with multiple children.
Definition: expression.hh:118