125 lines
3.1 KiB
C++
125 lines
3.1 KiB
C++
/*=============================================================================
|
|
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)
|
|
==============================================================================*/
|
|
|
|
#include <boost/phoenix.hpp>
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
|
|
namespace proto = boost::proto;
|
|
namespace phoenix = boost::phoenix;
|
|
|
|
template <typename Rule>
|
|
struct identity_transform;
|
|
|
|
struct identity_actions
|
|
{
|
|
template <typename Rule>
|
|
struct when : phoenix::call<identity_transform<Rule> > {};
|
|
};
|
|
|
|
template <>
|
|
struct identity_actions::when<phoenix::rule::argument>
|
|
: proto::call<
|
|
identity_transform<phoenix::rule::argument>(proto::_value, phoenix::_context)
|
|
> {};
|
|
|
|
template <>
|
|
struct identity_actions::when<phoenix::rule::terminal>
|
|
: proto::call<
|
|
identity_transform<phoenix::rule::terminal>(proto::_value, phoenix::_context)
|
|
> {};
|
|
|
|
template <>
|
|
struct identity_actions::when<phoenix::rule::custom_terminal>
|
|
: proto::lazy<
|
|
identity_transform<proto::_value>(proto::_value, phoenix::_context)
|
|
> {};
|
|
|
|
template <>
|
|
struct identity_transform<phoenix::rule::terminal>
|
|
{
|
|
typedef std::string result_type;
|
|
|
|
template <typename Terminal, typename Context>
|
|
std::string operator()(Terminal const & terminal, Context) const
|
|
{
|
|
std::stringstream ss;
|
|
ss << "val(" << terminal << ")";
|
|
return ss.str();
|
|
}
|
|
|
|
template <typename Context>
|
|
std::string operator()(char const * terminal, Context) const
|
|
{
|
|
std::stringstream ss;
|
|
ss << "val(\"" << terminal << "\")";
|
|
return ss.str();
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct identity_transform<boost::reference_wrapper<T> >
|
|
{
|
|
typedef std::string result_type;
|
|
|
|
template <typename Terminal, typename Context>
|
|
std::string operator()(Terminal const & terminal, Context) const
|
|
{
|
|
std::stringstream ss;
|
|
ss << "ref(" << terminal << ")";
|
|
return ss.str();
|
|
}
|
|
|
|
|
|
template <int N, typename Context>
|
|
std::string operator()(boost::reference_wrapper<char const *> terminal, Context) const
|
|
{
|
|
std::stringstream ss;
|
|
ss << "ref(\"" << terminal << "\")";
|
|
return ss.str();
|
|
}
|
|
|
|
template <int N, typename Context>
|
|
std::string operator()(boost::reference_wrapper<char const [N]> terminal, Context) const
|
|
{
|
|
std::stringstream ss;
|
|
ss << "ref(\"" << terminal << "\")";
|
|
return ss.str();
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct identity_transform<phoenix::rule::argument>
|
|
{
|
|
typedef std::string result_type;
|
|
|
|
template <typename N, typename Context>
|
|
std::string operator()(N, Context) const
|
|
{
|
|
std::stringstream ss;
|
|
ss << "_" << N::value;
|
|
return ss.str();
|
|
}
|
|
};
|
|
|
|
|
|
template <typename Expr>
|
|
void identity(Expr const & expr)
|
|
{
|
|
std::cout << phoenix::eval(expr, phoenix::context(int(), identity_actions())) << "\n";
|
|
}
|
|
|
|
int main()
|
|
{
|
|
|
|
identity(phoenix::val(8));
|
|
identity(phoenix::val("8"));
|
|
identity(phoenix::ref("blubb"));
|
|
identity(phoenix::arg_names::_1);
|
|
}
|