Boost
C++ Libraries
...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
This is an older version of Boost and was released in 2021. The current version is 1.89.0.
When having more and more expressions, you start to realize that this is a very repetetive task. Phoenix provides boilerplate macros that make defining Phoenix Expressions as you have seen in the previous section look like a piece of cake.
BOOST_PHOENIX_DEFINE_EXPRESSION
is a macro that can be used to generate all the necessary boilerplate
to create Phoenix Expressions
BOOST_PHOENIX_DEFINE_EXPRESSION( (namespace_seq)(name) , (child_grammar0) (child_grammar1) ... )
The above macro generates the necessary code for an expression name in namespace namespace_seq.
The sequence of (child_grammarN) declares how many children the expression
will have and what proto::grammar
they match.
The macro should be used at global scope. namespace_seq
shall be the sequence of namespaces under which the following symbols
will be defined:
namespace tag { struct name; } namespace expression { template <typename A0, typename A1 ... typename AN> struct name : boost::phoenix::expr< tag::name , A0 , A1 ... , AN > } namespace rule { struct name : boost::phoenix::expr< child_grammar0 , child_grammar1 ... , child_grammarN > {}; } namespace functional { struct make_name; // A polymorphic function object that can be called to create the expression node } namespace result_of { template <typename A0, typename A1 ... typename AN> struct make_name; // The result type of the expression node } // convenience polymorphic function to create an expression node template <typename A0, typename A1 ... typename AN> result_of::make_name<A0, A1 ... AN> make_name(A0 const & a0, A1 const & a1 ... AN const & an);
This macros also adds a specialization for meta_grammar::case_<tag::name> to enable the rule for further use
in actions.
#include <boost/phoenix/core/expression.hpp>
The example from the previous section can be rewritten as:
BOOST_PHOENIX_DEFINE_EXPRESSION( (plus) , (meta_grammar) // Lhs (meta_grammar) // Rhs ) template <typename Lhs, typename Rhs> typename plus<Lhs, Rhs>::type plus(Lhs const & lhs, Rhs const & rhs) { return expression::plus<Lhs, Rhs>::make(lhs, rhs); }
BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG
is a macro that can be used to generate all the necessary boilerplate
to create Phoenix Expressions
BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG( (namespace_seq)(name) , (child_grammar0) (child_grammar1) ... (child_grammarN) , N )
The above macro generates the necessary code for an expression name in namespace namespace_seq.
N is the maximum number
of variable children. All but the last elements in the grammar sequence
are required children of the expression, and the last denotes a variable
number of children. The number of children an expression of this kind
can hold is therefor N-1 plus
the size of the sequence
The macro should be used at global scope. namespace_seq
shall be the sequence of namespaces under which the following symbols
will be defined:
namespace tag { struct name; } namespace expression { template <typename A0, typename A1 ... typename AN> struct name : boost::phoenix::expr< tag::name , A0 , A1 ... , AN > {}; } namespace rule { struct name : expression::name< child_grammar0 , child_grammar1 ... , proto::vararg<child_grammarN> > {}; } namespace functional { struct make_name; // A polymorphic function object that can be called to create the expression node } namespace result_of { template <typename A0, typename A1 ... typename AN> struct make_name; // The result type of the expression node } // convenience polymorphic function to create an expression node template <typename A0, typename A1 ... typename AN> result_of::make_name<A0, A1 ... AN> make_name(A0 const & a0, A1 const & a1 ... AN const & an);
This macros also adds a specialization for meta_grammar::case_<tag::name> to enable the rule for further use
in actions.
#include <boost/phoenix/core/expression.hpp>
BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG( (boost)(phoenix)(mem_fun_ptr) , (meta_grammar) // Pointer to Object (meta_grammar) // Member pointer (meta_grammar) // Variable number of arguments , BOOST_PHOENIX_LIMIT )
This defines the member function pointer operator expression as described in operators.
BOOST_PHOENIX_DEFINE_EXPRESSION_EXT
is a macro that can be used to generate all the necessary boilerplate
to create Phoenix Expressions
BOOST_PHOENIX_DEFINE_EXPRESSION_EXT( actor , (namespace_seq)(name) , (child_grammar0) (child_grammar1) ... (child_grammarN) , N )
The above macro generates the necessary code for an expression name in namespace namespace_seq.
The sequence of (child_grammarN) declares how many children the expression
will have and what proto::grammar
they match.
The macro should be used at global scope. namespace_seq
shall be the sequence of namespaces under which the following symbols
will be defined:
namespace tag { struct name; } namespace expression { template <typename A0, typename A1 ... typename AN> struct name : boost::phoenix::expr_ext< actor , tag::name , A0 , A1 ... , AN > } namespace rule { struct name : boost::phoenix::expr< child_grammar0 , child_grammar1 ... , child_grammarN > {}; } namespace functional { struct make_name; // A polymorphic function object that can be called to create the expression node } namespace result_of { template <typename A0, typename A1 ... typename AN> struct make_name; // The result type of the expression node } // convenience polymorphic function to create an expression node template <typename A0, typename A1 ... typename AN> result_of::make_name<A0, A1 ... AN> make_name(A0 const & a0, A1 const & a1 ... AN const & an);
This macros also adds a specialization for meta_grammar::case_<tag::name> to enable the rule for further use
in actions.
#include <boost/phoenix/core/expression.hpp>
BOOST_PHOENIX_DEFINE_EXPRESSION_EXT( if_actor , (boost)(phoenix)(if_) , (meta_grammar) // Cond (meta_grammar) // Then )
This defines the if_ expression. The custom actor defines else_ as a member.
BOOST_PHOENIX_DEFINE_EXPRESSION_EXT_VARARG
is a macro that can be used to generate all the necessary boilerplate
to create Phoenix Expressions
BOOST_PHOENIX_DEFINE_EXPRESSION_EXT_VARARG( actor , (namespace_seq)(name) , (child_grammar0) (child_grammar1) ... (child_grammarN) , N )
The above macro generates the necessary code for an expression name in namespace namespace_seq.
N is the maximum number
of variable children. All but the last elements in the grammar sequence
are required children of the expression, and the last denotes a variable
number of children. The number of children an expression of this kind
can hold is therefor N-1 plus
the size of the sequence
The macro should be used at global scope. namespace_seq
shall be the sequence of namespaces under which the following symbols
will be defined:
namespace tag { struct name; } namespace expression { template <typename A0, typename A1 ... typename AN> struct name : boost::phoenix::expr_ext< actor , tag::name , A0 , A1 ... , AN > {}; } namespace rule { struct name : expression::name< child_grammar0 , child_grammar1 ... , proto::vararg<child_grammarN> > {}; } namespace functional { struct make_name; // A polymorphic function object that can be called to create the expression node } namespace result_of { template <typename A0, typename A1 ... typename AN> struct make_name; // The result type of the expression node } // convenience polymorphic function to create an expression node template <typename A0, typename A1 ... typename AN> result_of::make_name<A0, A1 ... AN> make_name(A0 const & a0, A1 const & a1 ... AN const & an);
This macros also adds a specialization for meta_grammar::case_<tag::name> to enable the rule for further use
in actions.
#include <boost/phoenix/core/expression.hpp>
TBD