action.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*=============================================================================
  2. Copyright (arg) 2001-2014 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_X3_ACTION_JANUARY_07_2007_1128AM)
  7. #define BOOST_SPIRIT_X3_ACTION_JANUARY_07_2007_1128AM
  8. #include <boost/spirit/home/x3/support/context.hpp>
  9. #include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
  10. #include <boost/spirit/home/x3/core/call.hpp>
  11. #include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
  12. #include <boost/range/iterator_range.hpp>
  13. namespace boost { namespace spirit { namespace x3
  14. {
  15. struct raw_attribute_type;
  16. struct parse_pass_context_tag;
  17. template <typename Context>
  18. inline bool& _pass(Context const& context)
  19. {
  20. return x3::get<parse_pass_context_tag>(context);
  21. }
  22. template <typename Subject, typename Action>
  23. struct action : unary_parser<Subject, action<Subject, Action>>
  24. {
  25. typedef unary_parser<Subject, action<Subject, Action>> base_type;
  26. static bool const is_pass_through_unary = true;
  27. static bool const has_action = true;
  28. action(Subject const& subject, Action f)
  29. : base_type(subject), f(f) {}
  30. template <typename Iterator, typename Context, typename RuleContext, typename Attribute>
  31. bool call_action(
  32. Iterator& first, Iterator const& last
  33. , Context const& context, RuleContext& rcontext, Attribute& attr) const
  34. {
  35. bool pass = true;
  36. auto action_context = make_context<parse_pass_context_tag>(pass, context);
  37. call(f, first, last, action_context, rcontext, attr);
  38. return pass;
  39. }
  40. template <typename Iterator, typename Context
  41. , typename RuleContext, typename Attribute>
  42. bool parse_main(Iterator& first, Iterator const& last
  43. , Context const& context, RuleContext& rcontext, Attribute& attr) const
  44. {
  45. Iterator save = first;
  46. if (this->subject.parse(first, last, context, rcontext, attr))
  47. {
  48. if (call_action(first, last, context, rcontext, attr))
  49. return true;
  50. // reset iterators if semantic action failed the match
  51. // retrospectively
  52. first = save;
  53. }
  54. return false;
  55. }
  56. // attr==raw_attribute_type, action wants iterator_range (see raw.hpp)
  57. template <typename Iterator, typename Context, typename RuleContext>
  58. bool parse_main(Iterator& first, Iterator const& last
  59. , Context const& context, RuleContext& rcontext, raw_attribute_type&) const
  60. {
  61. boost::iterator_range<Iterator> rng;
  62. // synthesize the attribute since one is not supplied
  63. return parse_main(first, last, context, rcontext, rng);
  64. }
  65. // attr==unused, action wants attribute
  66. template <typename Iterator, typename Context, typename RuleContext>
  67. bool parse(Iterator& first, Iterator const& last
  68. , Context const& context, RuleContext& rcontext, unused_type) const
  69. {
  70. typedef typename
  71. traits::attribute_of<action<Subject, Action>, Context>::type
  72. attribute_type;
  73. // synthesize the attribute since one is not supplied
  74. attribute_type attr{};
  75. return parse_main(first, last, context, rcontext, attr);
  76. }
  77. // main parse function
  78. template <typename Iterator, typename Context
  79. , typename RuleContext, typename Attribute>
  80. bool parse(Iterator& first, Iterator const& last
  81. , Context const& context, RuleContext& rcontext, Attribute& attr) const
  82. {
  83. return parse_main(first, last, context, rcontext, attr);
  84. }
  85. Action f;
  86. };
  87. template <typename P, typename Action>
  88. inline action<typename extension::as_parser<P>::value_type, Action>
  89. operator/(P const& p, Action f)
  90. {
  91. return { as_parser(p), f };
  92. }
  93. }}}
  94. #endif