debug_node.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 316 行
HPP
316 行
/*============================================================================= Copyright (c) 2001-2003 Joel de Guzman Copyright (c) 2002-2003 Hartmut Kaiser Copyright (c) 2003 Gustavo Guerra http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#if !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)#define BOOST_SPIRIT_DEBUG_NODE_HPP#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/debug_node.hpp"#endif#if defined(BOOST_SPIRIT_DEBUG)#include <string>#include <boost/type_traits/is_convertible.hpp>#include <boost/mpl/if.hpp>#include <boost/mpl/and.hpp>#include <boost/spirit/core/primitives/primitives.hpp> // for iscntrl_namespace boost { namespace spirit {/////////////////////////////////////////////////////////////////////////////////// Debug helper classes for rules, which ensure maximum non-intrusiveness of// the Spirit debug support/////////////////////////////////////////////////////////////////////////////////namespace impl { struct token_printer_aux_for_chars { template<typename CharT> static void print(std::ostream& o, CharT c) { if (c == static_cast<CharT>('\a')) o << "\\a"; else if (c == static_cast<CharT>('\b')) o << "\\b"; else if (c == static_cast<CharT>('\f')) o << "\\f"; else if (c == static_cast<CharT>('\n')) o << "\\n"; else if (c == static_cast<CharT>('\r')) o << "\\r"; else if (c == static_cast<CharT>('\t')) o << "\\t"; else if (c == static_cast<CharT>('\v')) o << "\\v"; else if (iscntrl_(c)) o << "\\" << static_cast<int>(c); else o << static_cast<char>(c); } }; // for token types where the comparison with char constants wouldn't work struct token_printer_aux_for_other_types { template<typename CharT> static void print(std::ostream& o, CharT c) { o << c; } }; template <typename CharT> struct token_printer_aux : mpl::if_< mpl::and_< is_convertible<CharT, char>, is_convertible<char, CharT> >, token_printer_aux_for_chars, token_printer_aux_for_other_types >::type { }; template<typename CharT> inline void token_printer(std::ostream& o, CharT c) { #if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER) token_printer_aux<CharT>::print(o, c); #else BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c); #endif }/////////////////////////////////////////////////////////////////////////////////// Dump infos about the parsing state of a rule/////////////////////////////////////////////////////////////////////////////////#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES template <typename IteratorT> inline void print_node_info(bool hit, int level, bool close, std::string const& name, IteratorT first, IteratorT last) { if (!name.empty()) { for (int i = 0; i < level; ++i) BOOST_SPIRIT_DEBUG_OUT << " "; if (close) { if (hit) BOOST_SPIRIT_DEBUG_OUT << "/"; else BOOST_SPIRIT_DEBUG_OUT << "#"; } BOOST_SPIRIT_DEBUG_OUT << name << ":\t\""; IteratorT iter = first; IteratorT ilast = last; for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j) { if (iter == ilast) break; token_printer(BOOST_SPIRIT_DEBUG_OUT, *iter); ++iter; } BOOST_SPIRIT_DEBUG_OUT << "\"\n"; } }#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES template <typename ResultT> inline ResultT & print_closure_info(ResultT &hit, int level, std::string const& name) { if (!name.empty()) { for (int i = 0; i < level-1; ++i) BOOST_SPIRIT_DEBUG_OUT << " "; // for now, print out the return value only BOOST_SPIRIT_DEBUG_OUT << "^" << name << ":\t"; if (hit.has_valid_attribute()) BOOST_SPIRIT_DEBUG_OUT << hit.value(); else BOOST_SPIRIT_DEBUG_OUT << "undefined attribute"; BOOST_SPIRIT_DEBUG_OUT << "\n"; } return hit; }#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES}/////////////////////////////////////////////////////////////////////////////////// Implementation note: The parser_context_linker, parser_scanner_linker and// closure_context_linker classes are wrapped by a PP constant to allow// redefinition of this classes outside of Spirit/////////////////////////////////////////////////////////////////////////////////#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED /////////////////////////////////////////////////////////////////////////// // // parser_context_linker is a debug wrapper for the ContextT template // parameter of the rule<>, subrule<> and the grammar<> classes // /////////////////////////////////////////////////////////////////////////// template<typename ContextT> struct parser_context_linker : public ContextT { typedef ContextT base_t; template <typename ParserT> parser_context_linker(ParserT const& p) : ContextT(p) {} template <typename ParserT, typename ScannerT> void pre_parse(ParserT const& p, ScannerT &scan) { this->base_t::pre_parse(p, scan);#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES if (trace_parser(p.derived())) { impl::print_node_info( false, scan.get_level(), false, parser_name(p.derived()), scan.first, scan.last); } scan.get_level()++;#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES } template <typename ResultT, typename ParserT, typename ScannerT> ResultT& post_parse(ResultT& hit, ParserT const& p, ScannerT &scan) {#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES --scan.get_level(); if (trace_parser(p.derived())) { impl::print_node_info( hit, scan.get_level(), true, parser_name(p.derived()), scan.first, scan.last); }#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES return this->base_t::post_parse(hit, p, scan); } };#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED///////////////////////////////////////////////////////////////////////////////// This class is to avoid linker problems and to ensure a real singleton// 'level' variable struct debug_support { int& get_level() { static int level = 0; return level; } }; template<typename ScannerT> struct parser_scanner_linker : public ScannerT { parser_scanner_linker(ScannerT const &scan_) : ScannerT(scan_) {} int &get_level() { return debug.get_level(); } private: debug_support debug; };#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)#define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED /////////////////////////////////////////////////////////////////////////// // // closure_context_linker is a debug wrapper for the closure template // parameter of the rule<>, subrule<> and grammar classes // /////////////////////////////////////////////////////////////////////////// template<typename ContextT> struct closure_context_linker : public parser_context_linker<ContextT> { typedef parser_context_linker<ContextT> base_t; template <typename ParserT> closure_context_linker(ParserT const& p) : parser_context_linker<ContextT>(p) {} template <typename ParserT, typename ScannerT> void pre_parse(ParserT const& p, ScannerT &scan) { this->base_t::pre_parse(p, scan); } template <typename ResultT, typename ParserT, typename ScannerT> ResultT& post_parse(ResultT& hit, ParserT const& p, ScannerT &scan) {#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES if (hit && trace_parser(p.derived())) { // for now, print out the return value only return impl::print_closure_info( this->base_t::post_parse(hit, p, scan), scan.get_level(), parser_name(p.derived()) ); }#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES return this->base_t::post_parse(hit, p, scan); } };#endif // !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)}} // namespace boost::spirit#endif // defined(BOOST_SPIRIT_DEBUG)#endif // !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?