Некоторые парсеры (например, примитивы и нетерминалы) могут принимать дополнительные атрибуты. Такие парсеры принимают форму:
p(a1, a2,..., aN)
гдеp— парсер. Каждый из аргументов (a1 ... aN) может быть либо непосредственным значением, либо функциейfс подписью:
T f(Unused, Context)
гдеT, возвращаемое значение функции, совместимо с ожидаемым типом аргумента иКонтекстявляется типом контекста парсера (первый аргументне используется, чтобы сделатьКонтекствторым аргументом). Это делается для единообразия с семантическими действиями.
Некоторые парсеры должны знать, какой набор символов работаетcharилиwchar_t. Например, парсерработает по-разному с кодировками ISO8859.1 и ASCII. При необходимости Spirit кодирует (метки) парсер с набором символов.
У нас есть пространство имен для каждого персонажа, которого будет поддерживать Дух. Это включаетascii,iso8859_1,стандартистандарт_wide(и в будущемуникод. В каждом из символов, кодирующих пространства имен, мы размещаем помеченные версии парсеров, таких какalnum,пространствои т. Д.
Пример:
using boost::spirit::ascii::space;
Пространства имен:
- Источник::spirit::ascii
- Источник::iso8859_1
- Источник::spirit::standard
- Оригинальное название:: Standard_wide
Для удобства использования компоненты в этих пространствах имен также вносятся в подпространства qi с теми же названиями:
- Источник::spirit::qi::ascii
- Источник:::iso8859_1
- Источник::spirit::qi::standard:
- boost::spirit::qi::standard_wide
Все разделы в ссылке представляют некоторые примеры реального мира. В примерах используется общий тестовый ремень, чтобы сохранить код примера как можно более минимальным и прямым к точке. Ниже приводится информация об испытаниях.
Некоторые включают:
#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>
Наши тестовые функции:
Эти функции тестируют парсеры без атрибутов.
template <typename P>
void test_parser(
char const* input, P const& p, bool full_match = true)
{
using boost::spirit::qi::parse;
char const* f(input);
char const* l(f + strlen(f));
if (parse(f, l, p) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename P>
void test_phrase_parser(
char const* input, P const& p, bool full_match = true)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::ascii::space;
char const* f(input);
char const* l(f + strlen(f));
if (phrase_parse(f, l, p, space) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
Эти функции тестируют парсеры с атрибутами, предоставленными пользователем.
template <typename P, typename T>
void test_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::parse;
char const* f(input);
char const* l(f + strlen(f));
if (parse(f, l, p, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
template <typename P, typename T>
void test_phrase_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::ascii::space;
char const* f(input);
char const* l(f + strlen(f));
if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
Функция утилитыprint_infoпечатает информацию, содержащуюся в классеinfo.
struct printer
{
typedef boost::spirit::utf8_string string;
void element(string const& tag, string const& value, int depth) const
{
for (int i = 0; i < (depth*4); ++i)
std::cout << ' ';
std::cout << "tag: " << tag;
if (value != "")
std::cout << ", value: " << value;
std::cout << std::endl;
}
};
void print_info(boost::spirit::info const& what)
{
using boost::spirit::basic_info_walker;
printer pr;
basic_info_walker<printer> walker(pr, what.tag, 0);
boost::apply_visitor(walker, what.value);
}
#include <boost/spirit/support_string_traits.hpp>
Струна может быть любым объектомs, типаS, который удовлетворяет следующим признакам выражения:
Предопределенные модели включают в себя:
- Литературная строка, например. "Привет, мир",
- указатель/ссылка на нулевой набор символов
- a
std::basic_string<Char>
Пространство именповышает::дух::чертыоткрыты для пользователей, чтобы предоставить свои собственные специализации. Точки настройки, реализованныеSpirit.Qi, пригодные для настройки поведения парсеров, описаны в разделеНастройка обработки атрибутов.