debug_handler.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM)
  7. #define BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/support/unused.hpp>
  12. #include <boost/spirit/home/qi/nonterminal/rule.hpp>
  13. #include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
  14. #include <boost/spirit/home/qi/detail/expectation_failure.hpp>
  15. #include <boost/function.hpp>
  16. #include <boost/fusion/include/at.hpp>
  17. #include <boost/fusion/include/vector.hpp>
  18. #include <boost/fusion/include/out.hpp>
  19. #include <iostream>
  20. namespace boost { namespace spirit { namespace qi
  21. {
  22. template <
  23. typename Iterator, typename Context
  24. , typename Skipper, typename F>
  25. struct debug_handler
  26. {
  27. typedef function<
  28. bool(Iterator& first, Iterator const& last
  29. , Context& context
  30. , Skipper const& skipper
  31. )>
  32. function_type;
  33. debug_handler(
  34. function_type subject_
  35. , F f_
  36. , std::string const& rule_name_)
  37. : subject(subject_)
  38. , f(f_)
  39. , rule_name(rule_name_)
  40. {
  41. }
  42. bool operator()(
  43. Iterator& first, Iterator const& last
  44. , Context& context, Skipper const& skipper) const
  45. {
  46. f(first, last, context, pre_parse, rule_name);
  47. try // subject might throw an exception
  48. {
  49. if (subject(first, last, context, skipper))
  50. {
  51. f(first, last, context, successful_parse, rule_name);
  52. return true;
  53. }
  54. f(first, last, context, failed_parse, rule_name);
  55. }
  56. catch (expectation_failure<Iterator> const& e)
  57. {
  58. f(first, last, context, failed_parse, rule_name);
  59. boost::throw_exception(e);
  60. }
  61. return false;
  62. }
  63. function_type subject;
  64. F f;
  65. std::string rule_name;
  66. };
  67. template <typename Iterator
  68. , typename T1, typename T2, typename T3, typename T4, typename F>
  69. void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
  70. {
  71. typedef rule<Iterator, T1, T2, T3, T4> rule_type;
  72. typedef
  73. debug_handler<
  74. Iterator
  75. , typename rule_type::context_type
  76. , typename rule_type::skipper_type
  77. , F>
  78. debug_handler;
  79. r.f = debug_handler(r.f, f, r.name());
  80. }
  81. struct simple_trace;
  82. namespace detail
  83. {
  84. // This class provides an extra level of indirection through a
  85. // template to produce the simple_trace type. This way, the use
  86. // of simple_trace below is hidden behind a dependent type, so
  87. // that compilers eagerly type-checking template definitions
  88. // won't complain that simple_trace is incomplete.
  89. template<typename T>
  90. struct get_simple_trace
  91. {
  92. typedef simple_trace type;
  93. };
  94. }
  95. template <typename Iterator
  96. , typename T1, typename T2, typename T3, typename T4>
  97. void debug(rule<Iterator, T1, T2, T3, T4>& r)
  98. {
  99. typedef rule<Iterator, T1, T2, T3, T4> rule_type;
  100. typedef
  101. debug_handler<
  102. Iterator
  103. , typename rule_type::context_type
  104. , typename rule_type::skipper_type
  105. , simple_trace>
  106. debug_handler;
  107. typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
  108. r.f = debug_handler(r.f, trace(), r.name());
  109. }
  110. }}}
  111. ///////////////////////////////////////////////////////////////////////////////
  112. // Utility macro for easy enabling of rule and grammar debugging
  113. #if !defined(BOOST_SPIRIT_DEBUG_NODE)
  114. #if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
  115. #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
  116. #else
  117. #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
  118. #endif
  119. #endif
  120. #define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
  121. BOOST_SPIRIT_DEBUG_NODE(name); \
  122. /***/
  123. #define BOOST_SPIRIT_DEBUG_NODES(seq) \
  124. BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
  125. /***/
  126. #endif