123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Distributed under 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_HANDLER_DECEMBER_05_2008_0734PM)
- #define BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/spirit/home/qi/nonterminal/rule.hpp>
- #include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
- #include <boost/spirit/home/qi/detail/expectation_failure.hpp>
- #include <boost/function.hpp>
- #include <string>
- namespace boost { namespace spirit { namespace qi
- {
- template <
- typename Iterator, typename Context
- , typename Skipper, typename F>
- struct debug_handler
- {
- typedef function<
- bool(Iterator& first, Iterator const& last
- , Context& context
- , Skipper const& skipper
- )>
- function_type;
- debug_handler(
- function_type subject_
- , F f_
- , std::string const& rule_name_)
- : subject(subject_)
- , f(f_)
- , rule_name(rule_name_)
- {
- }
- bool operator()(
- Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper) const
- {
- f(first, last, context, pre_parse, rule_name);
- try // subject might throw an exception
- {
- if (subject(first, last, context, skipper))
- {
- f(first, last, context, successful_parse, rule_name);
- return true;
- }
- f(first, last, context, failed_parse, rule_name);
- }
- catch (expectation_failure<Iterator> const& e)
- {
- f(first, last, context, failed_parse, rule_name);
- boost::throw_exception(e);
- }
- return false;
- }
- function_type subject;
- F f;
- std::string rule_name;
- };
- template <typename Iterator
- , typename T1, typename T2, typename T3, typename T4, typename F>
- void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
- {
- typedef rule<Iterator, T1, T2, T3, T4> rule_type;
- typedef
- debug_handler<
- Iterator
- , typename rule_type::context_type
- , typename rule_type::skipper_type
- , F>
- debug_handler;
- r.f = debug_handler(r.f, f, r.name());
- }
- struct simple_trace;
- namespace detail
- {
- // This class provides an extra level of indirection through a
- // template to produce the simple_trace type. This way, the use
- // of simple_trace below is hidden behind a dependent type, so
- // that compilers eagerly type-checking template definitions
- // won't complain that simple_trace is incomplete.
- template<typename T>
- struct get_simple_trace
- {
- typedef simple_trace type;
- };
- }
- template <typename Iterator
- , typename T1, typename T2, typename T3, typename T4>
- void debug(rule<Iterator, T1, T2, T3, T4>& r)
- {
- typedef rule<Iterator, T1, T2, T3, T4> rule_type;
- typedef
- debug_handler<
- Iterator
- , typename rule_type::context_type
- , typename rule_type::skipper_type
- , simple_trace>
- debug_handler;
- typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
- r.f = debug_handler(r.f, trace(), r.name());
- }
- }}}
- ///////////////////////////////////////////////////////////////////////////////
- // Utility macro for easy enabling of rule and grammar debugging
- #if !defined(BOOST_SPIRIT_DEBUG_NODE)
- #if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
- #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
- #else
- #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
- #endif
- #endif
- #define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
- BOOST_SPIRIT_DEBUG_NODE(name); \
- /***/
- #define BOOST_SPIRIT_DEBUG_NODES(seq) \
- BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
- /***/
- #endif
|