annotate DEPENDENCIES/generic/include/boost/spirit/home/x3/nonterminal/detail/rule.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 /*=============================================================================
Chris@102 2 Copyright (c) 2001-2014 Joel de Guzman
Chris@102 3
Chris@102 4 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@102 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@102 6 ==============================================================================*/
Chris@102 7 #if !defined(BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM)
Chris@102 8 #define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
Chris@102 9
Chris@102 10 #if defined(_MSC_VER)
Chris@102 11 #pragma once
Chris@102 12 #endif
Chris@102 13
Chris@102 14 #include <boost/spirit/home/x3/core/parser.hpp>
Chris@102 15 #include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
Chris@102 16 #include <boost/spirit/home/x3/support/utility/sfinae.hpp>
Chris@102 17 #include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
Chris@102 18 #include <boost/utility/addressof.hpp>
Chris@102 19
Chris@102 20 #if defined(BOOST_SPIRIT_X3_DEBUG)
Chris@102 21 #include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
Chris@102 22 #endif
Chris@102 23
Chris@102 24 namespace boost { namespace spirit { namespace x3
Chris@102 25 {
Chris@102 26 template <typename ID>
Chris@102 27 struct identity;
Chris@102 28
Chris@102 29 template <typename ID, typename Attribute = unused_type>
Chris@102 30 struct rule;
Chris@102 31
Chris@102 32 struct parse_pass_context_tag;
Chris@102 33
Chris@102 34 namespace detail
Chris@102 35 {
Chris@102 36 // we use this so we can detect if the default parse_rule
Chris@102 37 // is the being called.
Chris@102 38 struct default_parse_rule_result
Chris@102 39 {
Chris@102 40 default_parse_rule_result(bool r)
Chris@102 41 : r(r) {}
Chris@102 42 operator bool() const { return r; }
Chris@102 43 bool r;
Chris@102 44 };
Chris@102 45 }
Chris@102 46
Chris@102 47 // default parse_rule implementation
Chris@102 48 template <typename ID, typename Attribute, typename Iterator
Chris@102 49 , typename Context, typename ActualAttribute>
Chris@102 50 inline detail::default_parse_rule_result
Chris@102 51 parse_rule(
Chris@102 52 rule<ID, Attribute> rule_
Chris@102 53 , Iterator& first, Iterator const& last
Chris@102 54 , Context const& context, ActualAttribute& attr);
Chris@102 55 }}}
Chris@102 56
Chris@102 57 namespace boost { namespace spirit { namespace x3 { namespace detail
Chris@102 58 {
Chris@102 59 #if defined(BOOST_SPIRIT_X3_DEBUG)
Chris@102 60 template <typename Iterator, typename Attribute>
Chris@102 61 struct context_debug
Chris@102 62 {
Chris@102 63 context_debug(
Chris@102 64 char const* rule_name
Chris@102 65 , Iterator const& first, Iterator const& last
Chris@102 66 , Attribute const& attr
Chris@102 67 , bool const& ok_parse //was parse successful?
Chris@102 68 )
Chris@102 69 : ok_parse(ok_parse), rule_name(rule_name)
Chris@102 70 , first(first), last(last)
Chris@102 71 , attr(attr)
Chris@102 72 , f(detail::get_simple_trace())
Chris@102 73 {
Chris@102 74 f(first, last, attr, pre_parse, rule_name);
Chris@102 75 }
Chris@102 76
Chris@102 77 ~context_debug()
Chris@102 78 {
Chris@102 79 auto status = ok_parse ? successful_parse : failed_parse ;
Chris@102 80 f(first, last, attr, status, rule_name);
Chris@102 81 }
Chris@102 82
Chris@102 83 bool const& ok_parse;
Chris@102 84 char const* rule_name;
Chris@102 85 Iterator const& first;
Chris@102 86 Iterator const& last;
Chris@102 87 Attribute const& attr;
Chris@102 88 detail::simple_trace_type& f;
Chris@102 89 };
Chris@102 90 #endif
Chris@102 91
Chris@102 92 template <typename ID, typename Iterator, typename Context, typename Enable = void>
Chris@102 93 struct has_on_error : mpl::false_ {};
Chris@102 94
Chris@102 95 template <typename ID, typename Iterator, typename Context>
Chris@102 96 struct has_on_error<ID, Iterator, Context,
Chris@102 97 typename disable_if_substitution_failure<
Chris@102 98 decltype(
Chris@102 99 std::declval<ID>().on_error(
Chris@102 100 std::declval<Iterator&>()
Chris@102 101 , std::declval<Iterator>()
Chris@102 102 , std::declval<expectation_failure<Iterator>>()
Chris@102 103 , std::declval<Context>()
Chris@102 104 )
Chris@102 105 )>::type
Chris@102 106 >
Chris@102 107 : mpl::true_
Chris@102 108 {};
Chris@102 109
Chris@102 110 template <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>
Chris@102 111 struct has_on_success : mpl::false_ {};
Chris@102 112
Chris@102 113 template <typename ID, typename Iterator, typename Attribute, typename Context>
Chris@102 114 struct has_on_success<ID, Iterator, Context, Attribute,
Chris@102 115 typename disable_if_substitution_failure<
Chris@102 116 decltype(
Chris@102 117 std::declval<ID>().on_success(
Chris@102 118 std::declval<Iterator&>()
Chris@102 119 , std::declval<Iterator>()
Chris@102 120 , std::declval<Attribute&>()
Chris@102 121 , std::declval<Context>()
Chris@102 122 )
Chris@102 123 )>::type
Chris@102 124 >
Chris@102 125 : mpl::true_
Chris@102 126 {};
Chris@102 127
Chris@102 128 template <typename ID>
Chris@102 129 struct make_id
Chris@102 130 {
Chris@102 131 typedef identity<ID> type;
Chris@102 132 };
Chris@102 133
Chris@102 134 template <typename ID>
Chris@102 135 struct make_id<identity<ID>>
Chris@102 136 {
Chris@102 137 typedef identity<ID> type;
Chris@102 138 };
Chris@102 139
Chris@102 140 template <typename ID, typename RHS, typename Context>
Chris@102 141 Context const&
Chris@102 142 make_rule_context(RHS const& rhs, Context const& context
Chris@102 143 , mpl::false_ /* is_default_parse_rule */)
Chris@102 144 {
Chris@102 145 return context;
Chris@102 146 }
Chris@102 147
Chris@102 148 template <typename ID, typename RHS, typename Context>
Chris@102 149 auto make_rule_context(RHS const& rhs, Context const& context
Chris@102 150 , mpl::true_ /* is_default_parse_rule */ )
Chris@102 151 {
Chris@102 152 return make_unique_context<ID>(rhs, context);
Chris@102 153 }
Chris@102 154
Chris@102 155 template <typename Attribute, typename ID>
Chris@102 156 struct rule_parser
Chris@102 157 {
Chris@102 158 template <typename Iterator, typename Context, typename ActualAttribute>
Chris@102 159 static bool call_on_success(
Chris@102 160 Iterator& first, Iterator const& last
Chris@102 161 , Context const& context, ActualAttribute& attr
Chris@102 162 , mpl::false_ /* No on_success handler */ )
Chris@102 163 {
Chris@102 164 return true;
Chris@102 165 }
Chris@102 166
Chris@102 167 template <typename Iterator, typename Context, typename ActualAttribute>
Chris@102 168 static bool call_on_success(
Chris@102 169 Iterator& first, Iterator const& last
Chris@102 170 , Context const& context, ActualAttribute& attr
Chris@102 171 , mpl::true_ /* Has on_success handler */)
Chris@102 172 {
Chris@102 173 bool pass = true;
Chris@102 174 ID().on_success(
Chris@102 175 first
Chris@102 176 , last
Chris@102 177 , attr
Chris@102 178 , make_context<parse_pass_context_tag>(pass, context)
Chris@102 179 );
Chris@102 180 return pass;
Chris@102 181 }
Chris@102 182
Chris@102 183 template <typename RHS, typename Iterator, typename Context
Chris@102 184 , typename RContext, typename ActualAttribute>
Chris@102 185 static bool parse_rhs_main(
Chris@102 186 RHS const& rhs
Chris@102 187 , Iterator& first, Iterator const& last
Chris@102 188 , Context const& context, RContext& rcontext, ActualAttribute& attr
Chris@102 189 , mpl::false_)
Chris@102 190 {
Chris@102 191 // see if the user has a BOOST_SPIRIT_DEFINE for this rule
Chris@102 192 typedef
Chris@102 193 decltype(parse_rule(
Chris@102 194 rule<ID, Attribute>(), first, last
Chris@102 195 , make_unique_context<ID>(rhs, context), attr))
Chris@102 196 parse_rule_result;
Chris@102 197
Chris@102 198 // If there is no BOOST_SPIRIT_DEFINE for this rule,
Chris@102 199 // we'll make a context for this rule tagged by its ID
Chris@102 200 // so we can extract the rule later on in the default
Chris@102 201 // (generic) parse_rule function.
Chris@102 202 typedef
Chris@102 203 is_same<parse_rule_result, default_parse_rule_result>
Chris@102 204 is_default_parse_rule;
Chris@102 205
Chris@102 206 Iterator i = first;
Chris@102 207 bool r = rhs.parse(
Chris@102 208 i
Chris@102 209 , last
Chris@102 210 , make_rule_context<ID>(rhs, context, is_default_parse_rule())
Chris@102 211 , rcontext
Chris@102 212 , attr
Chris@102 213 );
Chris@102 214
Chris@102 215 if (r)
Chris@102 216 {
Chris@102 217 auto first_ = first;
Chris@102 218 x3::skip_over(first_, last, context);
Chris@102 219 r = call_on_success(first_, i, context, attr
Chris@102 220 , has_on_success<ID, Iterator, Context, ActualAttribute>());
Chris@102 221 }
Chris@102 222
Chris@102 223 if (r)
Chris@102 224 first = i;
Chris@102 225 return r;
Chris@102 226 }
Chris@102 227
Chris@102 228 template <typename RHS, typename Iterator, typename Context
Chris@102 229 , typename RContext, typename ActualAttribute>
Chris@102 230 static bool parse_rhs_main(
Chris@102 231 RHS const& rhs
Chris@102 232 , Iterator& first, Iterator const& last
Chris@102 233 , Context const& context, RContext& rcontext, ActualAttribute& attr
Chris@102 234 , mpl::true_ /* on_error is found */)
Chris@102 235 {
Chris@102 236 for (;;)
Chris@102 237 {
Chris@102 238 try
Chris@102 239 {
Chris@102 240 return parse_rhs_main(
Chris@102 241 rhs, first, last, context, rcontext, attr, mpl::false_());
Chris@102 242 }
Chris@102 243 catch (expectation_failure<Iterator> const& x)
Chris@102 244 {
Chris@102 245 switch (ID().on_error(first, last, x, context))
Chris@102 246 {
Chris@102 247 case error_handler_result::fail:
Chris@102 248 return false;
Chris@102 249 case error_handler_result::retry:
Chris@102 250 continue;
Chris@102 251 case error_handler_result::accept:
Chris@102 252 return true;
Chris@102 253 case error_handler_result::rethrow:
Chris@102 254 throw;
Chris@102 255 }
Chris@102 256 }
Chris@102 257 }
Chris@102 258 }
Chris@102 259
Chris@102 260 template <typename RHS, typename Iterator
Chris@102 261 , typename Context, typename RContext, typename ActualAttribute>
Chris@102 262 static bool parse_rhs_main(
Chris@102 263 RHS const& rhs
Chris@102 264 , Iterator& first, Iterator const& last
Chris@102 265 , Context const& context, RContext& rcontext, ActualAttribute& attr)
Chris@102 266 {
Chris@102 267 return parse_rhs_main(
Chris@102 268 rhs, first, last, context, rcontext, attr
Chris@102 269 , has_on_error<ID, Iterator, Context>()
Chris@102 270 );
Chris@102 271 }
Chris@102 272
Chris@102 273 template <typename RHS, typename Iterator
Chris@102 274 , typename Context, typename RContext, typename ActualAttribute>
Chris@102 275 static bool parse_rhs(
Chris@102 276 RHS const& rhs
Chris@102 277 , Iterator& first, Iterator const& last
Chris@102 278 , Context const& context, RContext& rcontext, ActualAttribute& attr
Chris@102 279 , mpl::false_)
Chris@102 280 {
Chris@102 281 return parse_rhs_main(rhs, first, last, context, rcontext, attr);
Chris@102 282 }
Chris@102 283
Chris@102 284 template <typename RHS, typename Iterator
Chris@102 285 , typename Context, typename RContext, typename ActualAttribute>
Chris@102 286 static bool parse_rhs(
Chris@102 287 RHS const& rhs
Chris@102 288 , Iterator& first, Iterator const& last
Chris@102 289 , Context const& context, RContext& rcontext, ActualAttribute& attr
Chris@102 290 , mpl::true_)
Chris@102 291 {
Chris@102 292 return parse_rhs_main(rhs, first, last, context, rcontext, unused);
Chris@102 293 }
Chris@102 294
Chris@102 295 template <typename RHS, typename Iterator, typename Context
Chris@102 296 , typename ActualAttribute, typename ExplicitAttrPropagation>
Chris@102 297 static bool call_rule_definition(
Chris@102 298 RHS const& rhs
Chris@102 299 , char const* rule_name
Chris@102 300 , Iterator& first, Iterator const& last
Chris@102 301 , Context const& context, ActualAttribute& attr
Chris@102 302 , ExplicitAttrPropagation)
Chris@102 303 {
Chris@102 304 typedef traits::make_attribute<Attribute, ActualAttribute> make_attribute;
Chris@102 305
Chris@102 306 // do down-stream transformation, provides attribute for
Chris@102 307 // rhs parser
Chris@102 308 typedef traits::transform_attribute<
Chris@102 309 typename make_attribute::type, Attribute, parser_id>
Chris@102 310 transform;
Chris@102 311
Chris@102 312 typedef typename make_attribute::value_type value_type;
Chris@102 313 typedef typename transform::type transform_attr;
Chris@102 314 value_type made_attr = make_attribute::call(attr);
Chris@102 315 transform_attr attr_ = transform::pre(made_attr);
Chris@102 316
Chris@102 317 bool ok_parse
Chris@102 318 //Creates a place to hold the result of parse_rhs
Chris@102 319 //called inside the following scope.
Chris@102 320 ;
Chris@102 321 {
Chris@102 322 //Create a scope to cause the dbg variable below (within
Chris@102 323 //the #if...#endif) to call it's DTOR before any
Chris@102 324 //modifications are made to the attribute, attr_ passed
Chris@102 325 //to parse_rhs (such as might be done in
Chris@102 326 //traits::post_transform when, for example,
Chris@102 327 //ActualAttribute is a recursive variant).
Chris@102 328 #if defined(BOOST_SPIRIT_X3_DEBUG)
Chris@102 329 context_debug<Iterator, typename make_attribute::value_type>
Chris@102 330 dbg(rule_name, first, last, attr_, ok_parse);
Chris@102 331 #endif
Chris@102 332 ok_parse=parse_rhs(rhs, first, last, context, attr_, attr_
Chris@102 333 , mpl::bool_
Chris@102 334 < ( RHS::has_action
Chris@102 335 && !ExplicitAttrPropagation::value
Chris@102 336 )
Chris@102 337 >()
Chris@102 338 );
Chris@102 339 }
Chris@102 340 if(ok_parse)
Chris@102 341 {
Chris@102 342 // do up-stream transformation, this integrates the results
Chris@102 343 // back into the original attribute value, if appropriate
Chris@102 344 traits::post_transform(attr, attr_);
Chris@102 345 }
Chris@102 346 return ok_parse;
Chris@102 347 }
Chris@102 348
Chris@102 349 // template <typename RuleDef, typename Iterator, typename Context
Chris@102 350 // , typename ActualAttribute, typename AttributeContext>
Chris@102 351 // static bool call_from_rule(
Chris@102 352 // RuleDef const& rule_def
Chris@102 353 // , char const* rule_name
Chris@102 354 // , Iterator& first, Iterator const& last
Chris@102 355 // , Context const& context, ActualAttribute& attr, AttributeContext& attr_ctx)
Chris@102 356 // {
Chris@102 357 // // This is called when a rule-body has already been established.
Chris@102 358 // // The rule body is already established by the rule_definition class,
Chris@102 359 // // we will not do it again. We'll simply call the RHS by calling
Chris@102 360 // // call_rule_definition.
Chris@102 361 //
Chris@102 362 // return call_rule_definition(
Chris@102 363 // rule_def.rhs, rule_name, first, last
Chris@102 364 // , context, attr, attr_ctx.attr_ptr
Chris@102 365 // , mpl::bool_<(RuleDef::explicit_attribute_propagation)>());
Chris@102 366 // }
Chris@102 367 //
Chris@102 368 // template <typename RuleDef, typename Iterator, typename Context
Chris@102 369 // , typename ActualAttribute>
Chris@102 370 // static bool call_from_rule(
Chris@102 371 // RuleDef const& rule_def
Chris@102 372 // , char const* rule_name
Chris@102 373 // , Iterator& first, Iterator const& last
Chris@102 374 // , Context const& context, ActualAttribute& attr, unused_type)
Chris@102 375 // {
Chris@102 376 // // This is called when a rule-body has *not yet* been established.
Chris@102 377 // // The rule body is established by the rule_definition class, so
Chris@102 378 // // we call it to parse and establish the rule-body.
Chris@102 379 //
Chris@102 380 // return rule_def.parse(first, last, context, unused, attr); // $$$ fix unused param $$$
Chris@102 381 // }
Chris@102 382 };
Chris@102 383 }}}}
Chris@102 384
Chris@102 385 #endif