seek.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*=============================================================================
  2. Copyright (c) 2011 Jamboree
  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. #ifndef BOOST_SPIRIT_REPOSITORY_QI_SEEK
  7. #define BOOST_SPIRIT_REPOSITORY_QI_SEEK
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/qi/meta_compiler.hpp>
  12. #include <boost/spirit/home/qi/parser.hpp>
  13. #include <boost/spirit/home/qi/detail/attributes.hpp>
  14. #include <boost/spirit/home/support/info.hpp>
  15. #include <boost/spirit/home/support/unused.hpp>
  16. #include <boost/spirit/home/support/has_semantic_action.hpp>
  17. #include <boost/spirit/home/support/handles_container.hpp>
  18. #include <boost/spirit/repository/home/support/seek.hpp>
  19. namespace boost { namespace spirit
  20. {
  21. ///////////////////////////////////////////////////////////////////////////
  22. // Enablers
  23. ///////////////////////////////////////////////////////////////////////////
  24. // enables seek[...]
  25. template <>
  26. struct use_directive<qi::domain, repository::tag::seek>
  27. : mpl::true_ {};
  28. }} // namespace boost::spirit
  29. namespace boost { namespace spirit { namespace repository {namespace qi
  30. {
  31. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  32. using repository::seek;
  33. #endif
  34. using repository::seek_type;
  35. template <typename Subject>
  36. struct seek_directive
  37. : spirit::qi::unary_parser<seek_directive<Subject> >
  38. {
  39. typedef Subject subject_type;
  40. template <typename Context, typename Iterator>
  41. struct attribute
  42. {
  43. typedef typename
  44. traits::attribute_of<subject_type, Context, Iterator>::type
  45. type;
  46. };
  47. seek_directive(Subject const& subject)
  48. : subject(subject)
  49. {}
  50. template
  51. <
  52. typename Iterator, typename Context
  53. , typename Skipper, typename Attribute
  54. >
  55. bool parse
  56. (
  57. Iterator& first, Iterator const& last
  58. , Context& context, Skipper const& skipper
  59. , Attribute& attr
  60. ) const
  61. {
  62. for (Iterator it(first); ; ++it)
  63. {
  64. if (subject.parse(it, last, context, skipper, attr))
  65. {
  66. first = it;
  67. return true;
  68. }
  69. // fail only after subject fails & no input
  70. if (it == last)
  71. return false;
  72. }
  73. }
  74. template <typename Context>
  75. info what(Context& context) const
  76. {
  77. return info("seek", subject.what(context));
  78. }
  79. Subject subject;
  80. };
  81. }}}} // namespace boost::spirit::repository::qi
  82. namespace boost { namespace spirit { namespace qi
  83. {
  84. ///////////////////////////////////////////////////////////////////////////
  85. // Parser generators: make_xxx function (objects)
  86. ///////////////////////////////////////////////////////////////////////////
  87. template <typename Subject, typename Modifiers>
  88. struct make_directive<repository::tag::seek, Subject, Modifiers>
  89. {
  90. typedef repository::qi::seek_directive<Subject> result_type;
  91. result_type operator()(unused_type, Subject const& subject, unused_type) const
  92. {
  93. return result_type(subject);
  94. }
  95. };
  96. }}} // namespace boost::spirit::qi
  97. namespace boost { namespace spirit { namespace traits
  98. {
  99. ///////////////////////////////////////////////////////////////////////////
  100. template <typename Subject>
  101. struct has_semantic_action<repository::qi::seek_directive<Subject> >
  102. : unary_has_semantic_action<Subject> {};
  103. ///////////////////////////////////////////////////////////////////////////
  104. template <typename Subject, typename Attribute, typename Context
  105. , typename Iterator>
  106. struct handles_container<repository::qi::seek_directive<Subject>, Attribute
  107. , Context, Iterator>
  108. : unary_handles_container<Subject, Attribute, Context, Iterator> {};
  109. }}} // namespace boost::spirit::traits
  110. #endif