/usr/include/boost/xpressive/detail/static/transforms
Edit: /usr/include/boost/xpressive/detail/static/transforms/as_action.hpp (11690B)
///////////////////////////////////////////////////////////////////////////////
// as_action.hpp
//
// Copyright 2008 Eric Niebler.
// Copyright 2008 David Jenkins.
//
// 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)
#ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
#define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost { namespace xpressive { namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// read_attr
// Placeholder that knows the slot number of an attribute as well as the type
// of the object stored in it.
template
struct read_attr
{
typedef Nbr nbr_type;
typedef Matcher matcher_type;
static Nbr nbr() { return Nbr(); }
};
template
struct read_attr
{
typedef Nbr nbr_type;
typedef Matcher matcher_type;
};
}}}
namespace boost { namespace xpressive { namespace grammar_detail
{
///////////////////////////////////////////////////////////////////////////////
// FindAttr
// Look for patterns like (a1= terminal) and return the type of the RHS.
template
struct FindAttr
: or_<
// Ignore nested actions, because attributes are scoped
when< subscript<_, _>, _state >
, when< terminal<_>, _state >
, when< proto::assign >, _>, call<_value(_right)> >
, otherwise< fold<_, _state, FindAttr > >
>
{};
///////////////////////////////////////////////////////////////////////////////
// as_read_attr
// For patterns like (a1 = RHS)[ref(i) = a1], transform to
// (a1 = RHS)[ref(i) = read_attr<1, RHS>] so that when reading the attribute
// we know what type is stored in the attribute slot.
struct as_read_attr : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef typename impl::expr expr_type;
typedef
typename FindAttr::template impl<
State
, mpl::void_
, int
>::result_type
attr_type;
typedef
typename proto::terminal<
detail::read_attr<
typename expr_type::proto_child0::nbr_type
, BOOST_PROTO_UNCVREF(attr_type)
>
>::type
result_type;
result_type operator ()(proto::ignore, proto::ignore, proto::ignore) const
{
result_type that = {{}};
return that;
}
};
};
///////////////////////////////////////////////////////////////////////////////
// DeepCopy
// Turn all refs into values, and also bind all attribute placeholders with
// the types from which they are being assigned.
struct DeepCopy
: or_<
when< terminal >, as_read_attr>
, when< terminal<_>, proto::_deep_copy>
, otherwise< nary_expr<_, vararg > >
>
{};
///////////////////////////////////////////////////////////////////////////////
// attr_nbr
// For an attribute placeholder, return the attribute's slot number.
struct attr_nbr : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef typename impl::expr expr_type;
typedef typename expr_type::proto_child0::nbr_type::type result_type;
};
};
struct max_attr;
///////////////////////////////////////////////////////////////////////////////
// MaxAttr
// In an action (rx)[act], find the largest attribute slot being used.
struct MaxAttr
: or_<
when< terminal >, attr_nbr>
, when< terminal<_>, make > >
// Ignore nested actions, because attributes are scoped:
, when< subscript<_, _>, make > >
, otherwise< fold<_, make >, max_attr> >
>
{};
///////////////////////////////////////////////////////////////////////////////
// max_attr
// Take the maximum of the current attr slot number and the state.
struct max_attr : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef
typename mpl::max<
typename impl::state
, typename MaxAttr::template impl::result_type
>::type
result_type;
};
};
///////////////////////////////////////////////////////////////////////////////
// as_attr_matcher
// turn a1=matcher into attr_matcher(1)
struct as_attr_matcher : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef typename impl::expr expr_type;
typedef typename impl::data data_type;
typedef
detail::attr_matcher<
typename proto::result_of::value::type
, typename data_type::traits_type
, typename data_type::icase_type
>
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param
, typename impl::data_param data
) const
{
return result_type(
proto::value(proto::left(expr)).nbr()
, proto::value(proto::right(expr))
, data.traits()
);
}
};
};
///////////////////////////////////////////////////////////////////////////////
// add_attrs
// Wrap an expression in attr_begin_matcher/attr_end_matcher pair
struct add_attrs : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef
detail::attr_begin_matcher<
typename MaxAttr::template impl, int>::result_type
>
begin_type;
typedef typename impl::expr expr_type;
typedef
typename shift_right<
typename terminal::type
, typename shift_right<
Expr
, terminal::type
>::type
>::type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param
, typename impl::data_param
) const
{
begin_type begin;
detail::attr_end_matcher end;
result_type that = {{begin}, {expr, {end}}};
return that;
}
};
};
///////////////////////////////////////////////////////////////////////////////
// InsertAttrs
struct InsertAttrs
: if_
{};
///////////////////////////////////////////////////////////////////////////////
// CheckAssertion
struct CheckAssertion
: proto::function, _>
{};
///////////////////////////////////////////////////////////////////////////////
// action_transform
// Turn A[B] into (mark_begin(n) >> A >> mark_end(n) >> action_matcher(n))
// If A and B use attributes, wrap the above expression in
// a attr_begin_matcher / attr_end_matcher pair, where Count is
// the number of attribute slots used by the pattern/action.
struct as_action : proto::transform
{
template
struct impl : proto::transform_impl
{
typedef typename proto::result_of::left::type expr_type;
typedef typename proto::result_of::right::type action_type;
typedef
typename DeepCopy::impl::result_type
action_copy_type;
typedef
typename InsertMark::impl::result_type
marked_expr_type;
typedef
typename mpl::if_c<
proto::matches::value
, detail::predicate_matcher
, detail::action_matcher
>::type
matcher_type;
typedef
typename proto::shift_right<
marked_expr_type
, typename proto::terminal::type
>::type
no_attr_type;
typedef
typename InsertAttrs::impl::result_type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param state
, typename impl::data_param data
) const
{
int dummy = 0;
marked_expr_type marked_expr =
InsertMark::impl()(proto::left(expr), state, data);
no_attr_type that = {
marked_expr
, {
matcher_type(
DeepCopy::impl()(
proto::right(expr)
, proto::left(expr)
, dummy
)
, proto::value(proto::left(marked_expr)).mark_number_
)
}
};
return InsertAttrs::impl()(that, state, data);
}
};
};
}}}
#endif