1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM)
8 #define BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM
14 #include <boost/spirit/home/support/unused.hpp>
15 #include <boost/spirit/home/qi/nonterminal/rule.hpp>
16 #include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
17 #include <boost/spirit/home/qi/detail/expectation_failure.hpp>
18 #include <boost/function.hpp>
19 #include <boost/fusion/include/at.hpp>
20 #include <boost/fusion/include/vector.hpp>
21 #include <boost/fusion/include/out.hpp>
24 namespace boost { namespace spirit { namespace qi
27 typename Iterator, typename Context
28 , typename Skipper, typename F>
32 bool(Iterator& first, Iterator const& last
34 , Skipper const& skipper
39 function_type subject_
41 , std::string const& rule_name_)
44 , rule_name(rule_name_)
49 Iterator& first, Iterator const& last
50 , Context& context, Skipper const& skipper) const
52 f(first, last, context, pre_parse, rule_name);
53 try // subject might throw an exception
55 if (subject(first, last, context, skipper))
57 f(first, last, context, successful_parse, rule_name);
60 f(first, last, context, failed_parse, rule_name);
62 catch (expectation_failure<Iterator> const& e)
64 f(first, last, context, failed_parse, rule_name);
65 boost::throw_exception(e);
70 function_type subject;
72 std::string rule_name;
75 template <typename Iterator
76 , typename T1, typename T2, typename T3, typename T4, typename F>
77 void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
79 typedef rule<Iterator, T1, T2, T3, T4> rule_type;
84 , typename rule_type::context_type
85 , typename rule_type::skipper_type
88 r.f = debug_handler(r.f, f, r.name());
95 // This class provides an extra level of indirection through a
96 // template to produce the simple_trace type. This way, the use
97 // of simple_trace below is hidden behind a dependent type, so
98 // that compilers eagerly type-checking template definitions
99 // won't complain that simple_trace is incomplete.
101 struct get_simple_trace
103 typedef simple_trace type;
107 template <typename Iterator
108 , typename T1, typename T2, typename T3, typename T4>
109 void debug(rule<Iterator, T1, T2, T3, T4>& r)
111 typedef rule<Iterator, T1, T2, T3, T4> rule_type;
116 , typename rule_type::context_type
117 , typename rule_type::skipper_type
121 typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
122 r.f = debug_handler(r.f, trace(), r.name());
127 ///////////////////////////////////////////////////////////////////////////////
128 // Utility macro for easy enabling of rule and grammar debugging
129 #if !defined(BOOST_SPIRIT_DEBUG_NODE)
130 #if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
131 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
133 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
137 #define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
138 BOOST_SPIRIT_DEBUG_NODE(name); \
141 #define BOOST_SPIRIT_DEBUG_NODES(seq) \
142 BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \