simple_trace.hpp 4.7 KB

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