1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 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_QI_DIRECTIVE_RAW_HPP 8 #define BOOST_SPIRIT_QI_DIRECTIVE_RAW_HPP 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 14 #include <boost/spirit/home/qi/meta_compiler.hpp> 15 #include <boost/spirit/home/qi/skip_over.hpp> 16 #include <boost/spirit/home/qi/parser.hpp> 17 #include <boost/spirit/home/qi/detail/assign_to.hpp> 18 #include <boost/spirit/home/support/unused.hpp> 19 #include <boost/spirit/home/support/info.hpp> 20 #include <boost/spirit/home/support/common_terminals.hpp> 21 #include <boost/spirit/home/support/unused.hpp> 22 #include <boost/spirit/home/support/has_semantic_action.hpp> 23 #include <boost/spirit/home/support/handles_container.hpp> 24 #include <boost/range/iterator_range_core.hpp> // TODO: use forward include 25 26 namespace boost { namespace spirit 27 { 28 /////////////////////////////////////////////////////////////////////////// 29 // Enablers 30 /////////////////////////////////////////////////////////////////////////// 31 template <> 32 struct use_directive<qi::domain, tag::raw> // enables raw 33 : mpl::true_ {}; 34 }} 35 36 namespace boost { namespace spirit { namespace qi 37 { 38 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 39 using spirit::raw; 40 #endif 41 using spirit::raw_type; 42 43 template <typename Subject> 44 struct raw_directive : unary_parser<raw_directive<Subject> > 45 { 46 typedef Subject subject_type; raw_directiveboost::spirit::qi::raw_directive47 raw_directive(Subject const& subject_) 48 : subject(subject_) {} 49 50 template <typename Context, typename Iterator> 51 struct attribute 52 { 53 typedef iterator_range<Iterator> type; 54 }; 55 56 template <typename Iterator, typename Context 57 , typename Skipper, typename Attribute> parseboost::spirit::qi::raw_directive58 bool parse(Iterator& first, Iterator const& last 59 , Context& context, Skipper const& skipper, Attribute& attr_) const 60 { 61 qi::skip_over(first, last, skipper); 62 Iterator i = first; 63 if (subject.parse(i, last, context, skipper, unused)) 64 { 65 spirit::traits::assign_to(first, i, attr_); 66 first = i; 67 return true; 68 } 69 return false; 70 } 71 72 template <typename Context> whatboost::spirit::qi::raw_directive73 info what(Context& context) const 74 { 75 return info("raw", subject.what(context)); 76 77 } 78 79 Subject subject; 80 }; 81 82 /////////////////////////////////////////////////////////////////////////// 83 // Parser generators: make_xxx function (objects) 84 /////////////////////////////////////////////////////////////////////////// 85 template <typename Subject, typename Modifiers> 86 struct make_directive<tag::raw, Subject, Modifiers> 87 { 88 typedef raw_directive<Subject> result_type; operator ()boost::spirit::qi::make_directive89 result_type operator()(unused_type, Subject const& subject, unused_type) const 90 { 91 return result_type(subject); 92 } 93 }; 94 }}} 95 96 namespace boost { namespace spirit { namespace traits 97 { 98 /////////////////////////////////////////////////////////////////////////// 99 template <typename Subject> 100 struct has_semantic_action<qi::raw_directive<Subject> > 101 : unary_has_semantic_action<Subject> {}; 102 103 /////////////////////////////////////////////////////////////////////////// 104 template <typename Subject, typename Attribute, typename Context 105 , typename Iterator> 106 struct handles_container<qi::raw_directive<Subject>, Attribute 107 , Context, Iterator> 108 : unary_handles_container<Subject, Attribute, Context, Iterator> {}; 109 }}} 110 111 #endif 112