![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Complex - Made easierBoost , Spirit 2.5.2 , Tutorials
|
![]() | Note |
---|---|
Несколько генераторов потерпят неудачу, если их непосредственное значение не будет равно поставляемому атрибуту. Среди них всегенераторы символови всегенераторы струн. Как правило, все генераторы, имеющие родного брата, созданного вариантом< |
В дополнение к<eps
>генератор, упомянутый ранееДух. Кармапредоставляет два специальных оператора, обеспечивающих динамическое управление потоком:И предикат<&
>иНе предикат<!
>. Основное свойство обоих предикатов — отбрасывать весь выход, испускаемый прикрепленным генератором. Это эквивалентно поведению предикатов, используемых для разбора. Там предикаты не потребляют никаких входных данных, позволяющих заглянуть вперед во входной поток. В Карме предикат и предикат преуспевают до тех пор, пока преуспевает его ассоциированный генератор, в то время как не предикат преуспевает, только если ассоциированный генератор терпит неудачу.
![]() | Note |
---|---|
Генератор предикатов вДух. Кармапотребляет атрибут, если таковой имеется. Это заставляет их вести себя иначе, чем предикаты вДухе.Qi, где они не выставляют никакого атрибута. Это связано с тем, что предикаты позволяют принимать решения на основе данных, доступных только во время выполнения. При этом вSpirit.Qiпри разборе решения принимается на основе взгляда вперед еще несколько входных токенов, вДух.Критерии должны быть предоставлены пользователем. Самый простой способ сделать это — предоставить атрибут. |
В качестве примера, следующий генератор успешно генерирует:
double d = 1.0; BOOST_ASSERT(generate(out, &double_(1.0), d)); // succeeds as d == 1.0
А вот этот провалится:
double d = 1.0; BOOST_ASSERT(!generate(out, !double_(1.0), d)); // fails as d == 1.0
Ни один из них не будет выделять какой-либо выход. Предикаты отбрасывают все излучаемое генераторами, к которым они применяются.
Иногда желательно «пропустить» (т.е. игнорировать) предоставленный атрибут. Это происходит, например, в альтернативных генераторах, где некоторые из альтернатив должны извлечь только часть общего атрибута, переданного альтернативному генератору.Дух.Кармаимеет для этого специальный псевдогенератор: директива<omit
><[]
>. Эта директива потребляет атрибут типа, определенного встроенным генератором, но не испускает никакого вывода.
![]() | Note |
---|---|
Дух. Карма< |
Очень похожий на наш первый пример, мы используем две альтернативы, чтобы разрешить два различных формата вывода в зависимости от того, равна ли мнимая часть комплексного числа нулю или нет. Первая альтернатива выполняется, если мнимая часть не равна нулю, вторая альтернатива — иначе. На этот раз мы принимаем решение во время выполнения с использованиемНе предиката<!
>в сочетании с особенностью многих примитивных генераторов кармы, чтобыне работалипри определенных условиях. Вот первая альтернатива для вашей ссылки:
!double_(0.0) << '(' << double_ << ", " << double_ << ')'
Генератор<!double_(0.0)
>делает несколько вещей. Во-первых, из-заНе предиката<!
>, он преуспевает только в том случае, если<double_(0.0)
>генераторвыходит из строя, в результате чего вся первая альтернатива выходит из строя иначе. Во-вторых, генератор<double_(0.0)
>преуспевает только в том случае, если значение его атрибута равно его непосредственному параметру (т.е. в данном случае<0.0
>). И в-третьих, не предикат не испускает никакого выхода (независимо от того, преуспевает он или терпит неудачу), отбрасывая любой возможно испущенный выход из<double_(0.0)
>.
Когда мы передаем мнимую часть комплексного числа в качестве значения атрибута для<!double_(0.0)
>, общая первая альтернатива будет выбрана только в том случае, если она не равна нулю (<!double_(0.0)
>не терпит неудачу). Это именно то, что нам нужно!
Теперь второй вариант должен излучать только реальную часть комплексного числа. Чтобы упростить общую грамматику, мы стремимся объединить типы атрибутов всех альтернатив. Так как тип атрибута, раскрытый первой альтернативой<tuple<double,double,double>
>, нам нужно пропустить первый и последний элемент атрибута (помните, мы передаем реальную часть как второй элемент атрибута). Для этого мы используем директиву<omit[]
>:
omit[double_] << double_ << omit[double_]
Общий атрибут этого выражения<tuple<double,double,double>
>, но<omit[]
>«съедает» первый и последний элемент. Выход, испускаемый этим выражением, состоит из одного сгенерированного двойника, представляющего второй элемент кортежа, т.е. реальную часть нашего комплексного числа.
![]() | Important |
---|---|
Обычно предпочтительнее использовать генераторные конструкции, не требующие семантических действий. Причина в том, что семантические действия часто используют конструкции типа:< |
Статья Complex - Made easier раздела Spirit 2.5.2 Tutorials может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
реклама |