Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Complex - A first more complex generator

Boost , Spirit 2.5.2 , Tutorials

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

В этом разделе мы разработаем генератор комплексных чисел, позволяющий представлять<std::complex>либо как<(real,imag)>(где<real>и<imag>являются реальной и мнимой частями комплексного числа), либо как простую<real>, если мнимая часть оказывается равной нулю. Этот пример подчеркивает силу духа. кармапозволяет комбинировать определение правил форматирования по времени с решениями, основанными на времени выполнения. Также на этот раз мы используемBoost.Phoenixдля выполнения семантических действий.

Наша цель состоит в том, чтобы обеспечить применение двух различных форматов вывода в зависимости от того, является ли мнимая часть комплексного числа нулевой или нет. Давайте напишем оба варианта:

    '(' << double_ << ", " << double_ << ')'
|   double_

где первая альтернатива должна быть использована для чисел, имеющих ненулевую воображаемую часть, в то время как вторая - для реальных чисел. Как правило, альтернативы испробованы в последовательности их определения до тех пор, пока одно из выражений (как определено<'|'>) не увенчается успехом. Если экспрессия генератора не увенчалась успехом, вся альтернатива терпит неудачу.

Если бы мы оставили эту грамматику форматирования, то наш генератор всегда выбирал бы первую альтернативу. Нам нужно добавить некоторые дополнительные правила, позволяющие сделать первый вариант неудачным. Таким образом, если первая альтернатива не сработает, будет выбрана вторая. Решение о том, выбирать ли первую альтернативу, должно приниматься во время выполнения, поскольку только тогда мы действительно знаем значение мнимой части комплексного числа.Дух.Кармаснабжает нас примитивным генератором<eps()>, который можно использовать в качестве семантического предиката. Он обладает свойством «успех» генерировать только в том случае, если его аргумент верен (хотя он никогда не генерирует какой-либо результат сам по себе).

double imag = ...;     // imaginary part
    eps(imag != 0) << '(' << double_ << ", " << double_ << ')'
|   double_

Если один из генераторных элементов последовательности выходит из строя, вся последовательность выходит из строя. Это именно то, что нам нужно, заставляя выбирать вторую альтернативу для комплексных чисел с воображаемыми частями, равными нулю.

Теперь перейдем к полному примеру, на этот раз с правильными семантическими действиями (полный файл cpp для этого примера можно найти здесь:complex_number.cpp).

Мы будем использовать<std::complex>для этого и всех последующих связанных примеров. И здесь можно увидеть полный код генератора, позволяющий вывести комплексное число либо как пару чисел (если мнимая часть ненулевая), либо как единое число (если комплекс — реальное число):

template <typename OutputIterator>
bool generate_complex(OutputIterator sink, std::complex<double> const& c)
{
    using boost::spirit::karma::eps;
    using boost::spirit::karma::double_;
    using boost::spirit::karma::_1;
    using boost::spirit::karma::generate;
    return generate(sink,
        //  Begin grammar
        (
            eps(c.imag() != 0) <<
            '(' << double_[_1 = c.real()] << ", " << double_[_1 = c.imag()] << ')'
        |   double_[_1 = c.real()]
        )
        //  End grammar
    );
}

Генераторы<double_>имеют семантическое действие:

_1 = n

который переходит<n>к первому элементу прилагаемого генератором семантического действия. Семантические действия вДух. Кармавызывается перед вызовом соответствующего генератора, и ожидается, что они предоставят генератору данные, которые будут использоваться. Семантическое действие, описанное выше, присваивает генерируемое значение (<n>) генератору (фактически, атрибуту<double_>).<_1>является заполнителем Феникса, относящимся к атрибуту генератора семантического действия. Если вам нужна дополнительная информация о семантических действиях, вы можете прочитать о них в этом разделе:Семантические действия.

Эти семантические действия легко понять, но имеют неожиданный побочный эффект, будучи немного менее эффективными, чем это может быть. Кроме того, они, как правило, делают грамматику форматирования менее читаемой. В одном из следующих разделов мы увидим, как можно использовать другие, встроенные функцииДуха. Кармадля полного избавления от семантических действий. При написании грамматики в духе всегда старайтесь избегать семантических действий, которые часто возможны. Семантические действия действительно мощные инструменты, но грамматика, как правило, более эффективна и читаема без них.


PrevUpHomeNext

Статья Complex - A first more complex generator раздела Spirit 2.5.2 Tutorials может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Tutorials ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 20:39:32/0.0072441101074219/0