1 /*============================================================================= 2 Copyright (c) 2016 Frank Hein, maxence business consulting gmbh 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_EXPECT_HPP 8 #define BOOST_SPIRIT_QI_DIRECTIVE_EXPECT_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/support/has_semantic_action.hpp> 16 #include <boost/spirit/home/qi/detail/attributes.hpp> 17 #include <boost/spirit/home/qi/detail/expectation_failure.hpp> 18 #include <boost/spirit/home/support/common_terminals.hpp> 19 #include <boost/spirit/home/support/handles_container.hpp> 20 #include <boost/spirit/home/support/unused.hpp> 21 #include <boost/spirit/home/support/info.hpp> 22 23 namespace boost { namespace spirit { 24 /////////////////////////////////////////////////////////////////////////// 25 // Enablers 26 /////////////////////////////////////////////////////////////////////////// 27 template <> 28 struct use_directive<qi::domain, tag::expect> // enables expect[p] 29 : mpl::true_ {}; 30 }} 31 32 namespace boost { namespace spirit { namespace qi { 33 34 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 35 using spirit::expect; 36 #endif 37 using spirit::expect_type; 38 39 template <typename Subject> 40 struct expect_directive : unary_parser<expect_directive<Subject> > 41 { 42 typedef result_of::compile<domain, Subject> subject_type; 43 44 template <typename Context, typename Iterator> 45 struct attribute 46 { 47 typedef traits::attribute_of<subject_type, Context, Iterator> 48 type; 49 }; 50 expect_directiveboost::spirit::qi::expect_directive51 expect_directive(Subject const& subject_) : subject(subject_) {} 52 53 template <typename Iterator, typename Context 54 , typename Skipper, typename Attribute> parseboost::spirit::qi::expect_directive55 bool parse(Iterator& first, Iterator const& last 56 , Context& context, Skipper const& skipper 57 , Attribute& attr_) const 58 { 59 typedef expectation_failure<Iterator> exception; 60 61 if (!subject.parse(first, last, context, skipper, attr_)) 62 { 63 boost::throw_exception( 64 exception(first, last, subject.what(context))); 65 #if defined(BOOST_NO_EXCEPTIONS) 66 return false; // for systems not supporting exceptions 67 #endif 68 } 69 return true; 70 } 71 72 template <typename Context> whatboost::spirit::qi::expect_directive73 info what(Context& context) const 74 { 75 return info("expect", subject.what(context)); 76 } 77 78 Subject subject; 79 }; 80 81 /////////////////////////////////////////////////////////////////////////// 82 // Parser generators: make_xxx function (objects) 83 /////////////////////////////////////////////////////////////////////////// 84 template <typename Subject, typename Modifiers> 85 struct make_directive<tag::expect, Subject, Modifiers> 86 { 87 typedef expect_directive<Subject> result_type; 88 operator ()boost::spirit::qi::make_directive89 result_type operator() 90 (unused_type, Subject const& subject, unused_type) const 91 { 92 return result_type(subject); 93 } 94 }; 95 96 }}} 97 98 namespace boost { namespace spirit { namespace traits { 99 /////////////////////////////////////////////////////////////////////////// 100 template <typename Subject> 101 struct has_semantic_action<qi::expect_directive<Subject> > 102 : unary_has_semantic_action<Subject> {}; 103 104 /////////////////////////////////////////////////////////////////////////// 105 template <typename Subject, typename Attribute 106 , typename Context, typename Iterator> 107 struct handles_container< 108 qi::expect_directive<Subject>, Attribute, Context, Iterator 109 > 110 : unary_handles_container<Subject, Attribute, Context, Iterator> {}; 111 }}} 112 113 #endif 114