1 /*============================================================================= 2 Copyright (c) 2001-2014 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 #if !defined(BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM) 8 #define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM 9 10 #include <boost/spirit/home/x3/support/context.hpp> 11 #include <boost/spirit/home/x3/core/parser.hpp> 12 #include <boost/spirit/home/x3/core/skip_over.hpp> 13 #include <boost/iterator/iterator_concepts.hpp> 14 15 namespace boost { namespace spirit { namespace x3 16 { 17 /////////////////////////////////////////////////////////////////////////// 18 template <typename Iterator, typename Parser, typename Attribute> 19 inline bool parse_main(Iterator & first,Iterator last,Parser const & p,Attribute & attr)20 parse_main( 21 Iterator& first 22 , Iterator last 23 , Parser const& p 24 , Attribute& attr) 25 { 26 // Make sure the iterator is at least a readable forward traversal iterator. 27 // If you got a compilation error here, then you are using a weaker iterator 28 // while calling this function, you need to supply a readable forward traversal 29 // iterator instead. 30 BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>)); 31 BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>)); 32 33 // If you get an error no matching function for call to 'as_parser' 34 // here, then p is not a parser or there is no suitable conversion 35 // from p to a parser. 36 return as_parser(p).parse(first, last, unused, unused, attr); 37 } 38 39 /////////////////////////////////////////////////////////////////////////// 40 template <typename Iterator, typename Parser, typename Attribute> 41 inline bool parse(Iterator & first,Iterator last,Parser const & p,Attribute & attr)42 parse( 43 Iterator& first 44 , Iterator last 45 , Parser const& p 46 , Attribute& attr) 47 { 48 return parse_main(first, last, p, attr); 49 } 50 51 /////////////////////////////////////////////////////////////////////////// 52 template <typename Iterator, typename Parser, typename Attribute> 53 inline bool parse(Iterator const & first_,Iterator last,Parser const & p,Attribute & attr)54 parse( 55 Iterator const& first_ 56 , Iterator last 57 , Parser const& p 58 , Attribute& attr) 59 { 60 Iterator first = first_; 61 return parse_main(first, last, p, attr); 62 } 63 64 /////////////////////////////////////////////////////////////////////////// 65 template <typename Iterator, typename Parser> 66 inline bool parse(Iterator & first,Iterator last,Parser const & p)67 parse( 68 Iterator& first 69 , Iterator last 70 , Parser const& p) 71 { 72 return parse_main(first, last, p, unused); 73 } 74 75 /////////////////////////////////////////////////////////////////////////// 76 template <typename Iterator, typename Parser> 77 inline bool parse(Iterator const & first_,Iterator last,Parser const & p)78 parse( 79 Iterator const& first_ 80 , Iterator last 81 , Parser const& p) 82 { 83 Iterator first = first_; 84 return parse_main(first, last, p, unused); 85 } 86 87 /////////////////////////////////////////////////////////////////////////// 88 enum class skip_flag 89 { 90 post_skip, // force post-skipping in phrase_parse() 91 dont_post_skip // inhibit post-skipping in phrase_parse() 92 }; 93 94 /////////////////////////////////////////////////////////////////////////// 95 template <typename Iterator, typename Parser, typename Skipper, typename Attribute> 96 inline bool phrase_parse_main(Iterator & first,Iterator last,Parser const & p,Skipper const & s,Attribute & attr,skip_flag post_skip=skip_flag::post_skip)97 phrase_parse_main( 98 Iterator& first 99 , Iterator last 100 , Parser const& p 101 , Skipper const& s 102 , Attribute& attr 103 , skip_flag post_skip = skip_flag::post_skip) 104 { 105 // Make sure the iterator is at least a readable forward traversal iterator. 106 // If you got a compilation error here, then you are using a weaker iterator 107 // while calling this function, you need to supply a readable forward traversal 108 // iterator instead. 109 BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>)); 110 BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>)); 111 112 static_assert(!std::is_same<Skipper, unused_type>::value, 113 "Error! Skipper cannot be unused_type."); 114 115 // If you get an error no matching function for call to 'as_parser' 116 // here, for either p or s, then p or s is not a parser or there is 117 // no suitable conversion from p to a parser. 118 auto skipper_ctx = make_context<skipper_tag>(as_parser(s)); 119 bool r = as_parser(p).parse(first, last, skipper_ctx, unused, attr); 120 if (post_skip == skip_flag::post_skip) 121 x3::skip_over(first, last, skipper_ctx); 122 return r; 123 } 124 125 /////////////////////////////////////////////////////////////////////////// 126 template <typename Iterator, typename Parser, typename Skipper, typename Attribute> 127 inline bool phrase_parse(Iterator & first,Iterator last,Parser const & p,Skipper const & s,Attribute & attr,skip_flag post_skip=skip_flag::post_skip)128 phrase_parse( 129 Iterator& first 130 , Iterator last 131 , Parser const& p 132 , Skipper const& s 133 , Attribute& attr 134 , skip_flag post_skip = skip_flag::post_skip) 135 { 136 return phrase_parse_main(first, last, p, s, attr, post_skip); 137 } 138 139 /////////////////////////////////////////////////////////////////////////// 140 template <typename Iterator, typename Parser, typename Skipper, typename Attribute> 141 inline bool phrase_parse(Iterator const & first_,Iterator last,Parser const & p,Skipper const & s,Attribute & attr,skip_flag post_skip=skip_flag::post_skip)142 phrase_parse( 143 Iterator const& first_ 144 , Iterator last 145 , Parser const& p 146 , Skipper const& s 147 , Attribute& attr 148 , skip_flag post_skip = skip_flag::post_skip) 149 { 150 Iterator first = first_; 151 return phrase_parse_main(first, last, p, s, attr, post_skip); 152 } 153 154 /////////////////////////////////////////////////////////////////////////// 155 template <typename Iterator, typename Parser, typename Skipper> 156 inline bool phrase_parse(Iterator & first,Iterator last,Parser const & p,Skipper const & s,skip_flag post_skip=skip_flag::post_skip)157 phrase_parse( 158 Iterator& first 159 , Iterator last 160 , Parser const& p 161 , Skipper const& s 162 , skip_flag post_skip = skip_flag::post_skip) 163 { 164 return phrase_parse_main(first, last, p, s, unused, post_skip); 165 } 166 167 /////////////////////////////////////////////////////////////////////////// 168 template <typename Iterator, typename Parser, typename Skipper> 169 inline bool phrase_parse(Iterator const & first_,Iterator last,Parser const & p,Skipper const & s,skip_flag post_skip=skip_flag::post_skip)170 phrase_parse( 171 Iterator const& first_ 172 , Iterator last 173 , Parser const& p 174 , Skipper const& s 175 , skip_flag post_skip = skip_flag::post_skip) 176 { 177 Iterator first = first_; 178 return phrase_parse_main(first, last, p, s, unused, post_skip); 179 } 180 181 /////////////////////////////////////////////////////////////////////////// 182 template <typename Skipper> 183 struct phrase_parse_context 184 { 185 typedef decltype( 186 make_context<skipper_tag>(as_parser(std::declval<Skipper>()))) 187 type; 188 }; 189 }}} 190 191 #endif 192