Vcsn  2.3
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  add,
36  compose,
37  tuple,
38  products,
39  shuffle = products,
42  ldivide,
43  mul,
44  word = mul, // 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 
64  template <typename ExpSet>
65  class printer
66  : public ExpSet::const_visitor
67  {
68  public:
69  using expressionset_t = ExpSet;
70  using super_t = typename expressionset_t::const_visitor;
71  using self_t = printer;
72 
74  using identities_t = typename expressionset_t::identities_t;
78 
80  using node_t = typename super_t::node_t;
82  using value_t = typename node_t::value_t;
83  using inner_t = typename super_t::inner_t;
84  template <type_t Type>
85  using unary_t = typename super_t::template unary_t<Type>;
86  template <type_t Type>
87  using variadic_t = typename super_t::template variadic_t<Type>;
88  using leaf_t = typename super_t::leaf_t;
89 
91  constexpr static const char* me() { return "print"; }
92 
94  printer(const expressionset_t& rs, std::ostream& out);
95 
97  void format(format fmt);
98 
100  std::ostream&
102  {
103  return print_(*v);
104  }
105 
109  void print_child(const node_t& child, precedence_t parent);
110 
111  private:
113  std::ostream& print_(const node_t& v);
114 
116  void print_(const weight_t& w)
117  {
118  rs_.weightset()->print(w, out_, fmt_.for_weights());
119  }
120 
128  VCSN_RAT_VISIT(one, v);
129  VCSN_RAT_VISIT(mul, v);
136 
137  using tuple_t = typename super_t::tuple_t;
138 
139  template <bool = context_t::is_lat,
140  typename Dummy = void>
141  struct visit_tuple
142  {
144  template <size_t I>
145  void print_(const tuple_t& v)
146  {
147  if (I)
149  auto rs = detail::project<I>(visitor_.rs_);
150  auto print = make_printer(rs, visitor_.out_);
151  print.format(visitor_.fmt_);
152  print.print_child(*std::get<I>(v.sub()), precedence_t::tuple);
153  }
154 
156  template <size_t... I>
158  {
159  using swallow = int[];
160  (void) swallow
161  {
162  (print_<I>(v),
163  0)...
164  };
165  }
166 
168  void operator()(const tuple_t& v)
169  {
171  print_(v, labelset_t::indices);
173  }
174  const self_t& visitor_;
175  };
176 
177  template <typename Dummy>
178  struct visit_tuple<false, Dummy>
179  {
180  void operator()(const tuple_t&)
181  {
183  }
184  const self_t& visitor_;
185  };
186 
187  void visit(const tuple_t& v, std::true_type) override
188  {
189  visit_tuple<>{*this}(v);
190  }
191 
192 
197  bool is_letter_(const node_t& v) const
198  {
199  auto atom = dynamic_cast<const atom_t*>(&v);
200  return atom && rs_.labelset()->is_letter(atom->value());
201  }
202 
217  bool is_word_(const node_t& v) const
218  {
219  auto atom = dynamic_cast<const atom_t*>(&v);
220  return (atom
221  && (context_t::is_lat
222  || ! rs_.labelset()->is_letter(atom->value())));
223  }
224 
229  bool is_braced_(const node_t& v) const
230  {
231  if (auto s = dynamic_cast<const add_t*>(&v))
232  {
233  auto range = letter_range(s->begin(), s->end());
234  return (end(range) == s->end()
235  && 3 < boost::distance(range));
236  }
237  else
238  return false;
239  }
240 
242  precedence_t precedence_(const node_t& v) const;
243 
245  void print_child_(const node_t& child, const node_t& parent);
246 
248  template <rat::exp::type_t Type>
249  void print_(const unary_t<Type>& n, const char* op);
250 
252  template <rat::exp::type_t Type>
253  void print_(const variadic_t<Type>& n, const char* op);
254 
256  ATTRIBUTE_PURE
257  bool shows_left_weight_(const node_t& n)
258  {
259  return n.type() == rat::type_t::lweight;
260  }
261 
264  template <typename Iterator>
265  auto letter_range(Iterator i, Iterator end) const
266  -> boost::iterator_range<Iterator>
267  {
269  (i, end,
270  [this](const value_t& c) { return is_letter_(*c); },
271  [this](const value_t& lhs, const value_t& rhs)
272  {
273  auto l = std::dynamic_pointer_cast<const atom_t>(lhs)->value();
274  auto r = std::dynamic_pointer_cast<const atom_t>(rhs)->value();
275  const auto& ls = *rs_.labelset();
276  // Require strictly increasing order.
277  return ls.less(l, r) || ls.equal(l, r);
278  });
279  }
280 
282  template <typename LS = labelset_t>
283  auto print_add_(const add_t& v)
284  -> std::enable_if_t<detail::has_generators_mem_fn<LS>{}, void>
285  {
286  bool first = true;
287  // Use classes for sums of letters.
288  for (auto i = std::begin(v), end = std::end(v);
289  i != end;
290  /* nothing. */)
291  {
292  if (! first)
293  out_ << add_;
294  first = false;
295  // If in front of a row of letters, in strictly increasing
296  // order, issue a class.
297  auto r = letter_range(i, end);
298  if (3 < distance(r))
299  {
300  // Gather the letters.
301  auto letters = std::vector<label_t>{};
302  for (/* nothing. */; i != r.end(); ++i)
303  letters
304  .emplace_back(down_pointer_cast<const atom_t>(*i)->value());
305  vcsn::detail::print_label_class(*rs_.labelset(), letters,
306  out_, fmt_);
307  }
308  else
309  {
310  // Otherwise, just print the child.
311  print_child_(**i, v);
312  ++i;
313  }
314  }
315  }
316 
318  template <typename LS = labelset_t>
319  auto print_add_(const add_t& v)
320  -> std::enable_if_t<!detail::has_generators_mem_fn<LS>{}, void>
321  {
322  print_(v, add_);
323  }
324 
326  std::ostream& out_;
328  class format fmt_;
332  const bool debug_ = !!getenv("VCSN_PARENS");
333 
338  const char* lgroup_ = nullptr;
339  const char* rgroup_ = nullptr;
341  const char* langle_ = nullptr;
342  const char* rangle_ = nullptr;
344  const char* lparen_ = nullptr;
345  const char* rparen_ = nullptr;
347  const char* lexponent_ = nullptr;
348  const char* rexponent_ = nullptr;
350  const char* lweight_ = nullptr;
351  const char* rweight_ = nullptr;
353  const char* ldivide_ = nullptr;
355  const char* star_ = nullptr;
356  const char* complement_ = nullptr;
358  const char* compose_ = nullptr;
359  const char* transposition_ = nullptr;
360  const char* conjunction_ = nullptr;
361  const char* infiltrate_ = nullptr;
362  const char* shuffle_ = nullptr;
363  const char* product_ = nullptr;
364  const char* add_ = nullptr;
365 
367  const char* tuple_left = nullptr;
369  const char* tuple_middle = nullptr;
371  const char* tuple_right = nullptr;
372 
374  const char* zero_ = nullptr;
375  const char* one_ = nullptr;
376  unsigned int exponent_threshold_ = 0;
377  };
378 
379  template <typename ExpSet>
381  make_printer(const ExpSet& rs, std::ostream& out)
382  {
383  return {rs, out};
384  }
385  } // namespace rat
386 } // namespace vcsn
387 
388 #include <vcsn/core/rat/printer.hxx>
return v
Definition: multiply.hh:361
const char * infiltrate_
Definition: printer.hh:361
void visit(const tuple_t &v, std::true_type) override
Specific handling to using exponents as syntactic sugar.
Definition: printer.hh:187
VCSN_RAT_VISIT(shuffle, v)
Definition: printer.hh:131
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:66
typename expressionset_t::const_visitor super_t
Definition: printer.hh:70
labelset_t_of< context_t > labelset_t
Definition: printer.hh:75
const char * product_
Definition: printer.hh:363
auto print_add_(const add_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:319
const char * lweight_
External product.
Definition: printer.hh:350
VCSN_RAT_VISIT(infiltrate, v)
Definition: printer.hh:125
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
boost::iterator_range< Iterator > initial_sorted_range(Iterator begin, Iterator end, Pred pred, Less less)
The longest initial range of elements matching the predicate.
Definition: algorithm.hh:80
const char * rparen_
Definition: printer.hh:345
const char * lexponent_
Left and right braces for exponents.
Definition: printer.hh:347
const char * ldivide_
Left-quotient.
Definition: printer.hh:353
const char * rexponent_
Definition: printer.hh:348
unsigned int exponent_threshold_
Definition: printer.hh:376
typename super_t::leaf_t leaf_t
Definition: printer.hh:88
const char * zero_
The constants.
Definition: printer.hh:374
VCSN_RAT_VISIT(add, v)
Definition: printer.hh:133
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:265
VCSN_RAT_VISIT(compose, v)
Definition: printer.hh:122
typename expressionset_t::identities_t identities_t
Definition: printer.hh:74
void print_(const tuple_t &v, detail::index_sequence< I... >)
Print all the tapes.
Definition: printer.hh:157
const char * tuple_middle
Tuple tape separator.
Definition: printer.hh:369
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:63
VCSN_RAT_VISIT(ldivide, v)
Definition: printer.hh:126
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
context_t_of< expressionset_t > context_t
Definition: printer.hh:73
typename super_t::tuple_t tuple_t
Definition: printer.hh:137
VCSN_RAT_VISIT(complement, v)
Definition: printer.hh:123
bool is_word_(const node_t &v) const
Whether v is an atom whose label is not a letter.
Definition: printer.hh:217
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:64
An inner node implementing a weight.
Definition: expression.hh:264
const char * tuple_left
Left tuple delimiter.
Definition: printer.hh:367
const char * lgroup_
Left and right boundaries (typically braces for LaTeX).
Definition: printer.hh:338
bool is_letter_(const node_t &v) const
Whether v is an atom whose label is a letter.
Definition: printer.hh:197
const char * add_
Definition: printer.hh:364
typename super_t::template unary_t< Type > unary_t
Definition: printer.hh:85
precedence_t precedence_(const node_t &v) const
The precedence of v (to decide when to print parens).
Definition: printer.hxx:163
std::ostream & out_
Output stream.
Definition: printer.hh:326
const label_t & value() const
Definition: expression.hxx:34
void print_(const weight_t &w)
Print a weight.
Definition: printer.hh:116
VCSN_RAT_VISIT(transposition, v)
Definition: printer.hh:134
weight_t_of< context_t > weight_t
Definition: printer.hh:77
precedence_t
The possible node precedence levels, increasing.
Definition: printer.hh:33
const char * rgroup_
Definition: printer.hh:339
bool is_braced_(const node_t &v) const
Whether is naturally braced.
Definition: printer.hh:229
std::ostream & operator()(const value_t &v)
Entry point: print v.
Definition: printer.hh:101
std::ostream & print(const Aut &aut, std::ostream &out=std::cout, const std::string &fmt="default")
Definition: print.hh:74
auto rs
Definition: lift.hh:152
printer(const expressionset_t &rs, std::ostream &out)
A printer.
Definition: printer.hxx:40
const char * transposition_
Definition: printer.hh:359
const char * tuple_right
Right tuple delimiter.
Definition: printer.hh:371
Definition: a-star.hh:8
void print_child_(const node_t &child, const node_t &parent)
Print a child node, given its parent.
Definition: printer.hxx:302
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:62
ExpSet expressionset_t
Definition: printer.hh:69
const expressionset_t & rs_
The expressionset.
Definition: printer.hh:330
void format(format fmt)
Set output format.
Definition: printer.hxx:69
const char * conjunction_
Definition: printer.hh:360
An input/output format for valuesets.
Definition: format.hh:13
std::ostream & print_(const node_t &v)
Print v.
Definition: printer.hxx:52
VCSN_RAT_VISIT(star, v)
Definition: printer.hh:132
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: printer.hh:91
const char * lparen_
Left and right parentheses.
Definition: printer.hh:344
typename super_t::inner_t inner_t
Definition: printer.hh:83
void operator()(const tuple_t &v)
Entry point.
Definition: printer.hh:168
Pretty-printer for rational expressions.
Definition: fwd.hh:28
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:324
const char * one_
Definition: printer.hh:375
const char * rweight_
Definition: printer.hh:351
typename node_t::value_t value_t
A shared_ptr to node_t.
Definition: printer.hh:82
label_t_of< context_t > label_t
Definition: printer.hh:76
const char * compose_
Operator for composition: @.
Definition: printer.hh:358
const char * langle_
Left and right angle brackets for weights.
Definition: printer.hh:341
const char * star_
The expression operators.
Definition: printer.hh:355
const bool debug_
Whether to be overly verbose.
Definition: printer.hh:332
void print_child(const node_t &child, precedence_t parent)
Print a child node, given its parent's precedence.
Definition: printer.hxx:281
void print_(const tuple_t &v)
Print one tape.
Definition: printer.hh:145
auto print_add_(const add_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:283
An inner node with multiple children.
Definition: expression.hh:118
const char * rangle_
Definition: printer.hh:342
ATTRIBUTE_PURE bool shows_left_weight_(const node_t &n)
Whether the left weight shows.
Definition: printer.hh:257
const char * shuffle_
Definition: printer.hh:362
static constexpr const char *const superscripts[]
Exponents in UTF-8.
Definition: printer.hh:58
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
VCSN_RAT_VISIT(conjunction, v)
Definition: printer.hh:124
VCSN_RAT_VISIT(atom, v)
typename super_t::node_t node_t
Actual node, without indirection.
Definition: printer.hh:80
class format fmt_
Output format.
Definition: printer.hh:328
typename super_t::template variadic_t< Type > variadic_t
Definition: printer.hh:87
const char * complement_
Definition: printer.hh:356
printer< ExpSet > make_printer(const ExpSet &rs, std::ostream &out)
Definition: printer.hh:381
format for_weights() const
A copy of this format, but to print weights.
Definition: format.hh:50