1/*=============================================================================
2    Copyright (c) 2001-2003 Joel de Guzman
3    Copyright (c) 2002-2003 Hartmut Kaiser
4    http://spirit.sourceforge.net/
5
6    Use, modification and distribution is subject to the Boost Software
7    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8    http://www.boost.org/LICENSE_1_0.txt)
9=============================================================================*/
10#if !defined(BOOST_SPIRIT_PARSER_NAMES_IPP)
11#define BOOST_SPIRIT_PARSER_NAMES_IPP
12
13#if defined(BOOST_SPIRIT_DEBUG)
14
15#include <string>
16#include <iostream>
17#include <map>
18
19#include <boost/config.hpp>
20#ifdef BOOST_NO_STRINGSTREAM
21#include <strstream>
22#define BOOST_SPIRIT_SSTREAM std::strstream
23std::string BOOST_SPIRIT_GETSTRING(std::strstream& ss)
24{
25    ss << ends;
26    std::string rval = ss.str();
27    ss.freeze(false);
28    return rval;
29}
30#else
31#include <sstream>
32#define BOOST_SPIRIT_GETSTRING(ss) ss.str()
33#define BOOST_SPIRIT_SSTREAM std::stringstream
34#endif
35
36namespace boost { namespace spirit {
37
38BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
39
40///////////////////////////////////////////////////////////////////////////////
41//  from actions.hpp
42    template <typename ParserT, typename ActionT>
43    inline std::string
44    parser_name(action<ParserT, ActionT> const& p)
45    {
46        return std::string("action")
47            + std::string("[")
48            + parser_name(p.subject())
49            + std::string("]");
50    }
51
52///////////////////////////////////////////////////////////////////////////////
53//  from directives.hpp
54    template <typename ParserT>
55    inline std::string
56    parser_name(contiguous<ParserT> const& p)
57    {
58        return std::string("contiguous")
59            + std::string("[")
60            + parser_name(p.subject())
61            + std::string("]");
62    }
63
64    template <typename ParserT>
65    inline std::string
66    parser_name(inhibit_case<ParserT> const& p)
67    {
68        return std::string("inhibit_case")
69            + std::string("[")
70            + parser_name(p.subject())
71            + std::string("]");
72    }
73
74    template <typename A, typename B>
75    inline std::string
76    parser_name(longest_alternative<A, B> const& p)
77    {
78        return std::string("longest_alternative")
79            + std::string("[")
80            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
81            + std::string("]");
82    }
83
84    template <typename A, typename B>
85    inline std::string
86    parser_name(shortest_alternative<A, B> const& p)
87    {
88        return std::string("shortest_alternative")
89            + std::string("[")
90            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
91            + std::string("]");
92    }
93
94///////////////////////////////////////////////////////////////////////////////
95//  from numerics.hpp
96    template <typename T, int Radix, unsigned MinDigits, int MaxDigits>
97    inline std::string
98    parser_name(uint_parser<T, Radix, MinDigits, MaxDigits> const& /*p*/)
99    {
100        BOOST_SPIRIT_SSTREAM stream;
101        stream << Radix << ", " << MinDigits << ", " << MaxDigits;
102        return std::string("uint_parser<")
103            + BOOST_SPIRIT_GETSTRING(stream)
104            + std::string(">");
105    }
106
107    template <typename T, int Radix, unsigned MinDigits, int MaxDigits>
108    inline std::string
109    parser_name(int_parser<T, Radix, MinDigits, MaxDigits> const& /*p*/)
110    {
111        BOOST_SPIRIT_SSTREAM stream;
112        stream << Radix << ", " << MinDigits << ", " << MaxDigits;
113        return std::string("int_parser<")
114            + BOOST_SPIRIT_GETSTRING(stream)
115            + std::string(">");
116    }
117
118    template <typename T, typename RealPoliciesT>
119    inline std::string
120    parser_name(real_parser<T, RealPoliciesT> const& /*p*/)
121    {
122        return std::string("real_parser");
123    }
124
125///////////////////////////////////////////////////////////////////////////////
126//  from operators.hpp
127    template <typename A, typename B>
128    inline std::string
129    parser_name(sequence<A, B> const& p)
130    {
131        return std::string("sequence")
132            + std::string("[")
133            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
134            + std::string("]");
135    }
136
137    template <typename A, typename B>
138    inline std::string
139    parser_name(sequential_or<A, B> const& p)
140    {
141        return std::string("sequential_or")
142            + std::string("[")
143            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
144            + std::string("]");
145    }
146
147    template <typename A, typename B>
148    inline std::string
149    parser_name(alternative<A, B> const& p)
150    {
151        return std::string("alternative")
152            + std::string("[")
153            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
154            + std::string("]");
155    }
156
157    template <typename A, typename B>
158    inline std::string
159    parser_name(intersection<A, B> const& p)
160    {
161        return std::string("intersection")
162            + std::string("[")
163            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
164            + std::string("]");
165    }
166
167    template <typename A, typename B>
168    inline std::string
169    parser_name(difference<A, B> const& p)
170    {
171        return std::string("difference")
172            + std::string("[")
173            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
174            + std::string("]");
175    }
176
177    template <typename A, typename B>
178    inline std::string
179    parser_name(exclusive_or<A, B> const& p)
180    {
181        return std::string("exclusive_or")
182            + std::string("[")
183            + parser_name(p.left()) + std::string(", ") + parser_name(p.right())
184            + std::string("]");
185    }
186
187    template <typename S>
188    inline std::string
189    parser_name(optional<S> const& p)
190    {
191        return std::string("optional")
192            + std::string("[")
193            + parser_name(p.subject())
194            + std::string("]");
195    }
196
197    template <typename S>
198    inline std::string
199    parser_name(kleene_star<S> const& p)
200    {
201        return std::string("kleene_star")
202            + std::string("[")
203            + parser_name(p.subject())
204            + std::string("]");
205    }
206
207    template <typename S>
208    inline std::string
209    parser_name(positive<S> const& p)
210    {
211        return std::string("positive")
212            + std::string("[")
213            + parser_name(p.subject())
214            + std::string("]");
215    }
216
217///////////////////////////////////////////////////////////////////////////////
218//  from parser.hpp
219    template <typename DerivedT>
220    inline std::string
221    parser_name(parser<DerivedT> const& /*p*/)
222    {
223        return std::string("parser");
224    }
225
226///////////////////////////////////////////////////////////////////////////////
227//  from primitives.hpp
228    template <typename DerivedT>
229    inline std::string
230    parser_name(char_parser<DerivedT> const &/*p*/)
231    {
232        return std::string("char_parser");
233    }
234
235    template <typename CharT>
236    inline std::string
237    parser_name(chlit<CharT> const &p)
238    {
239        return std::string("chlit(\'")
240            + std::string(1, p.ch)
241            + std::string("\')");
242    }
243
244    template <typename CharT>
245    inline std::string
246    parser_name(range<CharT> const &p)
247    {
248        return std::string("range(")
249            + std::string(1, p.first) + std::string(", ") + std::string(1, p.last)
250            + std::string(")");
251    }
252
253    template <typename IteratorT>
254    inline std::string
255    parser_name(chseq<IteratorT> const &p)
256    {
257        return std::string("chseq(\"")
258            + std::string(p.first, p.last)
259            + std::string("\")");
260    }
261
262    template <typename IteratorT>
263    inline std::string
264    parser_name(strlit<IteratorT> const &p)
265    {
266        return std::string("strlit(\"")
267            + std::string(p.seq.first, p.seq.last)
268            + std::string("\")");
269    }
270
271    inline std::string
272    parser_name(nothing_parser const&)
273    {
274        return std::string("nothing");
275    }
276
277    inline std::string
278    parser_name(epsilon_parser const&)
279    {
280        return std::string("epsilon");
281    }
282
283    inline std::string
284    parser_name(anychar_parser const&)
285    {
286        return std::string("anychar");
287    }
288
289    inline std::string
290    parser_name(alnum_parser const&)
291    {
292        return std::string("alnum");
293    }
294
295    inline std::string
296    parser_name(alpha_parser const&)
297    {
298        return std::string("alpha");
299    }
300
301    inline std::string
302    parser_name(cntrl_parser const&)
303    {
304        return std::string("cntrl");
305    }
306
307    inline std::string
308    parser_name(digit_parser const&)
309    {
310        return std::string("digit");
311    }
312
313    inline std::string
314    parser_name(graph_parser const&)
315    {
316        return std::string("graph");
317    }
318
319    inline std::string
320    parser_name(lower_parser const&)
321    {
322        return std::string("lower");
323    }
324
325    inline std::string
326    parser_name(print_parser const&)
327    {
328        return std::string("print");
329    }
330
331    inline std::string
332    parser_name(punct_parser const&)
333    {
334        return std::string("punct");
335    }
336
337    inline std::string
338    parser_name(blank_parser const&)
339    {
340        return std::string("blank");
341    }
342
343    inline std::string
344    parser_name(space_parser const&)
345    {
346        return std::string("space");
347    }
348
349    inline std::string
350    parser_name(upper_parser const&)
351    {
352        return std::string("upper");
353    }
354
355    inline std::string
356    parser_name(xdigit_parser const&)
357    {
358        return std::string("xdigit");
359    }
360
361    inline std::string
362    parser_name(eol_parser const&)
363    {
364        return std::string("eol");
365    }
366
367    inline std::string
368    parser_name(end_parser const&)
369    {
370        return std::string("end");
371    }
372
373///////////////////////////////////////////////////////////////////////////////
374//  from rule.hpp
375    namespace impl {
376        struct node_registry
377        {
378            typedef std::pair<std::string, bool> rule_info;
379            typedef std::map<void const *, rule_info> rule_infos;
380
381            std::string find_node(void const *r)
382            {
383                rule_infos::const_iterator cit = infos.find(r);
384                if (cit != infos.end())
385                    return (*cit).second.first;
386                return std::string("<unknown>");
387            }
388
389            bool trace_node(void const *r)
390            {
391                rule_infos::const_iterator cit = infos.find(r);
392                if (cit != infos.end())
393                    return (*cit).second.second;
394                return BOOST_SPIRIT_DEBUG_TRACENODE;
395            }
396
397            bool register_node(void const *r, char const *name_to_register,
398                bool trace_node)
399            {
400                if (infos.find(r) != infos.end())
401                    return false;
402
403                return infos.insert(rule_infos::value_type(r,
404                    rule_info(std::string(name_to_register), trace_node))
405                ).second;
406            }
407
408            bool unregister_node(void const *r)
409            {
410                if (infos.find(r) == infos.end())
411                    return false;
412                return (1 == infos.erase(r));
413            }
414
415        private:
416            rule_infos infos;
417        };
418
419        inline node_registry &
420        get_node_registry()
421        {
422            static node_registry node_infos;
423            return node_infos;
424        }
425    }   // namespace impl
426
427    template<
428        typename DerivedT, typename EmbedT,
429        typename T0, typename T1, typename T2
430    >
431    inline std::string
432    parser_name(impl::rule_base<DerivedT, EmbedT, T0, T1, T2> const& p)
433    {
434        return std::string("rule_base")
435            + std::string("(")
436            + impl::get_node_registry().find_node(&p)
437            + std::string(")");
438    }
439
440    template<typename T0, typename T1, typename T2>
441    inline std::string
442    parser_name(rule<T0, T1, T2> const& p)
443    {
444        return std::string("rule")
445            + std::string("(")
446            + impl::get_node_registry().find_node(&p)
447            + std::string(")");
448    }
449
450///////////////////////////////////////////////////////////////////////////////
451//  from subrule.hpp
452    template <typename FirstT, typename RestT>
453    inline std::string
454    parser_name(subrule_list<FirstT, RestT> const &p)
455    {
456        return std::string("subrule_list")
457            + std::string("(")
458            + impl::get_node_registry().find_node(&p)
459            + std::string(")");
460    }
461
462    template <int ID, typename DefT, typename ContextT>
463    inline std::string
464    parser_name(subrule_parser<ID, DefT, ContextT> const &p)
465    {
466        return std::string("subrule_parser")
467            + std::string("(")
468            + impl::get_node_registry().find_node(&p)
469            + std::string(")");
470    }
471
472    template <int ID, typename ContextT>
473    inline std::string
474    parser_name(subrule<ID, ContextT> const &p)
475    {
476        BOOST_SPIRIT_SSTREAM stream;
477        stream << ID;
478        return std::string("subrule<")
479            + BOOST_SPIRIT_GETSTRING(stream)
480            + std::string(">(")
481            + impl::get_node_registry().find_node(&p)
482            + std::string(")");
483    }
484
485///////////////////////////////////////////////////////////////////////////////
486//  from grammar.hpp
487    template <typename DerivedT, typename ContextT>
488    inline std::string
489    parser_name(grammar<DerivedT, ContextT> const& p)
490    {
491        return std::string("grammar")
492            + std::string("(")
493            + impl::get_node_registry().find_node(&p)
494            + std::string(")");
495    }
496
497///////////////////////////////////////////////////////////////////////////////
498//  decide, if a node is to be traced or not
499    template<
500        typename DerivedT, typename EmbedT,
501        typename T0, typename T1, typename T2
502    >
503    inline bool
504    trace_parser(impl::rule_base<DerivedT, EmbedT, T0, T1, T2>
505        const& p)
506    {
507        return impl::get_node_registry().trace_node(&p);
508    }
509
510    template<typename T0, typename T1, typename T2>
511    inline bool
512    trace_parser(rule<T0, T1, T2> const& p)
513    {
514        return impl::get_node_registry().trace_node(&p);
515    }
516
517    template <typename DerivedT, typename ContextT>
518    inline bool
519    trace_parser(grammar<DerivedT, ContextT> const& p)
520    {
521        return impl::get_node_registry().trace_node(&p);
522    }
523
524    template <typename DerivedT, int N, typename ContextT>
525    inline bool
526    trace_parser(impl::entry_grammar<DerivedT, N, ContextT> const& p)
527    {
528        return impl::get_node_registry().trace_node(&p);
529    }
530
531    template <int ID, typename ContextT>
532    bool
533    trace_parser(subrule<ID, ContextT> const& p)
534    {
535        return impl::get_node_registry().trace_node(&p);
536    }
537
538    template <typename ParserT, typename ActorTupleT>
539    bool
540    trace_parser(init_closure_parser<ParserT, ActorTupleT> const& p)
541    {
542        return impl::get_node_registry().trace_node(&p);
543    }
544
545///////////////////////////////////////////////////////////////////////////////
546BOOST_SPIRIT_CLASSIC_NAMESPACE_END
547
548}} // namespace boost::spirit
549
550#undef BOOST_SPIRIT_SSTREAM
551#undef BOOST_SPIRIT_GETSTRING
552
553#endif // defined(BOOST_SPIRIT_DEBUG)
554
555#endif // !defined(BOOST_SPIRIT_PARSER_NAMES_IPP)
556