Vcsn  2.2
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  {
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  exponent = unary,
52  zero,
53  one,
54  atom,
55  };
56 
58  constexpr static const char* const superscripts[] =
59  {
60  "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"
61  };
62 
63  template <typename ExpSet>
64  class printer
65  : public ExpSet::const_visitor
66  {
67  public:
68  using expressionset_t = ExpSet;
70  using identities_t = typename expressionset_t::identities_t;
74 
75  using super_t = typename expressionset_t::const_visitor;
77  using node_t = typename super_t::node_t;
79  using value_t = typename node_t::value_t;
80  using inner_t = typename super_t::inner_t;
81  template <type_t Type>
82  using unary_t = typename super_t::template unary_t<Type>;
83  template <type_t Type>
84  using variadic_t = typename super_t::template variadic_t<Type>;
85  using leaf_t = typename super_t::leaf_t;
86 
88  constexpr static const char* me() { return "print"; }
89 
91  printer(const expressionset_t& rs, std::ostream& out);
92 
94  void format(format fmt);
95 
97  std::ostream& operator()(const node_t& v);
98 
100  std::ostream&
101  operator()(const std::shared_ptr<const node_t>& v)
102  {
103  return operator()(*v);
104  }
105 
107  void print_child(const node_t& child, precedence_t parent);
108 
109  private:
116  VCSN_RAT_VISIT(one, v);
124 
125  using tuple_t = typename super_t::tuple_t;
126 
127  template <bool = context_t::is_lat,
128  typename Dummy = void>
129  struct visit_tuple
130  {
132  template <size_t I>
133  void print_(const tuple_t& v)
134  {
135  if (I)
137  auto rs = detail::project<I>(visitor_.rs_);
138  auto print = make_printer(rs, visitor_.out_);
139  print.format(visitor_.fmt_);
140  print.print_child(*std::get<I>(v.sub()), precedence_t::tuple);
141  }
142 
144  template <size_t... I>
146  {
147  using swallow = int[];
148  (void) swallow
149  {
150  (print_<I>(v),
151  0)...
152  };
153  }
154 
156  void operator()(const tuple_t& v)
157  {
159  print_(v, labelset_t::indices);
161  }
163  };
164 
165  template <typename Dummy>
166  struct visit_tuple<false, Dummy>
167  {
168  void operator()(const tuple_t&)
169  {
171  }
173  };
174 
175  void visit(const tuple_t& v, std::true_type) override
176  {
177  visit_tuple<>{*this}(v);
178  }
179 
180 
185  bool is_letter_(const node_t& v) const
186  {
187  auto atom = dynamic_cast<const atom_t*>(&v);
188  return atom && rs_.labelset()->is_letter(atom->value());
189  }
190 
205  bool is_word_(const node_t& v) const
206  {
207  auto atom = dynamic_cast<const atom_t*>(&v);
208  return (atom
209  && (context_t::is_lat
210  || ! rs_.labelset()->is_letter(atom->value())));
211  }
212 
217  bool is_braced_(const node_t& v) const
218  {
219  if (auto s = dynamic_cast<const sum_t*>(&v))
220  {
221  auto range = letter_range(s->begin(), s->end());
222  return (end(range) == s->end()
223  && 3 < boost::distance(range));
224  }
225  else
226  return false;
227  }
228 
230  precedence_t precedence_(const node_t& v) const;
231 
233  void print_child_(const node_t& child, const node_t& parent);
234 
236  template <rat::exp::type_t Type>
237  void print_(const unary_t<Type>& n, const char* op);
238 
240  template <rat::exp::type_t Type>
241  void print_(const variadic_t<Type>& n, const char* op);
242 
244  ATTRIBUTE_PURE
245  bool shows_left_weight_(const node_t& n)
246  {
247  return n.type() == rat::type_t::lweight;
248  }
249 
252  template <typename Iterator>
253  auto letter_range(Iterator i, Iterator end) const
254  -> boost::iterator_range<Iterator>
255  {
257  (i, end,
258  [this](const value_t& c) { return is_letter_(*c); },
259  [this](const value_t& lhs, const value_t& rhs)
260  {
261  auto l = std::dynamic_pointer_cast<const atom_t>(lhs)->value();
262  auto r = std::dynamic_pointer_cast<const atom_t>(rhs)->value();
263  const auto& ls = *rs_.labelset();
264  // Require strictly increasing order.
265  return ls.less(l, r) || ls.equal(l, r);
266  });
267  }
268 
270  template <typename LS = labelset_t>
271  auto print_sum_(const sum_t& v)
272  -> std::enable_if_t<detail::has_generators_mem_fn<LS>{}, void>
273  {
274  bool first = true;
275  // Use classes for sums of letters.
276  for (auto i = std::begin(v), end = std::end(v);
277  i != end;
278  /* nothing. */)
279  {
280  if (! first)
281  out_ << sum_;
282  first = false;
283  // If in front of a row of letters, in strictly increasing
284  // order, issue a class.
285  auto r = letter_range(i, end);
286  if (3 < distance(r))
287  {
288  // Gather the letters.
289  auto letters = std::vector<label_t>{};
290  for (/* nothing. */; i != r.end(); ++i)
291  letters
292  .emplace_back(down_pointer_cast<const atom_t>(*i)->value());
293  vcsn::detail::print_label_class(*rs_.labelset(), letters,
294  out_, fmt_);
295  }
296  else
297  {
298  // Otherwise, just print the child.
299  print_child_(**i, v);
300  ++i;
301  }
302  }
303  }
304 
306  template <typename LS = labelset_t>
307  auto print_sum_(const sum_t& v)
308  -> std::enable_if_t<!detail::has_generators_mem_fn<LS>{}, void>
309  {
310  print_(v, sum_);
311  }
312 
314  std::ostream& out_;
316  class format fmt_;
320  const bool debug_ = !!getenv("VCSN_PARENS");
321 
326  const char* lgroup_ = nullptr;
327  const char* rgroup_ = nullptr;
329  const char* langle_ = nullptr;
330  const char* rangle_ = nullptr;
332  const char* lparen_ = nullptr;
333  const char* rparen_ = nullptr;
335  const char* lexponent_ = nullptr;
336  const char* rexponent_ = nullptr;
338  const char* lmul_ = nullptr;
339  const char* rmul_ = nullptr;
341  const char* ldiv_ = nullptr;
343  const char* star_ = nullptr;
344  const char* complement_ = nullptr;
345  const char* transposition_ = nullptr;
346  const char* conjunction_ = nullptr;
347  const char* infiltration_ = nullptr;
348  const char* shuffle_ = nullptr;
349  const char* product_ = nullptr;
350  const char* sum_ = nullptr;
351 
353  const char* tuple_left = nullptr;
355  const char* tuple_middle = nullptr;
357  const char* tuple_right = nullptr;
358 
360  const char* zero_ = nullptr;
361  const char* one_ = nullptr;
362  unsigned int exponent_threshold_ = 0;
363  };
364 
365  template <typename ExpSet>
367  make_printer(const ExpSet& rs, std::ostream& out)
368  {
369  return {rs, out};
370  }
371  } // namespace rat
372 } // namespace vcsn
373 
374 #include <vcsn/core/rat/printer.hxx>
const char * star_
The expression operators.
Definition: printer.hh:343
printer(const expressionset_t &rs, std::ostream &out)
A printer.
Definition: printer.hxx:41
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
const char * lparen_
Left and right parentheses.
Definition: printer.hh:332
void print_(const tuple_t &v)
Print one tape.
Definition: printer.hh:133
VCSN_RAT_VISIT(transposition, v)
Definition: printer.hh:122
void visit(const tuple_t &v, std::true_type) override
Definition: printer.hh:175
const expressionset_t & rs_
The expressionset.
Definition: printer.hh:318
const char * transposition_
Definition: printer.hh:345
std::ostream & out_
Output stream.
Definition: printer.hh:314
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: printer.hh:88
typename super_t::inner_t inner_t
Definition: printer.hh:80
weight_t_of< context_t > weight_t
Definition: printer.hh:73
const char * rparen_
Definition: printer.hh:333
VCSN_RAT_VISIT(infiltration, v)
Definition: printer.hh:113
const char * rgroup_
Definition: printer.hh:327
const char * conjunction_
Definition: printer.hh:346
const char * tuple_left
Left tuple delimiter.
Definition: printer.hh:353
const char * langle_
Left and right angle brackets for weights.
Definition: printer.hh:329
Definition: a-star.hh:8
void print_child_(const node_t &child, const node_t &parent)
Print the given child node, also knowing its parent.
Definition: printer.hxx:298
const char * tuple_middle
Tuple tape separator.
Definition: printer.hh:355
bool is_braced_(const node_t &v) const
Whether is naturally braced.
Definition: printer.hh:217
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:55
const char * product_
Definition: printer.hh:349
context_t_of< expressionset_t > context_t
Definition: printer.hh:69
const char * sum_
Definition: printer.hh:350
An input/output format for valuesets.
Definition: format.hh:11
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
An inner node with multiple children.
Definition: expression.hh:118
std::ostream & operator()(const std::shared_ptr< const node_t > &v)
Entry point: print v.
Definition: printer.hh:101
ExpSet expressionset_t
Definition: printer.hh:68
typename super_t::template unary_t< Type > unary_t
Definition: printer.hh:82
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:58
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:307
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
VCSN_RAT_VISIT(ldiv, v)
Definition: printer.hh:114
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:56
const char * ldiv_
Quotient.
Definition: printer.hh:341
VCSN_RAT_VISIT(sum, v)
Definition: printer.hh:121
static constexpr const char *const superscripts[]
Exponents in UTF-8.
Definition: printer.hh:58
const char * infiltration_
Definition: printer.hh:347
typename expressionset_t::const_visitor super_t
Definition: printer.hh:75
labelset_t_of< context_t > labelset_t
Definition: printer.hh:71
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:271
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:253
typename super_t::template variadic_t< Type > variadic_t
Definition: printer.hh:84
const char * complement_
Definition: printer.hh:344
auto rs
Definition: lift.hh:151
unsigned int exponent_threshold_
Definition: printer.hh:362
void print_(const tuple_t &v, detail::index_sequence< I... >)
Print all the tapes.
Definition: printer.hh:145
printer< ExpSet > make_printer(const ExpSet &rs, std::ostream &out)
Definition: printer.hh:367
typename node_t::value_t value_t
A shared_ptr to node_t.
Definition: printer.hh:79
void format(format fmt)
Set output format.
Definition: printer.hxx:71
VCSN_RAT_VISIT(shuffle, v)
Definition: printer.hh:119
precedence_t precedence_(const node_t &v) const
The precedence of v (to decide when to print parens).
Definition: printer.hxx:162
ATTRIBUTE_PURE bool shows_left_weight_(const node_t &n)
Whether the left weight shows.
Definition: printer.hh:245
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
std::ostream & print(const Aut &aut, std::ostream &out, const std::string &fmt)
Definition: print.hh:77
const char * zero_
The constants.
Definition: printer.hh:360
VCSN_RAT_VISIT(conjunction, v)
Definition: printer.hh:112
precedence_t
The possible node precedence levels, increasing.
Definition: printer.hh:34
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:54
bool is_letter_(const node_t &v) const
Whether v is an atom whose label is a letter.
Definition: printer.hh:185
const char * lexponent_
Left and right braces for exponents.
Definition: printer.hh:335
An inner node implementing a weight.
Definition: expression.hh:264
typename expressionset_t::identities_t identities_t
Definition: printer.hh:70
label_t_of< context_t > label_t
Definition: printer.hh:72
bool is_word_(const node_t &v) const
Whether v is an atom whose label is not a letter.
Definition: printer.hh:205
const char * rangle_
Definition: printer.hh:330
void operator()(const tuple_t &v)
Entry point.
Definition: printer.hh:156
VCSN_RAT_VISIT(star, v)
Definition: printer.hh:120
const char * lgroup_
Left and right boundaries (typically braces for LaTeX).
Definition: printer.hh:326
std::ostream & operator()(const node_t &v)
Entry point: print v.
Definition: printer.hxx:54
const char * tuple_right
Right tuple delimiter.
Definition: printer.hh:357
const bool debug_
Whether to be overly verbose.
Definition: printer.hh:320
const label_t & value() const
Definition: expression.hxx:36
void print_(const unary_t< Type > &n, const char *op)
Print a unary node.
const char * lmul_
External product.
Definition: printer.hh:338
const char * shuffle_
Definition: printer.hh:348
typename super_t::leaf_t leaf_t
Definition: printer.hh:85
void print_child(const node_t &child, precedence_t parent)
Print the given child node, also knowing its parent's precedence.
Definition: printer.hxx:277
typename super_t::tuple_t tuple_t
Definition: printer.hh:125
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 char * rexponent_
Definition: printer.hh:336
const char * rmul_
Definition: printer.hh:339
const char * one_
Definition: printer.hh:361
VCSN_RAT_VISIT(complement, v)
Definition: printer.hh:111
VCSN_RAT_VISIT(atom, v)
typename super_t::node_t node_t
Actual node, without indirection.
Definition: printer.hh:77
class format fmt_
Output format.
Definition: printer.hh:316