Vcsn  2.1
Be Rational
printer.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 
5 #include <vcsn/algos/focus.hh> // bad layering: should not be in algos.
8 #include <vcsn/ctx/traits.hh>
9 #include <vcsn/labelset/labelset.hh> // has_genset_mem_fn
10 #include <vcsn/misc/algorithm.hh> // initial_range
11 #include <vcsn/misc/attributes.hh>
12 #include <vcsn/misc/builtins.hh>
13 #include <vcsn/misc/cast.hh>
14 #include <vcsn/misc/format.hh>
15 
16 namespace vcsn
17 {
18  namespace rat
19  {
20 
34  enum class precedence_t
35  {
36  sum,
37  tuple,
38  products,
39  shuffle = products,
42  ldiv,
43  prod,
44  word = prod, // Multi-letter atoms.
45  lweight,
46  rweight,
47  unary, // All the unary (postfix) operators.
48  star = unary,
49  complement = unary,
51  zero,
52  one,
53  atom,
54  };
55 
56  template <typename ExpSet>
57  class printer
58  : public ExpSet::const_visitor
59  {
60  public:
61  using expressionset_t = ExpSet;
63  using identities_t = typename expressionset_t::identities_t;
67 
68  using super_t = typename expressionset_t::const_visitor;
70  using node_t = typename super_t::node_t;
72  using value_t = typename node_t::value_t;
73  using inner_t = typename super_t::inner_t;
74  template <type_t Type>
75  using unary_t = typename super_t::template unary_t<Type>;
76  template <type_t Type>
77  using variadic_t = typename super_t::template variadic_t<Type>;
78  using leaf_t = typename super_t::leaf_t;
79 
81  constexpr static const char* me() { return "print"; }
82 
84  printer(const expressionset_t& rs, std::ostream& out);
85 
87  void format(format fmt);
88 
90  std::ostream& operator()(const node_t& v);
91 
93  std::ostream&
94  operator()(const std::shared_ptr<const node_t>& v)
95  {
96  return operator()(*v);
97  }
98 
100  void print_child(const node_t& child, precedence_t parent);
101 
102  private:
109  VCSN_RAT_VISIT(one, v);
117 
118  using tuple_t = typename super_t::tuple_t;
119 
120  template <bool = context_t::is_lat,
121  typename Dummy = void>
122  struct visit_tuple
123  {
125  template <size_t I>
126  void print_(const tuple_t& v)
127  {
128  if (I)
130  auto rs = detail::make_project<I>(visitor_.rs_);
131  auto print = make_printer(rs, visitor_.out_);
132  print.format(visitor_.fmt_);
133  print.print_child(*std::get<I>(v.sub()), precedence_t::tuple);
134  }
135 
137  template <size_t... I>
139  {
140  using swallow = int[];
141  (void) swallow
142  {
143  (print_<I>(v),
144  0)...
145  };
146  }
147 
149  void operator()(const tuple_t& v)
150  {
154  }
156  };
157 
158  template <typename Dummy>
159  struct visit_tuple<false, Dummy>
160  {
161  void operator()(const tuple_t&)
162  {
164  }
166  };
167 
168  void visit(const tuple_t& v, std::true_type) override
169  {
170  visit_tuple<>{*this}(v);
171  }
172 
173 
178  bool is_letter_(const node_t& v) const
179  {
180  auto atom = dynamic_cast<const atom_t*>(&v);
181  return atom && rs_.labelset()->is_letter(atom->value());
182  }
183 
198  bool is_word_(const node_t& v) const
199  {
200  auto atom = dynamic_cast<const atom_t*>(&v);
201  return (atom
202  && (context_t::is_lat
203  || ! rs_.labelset()->is_letter(atom->value())));
204  }
205 
210  bool is_braced_(const node_t& v) const
211  {
212  if (auto s = dynamic_cast<const sum_t*>(&v))
213  {
214  auto range = letter_range(s->begin(), s->end());
215  return (end(range) == s->end()
216  && 3 < boost::distance(range));
217  }
218  else
219  return false;
220  }
221 
223  precedence_t precedence_(const node_t& v) const;
224 
226  void print_child_(const node_t& child, const node_t& parent);
227 
229  template <rat::exp::type_t Type>
230  void print_(const unary_t<Type>& n, const char* op);
231 
233  template <rat::exp::type_t Type>
234  void print_(const variadic_t<Type>& n, const char* op);
235 
237  ATTRIBUTE_PURE
238  bool shows_left_weight_(const node_t& n)
239  {
240  return n.type() == rat::type_t::lweight;
241  }
242 
245  template <typename Iterator>
246  auto letter_range(Iterator i, Iterator end) const
247  -> boost::iterator_range<Iterator>
248  {
250  (i, end,
251  [this](const value_t& c) { return is_letter_(*c); },
252  [this](const value_t& lhs, const value_t& rhs)
253  {
254  auto l = std::dynamic_pointer_cast<const atom_t>(lhs)->value();
255  auto r = std::dynamic_pointer_cast<const atom_t>(rhs)->value();
256  const auto& ls = *rs_.labelset();
257  // Require strictly increasing order.
258  return ls.less(l, r) || ls.equal(l, r);
259  });
260  }
261 
263  template <typename LS = labelset_t>
264  auto print_sum_(const sum_t& v)
266  {
267  bool first = true;
268  // Use classes for sums of letters.
269  for (auto i = std::begin(v), end = std::end(v);
270  i != end;
271  /* nothing. */)
272  {
273  if (! first)
274  out_ << sum_;
275  first = false;
276  // If in front of a row of letters, in strictly increasing
277  // order, issue a class.
278  auto r = letter_range(i, end);
279  if (3 < distance(r))
280  {
281  // Gather the letters.
282  auto letters = std::vector<label_t>{};
283  for (/* nothing. */; i != r.end(); ++i)
284  letters
285  .emplace_back(down_pointer_cast<const atom_t>(*i)->value());
286  vcsn::detail::print_label_class(*rs_.labelset(), letters,
287  out_, fmt_);
288  }
289  else
290  {
291  // Otherwise, just print the child.
292  print_child_(**i, v);
293  ++i;
294  }
295  }
296  }
297 
299  template <typename LS = labelset_t>
300  auto print_sum_(const sum_t& v)
302  {
303  print_(v, sum_);
304  }
305 
307  std::ostream& out_;
309  class format fmt_;
313  const bool debug_ = !!getenv("VCSN_PARENS");
314 
319  const char* lgroup_ = nullptr;
320  const char* rgroup_ = nullptr;
322  const char* langle_ = nullptr;
323  const char* rangle_ = nullptr;
325  const char* lparen_ = nullptr;
326  const char* rparen_ = nullptr;
328  const char* lmul_ = nullptr;
329  const char* rmul_ = nullptr;
331  const char* ldiv_ = nullptr;
333  const char* star_ = nullptr;
334  const char* complement_ = nullptr;
335  const char* transposition_ = nullptr;
336  const char* conjunction_ = nullptr;
337  const char* infiltration_ = nullptr;
338  const char* shuffle_ = nullptr;
339  const char* product_ = nullptr;
340  const char* sum_ = nullptr;
341 
343  const char* tuple_left = nullptr;
345  const char* tuple_middle = nullptr;
347  const char* tuple_right = nullptr;
348 
350  const char* zero_ = nullptr;
351  const char* one_ = nullptr;
352  };
353 
354  template <typename ExpSet>
356  make_printer(const ExpSet& rs, std::ostream& out)
357  {
358  return {rs, out};
359  }
360  } // namespace rat
361 } // namespace vcsn
362 
363 #include <vcsn/core/rat/printer.hxx>
std::ostream & print_label_class(const LabelSet &ls, const std::vector< typename LabelSet::value_t > &letters, std::ostream &out, format fmt)
Print a set of labels (letterized) with classes.
Definition: labelset.hh:329
typename super_t::tuple_t tuple_t
Definition: printer.hh:118
typename super_t::template unary_t< Type > unary_t
Definition: printer.hh:75
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:46
const char * lgroup_
Left and right boundaries (typically braces for LaTeX).
Definition: printer.hh:319
const char * one_
Definition: printer.hh:351
std::ostream & operator()(const std::shared_ptr< const node_t > &v)
Entry point: print v.
Definition: printer.hh:94
void print_child(const node_t &child, precedence_t parent)
Print the given child node, also knowing its parent's precedence.
Definition: printer.hxx:195
const char * rparen_
Definition: printer.hh:326
typename node_t::value_t value_t
A shared_ptr to node_t.
Definition: printer.hh:72
const char * star_
The expression operators.
Definition: printer.hh:333
void print_(const tuple_t &v, detail::index_sequence< I...>)
Print all the tapes.
Definition: printer.hh:138
typename super_t::leaf_t leaf_t
Definition: printer.hh:78
const char * zero_
The constants.
Definition: printer.hh:350
auto letter_range(Iterator i, Iterator end) const -> boost::iterator_range< Iterator >
Return the longest range of expressions that are letters, in strictly increasing order.
Definition: printer.hh:246
void print_(const unary_t< Type > &n, const char *op)
Print a unary node.
bool is_word_(const node_t &v) const
Whether v is an atom whose label is not a letter.
Definition: printer.hh:198
typename expressionset_t::identities_t identities_t
Definition: printer.hh:63
const char * tuple_middle
Tuple tape separator.
Definition: printer.hh:345
typename super_t::template variadic_t< Type > variadic_t
Definition: printer.hh:77
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:45
const char * lparen_
Left and right parentheses.
Definition: printer.hh:325
typename std::enable_if< Cond, T >::type enable_if_t
Definition: type_traits.hh:16
VCSN_RAT_VISIT(complement, v)
Definition: printer.hh:104
printer< ExpSet > make_printer(const ExpSet &rs, std::ostream &out)
Definition: printer.hh:356
typename super_t::node_t node_t
Actual node, without indirection.
Definition: printer.hh:70
const char * complement_
Definition: printer.hh:334
std::ostream & out_
Output stream.
Definition: printer.hh:307
std::ostream & operator()(const node_t &v)
Entry point: print v.
Definition: printer.hxx:53
bool is_letter_(const node_t &v) const
Whether v is an atom whose label is a letter.
Definition: printer.hh:178
label_t_of< context_t > label_t
Definition: printer.hh:65
void visit(const tuple_t &v, std::true_type) override
Definition: printer.hh:168
const char * langle_
Left and right angle brackets for weights.
Definition: printer.hh:322
precedence_t precedence_(const node_t &v) const
The precedence of v (to decide when to print parens).
Definition: printer.hxx:127
const bool debug_
Whether to be overly verbose.
Definition: printer.hh:313
weight_t_of< context_t > weight_t
Definition: printer.hh:66
const char * ldiv_
Quotient.
Definition: printer.hh:331
void print_child_(const node_t &child, const node_t &parent)
Print the given child node, also knowing its parent.
Definition: printer.hxx:216
An input/output format.
Definition: format.hh:11
void operator()(const tuple_t &v)
Entry point.
Definition: printer.hh:149
const char * rgroup_
Definition: printer.hh:320
std::ostream & print(const Aut &aut, std::ostream &out, const std::string &format)
Definition: print.hh:77
VCSN_RAT_VISIT(prod, v)
Definition: printer.hh:110
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
auto print_sum_(const sum_t &v) -> enable_if_t<!detail::has_genset_mem_fn< LS >
Print a sum, when the labelset does not have a genset() function.
Definition: printer.hh:300
const char * transposition_
Definition: printer.hh:335
typename super_t::inner_t inner_t
Definition: printer.hh:73
VCSN_RAT_VISIT(conjunction, v)
Definition: printer.hh:105
const char * tuple_right
Right tuple delimiter.
Definition: printer.hh:347
precedence_t
The possible node precedence levels, increasing.
Definition: printer.hh:34
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
ExpSet expressionset_t
Definition: printer.hh:61
bool is_braced_(const node_t &v) const
Whether is naturally braced.
Definition: printer.hh:210
const expressionset_t & rs_
The expressionset.
Definition: printer.hh:311
const char * tuple_left
Left tuple delimiter.
Definition: printer.hh:343
printer(const expressionset_t &rs, std::ostream &out)
A printer.
Definition: printer.hxx:40
const label_t & value() const
Definition: expression.hxx:36
const char * rmul_
Definition: printer.hh:329
const char * shuffle_
Definition: printer.hh:338
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: printer.hh:81
context_t_of< expressionset_t > context_t
Definition: printer.hh:62
const char * sum_
Definition: printer.hh:340
auto rs
Definition: lift.hh:151
VCSN_RAT_VISIT(shuffle, v)
Definition: printer.hh:112
const char * infiltration_
Definition: printer.hh:337
labelset_t_of< context_t > labelset_t
Definition: printer.hh:64
VCSN_RAT_VISIT(star, v)
Definition: printer.hh:113
VCSN_RAT_VISIT(transposition, v)
Definition: printer.hh:115
VCSN_RAT_VISIT(ldiv, v)
Definition: printer.hh:107
An inner node implementing a weight.
Definition: expression.hh:264
VCSN_RAT_VISIT(atom, v)
void format(format fmt)
Set output format.
Definition: printer.hxx:70
const char * rangle_
Definition: printer.hh:323
void print_(const tuple_t &v)
Print one tape.
Definition: printer.hh:126
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
auto print_sum_(const sum_t &v) -> enable_if_t< detail::has_genset_mem_fn< LS >
Print a sum, when the labelset has a genset() function.
Definition: printer.hh:264
VCSN_RAT_VISIT(sum, v)
Definition: printer.hh:114
VCSN_RAT_VISIT(infiltration, v)
Definition: printer.hh:106
const char * conjunction_
Definition: printer.hh:336
class format fmt_
Output format.
Definition: printer.hh:309
typename expressionset_t::const_visitor super_t
Definition: printer.hh:68
const char * lmul_
External product.
Definition: printer.hh:328
boost::iterator_range< Iterator > initial_sorted_range(Iterator begin, Iterator end, Pred pred, Less less)
The return the longest initial range of elements matching the predicate.
Definition: algorithm.hh:70
const char * product_
Definition: printer.hh:339
ATTRIBUTE_PURE bool shows_left_weight_(const node_t &n)
Whether the left weight shows.
Definition: printer.hh:238
An inner node with multiple children.
Definition: expression.hh:118
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:50