/*============================================================================= Copyright (c) 2001-2007 Joel de Guzman Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #if !defined(BOOST_SPIRIT_ARGUMENT_FEB_17_2007_0339PM) #define BOOST_SPIRIT_ARGUMENT_FEB_17_2007_0339PM #include #include #include #include #include #include #include #include #if !defined(SPIRIT_ARG_LIMIT) # define SPIRIT_ARG_LIMIT PHOENIX_LIMIT #endif #define SPIRIT_DECLARE_ARG(z, n, data) \ phoenix::actor > const \ BOOST_PP_CAT(_, BOOST_PP_INC(n)) = argument(); \ phoenix::actor > const \ BOOST_PP_CAT(_r, n) = attribute(); namespace boost { namespace spirit { namespace result_of { template struct get_arg { typedef typename fusion::result_of::size::type sequence_size; // report invalid argument not found (N is out of bounds) BOOST_MPL_ASSERT_MSG( (N < sequence_size::value), index_is_out_of_bounds, ()); typedef typename fusion::result_of::at_c::type type; static type call(Sequence& seq) { return fusion::at_c(seq); } }; template struct get_arg : get_arg { }; } template typename result_of::get_arg::type get_arg(T& val) { return result_of::get_arg::call(val); } struct attribute_context { typedef mpl::true_ no_nullary; template struct result { // FIXME: is this remove_const really necessary? typedef typename remove_const< typename mpl::at_c::type >::type type; }; template typename result::type eval(Env const& env) const { return fusion::at_c<0>(env.args()); } }; template struct argument { typedef mpl::true_ no_nullary; template struct result { typedef typename mpl::at_c::type arg_type; typedef typename result_of::get_arg::type type; }; template typename result::type eval(Env const& env) const { return get_arg(fusion::at_c<0>(env.args())); } }; template struct attribute { typedef mpl::true_ no_nullary; template struct result { typedef typename mpl::at_c::type arg_type; typedef typename result_of::get_arg< typename result_of::get_arg::type , N >::type type; }; template typename result::type eval(Env const& env) const { return get_arg(get_arg<0>(fusion::at_c<1>(env.args()))); } }; template struct local_var { typedef mpl::true_ no_nullary; template struct result { typedef typename mpl::at_c::type arg_type; typedef typename result_of::get_arg< typename result_of::get_arg::type , N >::type type; }; template typename result::type eval(Env const& env) const { return get_arg(get_arg<1>(fusion::at_c<1>(env.args()))); } }; struct lexer_state { typedef mpl::true_ no_nullary; template struct result { typedef typename mpl::at_c::type::state_type type; }; template typename result::type eval(Env const& env) const { return fusion::at_c<3>(env.args()).state; } }; namespace arg_names { // _0 refers to the whole attribute as generated by the lhs parser phoenix::actor const _0 = attribute_context(); // _1, _2, ... refer to the attributes of the single components the lhs // parser is composed of phoenix::actor > const _1 = argument<0>(); phoenix::actor > const _2 = argument<1>(); phoenix::actor > const _3 = argument<2>(); // 'pass' may be used to make a match fail in retrospective phoenix::actor > const pass = phoenix::argument<2>(); // 'id' may be used in a lexer semantic action to refer to the token id // of a matched token phoenix::actor > const id = phoenix::argument<1>(); // 'state' may be used in a lexer semantic action to refer to the // current lexer state phoenix::actor const state = lexer_state(); // _val refers to the 'return' value of a rule // _r0, _r1, ... refer to the rule arguments phoenix::actor > const _val = attribute<0>(); phoenix::actor > const _r0 = attribute<0>(); phoenix::actor > const _r1 = attribute<1>(); phoenix::actor > const _r2 = attribute<2>(); // Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP BOOST_PP_REPEAT_FROM_TO( 3, SPIRIT_ARG_LIMIT, SPIRIT_DECLARE_ARG, _) // _a, _b, ... refer to the local variables of a rule phoenix::actor > const _a = local_var<0>(); phoenix::actor > const _b = local_var<1>(); phoenix::actor > const _c = local_var<2>(); phoenix::actor > const _d = local_var<3>(); phoenix::actor > const _e = local_var<4>(); phoenix::actor > const _f = local_var<5>(); phoenix::actor > const _g = local_var<6>(); phoenix::actor > const _h = local_var<7>(); phoenix::actor > const _i = local_var<8>(); phoenix::actor > const _j = local_var<9>(); } }} #undef SPIRIT_DECLARE_ARG #endif