1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 Copyright (c) 2001-2011 Hartmut Kaiser 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 =============================================================================*/ 8 #if !defined(SPIRIT_KLEENE_JANUARY_07_2007_0818AM) 9 #define SPIRIT_KLEENE_JANUARY_07_2007_0818AM 10 11 #if defined(_MSC_VER) 12 #pragma once 13 #endif 14 15 #include <boost/spirit/home/qi/meta_compiler.hpp> 16 #include <boost/spirit/home/qi/parser.hpp> 17 #include <boost/spirit/home/support/container.hpp> 18 #include <boost/spirit/home/qi/detail/attributes.hpp> 19 #include <boost/spirit/home/qi/detail/fail_function.hpp> 20 #include <boost/spirit/home/qi/detail/pass_container.hpp> 21 #include <boost/spirit/home/support/has_semantic_action.hpp> 22 #include <boost/spirit/home/support/handles_container.hpp> 23 #include <boost/spirit/home/support/info.hpp> 24 25 namespace boost { namespace spirit 26 { 27 /////////////////////////////////////////////////////////////////////////// 28 // Enablers 29 /////////////////////////////////////////////////////////////////////////// 30 //[composite_parsers_kleene_enable_ 31 template <> 32 struct use_operator<qi::domain, proto::tag::dereference> // enables *p 33 : mpl::true_ {}; 34 //] 35 }} 36 37 namespace boost { namespace spirit { namespace qi 38 { 39 //[composite_parsers_kleene 40 template <typename Subject> 41 struct kleene : unary_parser<kleene<Subject> > 42 { 43 typedef Subject subject_type; 44 45 template <typename Context, typename Iterator> 46 struct attribute 47 { 48 // Build a std::vector from the subject's attribute. Note 49 // that build_std_vector may return unused_type if the 50 // subject's attribute is an unused_type. 51 typedef typename 52 traits::build_std_vector< 53 typename traits:: 54 attribute_of<Subject, Context, Iterator>::type 55 >::type 56 type; 57 }; 58 kleeneboost::spirit::qi::kleene59 kleene(Subject const& subject_) 60 : subject(subject_) {} 61 62 template <typename F> parse_containerboost::spirit::qi::kleene63 bool parse_container(F f) const 64 { 65 while (!f (subject)) 66 ; 67 return true; 68 } 69 70 template <typename Iterator, typename Context 71 , typename Skipper, typename Attribute> parseboost::spirit::qi::kleene72 bool parse(Iterator& first, Iterator const& last 73 , Context& context, Skipper const& skipper 74 , Attribute& attr_) const 75 { 76 // ensure the attribute is actually a container type 77 traits::make_container(attr_); 78 79 typedef detail::fail_function<Iterator, Context, Skipper> 80 fail_function; 81 82 Iterator iter = first; 83 fail_function f(iter, last, context, skipper); 84 parse_container(detail::make_pass_container(f, attr_)); 85 86 first = f.first; 87 return true; 88 } 89 90 template <typename Context> whatboost::spirit::qi::kleene91 info what(Context& context) const 92 { 93 return info("kleene", subject.what(context)); 94 } 95 96 Subject subject; 97 }; 98 //] 99 100 /////////////////////////////////////////////////////////////////////////// 101 // Parser generators: make_xxx function (objects) 102 /////////////////////////////////////////////////////////////////////////// 103 //[composite_parsers_kleene_generator 104 template <typename Elements, typename Modifiers> 105 struct make_composite<proto::tag::dereference, Elements, Modifiers> 106 : make_unary_composite<Elements, kleene> 107 {}; 108 //] 109 110 // /////////////////////////////////////////////////////////////////////////// 111 // // Define what attributes are compatible with a kleene 112 // template <typename Attribute, typename Subject, typename Context, typename Iterator> 113 // struct is_attribute_compatible<Attribute, kleene<Subject>, Context, Iterator> 114 // : traits::is_container_compatible<qi::domain, Attribute 115 // , kleene<Subject>, Context, Iterator> 116 // {}; 117 }}} 118 119 namespace boost { namespace spirit { namespace traits 120 { 121 /////////////////////////////////////////////////////////////////////////// 122 template <typename Subject> 123 struct has_semantic_action<qi::kleene<Subject> > 124 : unary_has_semantic_action<Subject> {}; 125 126 /////////////////////////////////////////////////////////////////////////// 127 template <typename Subject, typename Attribute, typename Context 128 , typename Iterator> 129 struct handles_container<qi::kleene<Subject>, Attribute 130 , Context, Iterator> 131 : mpl::true_ {}; 132 }}} 133 134 #endif 135