lexeme.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*=============================================================================
  2. Copyright (c) 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_LEXEME_MARCH_24_2007_0802AM)
  7. #define BOOST_SPIRIT_X3_LEXEME_MARCH_24_2007_0802AM
  8. #include <boost/spirit/home/x3/support/context.hpp>
  9. #include <boost/spirit/home/x3/support/unused.hpp>
  10. #include <boost/spirit/home/x3/core/skip_over.hpp>
  11. #include <boost/spirit/home/x3/core/parser.hpp>
  12. #include <boost/type_traits/remove_reference.hpp>
  13. #include <boost/utility/enable_if.hpp>
  14. namespace boost { namespace spirit { namespace x3
  15. {
  16. template <typename Subject>
  17. struct lexeme_directive : unary_parser<Subject, lexeme_directive<Subject>>
  18. {
  19. typedef unary_parser<Subject, lexeme_directive<Subject> > base_type;
  20. static bool const is_pass_through_unary = true;
  21. static bool const handles_container = Subject::handles_container;
  22. constexpr lexeme_directive(Subject const& subject)
  23. : base_type(subject) {}
  24. template <typename Iterator, typename Context
  25. , typename RContext, typename Attribute>
  26. typename enable_if<has_skipper<Context>, bool>::type
  27. parse(Iterator& first, Iterator const& last
  28. , Context const& context, RContext& rcontext, Attribute& attr) const
  29. {
  30. x3::skip_over(first, last, context);
  31. auto const& skipper = x3::get<skipper_tag>(context);
  32. typedef unused_skipper<
  33. typename remove_reference<decltype(skipper)>::type>
  34. unused_skipper_type;
  35. unused_skipper_type unused_skipper(skipper);
  36. return this->subject.parse(
  37. first, last
  38. , make_context<skipper_tag>(unused_skipper, context)
  39. , rcontext
  40. , attr);
  41. }
  42. template <typename Iterator, typename Context
  43. , typename RContext, typename Attribute>
  44. typename disable_if<has_skipper<Context>, bool>::type
  45. parse(Iterator& first, Iterator const& last
  46. , Context const& context, RContext& rcontext, Attribute& attr) const
  47. {
  48. // no need to pre-skip if skipper is unused
  49. return this->subject.parse(
  50. first, last
  51. , context
  52. , rcontext
  53. , attr);
  54. }
  55. };
  56. struct lexeme_gen
  57. {
  58. template <typename Subject>
  59. constexpr lexeme_directive<typename extension::as_parser<Subject>::value_type>
  60. operator[](Subject const& subject) const
  61. {
  62. return { as_parser(subject) };
  63. }
  64. };
  65. constexpr auto lexeme = lexeme_gen{};
  66. }}}
  67. #endif