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