Некоторые генераторы (например, примитивы и нетерминалы) могут принимать дополнительные атрибуты. Такие генераторы принимают форму:
g(a1, a2,..., aN)
где<g
>- генератор. Каждый из аргументов (a1 ... aN) может быть либо непосредственным значением, либо функцией<f
>с подписью:
T f(Unused, Context)
где<T
>, возвращаемое значение функции, совместимо с ожидаемым типом аргумента и<Context
>является типом контекста генератора (первый аргумент<unused
>, чтобы сделать<Context
>вторым аргументом). Это делается для единообразия ссемантическими действиями.
Некоторые генераторы должны знать, какой набор символов работает<char
>или<wchar_t
>. Например, генератор<alnum
>работает по-разному с кодировками ISO8859.1 и ASCII. При необходимости Spirit кодирует (метки) генератор с набором символов.
У нас есть пространство имен для каждого персонажа, которого будет поддерживать Дух. В том числе<ascii
>,<iso8859_1
>,<standard
>и<standard_wide
>(и в будущем<unicode
>). В каждом из символов, кодирующих пространства имен, мы размещаем помеченные версии генераторов, таких как<alnum
>,<space
>и т. Д.
Пример:
using boost::spirit::ascii::space;
Пространства имен:
- Источник::spirit::ascii
- Источник::iso8859_1
- Источник::spirit::standard
- Оригинальное название:: Standard_wide
Для удобства использования компоненты в этих пространствах имен также вносятся в пространства подимен кармы с теми же именами:
- Источник::spirit::karma::ascii
- Источник::Spirit::karma::iso8859_1
- Источник::spirit::karma::standard:
- boost::spirit::karma::standard_wide
Все разделы в ссылке представляют некоторые примеры реального мира. В примерах используется общий тестовый ремень, чтобы сохранить код примера как можно более минимальным и прямым к точке. Ниже приводится информация об испытаниях.
Некоторые включают:
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <iostream>
#include <string>
Используемый выходной итератор:
typedef std::back_insert_iterator<std::string> output_iterator_type;
Наши тестовые функции:
Это тестирует генераторы без атрибутов.
template <typename G>
void test_generator(char const* expected, G const& g)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
Они проверяют генераторы с одним или несколькими атрибутами, предоставленными пользователем.
template <typename G, typename T>
void test_generator_attr(char const* expected, G const& g, T const& attr)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g, attr) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename G, typename T1, typename T2>
void test_generator_attr(char const* expected, G const& g, T1 const& attr1,
T2 const& attr2)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g, attr1, attr2) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
Это проверяет генераторы с одним атрибутом и при использовании разграниченного вывода.
template <typename G, typename Delimiter, typename T>
void test_generator_attr_delim(char const* expected, G const& g, Delimiter const& d, T const& attr)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate_delimited(out, g, d, attr) && s == expected)
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
Примеры двоичных генераторов используют один или несколько из следующих тестов.
template <typename G>
void test_binary_generator(char const* expected, std::size_t size, G const& g)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g) && !std::memcmp(s.c_str(), expected, size))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename G, typename T>
void test_binary_generator_attr(char const* expected, std::size_t size, G const& g, T const& attr)
{
std::string s;
std::back_insert_iterator<std::string> out(s);
if (boost::spirit::karma::generate(out, g, attr) && !std::memcmp(s.c_str(), expected, size))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
Предопределенные модели включают в себя:
- Литературная строка, например. "Привет, мир",
- указатель/ссылка на нулевой набор символов
- a<
std::basic_string<Char>
>
Пространство имен<boost::spirit::traits
>открыто для пользователей, чтобы предоставить свои собственные специализации. Точки настройки, реализованныеДух. Карма, пригодная для настройки поведения генераторов, описана в разделеНастройка обработки атрибутов.