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
快速的例子:assign_a动作器
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,
给定输入 123456 Hello 789,
- assign_a(i) will extract the number 123456 and assign it to i, |assign_a(i)将抽取数字123456并将其赋值给i
- assign_a(s) will extract the string "Hello" and assign it to s, |assign_a(s)将抽取字符串“hello”并将其赋值给s
- assign_a(j,i) will assign i to j, j=i, without using the parse result. |assign_a(j,i)将把i赋值给j,及j=i,而不是使用分析结果
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.
从技术上讲,表达式assign_a(v)是一个生成语意动作的模板函数。事实上,由于通常需要包含模板参数,动作器的实例并不是直接创建的。取而代之的是提供生成器函数(“帮手函数”)以用于根据参数生成动作其。所有的帮手函数都有“_a”后缀。比如,append_actor是使用append_a函数生成的。
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.
所生成的语意动作是多态的,并且应能够处理任何兼容于传递自分析器的参数类型的类型。这可能很绕口,但比如一个string可以接受一个传入所产生的语义动作的first,last迭代器对(见上)。实际上,任何有 assign(first, last)成员函数的标准库容器都可以使用。
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
- ref是一个对对象的引用,储存于策略持有者动作器
- value_ref and key_ref are const references stored in a policy holder actor
- value_ref 和 key_ref是静态引用,储存于策略持有者动作器
- value is the parse result. This could be the result for the single argument () operator or the two argument () operator
- value是分析结果,这可以是适用于单参数或者双参数的operator()结果。
- vt stands for the value_type type: type& ref; // vt is type::value_type.
- vt即value_typ的类型: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.
预定义动作器的头文件位于boost/spirit/actor。文件actors.hpp包含了所有动作器的头文件。你也可以仅仅包含你需要的特定的头文件。下面的列表列举了这些头文件。
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/assign_key.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:
且你想统计整数的个数。而动作器increment_a对其引用的对象使用++:
int count = 0;
rule<> r = list_p.direct(int_p[increment_a(count)], ch_p(','));
Append values to a vector (or other container)
把值加入vector(或者其他容器)
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>填充数值。那么动作器push_back_a可用来向vector的后端插入整数
vector<int> v;
rule<> r = list_p.direct(int_p[push_back_a(v)], ch_p(','));
insert key-value pairs into a map
向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>。这里assign_a可以用来将索引-值保存在一个临时变量中,同时insert_a可以用来把它插入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.
语意动作通过对operator()的调用被激活:单参数的operator()适用于字符分析器而双参数(first,last)的适用于句子分析器。
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.
因此,这类动作器被分割成a)一个实际执行动作(act成员函数)的动作策略,b)持有传递给act成员函数的对象引用的策略持有者动作器。
Policy holder actors
策略持有者动作器
The available policy holders are enumerated below.
可用的策略持有者动作器列于下表:
Policy holders 策略持有者 | |||||||||||||||||||||||
Name 名称 | Stored variables 保存的变量 | Act signature Act函数签名 | |||||||||||||||||||||
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 1个引用 | act(ref, value) or act(ref, first, last) | |||||||||||||||||||||
ref_const_ref_const_ref_actor | 1 ref, 2 const ref 1个引用,两个常量引用 | act(ref, const_ref1, const_ref2) |
Include Files
包含文件
The predefined policy header files are located in boost/spirit/actor:
预定义的策略持有者动作器的头文件位于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:
这里member是动作策略成员,它的类型可以为:
- 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.
而value标明策略是否使用分析结果
Holder example: ref_actor class
持有者例子:ref_actor类
// 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_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函数
// 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)