2
0
mirror of https://github.com/boostorg/phoenix.git synced 2026-02-14 00:52:09 +00:00
Files
phoenix/doc/reference.qbk
Thomas Heller 8704956655 updated the html docs
[SVN r68289]
2011-01-19 14:18:08 +00:00

900 lines
24 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)
===============================================================================/]
[def __unspecified__ /unspecified/]
[template expression[type] expression::[type]]
[template rule[type] expression::[type]]
[section Reference]
While the previous section gave a brief overview on how to use the Phoenix
library, this section will provide as the reference to the interfaces defined in
phoenix.
With Phoenix being a domain specific embedded language this reference manual is
different than most references to C++ libraries.
Phoenix is designed in a way that the language constructs are clearly separated
from how they are evaluated. This follows the design principles of the C++
standard library.
This design also allows us to see the code (i.e. Phoenix Actors) as data, and the
different evaluation schemes, which act as the algorithms.
The remainder of this section is structured as following:
[variablelist
[
[
The Language
]
[
Definition of the Phoenix grammar
]
[
Reference to the mechanisms used to generate Phoenix actors
]
[
Extension mechanism of the Phoenix grammar
]
]
[
[
Evaluation
]
[
How Phoenix actors get evaluated
]
[
Reference to the predefined evaluators
]
[
Extension mechanism of the evaluation process
]
]
[
[
Advanced Tutorials
]
[
In depth discussion of the advertised features in the previous
sections
]
]
]
[heading Concepts]
Throughout this reference section various concepts are used. To disambiguate
their meanings consider the following definitions.
[heading Phoenix Actor]
A Phoenix Actor is the C++ Expression that is generated by the Phoenix
Generators.
[heading Phoenix Generator]
The Generator is a C++ Expression that results in a Phoenix Actor.
This Generator is:
* A function (can be a free function, operator, or member function)
* An instance of a Phoenix Actor
[section Core Mechanisms]
[section `actor`]
[heading Description]
`actor` is main interface to evaluate any Phoenix expression. It is used to wrap
the Phoenix Expression Templates and provides various operator() overloads.
[heading Synopsis]
namespace result_of
{
template <
typename Expr
, typename A0 = void
, typename A1 = void
...
, typename AN = void
, typename Dummy = void
>
struct actor
{
typedef __unspecified__ type;
};
}
template <typename Expr>
struct actor;
[heading Template Parameters]
[table
[[Parameter] [Description]]
[[`Expr`] [The type of the expression]]
[[`A0`...`AN`] [The type of the supplied arguments]]
]
[variablelist Notation
[[`expr`] [An instance of a Phoenix actor]]
[[`a0`...`a1`] [Heterogenous values]]
]
[heading Expression Semantics]
[table
[[Expression] [Semantic]]
[[`result_of::actor<Expr, A0...AN>::type`] [The result type of the evaluated expression]]
[[`boost::result_of<actor<Expr>(A0...AN)>::type`] [Same as `result_of::actor<Expr, A0...AN>::type`]]
[[`expr(a0...aN)`] [Evaluates the expression]]
]
The expression is evaluated using the defined __phoenix_evaluator_default__.
[header Header]
#include <boost/phoenix/core/actor.hpp>
[heading Example]
See the __phoenix_starter_kit__ and the __phoenix_language__ for examples
[endsect]
[section `meta_grammar`]
[heading Description]
`meta_grammar` is an open extensible set of __proto__ grammar rules.
It is used to define what valid Phoenix Expressions are.
[heading Synopsis]
struct meta_grammar
: proto::switch<meta_grammar>
{
template <typename Tag, typename Dummy = void>
struct case_
: proto::not<proto::_>
{};
};
[heading Template Parameters]
[table
[[Parameter] [Description]]
[[`Tag`] [The tag of the phoenix expression]]
]
[heading Expression Semantics]
[variablelist Notation
[[`Expr`] [Any type]]
]
[table
[[Expression] [Semantic]]
[[`proto::matches<Expr, meta_grammar>::type`] [Calculates wether `Expr` matches meta_grammar]]
]
By default, `meta_grammar` matches nothing. By including the headers described in the __phoenix_language__ section,
the appropriate rules are added to the grammar.
[header Header]
#include <boost/phoenix/core/meta_grammar.hpp>
[heading Example]
// Adding terminals to the set of valid Phoenix expressions
template <>
struct meta_grammar::case_<proto::tag::terminal>
: proto::terminal<proto::_>
{};
// Adding terminals to the set of valid Phoenix expressions and supply a
// transform that is called whenever a terminal is found
template <>
struct meta_grammar::case_<proto::tag::terminal>
: proto::when<
proto::terminal<proto::_>
, proto::_value // return the value of the terminal
>
{};
// Adding terminals to the set of valid Phoenix expressions and supply a
// transform that is supplied by an external transform.
template <>
struct meta_grammar::case_<proto::tag::terminal>
: proto::when<
proto::terminal<proto::_>
, proto::external_transform
>
{};
[note
The last form is how phoenix grammar rules are defined in the library.
See __phoenix_evaluator__ for more details
]
[endsect]
[section:environment `environment`]
[heading Description]
To evaluate a phoenix expression, an environment needs to be provided. This
environment is a Fusion Random Access Sequences.
[heading Synopsis]
namespace result_of
{
template <typename Parameter, typename Actions>
struct environment
{
typedef __unspecified__ type;
};
}
template <typename Parameter, typename Actions>
typename environment<Parameter, Actions>::type
environment(Paramater & parameter, Actions const & actions);
struct _env;
struct _params;
struct _actions;
[heading Template Parameter]
[heading Expression Semantics]
[heading Header]
#include <boost/phoenix/core/environment.hpp>
[heading Examples]
[endsect]
[section:evaluator `evaluator`]
[heading Description]
`evaluator` is responsible for evaluating Phoenix expressions.
[heading Synopsis]
struct evaluator;
[heading Expression Semantics]
[table
[[Expression] [Semantic]]
[[`eval(expr, env)`] [Evaluates `expr` with the parameters and actions supplied by `env`]]
]
[header Header]
#include <boost/phoenix/core/meta_grammar.hpp>
[heading Examples]
[section:default_actions `default_actions`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section:is_nullary `is_nullary`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section:arity `arity`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[endsect]
[section:expression `expression`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section:phoenix_define_expression `PHOENIX_DEFINE_EXPRESSION`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section:phoenix_define_expression_vararg `PHOENIX_DEFINE_EXPRESSION_VARARG`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section:phoenix_define_expression_ext `PHOENIX_DEFINE_EXPRESSION_EXT`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section:phoenix_define_expression_vararg_ext `PHOENIX_DEFINE_EXPRESSION_VARARG_EXT`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section Terminals]
[section Placeholders]
[endsect]
[section `is_custom_terminal`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[section `custom_terminal`]
[heading Description]
[heading Synopsis]
[heading Expression Semantics]
[header Header]
[heading Examples]
[endsect]
[endsect]
[endsect]
[section The Language]
The definition of the language is split into the following parts:
* formal language definition of the Phoenix Generators in EBNF notation
* Synopsis of the C++ expressions
[section Core]
terminal := value | reference | placeholder
value := "val" "(" expression ")"
reference := "ref" "(" C++ expression ")"
| "cref" "(" C++ expression ")"
placeholder := _1 | _2 | _3 | ... | _N
| arg1 | arg2 | arg3 | ... | argN
Terminals are the core building blocks. Phoenix, by default distinguishes
between 3 types of terminals:
# Value Terminals
# Reference Terminals
# Placeholders
The last two terminal types are handled by the terminal customization points.
[section Value]
Whenever we see a constant in a partially applied function, an
expression::value<T>::type
(where T is the type of the constant) is automatically created for
us. For instance:
add(arg1, 6)
Passing a second argument, `6`, an `expression::value<int>::type` is implicitly created
behind the scenes. This is also equivalent to:
add(arg1, val(6))
`val(x)` generates an `expression::value<T>::type` where `T` is the type of `x`. In most
cases, there's no need to explicitly use `val`, but, as we'll see later on,
there are situations where this is unavoidable.
[heading Synopsis]
namespace expression
{
template <typename T>
struct value
{
typedef __unspecified__ type;
static type make(T t);
};
}
namespace rule
{
struct value : proto::terminal<proto::_> {};
}
template <typename T>
typename expression::value<T>::type
val(T t);
[heading Parameters]
[table
[[Parameter] [Requirement] [Description]]
[[`T`] [Model of Copy Constructible] [Operation's Argument]]
[[`t`] [Object of type T] [Operation's Argument]]
]
[heading Expression Semantics]
expression::value<T>::type
[*Return type]: Returns a Phoenix Actor representing a terminal expression
[*Semantics]: A metafunction for generating a Phoenix value expression type
expression::value<T>::make(t);
[*Return type]: `expression::value<T>::type`
[*Semantics]: Creates a Phoenix Value expression initialized with a copy of of
the supplied argument
val(t);
[*Return type]: `expression::value<T>::type`
[*Semantics]: Calls `expression::value<T>::make(t)`, Automatically deduces type T
[header Header]
#include <boost/phoenix/core/value.hpp>
[header Example]
TODO
[endsect]
[section Reference]
Values are immutable constants. Attempting to modify a value will result in a
compile time error. When we want the function to modify the parameter, we use a
reference instead. For instance, imagine a lazy function `add_assign`:
void add_assign(T& x, T y) { x += y; } // pseudo code
Here, we want the first function argument, x, to be mutable. Obviously, we
cannot write:
add_assign(1, 2) // error first argument is immutable
In C++, we can pass in a reference to a variable as the first argument in our
example above. Yet, by default, the library forces arguments passed to partially
applied functions functions to be immutable values (see [link __phoenix_reference_value__]
). To achieve our intent, we use:
expression::reference<T>::type
This is similar to `expression::value<T>::type` before but instead holds a reference to a
variable.
We normally don't instantiate `expression::reference<T>::type` objects directly. Instead we
use `ref`. For example (where `i` is an `int` variable):
add_assign(ref(i), 2)
Another free function `cref(cv)` may also be used. `cref(cv)` creates an
`expression::reference<T const>::type` object. This is similar to `expression::value<T>::type` but
when the data to be passed as argument to a function is heavy and expensive to
copy by value, the `cref(cv)` offers a lighter alternative.
[heading Synopsis]
namespace expression
{
template <typename T>
struct reference
{
typedef __unspecified__ type;
static type make(T &t);
};
}
template <typename T>
typename expression::reference<T>::type
ref(T & t);
template <typename T>
typename expression::reference<T const>::type
cref(T const & t);
[heading Parameters]
[table
[[Parameter] [Requirement] [Description]]
[[T] [] [Operation's Argument]]
[[t] [Object of type T] [Operation's Argument]]
]
[heading Expression Semantics]
expression::reference<T>::type
[*Return type]: Returns a Phoenix Actor representing a terminal expression
[*Semantics]: A metafunction for generating a Phoenix reference expression type
expression::reference<T>::make(t);
[*Return type]: `expression::reference<T>::type`
[*Semantics]: Creates a Phoenix reference expression initialized with the supplied argument
ref(t);
[*Return type]: `expression::reference<T>::type`
[*Semantics]: Calls `expression::reference<T>::make(t)`, Automatically deduces type T
cref(t);
[*Return type]: `expression::reference<T const>::type`
[*Semantics]: Calls `expression::reference<T const>::make(t)`, Automatically deduces type T
[heading Header]
#include <boost/phoenix/core/reference.hpp>
[heading Example]
TODO
[endsect]
[section Arguments]
[heading Description]
The argument placeholder acts as an
imaginary data-bin where a function argument will be placed.
[heading Predefined Arguments]
There are a few predefined instances of `expression::argument<N>::type` named
`arg1`..`argN`, and its __bll__ counterpart `_1`..`_N`. (where N is a predefined
maximum).
[note You can set `PHOENIX_ARG_LIMIT`, the predefined maximum
placeholder index. By default, `PHOENIX_ARG_LIMIT` is set to `PHOENIX_LIMIT`
(See [link phoenix.reference.concepts.actor Actor]).]
[heading Synopsis]
namespace expression
{
template <int I>
struct argument
{
typedef __unspecified__ type;
static const type make();
};
}
namespace placeholders
{
expression::argument<1>::type const _1;
expression::argument<2>::type const _2;
expression::argument<3>::type const _3;
...
expression::argument<N>::type const _N;
expression::argument<1>::type const arg1;
expression::argument<2>::type const arg2;
expression::argument<3>::type const arg3;
...
expression::argument<N>::type const argN;
}
namespace arg_names
{
expression::argument<1>::type const _1;
expression::argument<2>::type const _2;
expression::argument<3>::type const _3;
...
expression::argument<N>::type const _N;
expression::argument<1>::type const arg1;
expression::argument<2>::type const arg2;
expression::argument<3>::type const arg3;
...
expression::argument<N>::type const argN;
}
[heading Parameters]
[table
[[Parameter] [Requirement] [Description]]
[[I] [] [Operation's Argument]]
]
[heading Expression Semantics]
expression::argument<I>::type
[*Return type]: Returns a Phoenix Actor representing a placeholder expression
[*Semantics]: A metafunction for generating a Phoenix placeholder expression type
We use an instance of: expression::argument<N>::type to represent the Nth function
argument. The argument placeholder acts as an
[heading Header]
#include <boost/phoenix/core/argument.hpp>
[heading Example]
TODO
[endsect]
[section Nothing]
Finally, the `expression::null::type` does nothing; (a "bum", if you will :-).
There's a sole `expression::null::type` instance named "nothing". This actor is
actually useful in situations where we don't want to do anything. (See
[link phoenix.reference.modules.statement.for__statement for_ Statement] for example).
[endsect]
[endsect]
[endsect]
[endsect]
[section EBNF]
[teletype]
[def __phoenix_peg__ [link phoenix.reference.phoenix_expressions.phoenix_ast phoenix]]
[def __phoenix_peg_terminals__ [link phoenix.reference.phoenix_expressions.phoenix_ast.terminals terminals]]
[def __phoenix_peg_operator__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator operator]]
[def __phoenix_peg_operator_arithmetic__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator.arithmetic arithmetic]]
[def __phoenix_peg_operator_bitwise__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator bitwise]]
[def __phoenix_peg_operator_comparision__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator comparision]]
[def __phoenix_peg_operator_if_else__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator if_else]]
[def __phoenix_peg_operator_io__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator io]]
[def __phoenix_peg_operator_logical__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator logical]]
[def __phoenix_peg_operator_member__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator member]]
[def __phoenix_peg_operator_self__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator self]]
[def __phoenix_peg_statement__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator statement]]
[def __phoenix_peg_object__ [link phoenix.reference.phoenix_expressions.phoenix_ast.object object]]
[def __phoenix_peg_function__ [link phoenix.reference.phoenix_expressions.phoenix_ast.function function]]
[def __phoenix_peg_bind__ [link phoenix.reference.phoenix_expressions.phoenix_ast.bind bind]]
[def __phoenix_peg_scope__ [link phoenix.reference.phoenix_expressions.phoenix_ast.scope scope]]
[def __phoenix_peg_fusion__ [link phoenix.reference.phoenix_expressions.phoenix_ast.fusion fusion]]
phoenix := statement ( "," statement )*
statement := expression | loops | if_statement | exception | switch
expression := operator
primary_expr := terminal
| "if_else(" expression "," expression "," expression ")"
| cast
| construction
| bind
| scope
| ( "(" expression ")" )
terminal := value | reference | placeholder
cast := ( "static_cast_" | "dynamic_cast_" | "reinterpret_cast_" | "const_cast_" ) "<" T ">(" expression ")"
construction := ( ( "construct" | "new_" ) "<" T ">(" [ expression ( "," expression )* ] ")" ) |
( "delete_(" expression ")" )
bind := "bind(" ( expression | function_pointer ) ( "," expression )* ")"
scope := let | lambda
local_var_def := local_var "=" expression
let := "let(" [ local_var_def ( "," local_var_def )* ] ")[" ( phoenix | local_var )* "]"
lambda := "lambda" [ "(" [ local_var_def ( "," local_var_def )* ] ")" ] "[" ( phoenix | local_var )* "]"
loops := for_loop | while_loop | do_while_loop
for_loop := "for_(" expression "," expression "," expression ")[" phoenix "]"
while_loop := "while_(" expression ")[" phoenix "]"
do_while_loop := "do_[" phoenix "].while_(" expression ")"
if_statement := "if_(" expression ")[" statement "]" [ ".else_[" phoenix "]" ]
exception := throw | try_catch
throw := "throw_(" [ expression ] ")"
try_catch := "try_[" phoenix "]"
( ".catch_<" E ">()[" phoenix "]" )*
[ ".catch_all[" phoenix "]" ]
switch := "switch_(" expression ")[" (
( case_statement ( "," case_statement )* [ "," default_statement ] ) |
default_statement
)
case_statement := "case_<" N ">(" phoenix ")"
default_statement := "default_(" phoenix ")"
operator := logical_or_op (
( "=" logical_or_op )* |
( "+=" logical_or_op )* |
( "-=" logical_or_op )* |
( "*=" logical_or_op )* |
( "/=" logical_or_op )* |
( "%=" logical_or_op )* |
( "&=" logical_or_op )* |
( "^=" logical_or_op )* |
( "|=" logical_or_op )* |
( "<<=" logical_or_op )* |
( ">>=" logical_or_op )*
)
logical_or_op := logical_and_op ( "||" logical_and_op )*
logical_and_op := bitwise_or_op ( "&&" bitwise_or_op )*
bitwise_or_op := bitwise_xor_op ( "|" bitwise_xor_op )*
bitwise_xor_op := bitwise_and_op ( "^" bitwise_and_op )*
bitwise_and_op := equality_op ( "&" equality_op )*
equality_op := relational_op (
( "==" relational_op )* |
( "!=" relational_op )*
)
relational_op := shift_op (
( "<" shift_op )* |
( ">" shift_op )* |
( "<=" shift_op )* |
( ">=" shift_op )*
)
shift_op := additive_op (
( "<<" additive_op )* |
( ">>" additive_op )*
)
additive_op := multiplicative_op (
( "+" multiplicative_op )* |
( "-" multiplicative_op )*
)
multiplicative_op := member_pointer_op (
( "*" member_pointer_op )* |
( "/" member_pointer_op )*
)
member_pointer_op := unary_op ( "->*" unary_op )*
unary_op := unary_postfix_op
| ( "*" unary_postfix_op )
| ( "&" unary_postfix_op )
| ( "+" unary_postfix_op )
| ( "-" unary_postfix_op )
| ( "~" unary_postfix_op )
| ( "!" unary_postfix_op )
| ( "++" unary_postfix_op )
| ( "--" unary_postfix_op )
unary_postfix_op := primary_expr
| ( primary_expr "[" expression "]" )
| ( primary_expr "()" )
| ( primary_expr "(" expression ( "," expression )* ")" )
| ( primary_expr "++" )
| ( primary_expr "--" )
[/include reference/basics.qbk]
[/include reference/organisation.qbk]
[/include reference/concepts.qbk]
[/include reference/actor.qbk]
[/include reference/composite.qbk]
[/section Modules]
[/include reference/core.qbk]
[/include reference/function.qbk]
[/include reference/operator.qbk]
[/include reference/statement.qbk]
[/include reference/object.qbk]
[/include reference/scope.qbk]
[/include reference/bind.qbk]
[/include reference/stl.qbk]
[/endsect]
[endsect]