~ubuntu-branches/ubuntu/breezy/aqsis/breezy

« back to all changes in this revision

Viewing changes to boost/boost/spirit/debug/debug_node.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Will Newton
  • Date: 2004-12-07 20:06:49 UTC
  • Revision ID: james.westby@ubuntu.com-20041207200649-fccswkrvp4oc8lmn
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=============================================================================
 
2
    Spirit v1.6.1
 
3
    Copyright (c) 2001-2003 Joel de Guzman
 
4
    Copyright (c) 2002-2003 Hartmut Kaiser
 
5
    Copyright (c) 2003 Gustavo Guerra
 
6
    http://spirit.sourceforge.net/
 
7
 
 
8
    Permission to copy, use, modify, sell and distribute this software is
 
9
    granted provided this copyright notice appears in all copies. This
 
10
    software is provided "as is" without express or implied warranty, and
 
11
    with no claim as to its suitability for any purpose.
 
12
=============================================================================*/
 
13
#if !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)
 
14
#define BOOST_SPIRIT_DEBUG_NODE_HPP
 
15
 
 
16
#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)
 
17
#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/debug_node.hpp"
 
18
#endif
 
19
 
 
20
#if defined(BOOST_SPIRIT_DEBUG)
 
21
 
 
22
#include <string>
 
23
 
 
24
#include <boost/type_traits/is_convertible.hpp>
 
25
#include <boost/mpl/if.hpp>
 
26
#include <boost/mpl/and.hpp>
 
27
#include <boost/spirit/core/primitives/primitives.hpp> // for iscntrl_
 
28
 
 
29
namespace boost { namespace spirit {
 
30
 
 
31
///////////////////////////////////////////////////////////////////////////////
 
32
//
 
33
//  Debug helper classes for rules, which ensure maximum non-intrusiveness of
 
34
//  the Spirit debug support
 
35
//
 
36
///////////////////////////////////////////////////////////////////////////////
 
37
 
 
38
namespace impl {
 
39
 
 
40
    struct token_printer_aux_for_chars
 
41
    {
 
42
        template<typename CharT>
 
43
        static void print(CharT c)
 
44
        {
 
45
            if (c == static_cast<CharT>('\a'))
 
46
                BOOST_SPIRIT_DEBUG_OUT << "\\a";
 
47
 
 
48
            else if (c == static_cast<CharT>('\b'))
 
49
                BOOST_SPIRIT_DEBUG_OUT << "\\b";
 
50
 
 
51
            else if (c == static_cast<CharT>('\f'))
 
52
                BOOST_SPIRIT_DEBUG_OUT << "\\f";
 
53
 
 
54
            else if (c == static_cast<CharT>('\n'))
 
55
                BOOST_SPIRIT_DEBUG_OUT << "\\n";
 
56
 
 
57
            else if (c == static_cast<CharT>('\r'))
 
58
                BOOST_SPIRIT_DEBUG_OUT << "\\r";
 
59
 
 
60
            else if (c == static_cast<CharT>('\t'))
 
61
                BOOST_SPIRIT_DEBUG_OUT << "\\t";
 
62
 
 
63
            else if (c == static_cast<CharT>('\v'))
 
64
                BOOST_SPIRIT_DEBUG_OUT << "\\v";
 
65
 
 
66
            else if (iscntrl_(c))
 
67
                BOOST_SPIRIT_DEBUG_OUT << "\\" << static_cast<int>(c);
 
68
 
 
69
            else
 
70
                BOOST_SPIRIT_DEBUG_OUT << static_cast<char>(c);
 
71
        }
 
72
    };
 
73
 
 
74
    // for token types where the comparison with char constants wouldn't work
 
75
    struct token_printer_aux_for_other_types
 
76
    {
 
77
        template<typename CharT>
 
78
        static void print(CharT c)
 
79
        {
 
80
            BOOST_SPIRIT_DEBUG_OUT << c;
 
81
        }
 
82
    };
 
83
 
 
84
    template <typename CharT>
 
85
    struct token_printer_aux
 
86
    :   mpl::if_<
 
87
            mpl::and_<
 
88
                is_convertible<CharT, char>,
 
89
                is_convertible<char, CharT> >,
 
90
            token_printer_aux_for_chars,
 
91
            token_printer_aux_for_other_types
 
92
        >::type
 
93
    {
 
94
    };
 
95
 
 
96
    template<typename CharT>
 
97
    inline void token_printer(CharT c)
 
98
    {
 
99
    #if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER)
 
100
 
 
101
        token_printer_aux<CharT>::print(c);
 
102
 
 
103
    #else
 
104
 
 
105
        BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(BOOST_SPIRIT_DEBUG_OUT, c);
 
106
 
 
107
    #endif
 
108
    }
 
109
 
 
110
///////////////////////////////////////////////////////////////////////////////
 
111
//
 
112
//  Dump infos about the parsing state of a rule
 
113
//
 
114
///////////////////////////////////////////////////////////////////////////////
 
115
 
 
116
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
 
117
    template <typename IteratorT>
 
118
    inline void
 
119
    print_node_info(bool hit, int level, bool close, std::string const& name,
 
120
        IteratorT first, IteratorT last)
 
121
    {
 
122
        if (!name.empty())
 
123
        {
 
124
            for (int i = 0; i < level; ++i)
 
125
                BOOST_SPIRIT_DEBUG_OUT << "  ";
 
126
            if (close)
 
127
            {
 
128
                if (hit)
 
129
                    BOOST_SPIRIT_DEBUG_OUT << "/";
 
130
                else
 
131
                    BOOST_SPIRIT_DEBUG_OUT << "#";
 
132
            }
 
133
            BOOST_SPIRIT_DEBUG_OUT << name << ":\t\"";
 
134
            IteratorT iter = first;
 
135
            IteratorT ilast = last;
 
136
            for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j)
 
137
            {
 
138
                if (iter == ilast)
 
139
                    break;
 
140
 
 
141
                token_printer(*iter);
 
142
                ++iter;
 
143
            }
 
144
            BOOST_SPIRIT_DEBUG_OUT << "\"\n";
 
145
        }
 
146
    }
 
147
#endif  // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
 
148
 
 
149
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
 
150
    template <typename ResultT>
 
151
    inline ResultT &
 
152
    print_closure_info(ResultT &hit, int level, std::string const& name)
 
153
    {
 
154
        if (!name.empty()) {
 
155
            for (int i = 0; i < level-1; ++i)
 
156
                BOOST_SPIRIT_DEBUG_OUT << "  ";
 
157
 
 
158
        // for now, print out the return value only
 
159
            BOOST_SPIRIT_DEBUG_OUT
 
160
                << "^" << name << ":\t" << hit.value() << "\n";
 
161
        }
 
162
        return hit;
 
163
    }
 
164
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
 
165
 
 
166
}
 
167
 
 
168
///////////////////////////////////////////////////////////////////////////////
 
169
//
 
170
//  Implementation note: The parser_context_linker, parser_scanner_linker and
 
171
//  closure_context_linker classes are wrapped by a PP constant to allow
 
172
//  redefinition of this classes outside of Spirit
 
173
//
 
174
///////////////////////////////////////////////////////////////////////////////
 
175
#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
 
176
#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED
 
177
 
 
178
    ///////////////////////////////////////////////////////////////////////////
 
179
    //
 
180
    //  parser_context_linker is a debug wrapper for the ContextT template
 
181
    //  parameter of the rule<>, subrule<> and the grammar<> classes
 
182
    //
 
183
    ///////////////////////////////////////////////////////////////////////////
 
184
    template<typename ContextT>
 
185
    struct parser_context_linker : public ContextT
 
186
    {
 
187
        typedef ContextT base_t;
 
188
 
 
189
        template <typename ParserT>
 
190
        parser_context_linker(ParserT const& p)
 
191
        : ContextT(p) {}
 
192
 
 
193
        template <typename ParserT, typename ScannerT>
 
194
        void pre_parse(ParserT const& p, ScannerT &scan)
 
195
        {
 
196
            this->base_t::pre_parse(p, scan);
 
197
 
 
198
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
 
199
            if (trace_parser(p)) {
 
200
                impl::print_node_info(
 
201
                    false,
 
202
                    scan.get_level(),
 
203
                    false,
 
204
                    parser_name(p),
 
205
                    scan.first,
 
206
                    scan.last);
 
207
            }
 
208
            scan.get_level()++;
 
209
#endif  // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
 
210
        }
 
211
 
 
212
        template <typename ResultT, typename ParserT, typename ScannerT>
 
213
        ResultT& post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
 
214
        {
 
215
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
 
216
            --scan.get_level();
 
217
            if (trace_parser(p)) {
 
218
                impl::print_node_info(
 
219
                    hit,
 
220
                    scan.get_level(),
 
221
                    true,
 
222
                    parser_name(p),
 
223
                    scan.first,
 
224
                    scan.last);
 
225
            }
 
226
#endif  // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
 
227
 
 
228
            return this->base_t::post_parse(hit, p, scan);
 
229
        }
 
230
    };
 
231
 
 
232
#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
 
233
 
 
234
#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
 
235
#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED
 
236
 
 
237
///////////////////////////////////////////////////////////////////////////////
 
238
//  This class is to avoid linker problems and to ensure a real singleton
 
239
//  'level' variable
 
240
    struct debug_support
 
241
    {
 
242
        int& get_level()
 
243
        {
 
244
            static int level = 0;
 
245
            return level;
 
246
        }
 
247
    };
 
248
 
 
249
    template<typename ScannerT>
 
250
    struct parser_scanner_linker : public ScannerT
 
251
    {
 
252
        parser_scanner_linker(ScannerT const &scan_) : ScannerT(scan_)
 
253
        {}
 
254
 
 
255
        int &get_level()
 
256
        { return debug.get_level(); }
 
257
 
 
258
        private: debug_support debug;
 
259
    };
 
260
 
 
261
#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
 
262
 
 
263
#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
 
264
#define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED
 
265
 
 
266
    ///////////////////////////////////////////////////////////////////////////
 
267
    //
 
268
    //  closure_context_linker is a debug wrapper for the closure template
 
269
    //  parameter of the rule<>, subrule<> and grammar classes
 
270
    //
 
271
    ///////////////////////////////////////////////////////////////////////////
 
272
 
 
273
    template<typename ContextT>
 
274
    struct closure_context_linker : public parser_context_linker<ContextT>
 
275
    {
 
276
        typedef parser_context_linker<ContextT> base_t;
 
277
 
 
278
        template <typename ParserT>
 
279
        closure_context_linker(ParserT const& p)
 
280
        : parser_context_linker<ContextT>(p) {}
 
281
 
 
282
        template <typename ParserT, typename ScannerT>
 
283
        void pre_parse(ParserT const& p, ScannerT &scan)
 
284
        { this->base_t::pre_parse(p, scan); }
 
285
 
 
286
        template <typename ResultT, typename ParserT, typename ScannerT>
 
287
        ResultT&
 
288
        post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
 
289
        {
 
290
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
 
291
            if (hit && trace_parser(p)) {
 
292
            // for now, print out the return value only
 
293
                return impl::print_closure_info(
 
294
                    this->base_t::post_parse(hit, p, scan),
 
295
                    scan.get_level(),
 
296
                    parser_name(p)
 
297
                );
 
298
            }
 
299
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
 
300
 
 
301
            return this->base_t::post_parse(hit, p, scan);
 
302
        }
 
303
    };
 
304
 
 
305
#endif // !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
 
306
 
 
307
}} // namespace boost::spirit
 
308
 
 
309
#endif // defined(BOOST_SPIRIT_DEBUG)
 
310
 
 
311
#endif // !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)
 
312