parser_binder.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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_PARSER_BINDER_DECEMBER_05_2008_0516_PM)
  7. #define BOOST_SPIRIT_PARSER_BINDER_DECEMBER_05_2008_0516_PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/fusion/include/at.hpp>
  12. #include <boost/mpl/bool.hpp>
  13. #include <boost/spirit/home/support/has_semantic_action.hpp>
  14. namespace boost { namespace spirit { namespace qi { namespace detail
  15. {
  16. // parser_binder for plain rules
  17. template <typename Parser, typename Auto>
  18. struct parser_binder
  19. {
  20. parser_binder(Parser const& p_)
  21. : p(p_) {}
  22. template <typename Iterator, typename Skipper, typename Context>
  23. bool call(Iterator& first, Iterator const& last
  24. , Context& context, Skipper const& skipper, mpl::true_) const
  25. {
  26. // If DeducedAuto is false (semantic actions is present), the
  27. // component's attribute is unused.
  28. return p.parse(first, last, context, skipper, unused);
  29. }
  30. template <typename Iterator, typename Skipper, typename Context>
  31. bool call(Iterator& first, Iterator const& last
  32. , Context& context, Skipper const& skipper, mpl::false_) const
  33. {
  34. // If DeducedAuto is true (no semantic action), we pass the rule's
  35. // attribute on to the component.
  36. return p.parse(first, last, context, skipper
  37. , fusion::at_c<0>(context.attributes));
  38. }
  39. template <typename Iterator, typename Skipper, typename Context>
  40. bool operator()(
  41. Iterator& first, Iterator const& last
  42. , Context& context, Skipper const& skipper) const
  43. {
  44. // If Auto is false, we need to deduce whether to apply auto rule
  45. typedef typename traits::has_semantic_action<Parser>::type auto_rule;
  46. return call(first, last, context, skipper, auto_rule());
  47. }
  48. Parser p;
  49. };
  50. // parser_binder for auto rules
  51. template <typename Parser>
  52. struct parser_binder<Parser, mpl::true_>
  53. {
  54. parser_binder(Parser const& p_)
  55. : p(p_) {}
  56. template <typename Iterator, typename Skipper, typename Context>
  57. bool operator()(
  58. Iterator& first, Iterator const& last
  59. , Context& context, Skipper const& skipper) const
  60. {
  61. // If Auto is true, we pass the rule's attribute on to the component.
  62. return p.parse(first, last, context, skipper
  63. , fusion::at_c<0>(context.attributes));
  64. }
  65. Parser p;
  66. };
  67. template <typename Auto, typename Parser>
  68. inline parser_binder<Parser, Auto>
  69. bind_parser(Parser const& p)
  70. {
  71. return parser_binder<Parser, Auto>(p);
  72. }
  73. }}}}
  74. #endif