1 // Copyright (c) 2009 Chris Hoeppler 2 // 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_REPOSITORY_QI_CONFIX_JUN_22_2009_1041AM) 7 #define BOOST_SPIRIT_REPOSITORY_QI_CONFIX_JUN_22_2009_1041AM 8 9 #if defined(_MSC_VER) 10 #pragma once 11 #endif 12 13 #include <boost/spirit/home/qi/domain.hpp> 14 #include <boost/spirit/home/qi/meta_compiler.hpp> 15 #include <boost/spirit/home/qi/auxiliary/lazy.hpp> 16 #include <boost/spirit/home/support/common_terminals.hpp> 17 #include <boost/spirit/home/support/info.hpp> 18 #include <boost/spirit/home/support/unused.hpp> 19 #include <boost/spirit/home/qi/detail/attributes.hpp> 20 21 #include <boost/spirit/repository/home/support/confix.hpp> 22 23 #include <boost/fusion/include/vector.hpp> 24 #include <boost/mpl/or.hpp> 25 26 /////////////////////////////////////////////////////////////////////////////// 27 namespace boost { namespace spirit 28 { 29 /////////////////////////////////////////////////////////////////////////// 30 // Enablers 31 /////////////////////////////////////////////////////////////////////////// 32 33 // enables confix(..., ...)[] 34 template <typename Prefix, typename Suffix> 35 struct use_directive<qi::domain 36 , terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > > 37 : mpl::true_ {}; 38 39 // enables *lazy* confix(..., ...)[] 40 template <> 41 struct use_lazy_directive<qi::domain, repository::tag::confix, 2> 42 : mpl::true_ {}; 43 44 }} 45 46 /////////////////////////////////////////////////////////////////////////////// 47 namespace boost { namespace spirit { namespace repository { namespace qi 48 { 49 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 50 using repository::confix; 51 #endif 52 using repository::confix_type; 53 54 /////////////////////////////////////////////////////////////////////////// 55 // the confix() generated parser 56 template <typename Subject, typename Prefix, typename Suffix> 57 struct confix_parser 58 : spirit::qi::unary_parser<confix_parser<Subject, Prefix, Suffix> > 59 { 60 typedef Subject subject_type; 61 62 template <typename Context, typename Iterator> 63 struct attribute 64 : traits::attribute_of<subject_type, Context, Iterator> 65 {}; 66 confix_parserboost::spirit::repository::qi::confix_parser67 confix_parser(Subject const& subject, Prefix const& prefix 68 , Suffix const& suffix) 69 : subject(subject), prefix(prefix), suffix(suffix) {} 70 71 template <typename Iterator, typename Context 72 , typename Skipper, typename Attribute> parseboost::spirit::repository::qi::confix_parser73 bool parse(Iterator& first, Iterator const& last 74 , Context& context, Skipper const& skipper 75 , Attribute& attr) const 76 { 77 Iterator iter = first; 78 79 if (!(prefix.parse(iter, last, context, skipper, unused) && 80 subject.parse(iter, last, context, skipper, attr) && 81 suffix.parse(iter, last, context, skipper, unused))) 82 { 83 return false; 84 } 85 86 first = iter; 87 return true; 88 } 89 90 template <typename Context> whatboost::spirit::repository::qi::confix_parser91 info what(Context const& ctx) const 92 { 93 return info("confix", subject.what(ctx)); 94 } 95 96 Subject subject; 97 Prefix prefix; 98 Suffix suffix; 99 }; 100 101 }}}} 102 103 /////////////////////////////////////////////////////////////////////////////// 104 namespace boost { namespace spirit { namespace qi 105 { 106 /////////////////////////////////////////////////////////////////////////// 107 // Parser generators: make_xxx function (objects) 108 /////////////////////////////////////////////////////////////////////////// 109 110 // creates confix(..., ...)[] directive 111 template <typename Prefix, typename Suffix, typename Subject 112 , typename Modifiers> 113 struct make_directive< 114 terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > 115 , Subject, Modifiers> 116 { 117 typedef typename 118 result_of::compile<qi::domain, Prefix, Modifiers>::type 119 prefix_type; 120 typedef typename 121 result_of::compile<qi::domain, Suffix, Modifiers>::type 122 suffix_type; 123 124 typedef repository::qi::confix_parser< 125 Subject, prefix_type, suffix_type> result_type; 126 127 template <typename Terminal> operator ()boost::spirit::qi::make_directive128 result_type operator()(Terminal const& term, Subject const& subject 129 , Modifiers const& modifiers) const 130 { 131 return result_type(subject 132 , compile<qi::domain>(fusion::at_c<0>(term.args), modifiers) 133 , compile<qi::domain>(fusion::at_c<1>(term.args), modifiers)); 134 } 135 }; 136 137 }}} 138 139 namespace boost { namespace spirit { namespace traits 140 { 141 template <typename Subject, typename Prefix, typename Suffix> 142 struct has_semantic_action< 143 repository::qi::confix_parser<Subject, Prefix, Suffix> > 144 : mpl::or_< 145 has_semantic_action<Subject> 146 , has_semantic_action<Prefix> 147 , has_semantic_action<Suffix> 148 > {}; 149 }}} 150 151 #endif 152 153