File indexing completed on 2025-12-16 10:08:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #if !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)
0011 #define BOOST_SPIRIT_DEBUG_NODE_HPP
0012
0013 #if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)
0014 #error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/debug_node.hpp"
0015 #endif
0016
0017 #if defined(BOOST_SPIRIT_DEBUG)
0018
0019 #include <string>
0020
0021 #include <boost/type_traits/is_convertible.hpp>
0022 #include <boost/mpl/if.hpp>
0023 #include <boost/mpl/and.hpp>
0024 #include <boost/spirit/home/classic/namespace.hpp>
0025 #include <boost/spirit/home/classic/core/primitives/primitives.hpp> // for iscntrl_
0026
0027 namespace boost { namespace spirit {
0028
0029 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0030
0031
0032
0033
0034
0035
0036
0037
0038 namespace impl {
0039
0040 struct token_printer_aux_for_chars
0041 {
0042 template<typename CharT>
0043 static void print(std::ostream& o, CharT c)
0044 {
0045 if (c == static_cast<CharT>('\a'))
0046 o << "\\a";
0047
0048 else if (c == static_cast<CharT>('\b'))
0049 o << "\\b";
0050
0051 else if (c == static_cast<CharT>('\f'))
0052 o << "\\f";
0053
0054 else if (c == static_cast<CharT>('\n'))
0055 o << "\\n";
0056
0057 else if (c == static_cast<CharT>('\r'))
0058 o << "\\r";
0059
0060 else if (c == static_cast<CharT>('\t'))
0061 o << "\\t";
0062
0063 else if (c == static_cast<CharT>('\v'))
0064 o << "\\v";
0065
0066 else if (iscntrl_(c))
0067 o << "\\" << static_cast<int>(c);
0068
0069 else
0070 o << static_cast<char>(c);
0071 }
0072 };
0073
0074
0075 struct token_printer_aux_for_other_types
0076 {
0077 template<typename CharT>
0078 static void print(std::ostream& o, CharT c)
0079 {
0080 o << c;
0081 }
0082 };
0083
0084 template <typename CharT>
0085 struct token_printer_aux
0086 : mpl::if_<
0087 mpl::and_<
0088 is_convertible<CharT, char>,
0089 is_convertible<char, CharT> >,
0090 token_printer_aux_for_chars,
0091 token_printer_aux_for_other_types
0092 >::type
0093 {
0094 };
0095
0096 template<typename CharT>
0097 inline void token_printer(std::ostream& o, CharT c)
0098 {
0099 #if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER)
0100
0101 token_printer_aux<CharT>::print(o, c);
0102
0103 #else
0104
0105 BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c);
0106
0107 #endif
0108 }
0109
0110
0111
0112
0113
0114
0115
0116 #if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
0117 template <typename IteratorT>
0118 inline void
0119 print_node_info(bool hit, int level, bool close, std::string const& name,
0120 IteratorT first, IteratorT last)
0121 {
0122 if (!name.empty())
0123 {
0124 for (int i = 0; i < level; ++i)
0125 BOOST_SPIRIT_DEBUG_OUT << " ";
0126 if (close)
0127 {
0128 if (hit)
0129 BOOST_SPIRIT_DEBUG_OUT << "/";
0130 else
0131 BOOST_SPIRIT_DEBUG_OUT << "#";
0132 }
0133 BOOST_SPIRIT_DEBUG_OUT << name << ":\t\"";
0134 IteratorT iter = first;
0135 IteratorT ilast = last;
0136 for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j)
0137 {
0138 if (iter == ilast)
0139 break;
0140
0141 token_printer(BOOST_SPIRIT_DEBUG_OUT, *iter);
0142 ++iter;
0143 }
0144 BOOST_SPIRIT_DEBUG_OUT << "\"\n";
0145 }
0146 }
0147 #endif
0148
0149 #if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
0150 template <typename ResultT>
0151 inline ResultT &
0152 print_closure_info(ResultT &hit, int level, std::string const& name)
0153 {
0154 if (!name.empty())
0155 {
0156 for (int i = 0; i < level-1; ++i)
0157 BOOST_SPIRIT_DEBUG_OUT << " ";
0158
0159
0160 BOOST_SPIRIT_DEBUG_OUT << "^" << name << ":\t";
0161 if (hit.has_valid_attribute())
0162 BOOST_SPIRIT_DEBUG_OUT << hit.value();
0163 else
0164 BOOST_SPIRIT_DEBUG_OUT << "undefined attribute";
0165 BOOST_SPIRIT_DEBUG_OUT << "\n";
0166 }
0167 return hit;
0168 }
0169 #endif
0170
0171 }
0172
0173
0174
0175
0176
0177
0178
0179
0180 #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
0181 #define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED
0182
0183
0184
0185
0186
0187
0188
0189 template<typename ContextT>
0190 struct parser_context_linker : public ContextT
0191 {
0192 typedef ContextT base_t;
0193
0194 template <typename ParserT>
0195 parser_context_linker(ParserT const& p)
0196 : ContextT(p) {}
0197
0198 template <typename ParserT, typename ScannerT>
0199 void pre_parse(ParserT const& p, ScannerT &scan)
0200 {
0201 this->base_t::pre_parse(p, scan);
0202
0203 #if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
0204 if (trace_parser(p.derived())) {
0205 impl::print_node_info(
0206 false,
0207 scan.get_level(),
0208 false,
0209 parser_name(p.derived()),
0210 scan.first,
0211 scan.last);
0212 }
0213 scan.get_level()++;
0214 #endif
0215 }
0216
0217 template <typename ResultT, typename ParserT, typename ScannerT>
0218 ResultT& post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
0219 {
0220 #if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
0221 --scan.get_level();
0222 if (trace_parser(p.derived())) {
0223 impl::print_node_info(
0224 hit,
0225 scan.get_level(),
0226 true,
0227 parser_name(p.derived()),
0228 scan.first,
0229 scan.last);
0230 }
0231 #endif
0232
0233 return this->base_t::post_parse(hit, p, scan);
0234 }
0235 };
0236
0237 #endif
0238
0239 #if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
0240 #define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED
0241
0242
0243
0244
0245 struct debug_support
0246 {
0247 int& get_level()
0248 {
0249 static int level = 0;
0250 return level;
0251 }
0252 };
0253
0254 template<typename ScannerT>
0255 struct parser_scanner_linker : public ScannerT
0256 {
0257 parser_scanner_linker(ScannerT const &scan_) : ScannerT(scan_)
0258 {}
0259
0260 int &get_level()
0261 { return debug.get_level(); }
0262
0263 private: debug_support debug;
0264 };
0265
0266 #endif
0267
0268 #if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
0269 #define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED
0270
0271
0272
0273
0274
0275
0276
0277
0278 template<typename ContextT>
0279 struct closure_context_linker : public parser_context_linker<ContextT>
0280 {
0281 typedef parser_context_linker<ContextT> base_t;
0282
0283 template <typename ParserT>
0284 closure_context_linker(ParserT const& p)
0285 : parser_context_linker<ContextT>(p) {}
0286
0287 template <typename ParserT, typename ScannerT>
0288 void pre_parse(ParserT const& p, ScannerT &scan)
0289 { this->base_t::pre_parse(p, scan); }
0290
0291 template <typename ResultT, typename ParserT, typename ScannerT>
0292 ResultT&
0293 post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
0294 {
0295 #if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
0296 if (hit && trace_parser(p.derived())) {
0297
0298 return impl::print_closure_info(
0299 this->base_t::post_parse(hit, p, scan),
0300 scan.get_level(),
0301 parser_name(p.derived())
0302 );
0303 }
0304 #endif
0305
0306 return this->base_t::post_parse(hit, p, scan);
0307 }
0308 };
0309
0310 #endif
0311
0312 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0313
0314 }}
0315
0316 #endif
0317
0318 #endif
0319