Vcsn  2.2a
Be Rational
printer.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 
5 #include <vcsn/algos/project.hh> // bad layering: should not be in algos.
8 #include <vcsn/ctx/traits.hh>
9 #include <vcsn/labelset/labelset.hh> // has_generators_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  {
33  enum class precedence_t
34  {
35  sum,
36  tuple,
37  products,
38  shuffle = products,
41  ldiv,
42  prod,
43  word = prod, // Multi-letter atoms.
44  lweight,
45  rweight,
46  unary, // All the unary (postfix) operators.
47  star = unary,
48  complement = unary,
50  exponent = unary,
51  zero,
52  one,
53  atom,
54  };
55 
57  constexpr static const char* const superscripts[] =
58  {
59  "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"
60  };
61 
63  template <typename ExpSet>
64  class printer
65  : public ExpSet::const_visitor
66  {
67  public:
68  using expressionset_t = ExpSet;
69  using super_t = typename expressionset_t::const_visitor;
70  using self_t = printer;
71 
73  using identities_t = typename expressionset_t::identities_t;
77 
79  using node_t = typename super_t::node_t;
81  using value_t = typename node_t::value_t;
82  using inner_t = typename super_t::inner_t;
83  template <type_t Type>
84  using unary_t = typename super_t::template unary_t<Type>;
85  template <type_t Type>
86  using variadic_t = typename super_t::template variadic_t<Type>;
87  using leaf_t = typename super_t::leaf_t;
88 
90  constexpr static const char* me() { return "print"; }
91 
93  printer(const expressionset_t& rs, std::ostream& out);
94 
96  void format(format fmt);
97 
99  std::ostream&
101  {
102  return print_(*v);
103  }
104 
108  void print_child(const node_t& child, precedence_t parent);
109 
110  private:
112  std::ostream& print_(const node_t& v);
113 
115  void print_(const weight_t& w)
116  {
117  rs_.weightset()->print(w, out_, fmt_.for_weights());
118  }
119 
126  VCSN_RAT_VISIT(one, v);
134 
135  using tuple_t = typename super_t::tuple_t;
136 
137  template <bool = context_t::is_lat,
138  typename Dummy = void>
139  struct visit_tuple
140  {
142  template <size_t I>
143  void print_(const tuple_t& v)
144  {
145  if (I)
147  auto rs = detail::project<I>(visitor_.rs_);
148  auto print = make_printer(rs, visitor_.out_);
149  print.format(visitor_.fmt_);
150  print.print_child(*std::get<I>(v.sub()), precedence_t::tuple);
151  }
152 
154  template <size_t... I>
156  {
157  using swallow = int[];
158  (void) swallow
159  {
160  (print_<I>(v),
161  0)...
162  };
163  }
164 
166  void operator()(const tuple_t& v)
167  {
169  print_(v, labelset_t::indices);
171  }
172  const self_t& visitor_;
173  };
174 
175  template <typename Dummy>
176  struct visit_tuple<false, Dummy>
177  {
178  void operator()(const tuple_t&)
179  {
181  }
182  const self_t& visitor_;
183  };
184 
185  void visit(const tuple_t& v, std::true_type) override
186  {
187  visit_tuple<>{*this}(v);
188  }
189 
190 
195  bool is_letter_(const node_t& v) const
196  {
197  auto atom = dynamic_cast<const atom_t*>(&v);
198  return atom && rs_.labelset()->is_letter(atom->value());
199  }
200 
215  bool is_word_(const node_t& v) const
216  {
217  auto atom = dynamic_cast<const atom_t*>(&v);
218  return (atom
219  && (context_t::is_lat
220  || ! rs_.labelset()->is_letter(atom->value())));
221  }
222 
227  bool is_braced_(const node_t& v) const
228  {
229  if (auto s = dynamic_cast<const sum_t*>(&v))
230  {
231  auto range = letter_range(s->begin(), s->end());
232  return (end(range) == s->end()
233  && 3 < boost::distance(range));
234  }
235  else
236  return false;
237  }
238 
240  precedence_t precedence_(const node_t& v) const;
241 
243  void print_child_(const node_t& child, const node_t& parent);
244 
246  template <rat::exp::type_t Type>
247  void print_(const unary_t<Type>& n, const char* op);
248 
250  template <rat::exp::type_t Type>
251  void print_(const variadic_t<Type>& n, const char* op);
252 
254  ATTRIBUTE_PURE
255  bool shows_left_weight_(const node_t& n)
256  {
257  return n.type() == rat::type_t::lweight;
258  }
259 
262  template <typename Iterator>
263  auto letter_range(Iterator i, Iterator end) const
264  -> boost::iterator_range<Iterator>
265  {
267  (i, end,
268  [this](const value_t& c) { return is_letter_(*c); },
269  [this](const value_t& lhs, const value_t& rhs)
270  {
271  auto l = std::dynamic_pointer_cast<const atom_t>(lhs)->value();
272  auto r = std::dynamic_pointer_cast<const atom_t>(rhs)->value();
273  const auto& ls = *rs_.labelset();
274  // Require strictly increasing order.
275  return ls.less(l, r) || ls.equal(l, r);
276  });
277  }
278 
280  template <typename LS = labelset_t>
281  auto print_sum_(const sum_t& v)
282  -> std::enable_if_t<detail::has_generators_mem_fn<LS>{}, void>
283  {
284  bool first = true;
285  // Use classes for sums of letters.
286  for (auto i = std::begin(v), end = std::end(v);
287  i != end;
288  /* nothing. */)
289  {
290  if (! first)
291  out_ << sum_;
292  first = false;
293  // If in front of a row of letters, in strictly increasing
294  // order, issue a class.
295  auto r = letter_range(i, end);
296  if (3 < distance(r))
297  {
298  // Gather the letters.
299  auto letters = std::vector<label_t>{};
300  for (/* nothing. */; i != r.end(); ++i)
301  letters
302  .emplace_back(down_pointer_cast<const atom_t>(*i)->value());
303  vcsn::detail::print_label_class(*rs_.labelset(), letters,
304  out_, fmt_);
305  }
306  else
307  {
308  // Otherwise, just print the child.
309  print_child_(**i, v);
310  ++i;
311  }
312  }
313  }
314 
316  template <typename LS = labelset_t>
317  auto print_sum_(const sum_t& v)
318  -> std::enable_if_t<!detail::has_generators_mem_fn<LS>{}, void>
319  {
320  print_(v, sum_);
321  }
322 
324  std::ostream& out_;
326  class format fmt_;
330  const bool debug_ = !!getenv("VCSN_PARENS");
331 
336  const char* lgroup_ = nullptr;
337  const char* rgroup_ = nullptr;
339  const char* langle_ = nullptr;
340  const char* rangle_ = nullptr;
342  const char* lparen_ = nullptr;
343  const char* rparen_ = nullptr;
345  const char* lexponent_ = nullptr;
346  const char* rexponent_ = nullptr;
348  const char* lmul_ = nullptr;
349  const char* rmul_ = nullptr;
351  const char* ldiv_ = nullptr;
353  const char* star_ = nullptr;
354  const char* complement_ = nullptr;
355  const char* transposition_ = nullptr;
356  const char* conjunction_ = nullptr;
357  const char* infiltration_ = nullptr;
358  const char* shuffle_ = nullptr;
359  const char* product_ = nullptr;
360  const char* sum_ = nullptr;
361 
363  const char* tuple_left = nullptr;
365  const char* tuple_middle = nullptr;
367  const char* tuple_right = nullptr;
368 
370  const char* zero_ = nullptr;
371  const char* one_ = nullptr;
372  unsigned int exponent_threshold_ = 0;
373  };
374 
375  template <typename ExpSet>
377  make_printer(const ExpSet& rs, std::ostream& out)
378  {
379  return {rs, out};
380  }
381  } // namespace rat
382 } // namespace vcsn
383 
384 #include <vcsn/core/rat/printer.hxx>
const char * conjunction_
Definition: printer.hh:356
void print_(const tuple_t &v, detail::index_sequence< I... >)
Print all the tapes.
Definition: printer.hh:155
const char * tuple_left
Left tuple delimiter.
Definition: printer.hh:363
printer< ExpSet > make_printer(const ExpSet &rs, std::ostream &out)
Definition: printer.hh:377
const char * shuffle_
Definition: printer.hh:358
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
typename super_t::leaf_t leaf_t
Definition: printer.hh:87
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
typename super_t::tuple_t tuple_t
Definition: printer.hh:135
bool is_braced_(const node_t &v) const
Whether is naturally braced.
Definition: printer.hh:227
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:54
An inner node implementing a weight.
Definition: expression.hh:264
const char * rmul_
Definition: printer.hh:349
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
context_t_of< expressionset_t > context_t
Definition: printer.hh:72
VCSN_RAT_VISIT(complement, v)
Definition: printer.hh:121
VCSN_RAT_VISIT(atom, v)
ExpSet expressionset_t
Definition: printer.hh:68
class format fmt_
Output format.
Definition: printer.hh:326
const char * lparen_
Left and right parentheses.
Definition: printer.hh:342
std::ostream & print(const Aut &aut, std::ostream &out, const std::string &fmt)
Definition: print.hh:78
const expressionset_t & rs_
The expressionset.
Definition: printer.hh:328
const char * ldiv_
Quotient.
Definition: printer.hh:351
VCSN_RAT_VISIT(sum, v)
Definition: printer.hh:131
void print_(const tuple_t &v)
Print one tape.
Definition: printer.hh:143
std::ostream & out_
Output stream.
Definition: printer.hh:324
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: printer.hh:90
auto print_sum_(const sum_t &v) -> std::enable_if_t< detail::has_generators_mem_fn< LS >
Print a sum, when the labelset has a genset() function.
Definition: printer.hh:281
typename super_t::inner_t inner_t
Definition: printer.hh:82
void print_(const weight_t &w)
Print a weight.
Definition: printer.hh:115
weight_t_of< context_t > weight_t
Definition: printer.hh:76
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:263
void operator()(const tuple_t &v)
Entry point.
Definition: printer.hh:166
const char * rparen_
Definition: printer.hh:343
VCSN_RAT_VISIT(infiltration, v)
Definition: printer.hh:123
std::ostream & operator()(const value_t &v)
Entry point: print v.
Definition: printer.hh:100
const char * rgroup_
Definition: printer.hh:337
typename super_t::template variadic_t< Type > variadic_t
Definition: printer.hh:86
const char * complement_
Definition: printer.hh:354
const char * langle_
Left and right angle brackets for weights.
Definition: printer.hh:339
unsigned int exponent_threshold_
Definition: printer.hh:372
void print_child_(const node_t &child, const node_t &parent)
Print a child node, given its parent.
Definition: printer.hxx:295
typename node_t::value_t value_t
A shared_ptr to node_t.
Definition: printer.hh:81
void format(format fmt)
Set output format.
Definition: printer.hxx:68
const char * tuple_middle
Tuple tape separator.
Definition: printer.hh:365
ATTRIBUTE_PURE bool shows_left_weight_(const node_t &n)
Whether the left weight shows.
Definition: printer.hh:255
const char * product_
Definition: printer.hh:359
auto rs
Definition: lift.hh:151
const char * sum_
Definition: printer.hh:360
bool is_letter_(const node_t &v) const
Whether v is an atom whose label is a letter.
Definition: printer.hh:195
const char * lexponent_
Left and right braces for exponents.
Definition: printer.hh:345
Pretty-printer for rational expressions.
Definition: fwd.hh:28
typename super_t::template unary_t< Type > unary_t
Definition: printer.hh:84
VCSN_RAT_VISIT(star, v)
Definition: printer.hh:130
auto print_sum_(const sum_t &v) -> std::enable_if_t<!detail::has_generators_mem_fn< LS >
Print a sum, when the labelset does not have a genset() function.
Definition: printer.hh:317
VCSN_RAT_VISIT(ldiv, v)
Definition: printer.hh:124
precedence_t
The possible node precedence levels, increasing.
Definition: printer.hh:33
const char * lmul_
External product.
Definition: printer.hh:348
const char * infiltration_
Definition: printer.hh:357
typename expressionset_t::const_visitor super_t
Definition: printer.hh:69
labelset_t_of< context_t > labelset_t
Definition: printer.hh:74
static constexpr const char *const superscripts[]
Exponents in UTF-8.
Definition: printer.hh:57
format for_weights() const
A copy of this format, but to print weights.
Definition: format.hh:48
void print_child(const node_t &child, precedence_t parent)
Print a child node, given its parent's precedence.
Definition: printer.hxx:274
std::ostream & print_(const node_t &v)
Print v.
Definition: printer.hxx:51
const char * rexponent_
Definition: printer.hh:346
An inner node with multiple children.
Definition: expression.hh:118
const char * one_
Definition: printer.hh:371
typename super_t::node_t node_t
Actual node, without indirection.
Definition: printer.hh:79
const label_t & value() const
Definition: expression.hxx:36
VCSN_RAT_VISIT(shuffle, v)
Definition: printer.hh:129
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:56
precedence_t precedence_(const node_t &v) const
The precedence of v (to decide when to print parens).
Definition: printer.hxx:159
const char * star_
The expression operators.
Definition: printer.hh:353
printer(const expressionset_t &rs, std::ostream &out)
A printer.
Definition: printer.hxx:39
const char * zero_
The constants.
Definition: printer.hh:370
VCSN_RAT_VISIT(conjunction, v)
Definition: printer.hh:122
VCSN_RAT_VISIT(transposition, v)
Definition: printer.hh:132
void visit(const tuple_t &v, std::true_type) override
Definition: printer.hh:185
typename expressionset_t::identities_t identities_t
Definition: printer.hh:73
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:55
label_t_of< context_t > label_t
Definition: printer.hh:75
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:71
bool is_word_(const node_t &v) const
Whether v is an atom whose label is not a letter.
Definition: printer.hh:215
const char * rangle_
Definition: printer.hh:340
const char * transposition_
Definition: printer.hh:355
const char * lgroup_
Left and right boundaries (typically braces for LaTeX).
Definition: printer.hh:336
const char * tuple_right
Right tuple delimiter.
Definition: printer.hh:367
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:335
const bool debug_
Whether to be overly verbose.
Definition: printer.hh:330
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:58
An input/output format for valuesets.
Definition: format.hh:11
Definition: a-star.hh:8