predefined_actors

| Predefined Actors |

## Actors

The framework has a number of predefined semantic action functors. Experience shows that these functors are so often used that they were included as part of the core framework to spare the user from having to reinvent the same functionality over and over again.

## Quick example: `assign_a` actor

`

        int i, j;
        std::string s;
        r = int_p[assign_a(i)] >> (+alpha_p)[assign_a(s)] >> int_p[assign_a(j,i)];

`

Given an input `123456 Hello 789`,

1. `assign_a(i)` will extract the number `123456` and assign it to `i`,
2. `assign_a(s)` will extract the string `"Hello"` and assign it to `s`,
3. `assign_a(j,i)` will assign i to j, j=i, without using the parse result.

Technically, the expression `assign_a(v)` is a template function that generates a semantic action. In fact, actor instances are not created directly since they usually involve a number of template parameters. Instead generator functions ("helper functions") are provided to generate actors from their arguments. All helper functions have the "_a" suffix. For example, `append_actor` is created using the `append_a` function.

The semantic action generated is polymorphic and should work with any type as long as it is compatible with the arguments received from the parser. It might not be obvious, but a string can accept the iterator first and last arguments that are passed into a generic semantic action (see above). In fact, any STL container that has an `assign(first, last)` member function can be used.

## Actors summary

Below are tables summarizing the "built-in" actors with the conventions given below.

- `ref` is a reference to an object stored in a policy holder actor
- `value_ref` and `key_ref` are const references stored in a policy holder actor
- `value` is the parse result. This could be the result for the single argument () operator or the two argument () operator
- `vt` stands for the `value_type` type: `type& ref; // vt is type::value_type`.

Note that examples are provided after the tables.

Unary operator actors
| ++ref | increment_a(ref) | --ref | decrement_a(ref)

Assign actors
ref = value | assign_a(ref)
| ref = value_ref | assign_a(ref, value_ref)

Container actors
ref.push_back(value) | push_back_a(ref)
| ref.push_back(value_ref) | push_back_a(ref, value_ref) | ref.push_front(value) | push_front_a(ref) | ref.push_front(value_ref) | push_front_a(ref, value_ref) | ref.clear() | clear_a(ref)

Associative container actors
| ref.insert(vt(value, value_ref)) | insert_key_a(ref, value_ref)
ref.insert(vt(key_ref,value_ref)) | insert_at_a(ref, key_ref_, value_ref)
ref.insert(vt(key_ref,value)) | insert_at_a(ref, key_ref)
| ref[value] = value_ref | assign_key_a(ref, value_ref) | ref.erase(ref,value) | erase_a(ref) | ref.erase(ref,key_ref) | erase_a(ref, key_ref)

Miscellanous actors
swaps aref and bref | swap_a(aref, bref)

### Include Files

The header files for the predefined actors are located in `boost/spirit/actor`. The file `actors.hpp` contains all the includes for all the actors. You may include just the specific header files that you need. The list below enumerates the header files.

        #include <boost/spirit/actor/assign_actor.hpp>
        #include <boost/spirit/actor/assign_key_actor.hpp>
        #include <boost/spirit/actor/clear_actor.hpp>
        #include <boost/spirit/actor/decrement_actor.hpp>
        #include <boost/spirit/actor/erase_actor.hpp>
        #include <boost/spirit/actor/increment_actor.hpp>
        #include <boost/spirit/actor/insert_key_actor.hpp>
        #include <boost/spirit/actor/insert_at_actor.hpp>
        #include <boost/spirit/actor/push_back_actor.hpp>
        #include <boost/spirit/actor/push_front_actor.hpp>
        #include <boost/spirit/actor/swap_actor.hpp>

### Examples

#### Increment a value

Suppose that your input string is

`

        1,2,-3,4,...

`

and we want to count the number of ints. The actor `increment_a` applies `++` to its reference:

`

        int count = 0;
        rule<> r = list_p.direct(int_p[increment_a(count)], ch_p(','));

`

#### Append values to a vector (or other container)

Here, you want to fill a `vector<int>` with the numbers. The actor `push_back_a` can be used to insert the integers at the back of the vector:

`

        vector<int> v;
        rule<> r = list_p.direct(int_p[push_back_a(v)], ch_p(','));

`

#### insert key-value pairs into a map

Suppose that your input string is

`

        (1,2) (3,4) ...

`

and you want to parse the pair into a `map<int,int>`. `assign_a` can be used to store key and values in a temporary key variable, while `insert_a` is used to insert it into the map:

        map<int, int>::value_type k;
        map<int, int> m;

        rule<> pair =
            confix_p(
                '('
              , int_p[assign_a(k.first)] >> ',' >> int_p[assign_a(k.second)]
              , ')'
            )
            [insert_at_a(m, k)]
            ;

## Policy holder actors and policy actions

The action takes place through a call to the `()` operator: single argument `()` operator call for character parsers and two argument (first, last) call for phrase parsers. Actors should implement at least one of the two `()` operator.

A lot of actors need to store reference to one or more objects. For example, actions on container need to store a reference to the container.

Therefore, this kind of actor have been broken down into a) an action policy that does the action (act member function), b) policy holder actor that stores the references and feeds the act member function.

### Policy holder actors

The available policy holders are enumerated below.

Policy holders
Name | Stored variables | Act signature
| ref_actor | 1 reference | `act(ref)` | ref_value_actor | 1 ref | `act(ref, value)` or `act(ref, first, last)` | ref_const_ref_actor | 1 ref and 1 const ref | `act(ref, const_ref)` | ref_const_ref_value_actor | 1 ref | `act(ref, value)` or `act(ref, first, last)` | ref_const_ref_const_ref_actor | 1 ref, 2 const ref | `act(ref, const_ref1, const_ref2)`

### Include Files

The predefined policy header files are located in `boost/spirit/actor`:

        #include <boost/spirit/actor/ref_actor.hpp>
        #include <boost/spirit/actor/ref_value_actor.hpp>
        #include <boost/spirit/actor/ref_const_ref.hpp>
        #include <boost/spirit/actor/ref_const_ref_value.hpp>
        #include <boost/spirit/actor/ref_const_ref_value.hpp>
        #include <boost/spirit/actor/ref_const_ref_const_ref.hpp>

### Holder naming convention

Policy holder have the following naming convention:

        <member>_ >> *<member> >> !value >> actor

where `member` is the action policy member which can be of type:

- ref, a reference
- const_ref, a const reference
- value, by value
- empty, no stored members

and `value` states if the policy uses the parse result or not.

### Holder example: `ref_actor` class

        // this is the building block for action that
        // take a reference and the parse result

        template<
            typename T, // reference type
            typename ActionT // action policy
        >
        class ref_value_actor : public ActionT
        {
        public:

            explicit ref_value_actor(T& ref_)
            : ref(ref_){}

            template<typename T2>
            void operator()(T2 const& val) const
            {
                act(ref, val); // defined in ActionT
            }

            template<typename IteratorT>
            void operator()(
                IteratorT const& first,
                IteratorT const& last) const
            {
                act(ref,first,last); // defined in ActionT
            }

        private:

           T& ref;
        };

### Actor example: `assign_actor`

`

        // assign_action assigns the parse result to the reference

        struct assign_action
        {
            template<
                typename T,
                typename ValueT
            >
            void act(T& ref, ValueT const& value) const
            {
                ref = value;
            }

            template<
                typename T,
                typename IteratorT
            >
            void act(
                T& ref,
                IteratorT const& first,
                IteratorT const& last) const
            {
                typedef typename T::value_type value_type;
                value_type vt(first, last);
                ref = vt;
            }
        };

`

### Helper function example: `assign_a` function

`

        // assign_a is a polymorphic helper function that generators an
        // assign_actor based on ref_value_actor, assign_action and the
        // type of its argument.

        template<typename T>
        inline ref_value_actor<T, assign_action>
        assign_a(T& ref)
        {
            return ref_value_actor<T, assign_action>(ref);
        }

`

Copyright © 2003 Jonathan de Halleux
Copyright © 2003 Joel de Guzman
Use, modification and distribution is subject to 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)