blob: 6429b984764f9622661d58d121faf7329d1512e2 [file] [log] [blame]
/*=============================================================================
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_BASIC_RULES_JAN_14_2007_1222PM)
#define BOOST_SPIRIT_BASIC_RULES_JAN_14_2007_1222PM
#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
#include <boost/spirit/home/support/meta_grammar/basic_transforms.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/proto/core.hpp>
#include <boost/proto/transform.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace meta_grammar
{
namespace detail
{
template <typename Director>
struct director_identity
{
template <typename>
struct apply : mpl::identity<Director> {};
};
}
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes an empty (the terminal is not saved in
// the elements tuple) terminal spirit::component given a domain,
// a proto-tag and a director. Example:
//
// a
//
///////////////////////////////////////////////////////////////////////////
template <typename Domain, typename Tag, typename Director>
struct empty_terminal_rule
: compose_empty<
proto::terminal<Tag>
, Domain
, detail::director_identity<Director>
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a non-empty (the terminal is saved in
// the elements tuple) terminal spirit::component given a domain,
// a proto-tag and a director. Example:
//
// a
//
///////////////////////////////////////////////////////////////////////////
template <typename Domain, typename Tag, typename Director>
struct terminal_rule
: compose_single<
proto::terminal<Tag>
, Domain
, detail::director_identity<Director>
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 1-element spirit::component given a
// domain, a proto-tag and a director. No folding takes place. Example:
//
// +a
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag, typename Director
, typename SubjectGrammar = proto::_
>
struct unary_rule
: compose_single<
proto::unary_expr<
Tag
, SubjectGrammar
>
, Domain
, detail::director_identity<Director>
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 2-element spirit::component given a
// domain, a proto-tag and a director. No folding takes place. Example:
//
// a - b
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag, typename Director
, typename LeftGrammar = proto::_, typename RightGrammar = proto::_
>
struct binary_rule
: compose_double<
proto::binary_expr<
Tag
, LeftGrammar
, RightGrammar
>
, Domain
, detail::director_identity<Director>
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 3-element spirit::component given a
// domain, a proto-tag and a director. No folding takes place. Example:
//
// if_else(cond_expr,true_exp,false_expr)
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag, typename Director
, typename Grammar0 = proto::_, typename Grammar1 = proto::_, typename Grammar2 = proto::_
>
struct ternary_rule
: compose_triple<
proto::nary_expr<
Tag
, Grammar0
, Grammar1
, Grammar2
>
, Domain
, detail::director_identity<Director>
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 1-element spirit::component from a
// binary expression. Only the RHS is stored.
//
// a[b]
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag, typename Director
, typename LeftGrammar = proto::_, typename RightGrammar = proto::_
>
struct binary_rule_rhs
: compose_right<
proto::binary_expr<
Tag
, LeftGrammar
, RightGrammar
>
, Domain
, detail::director_identity<Director>
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a multi-element spirit::component given a
// domain, a proto-tag and a director. All like-operators are folded
// into one. Example:
//
// a | b | c
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag, typename Director
, typename Grammar = proto::_
>
struct binary_rule_flat
: compose_list<
proto::when<
proto::binary_expr<Tag, Grammar, Grammar>
, proto::reverse_fold_tree<
proto::_
, fusion::nil()
, fusion::cons<Grammar, proto::_state>(Grammar, proto::_state)
>
>
, Domain
, Director
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 1-element function spirit::component
// given a domain, a proto-tag and a director. Example:
//
// f(a)
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag
, typename Director, typename ArgGrammar = proto::_>
struct function1_rule
: compose_function1<
proto::function<proto::terminal<Tag>, ArgGrammar>
, Domain
, Director
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 2-element function spirit::component
// given a domain, a proto-tag and a director. Example:
//
// f(a, b)
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag
, typename Director, typename ArgGrammar = proto::_>
struct function2_rule
: compose_function2<
proto::function<
proto::terminal<Tag>
, ArgGrammar
, ArgGrammar
>
, Domain
, Director
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule for directives. The directive (terminal) tag
// is pushed into the modifier state (the Visitor). Example:
//
// directive[a]
///////////////////////////////////////////////////////////////////////////
template <typename Tag, typename SubjectGrammar = proto::_>
struct deep_directive_meta_grammar
: meta_grammar::compose_deep_directive<
proto::when<
proto::subscript<proto::terminal<Tag>, SubjectGrammar>
, proto::call<SubjectGrammar(proto::_right)>
>
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 2-element spirit::component given a
// domain, a proto-tag, a director, and an embedded grammar.
// Example:
//
// directive[p]
//
// The difference to deep_directive_meta_grammar is that it stores both
// parts of the expression without modifying the modifier state
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag,
typename Director, typename EmbeddedGrammar = proto::_
>
struct subscript_rule
: compose_subscript<
proto::binary_expr<
proto::tag::subscript,
proto::terminal<Tag>,
EmbeddedGrammar
>,
Domain,
Director
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 2-element spirit::component given a
// domain, a proto-tag, a director, an argument and an embedded grammar.
// Example:
//
// directive(a)[p]
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag,
typename Director, typename ArgGrammar = proto::_,
typename EmbeddedGrammar = proto::_
>
struct subscript_function1_rule
: compose_subscript_function1<
proto::binary_expr<
proto::tag::subscript,
proto::function<proto::terminal<Tag>, ArgGrammar>,
EmbeddedGrammar
>,
Domain,
Director
>
{};
///////////////////////////////////////////////////////////////////////////
// A proto rule that composes a 3-element spirit::component given a
// domain, a proto-tag, a director, two arguments and an embedded grammar.
// Example:
//
// directive(a, b)[p]
//
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Tag,
typename Director, typename Arg1Grammar = proto::_,
typename Arg2Grammar = proto::_, typename EmbeddedGrammar = proto::_
>
struct subscript_function2_rule
: compose_subscript_function2<
proto::binary_expr<
proto::tag::subscript,
proto::function<proto::terminal<Tag>, Arg1Grammar, Arg2Grammar>,
EmbeddedGrammar
>,
Domain,
Director
>
{};
}}}
#endif