Некоторые парсеры (например, примитивы и нетерминалы) могут принимать дополнительные атрибуты. Такие парсеры принимают форму:
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, пригодные для настройки поведения парсеров, описаны в разделеНастройка обработки атрибутов.