Фреймворк имеет ряд предопределенных семантических функторов действия. Опыт показывает, что эти функторы так часто используются, что они были включены в базовую структуру, чтобы избавить пользователя от необходимости заново изобретать одну и ту же функциональность снова и снова.
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)];
assign_a(j,i)будет присваивать i j, j=i без использования результата разбора.
Технически выражениеassign_a(v)является шаблонной функцией, генерирующей семантическое действие. Фактически, примеры актеров не создаются напрямую, поскольку они обычно включают в себя ряд параметров шаблона. Вместо этого предоставляются функции генератора (функции-помощники) для генерации участников из их аргументов. Все вспомогательные функции имеют суффикс "a". Например,append_actorсоздается с помощью приложенияФункция.
Семантическое действие является полиморфным и должно работать с любым типом, если оно совместимо с аргументами, полученными от парсера. Это может быть неочевидным, но строка может принять итератор первый и последний аргументы, которые передаются в общее семантическое действие (см. выше). Фактически, можно использовать любой контейнер STL, который имеетназначение (первое, последнее)функция члена.
Actors summary
Ниже приведены таблицы, обобщающие участников "встроенных" с приведенными ниже конвенциями.
refявляетсяссылкойна объект, хранящийся в держателе полиса.
value_refиkey_refявляютсяconst references, хранящимися в акторе держателя полиса
— эторезультат разбора. Это может быть результатом для оператора одного аргумента () или оператора двух аргументов ()
vtозначаетvalue_typetype:type& ref; // vt is type::value_type.
Обратите внимание, что примеры приведены после таблиц.
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
Файлы заголовков для предопределенных акторов расположены вboost/spirit/actor. Файлactors.hppсодержит все включения для всех актеров. Вы можете включать только определенные файлы заголовка, которые вам нужны. В приведенном ниже списке перечислены файлы заголовков.
И мы хотим подсчитать количество интов. Актер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)
Здесь вы хотите заполнить векторчислами. Актерpush_back_aможет использоваться для вставки целых чисел в заднюю часть вектора:
vector<int> v;
rule<> r = list_p.direct(int_p[push_back_a(v)], ch_p(','));
insert key-value pairs into a map
Предположим, что ваша входная строка
(1,2) (3,4) ...
и вы хотите разобрать пару наmap.assign_aможно использовать для хранения ключа и значений во временной переменной ключа, в то время какinsert_aиспользуется для вставки его в карту:
Действие происходит через вызов оператору(): один аргумент()оператор вызывает парсеры символов и два аргумента (первый, последний) вызывают парсеры фраз. Актеры должны реализовать по крайней мере одного из двух операторов.
Многие актеры должны хранить ссылки на один или несколько объектов. Например, действия на контейнере должны хранить ссылку на контейнер.
Таким образом, этот тип актора был разбит наa)политику действия, которая выполняет действие (функция участника действия),b)субъект держателя политики, который хранит ссылки и питает функцию участника действия.
Policy holder actors
Ниже перечислены имеющиеся держатели политики.
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
Файлы заголовков политик расположены вboost/spirit/actor:
Обладатель политики имеет следующую конвенцию об именах:
<member>_ >> *<member> >> !value >> actor
гдечленявляется членом политики действий, который может быть:
Ref, ссылка
const_ref, ссылка на const
стоимость, по стоимости
пустой, без хранимых членов
изначениеуказывает, использует ли политика результат анализа или нет.
Holder example: ref_actor class
// this is the building block for action that
// take a reference and the parse result
template<
typename T, // reference typetypename 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;
};
// 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);
}
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)
Статья predefined_actors раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.