Line data Source code
1 : // Author(s): Wieger Wesselink 2 : // Copyright: see the accompanying file COPYING or copy at 3 : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING 4 : // 5 : // Distributed under the Boost Software License, Version 1.0. 6 : // (See accompanying file LICENSE_1_0.txt or copy at 7 : // http://www.boost.org/LICENSE_1_0.txt) 8 : // 9 : /// \file mcrl2/core/print.h 10 : /// \brief Functions for pretty printing ATerms. 11 : 12 : #ifndef MCRL2_CORE_PRINT_H 13 : #define MCRL2_CORE_PRINT_H 14 : 15 : #include "mcrl2/core/print_format.h" 16 : #include "mcrl2/core/traverser.h" 17 : #include <cctype> 18 : 19 : namespace mcrl2 20 : { 21 : namespace core 22 : { 23 : 24 : /// \cond INTERNAL_DOCS 25 : namespace detail 26 : { 27 : 28 : const int max_precedence = 10000; 29 : 30 : template <typename T> 31 : int precedence(const T&) 32 : { 33 : return max_precedence; 34 : } 35 : 36 : template <typename Derived> 37 : struct printer: public core::traverser<Derived> 38 : { 39 : typedef core::traverser<Derived> super; 40 : 41 : using super::enter; 42 : using super::leave; 43 : using super::apply; 44 : 45 : std::ostream* m_out; 46 : 47 1207644 : Derived& derived() 48 : { 49 1207644 : return static_cast<Derived&>(*this); 50 : } 51 : 52 352846 : std::ostream& out() 53 : { 54 352846 : return *m_out; 55 : } 56 : 57 352846 : void print(const std::string& s) 58 : { 59 352846 : out() << s; 60 352846 : } 61 : 62 : template <typename T> 63 29613 : void print_expression(const T& x, bool needs_parentheses) 64 : { 65 29613 : if (needs_parentheses) 66 : { 67 3912 : derived().print("("); 68 : } 69 29613 : derived().apply(x); 70 29613 : if (needs_parentheses) 71 : { 72 3912 : derived().print(")"); 73 : } 74 29613 : } 75 : 76 : template <typename T, typename U> 77 2368 : void print_unary_operand(const T& x, const U& operand) 78 : { 79 2368 : print_expression(operand, precedence(operand) < precedence(x)); 80 2368 : } 81 : 82 : template <typename T> 83 24 : void print_unary_left_operation(const T& x, const std::string& op) 84 : { 85 24 : derived().print(op); 86 24 : print_unary_operand(x, x.operand()); 87 24 : } 88 : 89 : template <typename T> 90 11 : void print_unary_right_operation(const T& x, const std::string& op) 91 : { 92 11 : print_unary_operand(x, x.operand()); 93 11 : derived().print(op); 94 11 : } 95 : 96 : template <typename T> 97 110 : void print_binary_operation(const T& x, const std::string& op) 98 : { 99 110 : const auto& x1 = x.left(); 100 110 : const auto& x2 = x.right(); 101 110 : auto p = precedence(x); 102 110 : auto p1 = precedence(x1); 103 110 : auto p2 = precedence(x2); 104 110 : print_expression(x1, (p1 < p) || (p1 == p && !is_left_associative(x))); 105 110 : derived().print(op); 106 110 : print_expression(x2, (p2 < p) || (p2 == p && !is_right_associative(x))); 107 110 : } 108 : 109 : template <typename Container> 110 13722 : void print_list(const Container& container, 111 : const std::string& opener = "(", 112 : const std::string& closer = ")", 113 : const std::string& separator = ", ", 114 : bool print_empty_container = false 115 : ) 116 : { 117 13722 : if (container.empty() && !print_empty_container) 118 : { 119 1101 : return; 120 : } 121 12621 : derived().print(opener); 122 44377 : for (auto i = container.begin(); i != container.end(); ++i) 123 : { 124 31756 : if (i != container.begin()) 125 : { 126 19135 : derived().print(separator); 127 : } 128 31756 : derived().apply(*i); 129 : } 130 12621 : derived().print(closer); 131 : } 132 : 133 : template <typename T> 134 : void apply(const atermpp::term_appl<T>& x) 135 : { 136 : derived().enter(x); 137 : derived().print(utilities::to_string(x)); 138 : derived().leave(x); 139 : } 140 : 141 : template <typename T> 142 : void apply(const std::list<T>& x) 143 : { 144 : derived().enter(x); 145 : print_list(x, "", "", ", "); 146 : derived().leave(x); 147 : } 148 : 149 : template <typename T> 150 172 : void apply(const atermpp::term_list<T>& x) 151 : { 152 172 : derived().enter(x); 153 172 : print_list(x, "", "", ", "); 154 172 : derived().leave(x); 155 172 : } 156 : 157 : template <typename T> 158 0 : void apply(const std::set<T>& x) 159 : { 160 0 : derived().enter(x); 161 0 : print_list(x, "", "", ", "); 162 0 : derived().leave(x); 163 0 : } 164 : 165 76159 : void apply(const core::identifier_string& x) 166 : { 167 76159 : derived().enter(x); 168 76159 : if (x == core::identifier_string()) 169 : { 170 0 : derived().print("@NoValue"); 171 : } 172 : else 173 : { 174 76159 : derived().print(std::string(x)); 175 : } 176 76159 : derived().leave(x); 177 76159 : } 178 : 179 : void apply(const atermpp::aterm& x) 180 : { 181 : derived().enter(x); 182 : derived().print(utilities::to_string(x)); 183 : derived().leave(x); 184 : } 185 : 186 : void apply(const atermpp::aterm_list& x) 187 : { 188 : derived().enter(x); 189 : derived().print(utilities::to_string(x)); 190 : derived().leave(x); 191 : } 192 : 193 : void apply(const atermpp::aterm_appl& x) 194 : { 195 : derived().enter(x); 196 : derived().print(utilities::to_string(x)); 197 : derived().leave(x); 198 : } 199 : 200 2209 : void apply(const atermpp::aterm_int& x) 201 : { 202 2209 : derived().enter(x); 203 2209 : derived().print(utilities::to_string(x)); 204 2209 : derived().leave(x); 205 2209 : } 206 : }; 207 : 208 : template <template <class> class Traverser> 209 : struct apply_printer: public Traverser<apply_printer<Traverser>> 210 : { 211 : typedef Traverser<apply_printer<Traverser>> super; 212 : 213 : using super::enter; 214 : using super::leave; 215 : using super::apply; 216 : 217 40439 : explicit apply_printer(std::ostream& out) 218 1401 : { 219 : typedef printer<apply_printer<Traverser> > Super; 220 40439 : static_cast<Super&>(*this).m_out = &out; 221 40439 : } 222 : 223 : }; 224 : 225 : } // namespace detail 226 : /// \endcond 227 : 228 : /// \brief Prints the object x to a stream. 229 : struct stream_printer 230 : { 231 : template <typename T> 232 468 : void operator()(const T& x, std::ostream& out) 233 : { 234 468 : core::detail::apply_printer<core::detail::printer> printer(out); 235 468 : printer.apply(x); 236 468 : } 237 : }; 238 : 239 : /// \brief Returns a string representation of the object x. 240 : template <typename T> 241 467 : std::string pp(const T& x) 242 : { 243 467 : std::ostringstream out; 244 467 : stream_printer()(x, out); 245 934 : return out.str(); 246 467 : } 247 : 248 : } // namespace core 249 : 250 : } // namespace mcrl2 251 : 252 : #endif // MCRL2_CORE_PRINT_H