Boost.Spirit用户手册翻译(19):预定义动作器

22 篇文章 0 订阅
 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,

  1. assign_a(i) will extract the number 123456 and assign it to i, |assign_a(i)将抽取数字123456并将其赋值给i
  2. assign_a(s) will extract the string "Hello" and assign it to s, |assign_a(s)将抽取字符串“hello”并将其赋值给s
  3. 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_refkey_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
一元操作符动作器
++refincrement_a(ref)
--refdecrement_a(ref)
Assign actors
赋值动作器
ref = valueassign_a(ref)
ref = value_refassign_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_refassign_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 brefswap_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_actor1 reference
一个引用
act(ref)
ref_value_actor1 ref
一个引用
act(ref, value) or act(ref, first, last)
ref_const_ref_actor1 ref and 1 const ref
一个引用和一个常量引用
act(ref, const_ref)
ref_const_ref_value_actor1 ref
1个引用
act(ref, value) or act(ref, first, last)
ref_const_ref_const_ref_actor1 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);
}


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值