a3a9e27578
[SVN r71229]
125 lines
3.7 KiB
Plaintext
125 lines
3.7 KiB
Plaintext
[/==============================================================================
|
|
Copyright (C) 2001-2010 Joel de Guzman
|
|
Copyright (C) 2001-2005 Dan Marsden
|
|
Copyright (C) 2001-2010 Thomas Heller
|
|
|
|
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)
|
|
===============================================================================/]
|
|
|
|
[section:actions More on Actions]
|
|
|
|
As you know from the [link phoenix.inside.actor Actors in Detail] section,
|
|
Actions are what brings life to a Phoenix expression tree.
|
|
|
|
When dealing with a Phoenix expression tree, it gets evaluated top-down.
|
|
Example:
|
|
|
|
_1 + 3 * _2
|
|
|
|
Can be visualized as an AST in the following way:
|
|
|
|
[$images/simple_ast.png]
|
|
|
|
In terms of actions this means:
|
|
|
|
* `rule::plus` is matched
|
|
* evaluate left:
|
|
* `rule::placeholder` is matched
|
|
* evaluate right:
|
|
* `rule::multiplies` is matched
|
|
* evaluate left:
|
|
* `rule::value` is matched
|
|
* evaluate right:
|
|
* `rule::placeholder` is matched
|
|
|
|
Every time a rule is matched, an action will be called. The action determines
|
|
how the Phoenix AST will be traversed.
|
|
|
|
[heading Writing an Action]
|
|
|
|
As mentioned in [link phoenix.inside.actor Actors in Detail] actions are
|
|
__proto_primitive_transforms__ for convenience Phoenix provides an abstraction
|
|
to this:
|
|
|
|
template <typename Fun>
|
|
struct call;
|
|
|
|
This is similar to __proto_call__ but does more. It calls the `Fun` function
|
|
object passed as template parameter with the `Context` and the children of the
|
|
expression associated with the rule.
|
|
|
|
Lets have an (simplified) example on how to write an evaluation action for
|
|
`rule::plus`:
|
|
|
|
struct plus_eval
|
|
{
|
|
typedef int result_type;
|
|
|
|
template <typename Lhs, typename Rhs, typename Context>
|
|
result_type operator()(Lhs const& lhs, Rhs const &rhs, Context & ctx)
|
|
{
|
|
return eval(lhs, ctx) + eval(rhs, ctx);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct default_actions::when<rule::plus>
|
|
: call<plus_eval>
|
|
{};
|
|
|
|
That's it. When evaluating a `plus` expression, the `plus_eval` callable gets
|
|
called with the left hand side and right hand side expression and the associated
|
|
Context.
|
|
|
|
[*But there is more:] As Actions /can/ be full fletched __proto_transforms__, you can
|
|
in fact use any proto expression you can imagine as the action. Phoenix predifines a
|
|
set of callables and transform to deal with the Context information passed along and
|
|
of course every Phoenix expression can be used as a Phoenix grammar or
|
|
__proto_pass_through_transform__.
|
|
|
|
[variablelist
|
|
[
|
|
[`functional::context(Env, Actions)`]
|
|
[A __proto_callable__ that creates a new context out of the `Env` and `Actions` parameter]
|
|
]
|
|
[
|
|
[`functional::env(Context)`]
|
|
[A __proto_callable__ that returns the environment out of the `Context` parameter]
|
|
]
|
|
[
|
|
[`functional::actions(Context)`]
|
|
[A __proto_callable__ that returns the actions out of the `Context` parameter]
|
|
]
|
|
[
|
|
[`_context`]
|
|
[A __proto_primitive_transform__ that returns the current context]
|
|
]
|
|
[
|
|
[`_env`]
|
|
[A __proto_primitive_transform__ that returns the current environment]
|
|
]
|
|
[
|
|
[`_actions`]
|
|
[A __proto_primitive_transform__ that returns the current actions]
|
|
]
|
|
[
|
|
[`context(env, actions)`]
|
|
[A regular function that creates a context]
|
|
]
|
|
[
|
|
[`env(ctx)`]
|
|
[A regular function that returns the environment from the given context]
|
|
]
|
|
[
|
|
[`actions(ctx)`]
|
|
[A regular function that returns the actions from the given context]
|
|
]
|
|
]
|
|
|
|
Phoenix is equipped with a predefined set of expressions, rules and actions to
|
|
make all the stuff work you learned in the __phoenix_starter_kit__ and __phoenix_modules__
|
|
sections. See the [link phoenix.inside.rules next section] for more details!
|
|
|
|
[endsect]
|