Chris@102
|
1 /*=============================================================================
|
Chris@102
|
2 Copyright (c) 2001-2014 Joel de Guzman
|
Chris@102
|
3 Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@102
|
4
|
Chris@102
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
7 ==============================================================================*/
|
Chris@102
|
8 #if !defined(BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
|
Chris@102
|
9 #define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
|
Chris@102
|
10
|
Chris@102
|
11 #if defined(_MSC_VER)
|
Chris@102
|
12 #pragma once
|
Chris@102
|
13 #endif
|
Chris@102
|
14
|
Chris@102
|
15 #include <boost/spirit/home/x3/support/unused.hpp>
|
Chris@102
|
16 #include <boost/spirit/home/x3/support/traits/print_token.hpp>
|
Chris@102
|
17 #include <boost/spirit/home/x3/support/traits/print_attribute.hpp>
|
Chris@102
|
18 #include <boost/spirit/home/x3/nonterminal/debug_handler_state.hpp>
|
Chris@102
|
19 #include <boost/fusion/include/out.hpp>
|
Chris@102
|
20 #include <boost/type_traits/is_same.hpp>
|
Chris@102
|
21 #include <ostream>
|
Chris@102
|
22
|
Chris@102
|
23 // The stream to use for debug output
|
Chris@102
|
24 #if !defined(BOOST_SPIRIT_X3_DEBUG_OUT)
|
Chris@102
|
25 #define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr
|
Chris@102
|
26 #endif
|
Chris@102
|
27
|
Chris@102
|
28 // number of tokens to print while debugging
|
Chris@102
|
29 #if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME)
|
Chris@102
|
30 #define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20
|
Chris@102
|
31 #endif
|
Chris@102
|
32
|
Chris@102
|
33 // number of spaces to indent
|
Chris@102
|
34 #if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT)
|
Chris@102
|
35 #define BOOST_SPIRIT_X3_DEBUG_INDENT 2
|
Chris@102
|
36 #endif
|
Chris@102
|
37
|
Chris@102
|
38 namespace boost { namespace spirit { namespace x3
|
Chris@102
|
39 {
|
Chris@102
|
40 namespace detail
|
Chris@102
|
41 {
|
Chris@102
|
42 template <typename Char>
|
Chris@102
|
43 inline void token_printer(std::ostream& o, Char c)
|
Chris@102
|
44 {
|
Chris@102
|
45 // allow customization of the token printer routine
|
Chris@102
|
46 x3::traits::print_token(o, c);
|
Chris@102
|
47 }
|
Chris@102
|
48 }
|
Chris@102
|
49
|
Chris@102
|
50 template <int IndentSpaces = 2, int CharsToPrint = 20>
|
Chris@102
|
51 struct simple_trace
|
Chris@102
|
52 {
|
Chris@102
|
53 simple_trace(std::ostream& out)
|
Chris@102
|
54 : out(out), indent(0) {}
|
Chris@102
|
55
|
Chris@102
|
56 void print_indent(int n) const
|
Chris@102
|
57 {
|
Chris@102
|
58 n *= IndentSpaces;
|
Chris@102
|
59 for (int i = 0; i != n; ++i)
|
Chris@102
|
60 out << ' ';
|
Chris@102
|
61 }
|
Chris@102
|
62
|
Chris@102
|
63 template <typename Iterator>
|
Chris@102
|
64 void print_some(
|
Chris@102
|
65 char const* tag
|
Chris@102
|
66 , Iterator first, Iterator const& last) const
|
Chris@102
|
67 {
|
Chris@102
|
68 print_indent(indent);
|
Chris@102
|
69 out << '<' << tag << '>';
|
Chris@102
|
70 int const n = CharsToPrint;
|
Chris@102
|
71 for (int i = 0; first != last && i != n && *first; ++i, ++first)
|
Chris@102
|
72 detail::token_printer(out, *first);
|
Chris@102
|
73 out << "</" << tag << '>' << std::endl;
|
Chris@102
|
74
|
Chris@102
|
75 // $$$ FIXME convert invalid xml characters (e.g. '<') to valid
|
Chris@102
|
76 // character entities. $$$
|
Chris@102
|
77 }
|
Chris@102
|
78
|
Chris@102
|
79 template <typename Iterator, typename Attribute, typename State>
|
Chris@102
|
80 void operator()(
|
Chris@102
|
81 Iterator const& first
|
Chris@102
|
82 , Iterator const& last
|
Chris@102
|
83 , Attribute const& attr
|
Chris@102
|
84 , State state
|
Chris@102
|
85 , std::string const& rule_name) const
|
Chris@102
|
86 {
|
Chris@102
|
87 switch (state)
|
Chris@102
|
88 {
|
Chris@102
|
89 case pre_parse:
|
Chris@102
|
90 print_indent(indent++);
|
Chris@102
|
91 out
|
Chris@102
|
92 << '<' << rule_name << '>'
|
Chris@102
|
93 << std::endl;
|
Chris@102
|
94 print_some("try", first, last);
|
Chris@102
|
95 break;
|
Chris@102
|
96
|
Chris@102
|
97 case successful_parse:
|
Chris@102
|
98 print_some("success", first, last);
|
Chris@102
|
99 if (!is_same<Attribute, unused_type>::value)
|
Chris@102
|
100 {
|
Chris@102
|
101 print_indent(indent);
|
Chris@102
|
102 out
|
Chris@102
|
103 << "<attributes>";
|
Chris@102
|
104 traits::print_attribute(out, attr);
|
Chris@102
|
105 out
|
Chris@102
|
106 << "</attributes>";
|
Chris@102
|
107 out << std::endl;
|
Chris@102
|
108 }
|
Chris@102
|
109 //~ if (!fusion::empty(context.locals))
|
Chris@102
|
110 //~ out
|
Chris@102
|
111 //~ << "<locals>"
|
Chris@102
|
112 //~ << context.locals
|
Chris@102
|
113 //~ << "</locals>";
|
Chris@102
|
114 print_indent(--indent);
|
Chris@102
|
115 out
|
Chris@102
|
116 << "</" << rule_name << '>'
|
Chris@102
|
117 << std::endl;
|
Chris@102
|
118 break;
|
Chris@102
|
119
|
Chris@102
|
120 case failed_parse:
|
Chris@102
|
121 print_indent(indent);
|
Chris@102
|
122 out << "<fail/>" << std::endl;
|
Chris@102
|
123 print_indent(--indent);
|
Chris@102
|
124 out
|
Chris@102
|
125 << "</" << rule_name << '>'
|
Chris@102
|
126 << std::endl;
|
Chris@102
|
127 break;
|
Chris@102
|
128 }
|
Chris@102
|
129 }
|
Chris@102
|
130
|
Chris@102
|
131 std::ostream& out;
|
Chris@102
|
132 mutable int indent;
|
Chris@102
|
133 };
|
Chris@102
|
134
|
Chris@102
|
135 namespace detail
|
Chris@102
|
136 {
|
Chris@102
|
137 typedef simple_trace<
|
Chris@102
|
138 BOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME>
|
Chris@102
|
139 simple_trace_type;
|
Chris@102
|
140
|
Chris@102
|
141 inline simple_trace_type&
|
Chris@102
|
142 get_simple_trace()
|
Chris@102
|
143 {
|
Chris@102
|
144 static simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT);
|
Chris@102
|
145 return tracer;
|
Chris@102
|
146 }
|
Chris@102
|
147 }
|
Chris@102
|
148 }}}
|
Chris@102
|
149
|
Chris@102
|
150 #endif
|