1/*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
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
9
10#if defined(_MSC_VER)
11#pragma once
12#endif
13
14#include <boost/spirit/home/qi/nonterminal/rule.hpp>
15#include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
16#include <boost/spirit/home/qi/detail/expectation_failure.hpp>
17#include <boost/function.hpp>
18#include <string>
19
20namespace boost { namespace spirit { namespace qi
21{
22 template <
23 typename Iterator, typename Context
24 , typename Skipper, typename F>
25 struct debug_handler
26 {
27 typedef function<
28 bool(Iterator& first, Iterator const& last
29 , Context& context
30 , Skipper const& skipper
31 )>
32 function_type;
33
34 debug_handler(
35 function_type subject_
36 , F f_
37 , std::string const& rule_name_)
38 : subject(subject_)
39 , f(f_)
40 , rule_name(rule_name_)
41 {
42 }
43
44 bool operator()(
45 Iterator& first, Iterator const& last
46 , Context& context, Skipper const& skipper) const
47 {
48 f(first, last, context, pre_parse, rule_name);
49 try // subject might throw an exception
50 {
51 if (subject(first, last, context, skipper))
52 {
53 f(first, last, context, successful_parse, rule_name);
54 return true;
55 }
56 f(first, last, context, failed_parse, rule_name);
57 }
58 catch (expectation_failure<Iterator> const& e)
59 {
60 f(first, last, context, failed_parse, rule_name);
61 boost::throw_exception(e);
62 }
63 return false;
64 }
65
66 function_type subject;
67 F f;
68 std::string rule_name;
69 };
70
71 template <typename Iterator
72 , typename T1, typename T2, typename T3, typename T4, typename F>
73 void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
74 {
75 typedef rule<Iterator, T1, T2, T3, T4> rule_type;
76
77 typedef
78 debug_handler<
79 Iterator
80 , typename rule_type::context_type
81 , typename rule_type::skipper_type
82 , F>
83 debug_handler;
84 r.f = debug_handler(r.f, f, r.name());
85 }
86
87 struct simple_trace;
88
89 namespace detail
90 {
91 // This class provides an extra level of indirection through a
92 // template to produce the simple_trace type. This way, the use
93 // of simple_trace below is hidden behind a dependent type, so
94 // that compilers eagerly type-checking template definitions
95 // won't complain that simple_trace is incomplete.
96 template<typename T>
97 struct get_simple_trace
98 {
99 typedef simple_trace type;
100 };
101 }
102
103 template <typename Iterator
104 , typename T1, typename T2, typename T3, typename T4>
105 void debug(rule<Iterator, T1, T2, T3, T4>& r)
106 {
107 typedef rule<Iterator, T1, T2, T3, T4> rule_type;
108
109 typedef
110 debug_handler<
111 Iterator
112 , typename rule_type::context_type
113 , typename rule_type::skipper_type
114 , simple_trace>
115 debug_handler;
116
117 typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
118 r.f = debug_handler(r.f, trace(), r.name());
119 }
120
121}}}
122
123///////////////////////////////////////////////////////////////////////////////
124// Utility macro for easy enabling of rule and grammar debugging
125#if !defined(BOOST_SPIRIT_DEBUG_NODE)
126 #if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
127 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
128 #else
129 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
130 #endif
131#endif
132
133#define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
134 BOOST_SPIRIT_DEBUG_NODE(name); \
135 /***/
136
137#define BOOST_SPIRIT_DEBUG_NODES(seq) \
138 BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
139 /***/
140
141#endif
142

source code of boost/libs/spirit/include/boost/spirit/home/qi/nonterminal/debug_handler.hpp