1 /*============================================================================= 2 Copyright (c) 2011 Jamboree 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 =============================================================================*/ 7 #ifndef BOOST_SPIRIT_REPOSITORY_QI_SEEK 8 #define BOOST_SPIRIT_REPOSITORY_QI_SEEK 9 10 11 #if defined(_MSC_VER) 12 #pragma once 13 #endif 14 15 16 #include <boost/spirit/home/qi/meta_compiler.hpp> 17 #include <boost/spirit/home/qi/parser.hpp> 18 #include <boost/spirit/home/qi/detail/attributes.hpp> 19 #include <boost/spirit/home/support/info.hpp> 20 #include <boost/spirit/home/support/unused.hpp> 21 #include <boost/spirit/home/support/has_semantic_action.hpp> 22 #include <boost/spirit/home/support/handles_container.hpp> 23 #include <boost/spirit/repository/home/support/seek.hpp> 24 25 26 namespace boost { namespace spirit 27 { 28 /////////////////////////////////////////////////////////////////////////// 29 // Enablers 30 /////////////////////////////////////////////////////////////////////////// 31 32 // enables seek[...] 33 template <> 34 struct use_directive<qi::domain, repository::tag::seek> 35 : mpl::true_ {}; 36 }} // namespace boost::spirit 37 38 39 namespace boost { namespace spirit { namespace repository {namespace qi 40 { 41 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 42 using repository::seek; 43 #endif 44 using repository::seek_type; 45 46 template <typename Subject> 47 struct seek_directive 48 : spirit::qi::unary_parser<seek_directive<Subject> > 49 { 50 typedef Subject subject_type; 51 52 template <typename Context, typename Iterator> 53 struct attribute 54 { 55 typedef typename 56 traits::attribute_of<subject_type, Context, Iterator>::type 57 type; 58 }; 59 seek_directiveboost::spirit::repository::qi::seek_directive60 seek_directive(Subject const& subject) 61 : subject(subject) 62 {} 63 64 template 65 < 66 typename Iterator, typename Context 67 , typename Skipper, typename Attribute 68 > parseboost::spirit::repository::qi::seek_directive69 bool parse 70 ( 71 Iterator& first, Iterator const& last 72 , Context& context, Skipper const& skipper 73 , Attribute& attr 74 ) const 75 { 76 for (Iterator it(first); ; ++it) 77 { 78 if (subject.parse(it, last, context, skipper, attr)) 79 { 80 first = it; 81 return true; 82 } 83 // fail only after subject fails & no input 84 if (it == last) 85 return false; 86 } 87 } 88 89 template <typename Context> whatboost::spirit::repository::qi::seek_directive90 info what(Context& context) const 91 { 92 return info("seek", subject.what(context)); 93 } 94 95 Subject subject; 96 }; 97 }}}} // namespace boost::spirit::repository::qi 98 99 100 namespace boost { namespace spirit { namespace qi 101 { 102 /////////////////////////////////////////////////////////////////////////// 103 // Parser generators: make_xxx function (objects) 104 /////////////////////////////////////////////////////////////////////////// 105 template <typename Subject, typename Modifiers> 106 struct make_directive<repository::tag::seek, Subject, Modifiers> 107 { 108 typedef repository::qi::seek_directive<Subject> result_type; 109 operator ()boost::spirit::qi::make_directive110 result_type operator()(unused_type, Subject const& subject, unused_type) const 111 { 112 return result_type(subject); 113 } 114 }; 115 }}} // namespace boost::spirit::qi 116 117 118 namespace boost { namespace spirit { namespace traits 119 { 120 /////////////////////////////////////////////////////////////////////////// 121 template <typename Subject> 122 struct has_semantic_action<repository::qi::seek_directive<Subject> > 123 : unary_has_semantic_action<Subject> {}; 124 125 /////////////////////////////////////////////////////////////////////////// 126 template <typename Subject, typename Attribute, typename Context 127 , typename Iterator> 128 struct handles_container<repository::qi::seek_directive<Subject>, Attribute 129 , Context, Iterator> 130 : unary_handles_container<Subject, Attribute, Context, Iterator> {}; 131 }}} // namespace boost::spirit::traits 132 133 134 #endif 135