![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Generator Semantic ActionsBoost , Spirit 2.5.2 , Tutorials
|
![]() | Important |
---|---|
Как правило, и более формально, семантическое действие< В приведенном выше примере функция F принимает< |
На самом деле, есть еще 2 аргумента (контекст генератора и ссылка на фулевый параметр «прохода»). На данный момент они нам не нужны, но мы увидим больше других аргументов позже.Дух.Кармапозволяет нам связать одну функцию аргумента, как выше. Остальные аргументы просто игнорируются.
Подводя итог, можно сказать, что возможными подписями семантических действий являются:
void f(Attrib&); void f(Attrib&, Context&); void f(Attrib&, Context&, bool&);
В следующем примере представлены различные способы прикрепления семантических действий:
Предположим, у нас есть:
namespace client { namespace karma = boost::spirit::karma; // A plain function void read_function(int& i) { i = 42; } // A member function struct reader { void print(int& i) const { i = 42; } }; // A function object struct read_action { void operator()(int& i, unused_type, unused_type) const { i = 42; } }; }
Обратите внимание, что с функциональными объектами мы должны иметь<operator()
>с 3 аргументами. Поскольку мы не заботимся о двух других, мы можем использовать<unused_type
>для них. Мы увидим больше<unused_type
>в другом месте. Привыкай к этому.<unused_type
>— класс поддержки, предоставляемый Духом. В большинстве случаев это означает «Мне все равно, просто используйте соответствующий по умолчанию».
Все следующие примеры генерируют выходы формы:
"{integer}"
Целое число внутри кудрявых брекетов.
Первый пример показывает, как прикрепить простую функцию:
generate(outiter, '{' << int_[&read_function] << '}');
Что нового?<int_
>является родным братом<double_
>. Я уверен, что вы можете догадаться, что делает этот генератор и какой атрибут он ожидает.
Следующий пример показывает, как прикрепить простой функциональный объект:
generate(outiter, '{' << int_[read_action()] << '}');
Мы можем использоватьBoost.Bindдля связывания функций членов:
reader r; generate(outiter, '{' << int_[boost::bind(&reader::print, &r, _1)] << '}');
Также мы можем использоватьBoost.Bindдля связывания простых функций:
generate(outiter, '{' << int_[boost::bind(&read_function, _1)] << '}');
И последнее, но не менее важное: мы также можем использоватьBoost.Lambda:
std::stringstream strm("42"); generate(outiter, '{' << int_[strm >> lambda::_1] << '}');
Существует больше способов связывания семантических функций действия, но примеры выше являются наиболее распространенными. Привязка семантических действий является первым препятствием, которое нужно преодолеть, когда вы начинаете генерировать с помощью Духа. Если вы еще этого не сделали, вероятно, будет хорошей идеей ознакомиться с инструментами, стоящими за этим, такими какBoost.BindиBoost.Lambda.
The examples above can be found here: actions.cpp
Феникс, библиотека-компаньон в комплекте с Духом, специально подходит для связывания смысловых действий. Это какBoost.Lambdaна стероидах, с особыми пользовательскими функциями, которые позволяют легко интегрировать семантические действия с Духом. Если ваши требования выходят за рамки простого и умеренного поколения, я предлагаю вам использовать эту библиотеку. Примеры, представленные отныне, должны использоваться исключительно в библиотеке Феникса.
![]() | Important |
---|---|
Существуют различные способы написания семантических действий.Дух. Карма: с использованием простых функций,Boost.Bind,Boost.LambdaилиPhoenix. Последние три позволяют использовать специальные заполнители для управления размещением параметров< Как правило, дляBoost.Bind, использовать< ДляBoost.Lambdaиспользуйте заполнители, определенные в пространстве имен< Для семантических действий, написанных с использованиемФеникса, используйте заполнители, определенные в пространстве имен< |
Статья Generator Semantic Actions раздела Spirit 2.5.2 Tutorials может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
реклама |