simple_trace.hpp 4.4 KB

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