1 /////////////////////////////////////////////////////////////////////////////// 2 // grammar.hpp 3 // 4 // Copyright 2008 Eric Niebler. Distributed under the Boost 5 // Software License, Version 1.0. (See accompanying file 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_GRAMMAR_HPP_EAN_11_12_2006 9 #define BOOST_XPRESSIVE_DETAIL_STATIC_GRAMMAR_HPP_EAN_11_12_2006 10 11 // MS compatible compilers support #pragma once 12 #if defined(_MSC_VER) 13 # pragma once 14 #endif 15 16 #include <boost/mpl/if.hpp> 17 #include <boost/mpl/bool.hpp> 18 #include <boost/mpl/assert.hpp> 19 #include <boost/proto/core.hpp> 20 #include <boost/xpressive/detail/static/is_pure.hpp> 21 #include <boost/xpressive/detail/static/transforms/as_matcher.hpp> 22 #include <boost/xpressive/detail/static/transforms/as_alternate.hpp> 23 #include <boost/xpressive/detail/static/transforms/as_sequence.hpp> 24 #include <boost/xpressive/detail/static/transforms/as_quantifier.hpp> 25 #include <boost/xpressive/detail/static/transforms/as_marker.hpp> 26 #include <boost/xpressive/detail/static/transforms/as_set.hpp> 27 #include <boost/xpressive/detail/static/transforms/as_independent.hpp> 28 #include <boost/xpressive/detail/static/transforms/as_modifier.hpp> 29 #include <boost/xpressive/detail/static/transforms/as_inverse.hpp> 30 #include <boost/xpressive/detail/static/transforms/as_action.hpp> 31 #include <boost/xpressive/detail/detail_fwd.hpp> 32 33 #define BOOST_XPRESSIVE_CHECK_REGEX(Expr, Char)\ 34 BOOST_MPL_ASSERT\ 35 ((\ 36 typename boost::mpl::if_c<\ 37 boost::xpressive::is_valid_regex<Expr, Char>::value\ 38 , boost::mpl::true_\ 39 , boost::xpressive::INVALID_REGULAR_EXPRESSION\ 40 >::type\ 41 )); 42 43 ////////////////////////////////////////////////////////////////////////// 44 //**********************************************************************// 45 //* << NOTE! >> *// 46 //* *// 47 //* Whenever you change this grammar, you MUST also make corresponding *// 48 //* changes to width_of.hpp and is_pure.hpp. *// 49 //* *// 50 //**********************************************************************// 51 ////////////////////////////////////////////////////////////////////////// 52 53 namespace boost { namespace xpressive 54 { 55 template<typename Char> 56 struct Grammar; 57 58 template<typename Char> 59 struct ActionableGrammar; 60 61 namespace grammar_detail 62 { 63 /////////////////////////////////////////////////////////////////////////// 64 // CharLiteral 65 template<typename Char> 66 struct CharLiteral; 67 68 /////////////////////////////////////////////////////////////////////////// 69 // ListSet 70 template<typename Char> 71 struct ListSet; 72 73 /////////////////////////////////////////////////////////////////////////// 74 // as_repeat 75 template<typename Char, typename Gram, typename Greedy> 76 struct as_repeat 77 : if_< 78 make<detail::use_simple_repeat<_child, Char> > 79 , as_simple_quantifier<Gram, Greedy> 80 , as_default_quantifier<Greedy> 81 > 82 {}; 83 84 /////////////////////////////////////////////////////////////////////////// 85 // NonGreedyRepeatCases 86 template<typename Gram> 87 struct NonGreedyRepeatCases 88 { 89 template<typename Tag, typename Dummy = void> 90 struct case_ 91 : not_<_> 92 {}; 93 94 template<typename Dummy> 95 struct case_<tag::dereference, Dummy> 96 : dereference<Gram> 97 {}; 98 99 template<typename Dummy> 100 struct case_<tag::unary_plus, Dummy> 101 : unary_plus<Gram> 102 {}; 103 104 template<typename Dummy> 105 struct case_<tag::logical_not, Dummy> 106 : logical_not<Gram> 107 {}; 108 109 template<uint_t Min, uint_t Max, typename Dummy> 110 struct case_<detail::generic_quant_tag<Min, Max>, Dummy> 111 : unary_expr<detail::generic_quant_tag<Min, Max>, Gram> 112 {}; 113 }; 114 115 /////////////////////////////////////////////////////////////////////////// 116 // InvertibleCases 117 template<typename Char, typename Gram> 118 struct InvertibleCases 119 { 120 template<typename Tag, typename Dummy = void> 121 struct case_ 122 : not_<_> 123 {}; 124 125 template<typename Dummy> 126 struct case_<tag::comma, Dummy> 127 : when<ListSet<Char>, as_list_set_matcher<Char> > 128 {}; 129 130 template<typename Dummy> 131 struct case_<tag::assign, Dummy> 132 : when<ListSet<Char>, as_list_set_matcher<Char> > 133 {}; 134 135 template<typename Dummy> 136 struct case_<tag::subscript, Dummy> 137 : when<subscript<detail::set_initializer_type, Gram>, call<as_set_matcher<Gram>(_right)> > 138 {}; 139 140 template<typename Dummy> 141 struct case_<detail::lookahead_tag, Dummy> 142 : when< 143 unary_expr<detail::lookahead_tag, Gram> 144 , as_lookahead<Gram> 145 > 146 {}; 147 148 template<typename Dummy> 149 struct case_<detail::lookbehind_tag, Dummy> 150 : when< 151 unary_expr<detail::lookbehind_tag, Gram> 152 , as_lookbehind<Gram> 153 > 154 {}; 155 156 template<typename Dummy> 157 struct case_<tag::terminal, Dummy> 158 : when< 159 or_< 160 CharLiteral<Char> 161 , terminal<detail::posix_charset_placeholder> 162 , terminal<detail::range_placeholder<_> > 163 , terminal<detail::logical_newline_placeholder> 164 , terminal<detail::assert_word_placeholder<detail::word_boundary<mpl::true_> > > 165 > 166 , as_matcher 167 > 168 {}; 169 }; 170 171 /////////////////////////////////////////////////////////////////////////// 172 // Cases 173 template<typename Char, typename Gram> 174 struct Cases 175 { 176 template<typename Tag, typename Dummy = void> 177 struct case_ 178 : not_<_> 179 {}; 180 181 template<typename Dummy> 182 struct case_<tag::terminal, Dummy> 183 : when< 184 _ 185 , in_sequence<as_matcher> 186 > 187 {}; 188 189 template<typename Dummy> 190 struct case_<tag::shift_right, Dummy> 191 : when< 192 shift_right<Gram, Gram> 193 , reverse_fold<_, _state, Gram> 194 > 195 {}; 196 197 template<typename Dummy> 198 struct case_<tag::bitwise_or, Dummy> 199 : when< 200 bitwise_or<Gram, Gram> 201 , in_sequence< 202 as_alternate_matcher< 203 reverse_fold_tree<_, make<fusion::nil>, in_alternate_list<Gram> > 204 > 205 > 206 > 207 {}; 208 209 template<typename Dummy, typename Greedy> 210 struct case_<optional_tag<Greedy> , Dummy> 211 : when< 212 unary_expr<optional_tag<Greedy>, Gram> 213 , in_sequence<call<as_optional<Gram, Greedy>(_child)> > 214 > 215 {}; 216 217 template<typename Dummy> 218 struct case_<tag::dereference, Dummy> 219 : when< 220 dereference<Gram> 221 , call<Gram(as_repeat<Char, Gram, mpl::true_>)> 222 > 223 {}; 224 225 template<typename Dummy> 226 struct case_<tag::unary_plus, Dummy> 227 : when< 228 unary_plus<Gram> 229 , call<Gram(as_repeat<Char, Gram, mpl::true_>)> 230 > 231 {}; 232 233 template<typename Dummy> 234 struct case_<tag::logical_not, Dummy> 235 : when< 236 logical_not<Gram> 237 , call<Gram(as_repeat<Char, Gram, mpl::true_>)> 238 > 239 {}; 240 241 template<uint_t Min, uint_t Max, typename Dummy> 242 struct case_<detail::generic_quant_tag<Min, Max>, Dummy> 243 : when< 244 unary_expr<detail::generic_quant_tag<Min, Max>, Gram> 245 , call<Gram(as_repeat<Char, Gram, mpl::true_>)> 246 > 247 {}; 248 249 template<typename Dummy> 250 struct case_<tag::negate, Dummy> 251 : when< 252 negate<switch_<NonGreedyRepeatCases<Gram> > > 253 , call<Gram(call<as_repeat<Char, Gram, mpl::false_>(_child)>)> 254 > 255 {}; 256 257 template<typename Dummy> 258 struct case_<tag::complement, Dummy> 259 : when< 260 complement<switch_<InvertibleCases<Char, Gram> > > 261 , in_sequence<call<as_inverse(call<switch_<InvertibleCases<Char, Gram> >(_child)>)> > 262 > 263 {}; 264 265 template<typename Dummy> 266 struct case_<detail::modifier_tag, Dummy> 267 : when<binary_expr<detail::modifier_tag, _, Gram>, as_modifier<Gram> > 268 {}; 269 270 template<typename Dummy> 271 struct case_<detail::lookahead_tag, Dummy> 272 : when< 273 unary_expr<detail::lookahead_tag, Gram> 274 , in_sequence<as_lookahead<Gram> > 275 > 276 {}; 277 278 template<typename Dummy> 279 struct case_<detail::lookbehind_tag, Dummy> 280 : when< 281 unary_expr<detail::lookbehind_tag, Gram> 282 , in_sequence<as_lookbehind<Gram> > 283 > 284 {}; 285 286 template<typename Dummy> 287 struct case_<detail::keeper_tag, Dummy> 288 : when< 289 unary_expr<detail::keeper_tag, Gram> 290 , in_sequence<as_keeper<Gram> > 291 > 292 {}; 293 294 template<typename Dummy> 295 struct case_<tag::comma, Dummy> 296 : when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > > 297 {}; 298 299 template<typename Dummy> 300 struct case_<tag::assign, Dummy> 301 : or_< 302 when<assign<detail::basic_mark_tag, Gram>, call<Gram(as_marker)> > 303 , when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > > 304 > 305 {}; 306 307 template<typename Dummy> 308 struct case_<tag::subscript, Dummy> 309 : or_< 310 when<subscript<detail::set_initializer_type, Gram>, in_sequence<call<as_set_matcher<Gram>(_right)> > > 311 , when<subscript<ActionableGrammar<Char>, _>, call<ActionableGrammar<Char>(as_action)> > 312 > 313 {}; 314 }; 315 316 /////////////////////////////////////////////////////////////////////////// 317 // ActionableCases 318 template<typename Char, typename Gram> 319 struct ActionableCases 320 { 321 template<typename Tag, typename Dummy = void> 322 struct case_ 323 : Cases<Char, Gram>::template case_<Tag> 324 {}; 325 326 // Only in sub-expressions with actions attached do we allow attribute assignements 327 template<typename Dummy> 328 struct case_<proto::tag::assign, Dummy> 329 : or_< 330 typename Cases<Char, Gram>::template case_<proto::tag::assign> 331 , when<proto::assign<terminal<detail::attribute_placeholder<_> >, _>, in_sequence<as_attr_matcher> > 332 > 333 {}; 334 }; 335 336 } // namespace detail 337 338 /////////////////////////////////////////////////////////////////////////// 339 // Grammar 340 template<typename Char> 341 struct Grammar 342 : proto::switch_<grammar_detail::Cases<Char, Grammar<Char> > > 343 {}; 344 345 template<typename Char> 346 struct ActionableGrammar 347 : proto::switch_<grammar_detail::ActionableCases<Char, ActionableGrammar<Char> > > 348 {}; 349 350 /////////////////////////////////////////////////////////////////////////// 351 // INVALID_REGULAR_EXPRESSION 352 struct INVALID_REGULAR_EXPRESSION 353 : mpl::false_ 354 {}; 355 356 /////////////////////////////////////////////////////////////////////////// 357 // is_valid_regex 358 template<typename Expr, typename Char> 359 struct is_valid_regex 360 : proto::matches<Expr, Grammar<Char> > 361 {}; 362 363 }} // namespace boost::xpressive 364 365 #endif 366