![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
ReferenceBoost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 22. Boost.Metaparse
|
![]() |
Note |
---|---|
Обратите внимание, что для обратной совместимости, когда< |
Для любого значения метапрограммирования шаблона<r
><s
>строка времени компиляции и<p
>положение источника эквивалентны:
accept<r, s, p>::type accept<r, s::type, p::type>
#include <boost/metaparse/accept.hpp>
struct accept_tag;
Этобирка.
Это тег значений, возвращаемых парсером, когда парсинг был успешным.
#include <boost/metaparse/accept_tag.hpp>
template <class P, class Pred, class Msg> struct accept_when;
При этом он уравновешивается<P
>. Когда<P
>отвергает вход,<accept_when
>также отвергает его. Когда<P
>принимает его,<accept_when
>оценивает<Pred
>с результатом разбора входа с<P
>. Когда<Pred
>возвращается<true
>,<accept_when
>принимает вход, и результатом разбора будет то, что<P
>возвращается. В противном случае<accept_when
>отклоняет ввод и<Msg
>используется в качестве причины ошибки.
#include <boost/metaparse/accept_when.hpp>
Для любого<p
>парсера,<pred
>предиката,<msg
>сообщения об ошибке парсинга,<s
>строки времени компиляции и<pos
>положения источника
accept_when<p, pred, msg>i::apply<s, pos>::type
является эквивалентным
p::apply<s, pos>::type
Когда<p::apply<s,pos>
>не возвращает ошибку и<pred::apply<get_result<p::apply<s,pos>>>::type
><true
>. В противном случае оно эквивалентно
fail<msg>
#include <boost/metaparse/accept_when.hpp> #include <boost/metaparse/one_char.hpp> #include <boost/metaparse/util/is_digit.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/define_error.hpp> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(digit_expected, "Digit expected"); using accept_digit = accept_when<one_char, util::is_digit<>, digit_expected>; static_assert( !is_error< accept_digit::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value, "accept_digit should accept a digit" ); static_assert( get_result< accept_digit::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value == '0', "the result of parsing should be the character value" ); static_assert( is_error< accept_digit::apply<BOOST_METAPARSE_STRING("x"), start> >::type::value, "accept_digit should reject a character that is not a digit" );
struct alphanum;
Этопарсер.
Он принимает один символ в диапазоне<a-z
>,<A-Z
>или<0-9
>. Результатом парсера является принятый характер.
#include <boost/metaparse/alphanum.hpp>
Следующие эквивалентны:
alphanum one_of<digit, letter>
#include <boost/metaparse/alphanum.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; static_assert( !is_error<alphanum::apply<BOOST_METAPARSE_STRING("0"), start>>::type::value, "alphanum should accept a digit" ); static_assert( !is_error<alphanum::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "alphanum should accept a character" ); static_assert( get_result< alphanum::apply<BOOST_METAPARSE_STRING("x"), start> >::type::value == 'x', "the result of parsing should be the character value" ); static_assert( is_error<alphanum::apply<BOOST_METAPARSE_STRING(","), start>>::type::value, "alphanum should reject a comma" );
template <char C, class T> struct always_c;
Он принимает входы, начинающиеся с символа<C
>. Он потребляет этот характер, и результат разбора<T
>. Другие материалы отклонены.
#include <boost/metaparse/always_c.hpp>
Для любого<c
>символа и<t
>класса эквивалентны:
always_c<c, t> always<lit_c<c>, t>
#include <boost/metaparse/always_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using always13 = always_c<'x', std::integral_constant<int, 13>>; static_assert( !is_error<always13::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "always13 should accept x" ); static_assert( std::is_same< get_result<always13::apply<BOOST_METAPARSE_STRING("x"), start>>::type, std::integral_constant<int, 13> >::type::value, "the result of parsing should be the integral_constant type" ); static_assert( is_error<always13::apply<BOOST_METAPARSE_STRING("y"), start>>::type::value, "always13 should reject characters other than x" );
template <class P, class T> struct always;
Он принимает ввод, если и только если<P
>принимает его, но результат разбора будет<T
>вместо результата<P
>возвращен.
#include <boost/metaparse/always.hpp>
Для любого<p
>парсера и<t
>класса эквивалентны:
always<p, t> last_of<p, return_<t>>
#include <boost/metaparse/always.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using always13 = always<lit_c<'x'>, std::integral_constant<int, 13>>; static_assert( !is_error<always13::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "always13 should accept x" ); static_assert( std::is_same< get_result<always13::apply<BOOST_METAPARSE_STRING("x"), start>>::type, std::integral_constant<int, 13> >::type::value, "the result of parsing should be the integral_constant type" ); static_assert( is_error<always13::apply<BOOST_METAPARSE_STRING("y"), start>>::type::value, "always13 should reject characters other than x" );
#define BOOST_METAPARSE_DEFINE_ERROR(name, msg) \ // unspecified
Это макро.
Макро для определения классапарсинга сообщения об ошибке.<name
>- это имя класса, представляющего сообщение об ошибке, и<msg
>- строка, содержащая описание ошибки.
#include <boost/metaparse/define_error.hpp>
Для любого<n
>имени и<m
>строки буквально, учитывая следующее, определяется:
BOOST_METAPARSE_DEFINE_ERROR(n, m);
Следующие пары выражений эквивалентны:
n::get_value() std::string(m) n::type n
#include <boost/metaparse/define_error.hpp> #include <boost/metaparse/repeated1.hpp> #include <boost/metaparse/letter.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/sequence.hpp> #include <boost/metaparse/change_error_message.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_message.hpp> #include <boost/metaparse/string.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(age_expected, "Age expected"); using name_token = token<repeated1<letter>>; using age_token = token<change_error_message<int_, age_expected>>; using name_age = sequence<name_token, age_token>; static_assert( std::is_same< age_expected, get_message<name_age::apply<BOOST_METAPARSE_STRING("Joe "), start>>::type >::type::value, "the error message should be age_expected when the age is missing" );
#define BOOST_METAPARSE_STRING(s) \ // unspecified
Это макро.
Макро для определения<string
>значений.<s
>— буквальная строка. Для макроса требуется C++11.
Максимальная длина струны ограничена. Этот предел определяется макросом<BOOST_METAPARSE_LIMIT_STRING_SIZE
>.
На платформах, где<BOOST_METAPARSE_STRING
>не поддерживается, заголовок<string.hpp
>определяет макрос<BOOST_METAPARSE_V1_CONFIG_NO_BOOST_METAPARSE_STRING
>. Определение этого макроса перед включением заголовка отключает макрос<BOOST_METAPARSE_STRING
>.
#include <boost/metaparse/string.hpp>
Семантика этого макроса демонстрируется на примере. Следующий
BOOST_METAPARSE_STRING("hello")
является эквивалентным
string<'h','e','l','l','o'>
#include <boost/metaparse/string.hpp> #include <type_traits> using namespace boost::metaparse; using hello1 = string<'H','e','l','l','o'>; using hello2 = BOOST_METAPARSE_STRING("Hello"); static_assert( std::is_same< string<'H', 'e', 'l', 'l', 'o'>, BOOST_METAPARSE_STRING("Hello") >::type::value, "The type generated by the macro should be identical to the hand-crafted one." );
#define BOOST_METAPARSE_VERSION \\ unspecified
Это макро.
Macro содержит номер версии Boost. Метапарс.
#include <boost/metaparse/version.hpp>
Он имеет основные, второстепенные и выпускные компоненты:
major == BOOST_METAPARSE_VERSION / 10000000 minor == (BOOST_METAPARSE_VERSION % 10000000) / 100000 release == BOOST_METAPARSE_VERSION % 100000
упакованное значениепредставляет собой тип, представляющий постоянное значение. Он имеет публичный статический<const
>или<constexpr
>член, называемый<value
>. Класс представляет это значение как тип, поэтому им можно манипулировать с помощьюшаблонной метафункции. Это должно быть значениешаблонного метапрограммирования.
Например, следующее<struct
>представляет<true
>значение типа<bool
>:
struct true_type { static constexpr bool value = true; using type = true_type; };
<value
>является обернутым значением.<true_type::type
>является псевдонимом<true_type
>, что делает его значением метапрограммирования шаблона.
template <class P> struct build_parser;
Он создает простой интерфейс для парсера. Он возвращает класс метафункций, который принимает входную строку, парсирует ее с<P
>и возвращает результат парсинга. Он генерирует ошибку компиляции, когда парсинг не удается.
Он возвращает класс метафункции шаблона:
struct { template <class S> struct apply; };
#include <boost/metaparse/build_parser.hpp>
Для любого<p
>парсера и<s
>компилятора времени строка
build_parser<p>::type::apply<s>
является эквивалентным
get_result<p::apply<s>>
#include <boost/metaparse/build_parser.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> using namespace boost::metaparse; using string_to_int = build_parser<int_>::type; static_assert( string_to_int::apply<BOOST_METAPARSE_STRING("1113")>::type::value == 1113, "string_to_int should be a metafunction turning a string into an int" );
template <class P, class Msg> struct change_error_message;
При этом<P
>вводится в действие. Когда<P
>удается,<change_error_message
>возвращает результат<P
>возвращается, в противном случае<change_error_message
>отклоняет вход и причина будет<Msg
>.
#include <boost/metaparse/change_error_message.hpp>
Для любого<p
>парсера и<m
>парсинга сообщения об ошибке,<s
>строки времени компиляции и<pos
>положения источника
change_error_message<p, msg>::apply<s, pos>
<p::apply<s,pos>
>, когда<p
>принимает вход. Это эквивалентно<fail<msg>::apply<s,pos>
>.
#include <boost/metaparse/change_error_message.hpp> #include <boost/metaparse/repeated1.hpp> #include <boost/metaparse/letter.hpp> #include <boost/metaparse/keyword.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_message.hpp> #include <boost/metaparse/define_error.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(name_expected, "Name expected"); using keyword_name = token<keyword<BOOST_METAPARSE_STRING("name")>>; using name_token = token<repeated1<letter>>; using name_parser = last_of<keyword_name, change_error_message<name_token, name_expected>>; static_assert( !is_error< name_parser::apply<BOOST_METAPARSE_STRING("name Bela"), start> >::type::value, "name_parser should accept \"name <a name>\"" ); static_assert( is_error< name_parser::apply<BOOST_METAPARSE_STRING("name ?"), start> >::type::value, "name_parser should reject input when name is a question mark" ); static_assert( std::is_same< get_message< name_parser::apply<BOOST_METAPARSE_STRING("name ?"), start> >::type, name_expected >::type::value, "the error message should be the one specified by change_error_message" );
Метафункция шаблонаподдерживаеткарривание, когда она принимает меньше аргументов, чем обычно ожидает. Когда приведено меньше аргументов, то возвращается класс метафункций шаблона, ожидающий оставшихся аргументов. Ожидается, что этот класс метафункций шаблона также будет поддерживать карри.
Например, предполагается, что дается следующая метафункция:
template <class A, class B> struct plus;
Он принимает два значения, добавляет их и возвращает результат. Например:
static_assert( plus< std::integral_constant<int, 11>, std::integral_constant<int, 2> >::type::value == 13, "This should work" );
Если он поддерживает карри, то должны работать и следующие:
using inc = plus<std::integral_constant<int, 1>>; static_assert( inc::apply<std::integral_constant<int, 12>>::type::value == 13, "This should work" );
Вышеприведенный пример определяет класс метафункции шаблона<inc
>, называя<plus
>только одним аргументом: значениев коробке<1
>.
template <class P, class S> struct debug_parsing_error { debug_parsing_error(); };
Это класс шаблонов.
Возможность отладки ошибок, генерируемых парсером времени компиляции. Индивидуальный класс шаблонов должен быть создан и инициализирован с помощью конструктора по умолчанию. При разборе входной строки с помощью парсера генерируется ошибка, конструктор по умолчанию<debug_parsing_error
>печатает сообщение об ошибке на стандартный вывод во время выполнения и вызывает<exit
>.
![]() |
Note |
---|---|
Также доступны более мощные отладочные утилиты, такие какMetashell. |
#include <boost/metaparse/debug_parsing_error.hpp>
Для любого<p
>парсера времени компиляции и<s
>строки времени компиляции
debug_parsing_error<p, s>()
<s
>, используя<p
>во время компиляции. Во время выполнения конструктор печатает результат разбора до стандартного вывода и вызовов<exit
>.
#include <boost/metaparse/debug_parsing_error.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <type_traits> using namespace boost::metaparse; debug_parsing_error<int_, BOOST_METAPARSE_STRING("not an int")> do_debugging; int main() {}
Запустив скомпилированный исполняемый файл, вы получаете следующее:
Результаты анализа времени компиляции --------------------------- Оригинальное название: Not a Int
Парсинг провалился: линия 1, col 1: Digit ожидаемая
namespace error { struct digit_expected; }
Класс, представляющий ошибку, что цифровой символ ожидался в определенном месте.
#include <boost/metaparse/error/digit_expected.hpp>
struct digit;
Этопарсер.
Парсер принимает одного персонажа в диапазоне<0-9
>. Результатом парсера является принятый характер.
#include <boost/metaparse/digit.hpp>
Следующие эквивалентны:
digit accept_when<one_char, util::is_digit, error::digit_expected>
#include <boost/metaparse/digit.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; static_assert( !is_error<digit::apply<BOOST_METAPARSE_STRING("0"), start>>::type::value, "digit should accept a digit" ); static_assert( is_error<digit::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "digit should reject a character" ); static_assert( get_result< digit::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value == '0', "the result of parsing should be the character value" );
namespace util { template <char D> struct digit_to_int_c; }
Это класс шаблонов, похожий наметафункцию шаблона, но принимающий значение<char
>в качестве аргумента.
Преобразует символ, содержащий значение в диапазоне<['0'..'9']
>, в целое число.
Он возвращаетупакованноецелое значение.
#include <boost/metaparse/util/digit_to_int_c.hpp>
Следующие пары выражений эквивалентны.
digit_to_int_c<'0'>::type boost::mpl::int_<0> digit_to_int_c<'9'>::type boost::mpl::int_<9>
#include <boost/metaparse/util/digit_to_int_c.hpp> using namespace boost::metaparse; static_assert( util::digit_to_int_c<'0'>::type::value == 0, "it should convert a character to the corresponding integer value" ); static_assert( util::digit_to_int_c<'3'>::type::value == 3, "it should convert a character to the corresponding integer value" ); static_assert( util::digit_to_int_c<'9'>::type::value == 9, "it should convert a character to the corresponding integer value" );
namespace util { template <class D> struct digit_to_int; }
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Преобразует упакованный символ, содержащий значение в диапазоне<['0'..'9']
>в целое число.
Он возвращаетупакованноецелое значение.
#include <boost/metaparse/util/digit_to_int.hpp>
Для любого<C
>упакованного значения символа в диапазоне<['0'..'9']
>следующие выражения эквивалентны:
digit_to_int<>::apply<C>::type digit_to_int<C>::type digit_to_int_c<C::type::value>::type
#include <boost/metaparse/util/digit_to_int.hpp> #include <type_traits> using namespace boost::metaparse; struct nullary_metafunction_returning_4 { using type = std::integral_constant<char, '4'>; }; static_assert( util::digit_to_int<std::integral_constant<char, '0'>>::type::value == 0, "it should convert a character to the corresponding integer value" ); static_assert( util::digit_to_int<>::type ::apply<std::integral_constant<char, '7'>>::type::value == 7, "it should support currying" ); static_assert( util::digit_to_int<nullary_metafunction_returning_4>::type::value == 4, "it should support lazy evaluation" );
struct digit_val;
Этопарсер.
Он принимает одного персонажа в диапазоне<0-9
>. Результатом парсера является величина, представленная принятым персонажем.
#include <boost/metaparse/digit_val.hpp>
Следующие эквивалентны:
digit_val transform<digit, util::digit_to_int<>>
#include <boost/metaparse/digit_val.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; static_assert( !is_error<digit_val::apply<BOOST_METAPARSE_STRING("0"), start>>::type::value, "digit_val should accept a digit" ); static_assert( is_error<digit_val::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "digit_val should reject a character" ); static_assert( get_result< digit_val::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value == 0, "the result of parsing should be the int value" );
template <class Result> struct empty;
Этопарсер.
Он принимает только пустой вход. Результатом анализа является аргумент<Result
>.
#include <boost/metaparse/empty.hpp>
Для любого<c
>класса эквивалентны:
empty<c> except<one_char, c, error::end_of_input_expected>
#include <boost/metaparse/empty.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using want_empty = empty<BOOST_METAPARSE_STRING("result")>; static_assert( !is_error<want_empty::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "empty accepts the empty input" ); static_assert( is_error<want_empty::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "empty should reject non-empty input" ); static_assert( std::is_same< get_result<want_empty::apply<BOOST_METAPARSE_STRING(""), start>>::type, BOOST_METAPARSE_STRING("result") >::type::value, "the result of parsing should be the given value" );
namespace error { struct end_of_input_expected; }
Класс, представляющий ошибку, что вход содержит больше символов, чем должен.
#include <boost/metaparse/error/end_of_input_expected.hpp>
template <class P, class Msg = error::end_of_input_expected> struct entire_input;
Он анализирует вход с помощью<P
>и проверяет, потребляет ли он весь вход. Если<P
>терпит неудачу или не потребляет весь вход,<entire_input
>терпит неудачу. В противном случае<entire_input
>возвращает результат<P
>. Когда<P
>не потребляет весь ввод, сообщение об ошибке, возвращенное<entire_input
>, является<Msg
>.
#include <boost/metaparse/entire_input.hpp>
Для любого<p
>парсера и<e
>парсинга сообщение об ошибке эквивалентно:
entire_input<p, e> first_of< p, change_error_message<empty</* some metaprogramming value */>, e> >
#include <boost/metaparse/entire_input.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/get_message.hpp> #include <boost/metaparse/define_error.hpp> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(extra_chars_at_end, "Extra chars at end"); using int_parser = entire_input<int_, extra_chars_at_end>; static_assert( get_result< int_parser::apply<BOOST_METAPARSE_STRING("1113"), start> >::type::value == 1113, "it should parse the input if it contains only an integer" ); static_assert( std::is_same< get_message< int_parser::apply<BOOST_METAPARSE_STRING("1113mm"), start> >::type, extra_chars_at_end >::type::value, "it should return the specified error message when there are extra characters" );
template <class P, class Result, class ErrorMsg> struct except;
<except
>принимает ввод, когда<P
>отвергает его, и результатом разбора является<Result
>аргумент. Когда<P
>принимает ввод,<except
>отвергает его, и причина<ErrorMsg
>.
#include <boost/metaparse/except.hpp>
Для любого<p
>парсера,<c
>класса,<msg
>сообщения об ошибке парсинга,<s
>строки времени компиляции и<pos
>положения источника следующие эквивалентны:
get_result<except<p, c, msg>, s, pos>::type c get_remaining<except<p, c, msg>, s, pos>::type s get_position<except<p, c, msg>, s, pos>::type pos
Когда<p
>отклоняет ввод. Результатом анализатора является ошибка с сообщением об ошибке<msg
>в противном случае.
#include <boost/metaparse/except.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/get_message.hpp> #include <boost/metaparse/define_error.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR( number_is_not_allowed, "numbers are not allowed here" ); using except_int = except<int_, std::integral_constant<int, 1>, number_is_not_allowed>; static_assert( get_result< except_int::apply<BOOST_METAPARSE_STRING("foo"), start> >::type::value == 1, "it should accept the input when it is not an integer" ); static_assert( std::is_same< number_is_not_allowed, get_message<except_int::apply<BOOST_METAPARSE_STRING("13"), start>>::type >::type::value, "it should reject the input when it is an integer" );
namespace error { struct expected_to_fail; }
Класс, представляющий ошибку, что парсер должен был потерпеть неудачу, но не потерпел неудачу.
#include <boost/metaparse/error/expected_to_fail.hpp>
template <class P> struct fail_at_first_char_expected;
Он пытается разобрать вход с помощью<P
>. Когда<P
>отвергает ввод, не потребляя никакого символа,<fail_at_first_char_expected
>принимает ввод. В противном случае (когда<P
>принимает вход или когда он потребляет символы, прежде чем отклонить вход)<fail_at_first_char_expected
>отклоняет вход.
#include <boost/metaparse/fail_at_first_char_expected.hpp>
Для любого<p
>парсера,<s
>струны времени компиляции и<pos
>положения источника:
Если<is_error<p::apply<s,pos>>::type
>является ложным, то это равносильно:
fail_at_first_char_expected<p>::apply<s, pos>::type reject<error::expected_to_fail, pos>
Если<is_error<p::apply<s,pos>>::type
>истинно и<boost::mpl::equal_to<pos,get_position<p::apply<s,pos>>::type>::type
>также истинно, то следующие эквивалентны:
get_remaining<except<p, c, msg>, s, pos>::type accept</* unspecified */, s, pos>
В противном случае эквивалентны следующие:
get_remaining<except<p, c, msg>, s, pos>::type p::apply<s, pos>::type
#include <boost/metaparse/fail_at_first_char_expected.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/foldl_start_with_parser.hpp> #include <boost/metaparse/first_of.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using plus_int = last_of<lit_c<'+'>, int_>; using plus_exp = first_of< foldl_start_with_parser< plus_int, int_, boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type >, fail_at_first_char_expected<plus_int> >; static_assert( get_result< plus_exp::apply<BOOST_METAPARSE_STRING("1+2+3"), start> >::type::value == 6, "it should accept the input when it is a list of '+' separated ints" ); static_assert( is_error< plus_exp::apply<BOOST_METAPARSE_STRING("1+2+3+"), start> >::type::value, "it should reject the input when it has an extra +" );
template <class Msg> struct fail;
Этопарсер.
Парсер отвергает каждый ввод.
#include <boost/metaparse/fail.hpp>
Для любого<msg
>сообщения об ошибке разбора,<s
>строки времени компиляции и<pos
>положения источника
fail<msg>::apply<s, pos>::type
Обратная связь с<msg
>как сообщение об ошибке.
#include <boost/metaparse/fail.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_message.hpp> #include <boost/metaparse/define_error.hpp> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(sample_error, "This is an example parsing error"); using fail_p = fail<sample_error>; static_assert( is_error<fail_p::apply<BOOST_METAPARSE_STRING("foo"), start>>::type::value, "it should reject every input" ); static_assert( std::is_same< get_message<fail_p::apply<BOOST_METAPARSE_STRING("foo"), start>>::type, sample_error >::type::value, "the error message should be the type specified" );
struct fail_tag;
Этобирка.
Это тег значений, возвращаемых парсером, когда парсинг не был успешным.
#include <boost/metaparse/fail_tag.hpp>
template <class P1, /* ... */, class Pn> struct first_of;
<first_of
>применяет<P1
>...<Pn
>парсеры в последовательности. Он принимает ввод, когда все парсеры принимают его. Результатом парсинга является результат первого парсера.
#include <boost/metaparse/first_of.hpp>
Для любых<p1
>, ...<pn
>парсеров
first_of<p1, ..., pn>
является эквивалентным
nth_of_c<0, p1, ..., pn>
#include <boost/metaparse/first_of.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using int_with_semicolon = first_of<int_, lit_c<';'>>; static_assert( is_error< int_with_semicolon::apply<BOOST_METAPARSE_STRING("13"), start> >::type::value, "int without semicolon is rejected" ); static_assert( get_result< int_with_semicolon::apply<BOOST_METAPARSE_STRING("13;"), start> >::type::value, "the result is the result of the first parser" );
template <class P, class State, class ForwardOp> struct foldl1;
<foldl1
>применяется<P
>на входной строке многократно, пока<P
>принимает вход. Результат разбора эквивалентен<boost::mpl::fold<Sequence,State,ForwardOp>
>, где<Sequence
>— последовательность результатов приложений<P
>.
Когда<P
>впервые отвергает вход,<foldl1
>также отвергает его. По крайней мере, одно успешное применение<P
>требуется для<foldl1
>принятия ввода.
#include <boost/metaparse/foldl1.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимая два аргумента, эквивалентны:
foldl1<p, t, f> last_of<look_ahead<p>, foldl<p, t, f>>
#include <boost/metaparse/foldl1.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using int_token = token<int_>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldl1<int_token, boost::mpl::int_<0>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("11 13 3 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "when no numbers are provided, it should be an error" );
template <class P, class State, class ForwardOp> struct foldl_reject_incomplete;
То же самое, что<foldl
>, но как только<P
>отклоняет вход,<foldl_reject_incomplete
>проверяет, потребляет ли<P
>какие-либо символы, прежде чем отклонить вход. Если это так,<foldl_reject_incomplete
>отклоняет ввод с тем же сообщением об ошибке, это последнее приложение<P
>возвращается. В противном случае<foldl_reject_incomplete
>принимает ввод и дает тот же результат, что и<foldl
>.
Вот диаграмма, показывающая, как<foldl_reject_incomplete
>работает на примере:
using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
#include <boost/metaparse/foldl_reject_incomplete.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положения источника
foldl_reject_incomplete<p, t, f>::apply<s, pos>
является эквивалентным
first_of<foldl<p, t, f>, fail_at_first_char_expected<p> >::apply<s, pos>
#include <boost/metaparse/foldl_reject_incomplete.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/int.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldl_reject_incomplete<plus_int, boost::mpl::int_<11>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 + 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 +"), start> >::type::value, "when the last number is missing, it should be an error" );
template <class P, class State, class ForwardOp> struct foldl_reject_incomplete1;
То же самое, что<foldl1
>, но как только<P
>отклоняет вход,<foldl_reject_incomplete1
>проверяет, потребляет ли<P
>какие-либо символы, прежде чем отклонить вход. Если это так,<foldl_reject_incomplete1
>отклоняет ввод с тем же сообщением об ошибке, это последнее приложение<P
>возвращается. В противном случае<foldl_reject_incomplete1
>принимает ввод и дает тот же результат, что и<foldl1
>.
#include <boost/metaparse/foldl_reject_incomplete1.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положения источника
foldl_reject_incomplete1<p, t, f>::apply<s, pos>
является эквивалентным
first_of<foldl1<p, t, f>, fail_at_first_char_expected<p> >::apply<s, pos>
#include <boost/metaparse/foldl_reject_incomplete1.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/int.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldl_reject_incomplete1<plus_int, boost::mpl::int_<11>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 + 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 +"), start> >::type::value, "when the last number is missing, it should be an error" ); static_assert( is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "when no numbers are provided, it should be an error" );
template <class P, class StateP, class ForwardOp> struct foldl_reject_incomplete_start_with_parser;
Table 22.23. Arguments
Имя |
Тип |
---|---|
< |
|
< |
|
< |
класс метафункции шаблонас двумя аргументами |
То же самое, что<foldl_start_with_parser
>, но как только<P
>отклоняет вход,<foldl_reject_incomplete_start_with_parser
>проверяет, потребляет ли<P
>какие-либо символы, прежде чем отклонить вход. Если это так,<foldl_reject_incomplete_start_with_parser
>отклоняет ввод с тем же сообщением об ошибке, это последнее приложение<P
>возвращается. В противном случае<foldl_reject_incomplete_start_with_parser
>принимает вход и дает тот же результат, что и<foldl_start_with_parser
>.
Вот диаграмма, показывающая, как<foldl_reject_incomplete_start_with_parser
>работает на примере:
using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Более подробную информацию можно найти вВведение папки_reject_incomplete_start_with_parserразделаРуководство пользователя.
#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp>
Для любого<p
>парсера,<pt
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положение источника
foldl_reject_incomplete_start_with_parser<p, pt, f>::apply<s, pos>
является эквивалентным
first_of< foldl_start_with_parser<p, pt, f>, fail_at_first_char_expected<p> >::apply<s, pos>
#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldl_reject_incomplete_start_with_parser<plus_int, int_token, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("11 + 13 + 3 + 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error< ints::apply<BOOST_METAPARSE_STRING("11 + 13 + 3 +"), start> >::type::value, "when the last number is missing, it should be an error" );
template <class P, class StateP, class ForwardOp> struct foldl_start_with_parser;
Table 22.24. Arguments
Имя |
Тип |
---|---|
< |
|
< |
|
< |
класс метафункции шаблонас двумя аргументами |
То же самое, что<foldl
>, но перед сворачиванием он применяет парсер<StateP
>на входе. Если это не удается<foldl_start_with_parser
>. Если это удается,<foldl_start_with_parser
>работает как<foldl
>, принимая результат<StateP
>в качестве исходного состояния.
Вот диаграмма, показывающая, как<foldl_start_with_parser
>работает на примере:
using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Более подробную информацию можно найти в. Введение раздела foldl_start_with_parserРуководства пользователя.
#include <boost/metaparse/foldl_start_with_parser.hpp>
Для любого<p
>парсера,<pt
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положение источника
foldl_start_with_parser<p, pt, f>::apply<s, pos>
является эквивалентным
pt::apply<s, pos>
Когда вышеприведенное выражение возвращает ошибку разбора. Это
foldl<p, get_result<pt::apply<s, pos>>::type, f>::apply< get_remaining<pt::apply<s, pos>>::type, get_position<pt::apply<s, pos>>::type >
Иначе.
#include <boost/metaparse/foldl_start_with_parser.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldl_start_with_parser<plus_int, int_token, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("11 + 13 + 3 + 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "when no numbers are provided, it should be an error" );
template <class P, class State, class ForwardOp> struct foldl;
<foldl
>применяется<P
>к входной строке многократно, пока<P
>принимает вход. Результат разбора эквивалентен<boost::mpl::fold<Sequence,State,ForwardOp>
>, где<Sequence
>— последовательность результатов приложений<P
>.
Когда<P
>впервые отклоняет вход,<foldl
>все еще принимает вход, и результат разбора<State
>.
Вот диаграмма, показывающая, как<foldl
>работает на примере:
using int_token = token<int_>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Более подробную информацию можно найти в. Введение в папкуразделаРуководство пользователя.
#include <boost/metaparse/foldl.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положения источника
foldl<p, t, f>::apply<s, pos>
является эквивалентным
return_<t>::apply<s, pos>
Когда<p::apply<s,pos>
>возвращается ошибка. Это
foldl<p, f::apply<t, get_result<p::apply<s, pos>>::type>::type, f>::apply< get_remaining<p::apply<s, pos>>, get_position<p::apply<s, pos>> >
Иначе.
#include <boost/metaparse/foldl.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using int_token = token<int_>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldl<int_token, boost::mpl::int_<0>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("11 13 3 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING(""), start> >::type::value == 0, "the sum of no elements is 0" );
template <class P, class State, class BackwardOp> struct foldr1;
Table 22.26. Arguments
Имя |
Тип |
---|---|
< |
|
< |
|
< |
класс метафункции шаблонас двумя аргументами |
<foldr1
>применяется<P
>к входной строке многократно, пока<P
>принимает вход. Результат разбора эквивалентен<boost::reverse_fold<Sequence,State,BackwardOp>
>, где<Sequence
>— последовательность результатов приложений<P
>.
Когда<P
>впервые отвергает ввод,<foldr1
>также отвергает его. По крайней мере, одно успешное применение<P
>требуется для<foldr1
>принятия ввода.
#include <boost/metaparse/foldr1.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимая два аргумента, эквивалентны:
foldr1<p, t, f> last_of<look_ahead<p>, foldr<p, t, f>>
#include <boost/metaparse/foldr1.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using int_token = token<int_>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldr1<int_token, boost::mpl::int_<0>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("11 13 3 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "when no numbers are provided, it should be an error" );
template <class P, class State, class BackwardOp> struct foldr_reject_incomplete;
Table 22.27. Arguments
Имя |
Тип |
---|---|
< |
|
< |
|
< |
класс метафункции шаблонас двумя аргументами |
То же самое, что<foldr
>, но как только<P
>отклоняет вход,<foldr_reject_incomplete
>проверяет, потребляет ли<P
>какие-либо символы, прежде чем отклонить вход. Если это так,<foldr_reject_incomplete
>отклоняет вход с тем же сообщением об ошибке, что и последнее приложение<P
>. В противном случае<foldr_reject_incomplete
>принимает ввод и дает тот же результат, что и<foldr
>.
Вот диаграмма, показывающая, как<foldr_reject_incomplete
>работает на примере:
using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Обратите внимание, что<foldr_reject_incomplete
>складывается справа налево и поэтому не начинает складываться, пока не достигнет конца последовательности. Поскольку в конце последовательности он находит ошибку, складывания вообще не происходит.
#include <boost/metaparse/foldr_reject_incomplete.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положения источника
foldr_reject_incomplete<p, t, f>::apply<s, pos>
является эквивалентным
first_of<foldr<p, t, f>, fail_at_first_char_expected<p> >::apply<s, pos>
#include <boost/metaparse/foldr_reject_incomplete.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/int.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldr_reject_incomplete<plus_int, boost::mpl::int_<11>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 + 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 +"), start> >::type::value, "when the last number is missing, it should be an error" );
template <class P, class State, class BackwardOp> struct foldr_reject_incomplete1;
Table 22.28. Arguments
Имя |
Тип |
---|---|
< |
|
< |
|
< |
класс метафункции шаблонас двумя аргументами |
То же самое, что<foldr1
>, но как только<P
>отклоняет вход,<foldr_reject_incomplete1
>проверяет, потребляет ли<P
>какие-либо символы, прежде чем отклонить вход. Если это так,<foldr_reject_incomplete1
>отклоняет ввод с тем же сообщением об ошибке, что и это последнее приложение<P
>. В противном случае<foldr_reject_incomplete1
>принимает ввод и дает тот же результат, что и<foldr1
>.
#include <boost/metaparse/foldr_reject_incomplete1.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положения источника
foldr_reject_incomplete1<p, t, f>::apply<s, pos>
является эквивалентным
first_of<foldr1<p, t, f>, fail_at_first_char_expected<p> >::apply<s, pos>
#include <boost/metaparse/foldr_reject_incomplete1.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/int.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldr_reject_incomplete1<plus_int, boost::mpl::int_<11>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 + 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 +"), start> >::type::value, "when the last number is missing, it should be an error" ); static_assert( is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "when no numbers are provided, it should be an error" );
template <class P, class StateP, class BackwardOp> struct foldr_start_with_parser;
Table 22.29. Arguments
Имя |
Тип |
---|---|
< |
|
< |
|
< |
класс метафункции шаблонас двумя аргументами |
То же самое, что<foldr
>, но после складывания он применяет парсер,<StateP
>на входе. Если<StateP
>терпит неудачу,<foldr_start_with_parser
>терпит неудачу. Если это удается, результат разбора эквивалентен<boost::reverse_fold<Sequence,State,BackwardOp>
>, где<Sequence
>- последовательность результатов приложений<P
>и<State
>- результат<StateP
>, возвращенныйпослеповторного применения<P
>на входе.
Вот диаграмма, показывающая, как<foldr_start_with_parser
>работает на примере:
using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using int_plus = first_of<int_token, plus_token>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Более подробную информацию можно найти в. Введение раздела foldr_start_with_parserРуководства пользователя.
#include <boost/metaparse/foldr_start_with_parser.hpp>
Для любого парсера<p
>, класса<pt
>, класса метафункции<f
>, принимающего два аргумента,<s
>струны времени компиляции и<pos
>позиции источника, пусть<pos_
>будет позицией, где повторное применение<p
>на<s
>впервые не удается. Пусть<s_
>будет постфиксом<s
>, начиная с этой позиции.
foldr_start_with_parser<p, pt, f>::apply<s, pos>
является эквивалентным
pt::apply<s_, pos_>
Когда вышеприведенное выражение возвращает ошибку разбора. Это
return_< foldr<p, get_result<pt::apply<s_, pos_>>::type, f>::apply<s, pos> >::apply< get_remaining<pt::apply<s_, pos_>>::type, get_position<pt::apply<s_, pos_>>::type >
Иначе.
#include <boost/metaparse/foldr_start_with_parser.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/first_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using int_plus = first_of<int_token, plus_token>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldr_start_with_parser<int_plus, int_token, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("11 + 13 + 3 + 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "when no numbers are provided, it should be an error" );
template <class P, class State, class BackwardOp> struct foldr;
Table 22.30. Arguments
Имя |
Тип |
---|---|
< |
|
< |
|
< |
класс метафункции шаблонас двумя аргументами |
<foldr
>применяется<P
>к входной строке многократно, пока<P
>принимает вход. Результат разбора эквивалентен<boost::reverse_fold<Sequence,State,BackwardOp>
>, где<Sequence
>— последовательность результатов приложений<P
>.
Когда<P
>впервые отклоняет вход,<foldr
>все еще принимает вход, и результат разбора<State
>.
Вот диаграмма, показывающая, как<foldr
>работает на примере:
using int_token = token<int_>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Более подробную информацию можно найти в. Введение папкиразделаРуководство пользователя.
#include <boost/metaparse/foldr.hpp>
Для любого<p
>парсера,<t
>класса,<f
>класса метафункции, принимающего два аргумента,<s
>струны времени компиляции и<pos
>положения источника
foldr<p, t, f>::apply<s, pos>
является эквивалентным
return_<t>::apply<s, pos>
Когда<p::apply<s,pos>
>возвращается ошибка. Это
f::apply< get_result< foldr<p, t, f>::apply< get_remaining<p::apply<s, pos>>, get_position<p::apply<s, pos>> > >::type, get_result<p::apply<s, pos>>::type >
Иначе.
#include <boost/metaparse/foldr.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/plus.hpp> using namespace boost::metaparse; using int_token = token<int_>; using sum_op = boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; using ints = foldr<int_token, boost::mpl::int_<0>, sum_op>; static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING("11 13 3 21"), start> >::type::value == 48, "ints should sum the numbers" ); static_assert( get_result< ints::apply<BOOST_METAPARSE_STRING(""), start> >::type::value == 0, "the sum of no elements is 0" );
template <class SourcePosition> struct get_col;
Этоленивая шаблонная метафункция.
Возвращает колонку позиции источника.
#include <boost/metaparse/get_col.hpp>
Для любого<l
>,<c
>интегральных значений времени компиляции и<ch
>обернутых символов времени компиляции следующие эквивалентны:
get_col<source_position<l, c, ch>>::type c::type
#include <boost/metaparse/get_col.hpp> #include <boost/metaparse/source_position.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_source_position { using type = source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 0> >; }; static_assert( get_col< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 0> > >::type::value == 13, "It should return the column of a source position" ); static_assert( get_col<returns_source_position>::type::value == 13, "It should support lazy evaluation" );
template <class SourcePosition> struct get_line;
Этоленивая шаблонная метафункция.
Возвращает линию исходной позиции.
#include <boost/metaparse/get_line.hpp>
Для любого<l
>,<c
>интегральных значений времени компиляции и<ch
>обернутых символов времени компиляции следующие эквивалентны:
get_line<source_position<l, c, ch>>::type l::type
#include <boost/metaparse/get_line.hpp> #include <boost/metaparse/source_position.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_source_position { using type = source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 0> >; }; static_assert( get_line< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 0> > >::type::value == 11, "It should return the line of a source position" ); static_assert( get_line<returns_source_position>::type::value == 11, "It should support lazy evaluation" );
template <class E> struct get_message;
Этоленивая шаблонная метафункция.
Возвращает информацию о позиции источника результата разбора.
#include <boost/metaparse/get_message.hpp>
#include <boost/metaparse/get_message.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/reject.hpp> #include <boost/metaparse/define_error.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(sample_error, "Sample error message"); struct returns_reject { using type = reject<sample_error, start>; }; static_assert( std::is_same< sample_error, get_message<reject<sample_error, start>>::type >::type::value, "It should return the message" ); static_assert( std::is_same<sample_error, get_message<returns_reject>::type>::type::value, "It should support lazy evaluation" );
template <class D> struct get_position;
Этоленивая шаблонная метафункция.
Возвращает информацию о позиции источника результата разбора.
#include <boost/metaparse/get_position.hpp>
#include <boost/metaparse/get_position.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/accept.hpp> #include <boost/metaparse/reject.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/define_error.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(sample_error, "Sample error message"); struct returns_reject { using type = reject<sample_error, start>; }; static_assert( std::is_same< start, get_position<reject<sample_error, start>>::type >::type::value, "It should return the position of a reject" ); static_assert( std::is_same< start, get_position< accept<sample_error, BOOST_METAPARSE_STRING("foo"), start> >::type >::type::value, "It should return the position of an accept" ); static_assert( std::is_same<start, get_position<returns_reject>::type>::type::value, "It should support lazy evaluation" );
template <class SourcePosition> struct get_prev_char;
Этоленивая шаблонная метафункция.
Возвращает последний персонаж, с которым была обновлена исходная позиция. Значение, которое он возвращает для<start
>, не определено.
#include <boost/metaparse/get_prev_char.hpp>
Для любого<l
>,<c
>интегральных значений времени компиляции и<ch
>обернутых символов времени компиляции следующие эквивалентны:
get_prev_char<source_position<l, c, ch>>::type ch::type
#include <boost/metaparse/get_prev_char.hpp> #include <boost/metaparse/source_position.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_source_position { using type = source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'x'> >; }; static_assert( get_prev_char< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'x'> > >::type::value == 'x', "It should return the prev. char of a source position" ); static_assert( get_prev_char<returns_source_position>::type::value == 'x', "It should support lazy evaluation" );
template <class D> struct get_remaining;
Этоленивая шаблонная метафункция.
Возвращает информацию о позиции источника результата разбора.
#include <boost/metaparse/get_remaining.hpp>
#include <boost/metaparse/get_remaining.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/accept.hpp> #include <boost/metaparse/string.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_accept { using type = accept< std::integral_constant<int, 13>, BOOST_METAPARSE_STRING("foo"), start >; }; static_assert( std::is_same< BOOST_METAPARSE_STRING("foo"), get_remaining< accept< std::integral_constant<int, 13>, BOOST_METAPARSE_STRING("foo"), start > >::type >::type::value, "It should return the remaining input" ); static_assert( std::is_same< BOOST_METAPARSE_STRING("foo"), get_remaining<returns_accept>::type >::type::value, "It should support lazy evaluation" );
template <class D> struct get_result;
Этоленивая шаблонная метафункция.
Возвращает информацию о позиции источника результата разбора.
#include <boost/metaparse/get_result.hpp>
#include <boost/metaparse/get_result.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/accept.hpp> #include <boost/metaparse/string.hpp> using namespace boost::metaparse; struct returns_accept { using type = accept< std::integral_constant<int, 13>, BOOST_METAPARSE_STRING("foo"), start >; }; static_assert( get_result< accept< std::integral_constant<int, 13>, BOOST_METAPARSE_STRING("foo"), start > >::type::value == 13, "It should return the result of parsing" ); static_assert( get_result<returns_accept>::type::value == 13, "It should support lazy evaluation" );
template <class StartSymbol = BOOST_METAPARSE_STRING("S")> struct grammar { template <class S, class Pos> struct apply; template <class Name, class P> struct import; template <class S, class Action = /* unspecified */> struct rule; };
![]() |
Note |
---|---|
Обратите внимание, что использование этого добавляет значительные накладные расходы на ваши сборки. Когда кто-то использует ваш парсер, компилятор должен будет построить ваш грамматический парсер, использовать его для анализа вашей грамматики и создания парсера, а затем он может анализировать ввод, который пользователь хотел бы проанализировать с вашим парсером. Вы можете рассмотреть возможность использования парсерных комбинаторов, предоставляемых библиотекой. |
Парсерный комбинатор для построения парсеров на основе встроенного DSL, аналогичного EBNF. Его можно использовать следующим образом:
grammar<> // definitions
где определение может быть правилом или командой импорта.
Правила выглядят следующим образом:
::rule<BOOST_METAPARSE_STRING("name ::= def")> ::rule<BOOST_METAPARSE_STRING("name ::= def"), semantic_action>
<name
>состоит из букв, цифр и<_
>символа. Это название определяемого символа.<def
>описывает это правило. Это может быть
\
>можно использовать для побега. Принимаются следующие:<\n
>,<\r
>,<\t
>,<\\
>,<\'
>*
>, что означает повторение, принимающее 0 совпадений+
>, что означает повторение, ожидающее по крайней мере одного совпадения.Правила принимают факультативный аргумент<semantic_action
>. Это выражение лица, принимающего один аргумент. Когда это дано, это используется для преобразования результата правила.
Импорт может быть использован для превращения произвольного парсера в символ, доступный для правил. Определения импорта выглядят следующим образом:
::import<BOOST_METAPARSE_STRING("name"), parser>
<name
>— имя символа,<parser
>— парсер, связывающий имя.
Символ начала грамматики определяется шаблонным аргументом шаблона<grammar
>. Это необязательно, значение по умолчанию<S
>.
#include <boost/metaparse/grammar.hpp>
#define BOOST_METAPARSE_LIMIT_STRING_SIZE 64 #include <boost/metaparse/grammar.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/entire_input.hpp> #include <boost/metaparse/build_parser.hpp> #include <boost/metaparse/string.hpp> #include <boost/mpl/front.hpp> #include <boost/mpl/back.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/lambda.hpp> using boost::metaparse::token; using boost::metaparse::int_; using boost::metaparse::build_parser; using boost::metaparse::entire_input; using boost::metaparse::grammar; using boost::mpl::front; using boost::mpl::back; using boost::mpl::plus; using boost::mpl::fold; using boost::mpl::lambda; using boost::mpl::_1; using boost::mpl::_2; template <class A, class B> struct lazy_plus : boost::mpl::plus<typename A::type, typename B::type> {}; template <class Sequence, class State, class ForwardOp> struct lazy_fold : fold<typename Sequence::type, typename State::type, typename ForwardOp::type> {}; using plus_action = lazy_fold<back<_1>, front<_1>, lambda<lazy_plus<_1, back<_2>>>::type>; using plus_grammar = grammar<BOOST_METAPARSE_STRING("plus_exp")> ::import<BOOST_METAPARSE_STRING("int_token"), token<int_>>::type ::rule<BOOST_METAPARSE_STRING("ws ::= (' ' | '\n' | '\r' | '\t')*")>::type ::rule<BOOST_METAPARSE_STRING("plus_token ::= '+' ws"), front<_1>>::type ::rule<BOOST_METAPARSE_STRING("plus_exp ::= int_token (plus_token int_token)*"), plus_action>::type ; using plus_parser = build_parser<entire_input<plus_grammar>>; static_assert( plus_parser::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type::value == 10, "Arithmetic expression should be evaluated" );
template <class P, class T, class F> struct if_;
<if_
>всегда принимает входную строку. Результатом разбора является<T
>, когда<P
>принимает ввод и<F
>иное.
#include <boost/metaparse/if_.hpp>
Для любого<p
>парсера,<t
>и<f
>классов эквивалентны:
if_<p, t, f> one_of<last_of<p, return_<t>>, return_<f>>
#include <boost/metaparse/if_.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using int11 = std::integral_constant<int, 11>; using int13 = std::integral_constant<int, 13>; static_assert( get_result< if_<int_, int11, int13>::apply<BOOST_METAPARSE_STRING("1234"), start> >::type::value == 11, "When the int_ parser succeeds, the result of parsing should be 11" ); static_assert( get_result< if_<int_, int11, int13>::apply<BOOST_METAPARSE_STRING("foo"), start> >::type::value == 13, "When the int_ parser fails, the result of parsing should be 13" );
namespace error { template <int From, int To, int N> struct index_out_of_range; }
Table 22.39. Arguments
Имя |
Тип |
---|---|
< |
< |
< |
< |
< |
< |
Класс шаблонов, представляющий ошибку индексирования выше или ниже.<From
>и<To
>представляют диапазон, а<N
>является значением за пределами диапазона.
#include <boost/metaparse/error/index_out_of_range.hpp>
namespace util { template <class T, T LowerBound, T UpperBound> struct in_range_c { template <class U> struct apply; }; }
Этошаблонный класс метафункций.
Table 22.40. Arguments
Имя |
Тип |
---|---|
< |
Интегральный тип |
< |
значение типа< |
< |
значение типа< |
< |
Класс метафункций, подтверждающий, что<U
>находится в диапазоне<[LowerBound..UpperBound]
>или нет.
#include <boost/metaparse/util/in_range_c.hpp>
Для любого<T
>интегрального типа,<A
>,<B
>значения типа<T
>и<C
>обернутого значения эквивалентны:
in_range_c<T, A, B>::apply<C>::type::value A <= C::type::value && C::type::value <= B
#include <boost/metaparse/util/in_range_c.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( !util::in_range_c<int, 11, 13> ::apply<std::integral_constant<int, 10>>::type::value, "A value below the lower bound should not be in the range" ); static_assert( !util::in_range_c<int, 11, 13> ::apply<std::integral_constant<int, 14>>::type::value, "A value above the upper bound should not be in the range" ); static_assert( util::in_range_c<int, 11, 13> ::apply<std::integral_constant<int, 11>>::type::value, "The lower bound should be in the range" ); static_assert( util::in_range_c<int, 11, 13> ::apply<std::integral_constant<int, 13>>::type::value, "The upper bound should be in the range" ); static_assert( util::in_range_c<int, 11, 13> ::apply<std::integral_constant<int, 12>>::type::value, "A value between the bounds should be in the range" );
namespace util { template <class LowerBound, class UpperBound, class Item> struct in_range; }
Этошаблонная метафункция, поддерживающаякарриирование.
Он возвращает упакованное булевое значение. Значение<true
>, когда<Item
>находится в диапазоне<[LowerBound..UpperBound]
>и<false
>.<boost::mpl::less_equal
>используется для сравнения.
#include <boost/metaparse/util/in_range.hpp>
Для любых классов<L
>,<U
>и<T
>эквивалентны:
in_range<L, U>::apply<T>::type::value boost::mpl::less_equal<L, T>::type::value && boost::mpl::less_equal<T, U>::type::value
#include <boost/metaparse/util/in_range.hpp> #include <boost/mpl/int.hpp> using namespace boost::metaparse; static_assert( !util::in_range< boost::mpl::int_<11>, boost::mpl::int_<13>, boost::mpl::int_<10> >::type::value, "A value below the lower bound should not be in the range" ); static_assert( !util::in_range< boost::mpl::int_<11>, boost::mpl::int_<13>, boost::mpl::int_<14> >::type::value, "A value above the upper bound should not be in the range" ); static_assert( util::in_range< boost::mpl::int_<11>, boost::mpl::int_<13>, boost::mpl::int_<11> >::type::value, "The lower bound should be in the range" ); static_assert( util::in_range< boost::mpl::int_<11>, boost::mpl::int_<13>, boost::mpl::int_<13> >::type::value, "The upper bound should be in the range" ); static_assert( util::in_range< boost::mpl::int_<11>, boost::mpl::int_<13>, boost::mpl::int_<12> >::type::value, "A value between the bounds should be in the range" ); static_assert( util::in_range<> ::apply<boost::mpl::int_<11>>::type ::apply<boost::mpl::int_<13>>::type ::apply<boost::mpl::int_<12>>::type ::type::value, "It should support currying" );
struct int_;
Этопарсер.
Он принимает непустую последовательность символов в диапазоне<0-9
>. Результатом парсера является десятичное значение, представленное принятой последовательностью символов.
#include <boost/metaparse/int_.hpp>
Следующие эквивалентны:
int_ foldl1< digit_val, boost::mpl::int_<0>, boost::mpl::lambda< boost::mpl::plus< boost::mpl::times<boost::mpl::_2, boost::mpl::int_<10>>, boost::mpl::_1 > >::type >
#include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; static_assert( get_result< int_::apply<BOOST_METAPARSE_STRING("13"), start> >::type::value == 13, "It should parse an integer value" ); static_assert( is_error<int_::apply<BOOST_METAPARSE_STRING("six"), start>>::type::value, "It should reject the input if it is not a number" );
namespace util { template <int C> struct int_to_digit_c; }
Это класс шаблонов, похожий наметафункцию шаблона, но принимающий значение<int
>в качестве аргумента.
Преобразует целое значение в диапазоне<[0-9]
>в символ, представляющий это десятичное значение.
#include <boost/metaparse/util/int_to_digit_c.hpp>
Следующие пары выражений эквивалентны.
int_to_digit_c<0>::type boost::mpl::char_<'0'> int_to_digit<9>::type boost::mpl::char_<'9'>
#include <boost/metaparse/util/int_to_digit_c.hpp> using namespace boost::metaparse; static_assert( util::int_to_digit_c<0>::type::value == '0', "it should convert an integer value to the corresponding character" ); static_assert( util::int_to_digit_c<3>::type::value == '3', "it should convert an integer to the corresponding character" ); static_assert( util::int_to_digit_c<9>::type::value == '9', "it should convert an integer value to the corresponding character" );
namespace util { template <class D> struct int_to_digit; }
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Преобразует упакованное целое число в диапазоне<[0-9]
>в символ, представляющий это десятичное значение.
#include <boost/metaparse/util/int_to_digit.hpp>
Следующие пары выражений эквивалентны.
int_to_digit<boost::mpl::int_<0>>::type boost::mpl::char_<'0'> int_to_digit<boost::mpl::int_<9>>::type boost::mpl::char_<'9'>
#include <boost/metaparse/util/int_to_digit.hpp> #include <type_traits> using namespace boost::metaparse; struct nullary_metafunction_returning_4 { using type = std::integral_constant<int, 4>; }; static_assert( util::int_to_digit<std::integral_constant<int, 0>>::type::value == '0', "it should convert an integer value to the corresponding character" ); static_assert( util::int_to_digit<>::type ::apply<std::integral_constant<int, 7>>::type::value == '7', "it should support currying" ); static_assert( util::int_to_digit<nullary_metafunction_returning_4>::type::value == '4', "it should support lazy evaluation" );
namespace util { template <class C> struct is_digit; }
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Проверяет, является ли<C
>цифрой или нет. Возвращает упакованное булевое значение.
#include <boost/metaparse/util/is_digit.hpp>
Следующие выражения эквивалентны:
is_digit<boost::mpl::char_<'0'>>::type is_digit<>::apply<boost::mpl::char_<'0'>>::type boost::mpl::true_
Также эквивалентны следующие выражения:
is_digit<>::apply<c>::type boost::mpl::false_
#include <boost/metaparse/util/is_digit.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_char { using type = std::integral_constant<char, '0'>; }; static_assert( util::is_digit<std::integral_constant<char, '0'>>::type::value, "digit character should be a digit" ); static_assert( !util::is_digit<std::integral_constant<char, 'x'>>::type::value, "letter should not be a digit" ); static_assert( util::is_digit<>::type::apply<std::integral_constant<char, '0'>>::type::value, "it should support currying" ); static_assert( util::is_digit<returns_char>::type::value, "it should support lazy evaluation" );
template <class C> struct is_error;
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Определяет, является ли<C
>парсинговой ошибкой или нет. Возвращаетупакованноебулевое значение.
#include <boost/metaparse/is_error.hpp>
Для любой ошибки парсинга<e
><is_error<c>::type
>значение обернутого времени компиляции<true
>, для любого другого класса<c
><is_error<c>::type
>является значением обернутого времени компиляции<false
>.
#include <boost/metaparse/is_error.hpp> #include <boost/metaparse/accept.hpp> #include <boost/metaparse/reject.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/define_error.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(sample_error, "Sample error message"); struct returns_reject { typedef reject<sample_error, start> type; }; static_assert( !is_error< accept< std::integral_constant<int, 13>, BOOST_METAPARSE_STRING("foo"), start > >::type::value, "an accept should not be an error" ); static_assert( is_error<reject<sample_error, start>>::type::value, "an reject should be an error" ); static_assert( is_error<>::type::apply<reject<sample_error, start>>::type::value, "it should support currying" ); static_assert( is_error<returns_reject>::type::value, "it should support lazy evaluation" );
namespace util { template <class C> struct is_lcase_letter; }
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Проверяет, является ли<C
>письмом низшего регистра. Возвращает упакованное булевое значение.
#include <boost/metaparse/util/is_lcase_letter.hpp>
Следующие выражения эквивалентны:
is_lcase_letter<>::apply<boost::mpl::char_<'a'>>::type boost::mpl::true_ is_lcase_letter<>::apply<boost::mpl::char_<'z'>>::type boost::mpl::true_ is_lcase_letter<>::apply<c>::type boost::mpl::false_
#include <boost/metaparse/util/is_lcase_letter.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_char { using type = std::integral_constant<char, 'a'>; }; static_assert( util::is_lcase_letter<std::integral_constant<char, 'a'>>::type::value, "a should be a lower case letter" ); static_assert( !util::is_lcase_letter<std::integral_constant<char, 'A'>>::type::value, "A should not be a lower case letter" ); static_assert( util::is_lcase_letter<>::type ::apply<std::integral_constant<char, 'a'>>::type::value, "it should support currying" ); static_assert( util::is_lcase_letter<returns_char>::type::value, "it should support lazy evaluation" );
namespace util { template <class C> struct is_letter; }
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Проверяет, является ли<C
>письмом. Возвращает упакованное булевое значение.
#include <boost/metaparse/util/is_letter.hpp>
Следующие выражения эквивалентны:
is_letter<>::apply<boost::mpl::char_<'a'>>::type boost::mpl::true_ is_letter<>::apply<boost::mpl::char_<'z'>>::type boost::mpl::true_ is_letter<>::apply<boost::mpl::char_<'A'>>::type boost::mpl::true_ is_letter<>::apply<boost::mpl::char_<'Z'>>::type boost::mpl::true_ is_letter<>::apply<c>::type boost::mpl::false_
#include <boost/metaparse/util/is_letter.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_char { using type = std::integral_constant<char, 'A'>; }; static_assert( util::is_letter<std::integral_constant<char, 'A'>>::type::value, "A should be a letter" ); static_assert( !util::is_letter<std::integral_constant<char, '0'>>::type::value, "a number should not be a letter" ); static_assert( util::is_letter<>::type ::apply<std::integral_constant<char, 'A'>>::type::value, "it should support currying" ); static_assert( util::is_letter<returns_char>::type::value, "it should support lazy evaluation" );
namespace util { template <class C> struct is_ucase_letter; }
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Проверяет, является ли<C
>буквой верхнего регистра. Возвращает упакованное булевое значение.
#include <boost/metaparse/util/is_ucase_letter.hpp>
Следующие выражения эквивалентны:
is_ucase_letter<>::apply<boost::mpl::char_<'A'>>::type boost::mpl::true_ is_ucase_letter<>::apply<boost::mpl::char_<'Z'>>::type boost::mpl::true_ is_ucase_letter<>::apply<c>::type boost::mpl::false_
#include <boost/metaparse/util/is_ucase_letter.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_char { using type = std::integral_constant<char, 'A'>; }; static_assert( util::is_ucase_letter<std::integral_constant<char, 'A'>>::type::value, "A should be an upper case letter" ); static_assert( !util::is_ucase_letter<std::integral_constant<char, 'a'>>::type::value, "a should not be an upper case letter" ); static_assert( util::is_ucase_letter<>::type ::apply<std::integral_constant<char, 'A'>>::type::value, "it should support currying" ); static_assert( util::is_ucase_letter<returns_char>::type::value, "it should support lazy evaluation" );
namespace util { template <char C> struct is_whitespace_c; }
Это класс шаблонов, похожий наметафункцию шаблона, но принимающий значение<char
>в качестве аргумента.
Проверяет, является ли<C
>символом белого пространства. Возвращает упакованное булевое значение.
#include <boost/metaparse/util/is_whitespace_c.hpp>
Следующие выражения эквивалентны:
is_whitespace_c<' '>::type boost::mpl::true_ is_whitespace_c<'\t'>::type boost::mpl::true_ is_whitespace_c<'\r'>::type boost::mpl::true_ is_whitespace_c<'\n'>::type boost::mpl::true_
Для любого<c
>символа, кроме перечисленных выше, эквивалентны:
is_whitespace_c<c>::type boost::mpl::false_
#include <boost/metaparse/util/is_whitespace_c.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( util::is_whitespace_c<' '>::type::value, "a space should be a whitespace character" ); static_assert( !util::is_whitespace_c<'0'>::type::value, "a number should not be a whitespace character" );
namespace util { template <class C> struct is_whitespace; }
Этоленивая метафункция шаблона, которая поддерживаеткарриирование.
Проверяет, является ли<C
>символом белого пространства. Возвращает упакованное булевое значение.
#include <boost/metaparse/util/is_whitespace.hpp>
Для любой метафункции шаблона<C
>, возвращающей завернутое значение символа, эквивалентны:
is_whitespace<C>::type is_whitespace<>::type::apply<C>::type is_whitespace_c<C::type::value>::type
#include <boost/metaparse/util/is_whitespace.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_char { using type = std::integral_constant<char, ' '>; }; static_assert( util::is_whitespace<std::integral_constant<char, ' '>>::type::value, "a space should be a whitespace character" ); static_assert( !util::is_whitespace<std::integral_constant<char, '0'>>::type::value, "a number should not be a whitespace character" ); static_assert( util::is_whitespace<>::type ::apply<std::integral_constant<char, '\t'>>::type::value, "it should support currying" ); static_assert( util::is_whitespace<returns_char>::type::value, "it should support lazy evaluation" );
template <class P, int N> struct iterate_c;
Применяется<P
>на входной строке<N
>раз. Результатом разбора является последовательность результатов индивидуальных применений<P
>.<P
>должен принять ввод<N
>раз для<iterate_c
>, чтобы принять его.
#include <boost/metaparse/iterate_c.hpp>
Для любого парсера<p
>целое число<n
>эквивалентно:
iterate_c<p, n> sequence< p, // 1. p, // 2. // ... p // n. >
#include <boost/metaparse/iterate_c.hpp> #include <boost/metaparse/digit.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/char.hpp> using namespace boost::metaparse; static_assert( boost::mpl::equal< boost::mpl::vector< boost::mpl::char_<'1'>, boost::mpl::char_<'2'>, boost::mpl::char_<'3'> >, get_result< iterate_c<digit, 3>::apply<BOOST_METAPARSE_STRING("123"), start> >::type >::type::value, "the result should be the sequence of the individual applications of digit" ); static_assert( boost::mpl::equal< boost::mpl::vector< boost::mpl::char_<'1'>, boost::mpl::char_<'2'>, boost::mpl::char_<'3'> >, get_result< iterate_c<digit, 3>::apply<BOOST_METAPARSE_STRING("1234"), start> >::type >::type::value, "only three iterations should be made" ); static_assert( is_error< iterate_c<digit, 3>::apply<BOOST_METAPARSE_STRING("12"), start> >::type::value, "it should fail when digit can not be applied three times" );
template <class P, class N> struct iterate;
<P
>на входной строке<N
>раз. Результатом разбора является последовательность результатов индивидуальных применений<P
>.<P
>должен принять входное<N
>время для<iterate
>, чтобы принять его.
#include <boost/metaparse/iterate.hpp>
Для любого парсера<p
>,<n
>завернутое целое число эквивалентно:
iterate<p, n> iterate_c<p, n::type::value>
#include <boost/metaparse/iterate.hpp> #include <boost/metaparse/digit.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/char.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( boost::mpl::equal< boost::mpl::vector< boost::mpl::char_<'1'>, boost::mpl::char_<'2'>, boost::mpl::char_<'3'> >, get_result< iterate<digit, std::integral_constant<int, 3>>::apply< BOOST_METAPARSE_STRING("123"), start > >::type >::type::value, "the result should be the sequence of the individual applications of digit" ); static_assert( boost::mpl::equal< boost::mpl::vector< boost::mpl::char_<'1'>, boost::mpl::char_<'2'>, boost::mpl::char_<'3'> >, get_result< iterate<digit, std::integral_constant<int, 3>>::apply< BOOST_METAPARSE_STRING("1234"), start > >::type >::type::value, "only three iterations should be made" ); static_assert( is_error< iterate<digit, std::integral_constant<int, 3>>::apply< BOOST_METAPARSE_STRING("12"), start > >::type::value, "it should fail when digit can not be applied three times" );
template <class S, class ResultType = /* unspecified */> struct keyword;
Этопарсер.
Парсер принимает ключевое слово<S
>. Результатом парсинга является<ResultType
>, что является необязательным; если не дано, результат успешного парсинга не определен.
#include <boost/metaparse/keyword.hpp>
Для любого класса<r
>и<s
>струны времени компиляции, построенной из символов<c1
>...<cn
>, эквивалентны:
keyword<s, r> last_of<lit<c1>, /* ... */, lit<cn>, return_<r>>
#include <boost/metaparse/keyword.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( get_result< keyword<BOOST_METAPARSE_STRING("for"), std::integral_constant<int, 13>> ::apply<BOOST_METAPARSE_STRING("for"), start> >::type::value == 13, "the result of parsing the keyword is keyword's second argument" ); static_assert( is_error< keyword<BOOST_METAPARSE_STRING("for"), std::integral_constant<int, 13>> ::apply<BOOST_METAPARSE_STRING("if"), start> >::type::value, "a word other than the keyword is an error" );
template <class P1, /* ... */, class Pn> struct last_of;
<last_of
>применяет<P1
>...<Pn
>парсеры в последовательности. Он принимает ввод, когда все парсеры принимают его. Результатом парсинга является результат последнего парсера.
#include <boost/metaparse/last_of.hpp>
Для любых<p1
>, ...<pn
>парсеров
first_of<p1, ..., pn>
является эквивалентным
nth_of_c<n, p1, ..., pn>
#include <boost/metaparse/last_of.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using comma_int = last_of<lit_c<','>, int_>; static_assert( is_error<comma_int::apply<BOOST_METAPARSE_STRING("13"), start>>::type::value, "int without comma is rejected" ); static_assert( get_result< comma_int::apply<BOOST_METAPARSE_STRING(",13"), start> >::type::value, "the result is the result of the last parser" );
ленивая метафункция шаблонаявляетсяметафункцией шаблона, которая принимаетнулевую метафункциюв качестве аргументов, которые необходимо сначала оценить, чтобы получить значение аргумента.
Вот, например, метафункция<plus
>для значений<int
>:
template <class A, class B> struct plus : std::integral_constant<int, A::value + B::value> {};
Эта метафункция берет два числав коробкев качестве аргументов, отбрасывает их, добавляет их значения и снова упаковывает результат.
Работает, когда называется с упакованными номерами. Например:
static_assert( plus< std::intgeral_constant<int, 2>, std::integral_constant<int, 2> >::type::value == 4, "This should work" );
Однако, когда он называется с нулевой метафункцией, возвращающей упакованное значение, он ломается:
struct nullary_metafunction_returning_2 { using type = std::integral_constant<int, 2>; }; // Fails to compile plus<nullary_metafunction_returning_2, nullary_metafunction_returning_2>::type
Так<plus
>есть, а не.Ленивая шаблонная метафункция. Чтобы сделать его ленивым, он должен оценить свои аргументы, прежде чем использовать их:
template <class A, class B> struct lazy_plus : std::integral_constant<int, A::type::value + B::type::value> {};
Обратите внимание, что он использует<A::type::value
>и<B::type::value
>вместо<A::value
>и<B::value
>. Он работает, когда он называется с нулевыми метафункциями:
static_assert( plus< nullary_metafunction_returning_2, nullary_metafunction_returning_2 >::type::value == 4, "This should work" );
Поскольку он работает с нулевыми метафункциями в качестве аргументов, это ленивая шаблонная метафункция.
namespace error { struct letter_expected; }
Класс, представляющий ошибку, что буквенный символ ожидался в определенном месте.
#include <boost/metaparse/error/letter_expected.hpp>
struct letter;
Этопарсер.
Парсер принимает одного персонажа в диапазоне<a-z
>или<A-Z
>. Результатом парсера является принятый характер.
#include <boost/metaparse/letter.hpp>
Следующие эквивалентны:
letter accept_when<one_char, util::is_letter<>, error::letter_expected>
#include <boost/metaparse/letter.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; static_assert( !is_error<letter::apply<BOOST_METAPARSE_STRING("a"), start>>::type::value, "letter should accept a letter" ); static_assert( is_error<letter::apply<BOOST_METAPARSE_STRING("0"), start>>::type::value, "letter should reject a digit" ); static_assert( get_result< letter::apply<BOOST_METAPARSE_STRING("z"), start> >::type::value == 'z', "the result of parsing should be the character value" );
template <char C> struct lit;
Этопарсер.
Парсер принимает только характер<C
>. Результатом разбора является принятый характер.
#include <boost/metaparse/lit_c.hpp>
Для любого<c
>символа эквивалентны:
lit_c<c> lit<boost::mpl::char_<c>>
#include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; static_assert( is_error<lit_c<'x'>::apply<BOOST_METAPARSE_STRING("a"), start>>::type::value, "a different character should be an error" ); static_assert( is_error<lit_c<'x'>::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "empty input should be an error" ); static_assert( get_result< lit_c<'x'>::apply<BOOST_METAPARSE_STRING("x"), start> >::type::value == 'x', "result of parsing should be the accepted character" );
namespace error { template <char C> struct literal_expected; }
Класс шаблонов, представляющий ошибку, которую ожидал конкретный буквал.<C
>— буквальный, ожидаемый, но не найденный.
#include <boost/metaparse/error/literal_expected.hpp>
template <class C> struct lit;
Этопарсер.
Парсер принимает только характер<C
>. Результатом разбора является принятый характер.
#include <boost/metaparse/lit.hpp>
Для любого<c
>боксированного персонажа эквивалентны:
lit<c> accept_when< one_char, boost::mpl::lambda<boost::mpl::equal_to<boost::mpl::_1, c>>::type, error::literal_expected<c::type::value> >
#include <boost/metaparse/lit.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( is_error< lit<std::integral_constant<char, 'x'>> ::apply<BOOST_METAPARSE_STRING("a"), start> >::type::value, "a different character should be an error" ); static_assert( is_error< lit<std::integral_constant<char, 'x'>> ::apply<BOOST_METAPARSE_STRING(""), start> >::type::value, "empty input should be an error" ); static_assert( get_result< lit<std::integral_constant<char, 'x'>> ::apply<BOOST_METAPARSE_STRING("x"), start> >::type::value == 'x', "result of parsing should be the accepted character" );
template <class P> struct look_ahead;
Парсирует вход с помощью парсера<P
>. Когда<P
>возвращает ошибку,<look_ahead
>возвращает ошибку. Когда<P
>возвращает результат,<look_ahead
>возвращает результат, не потребляя ничего из входной строки.
#include <boost/metaparse/look_ahead.hpp>
Для любого<p
>парсера,<s
>струны времени компиляции и<pos
>положения источника
look_ahead<p>::apply<s, pos>
является эквивалентным
return_<get_result<p::apply<s, pos>>::type>::apply<s, pos>
Когда<p::apply<s,pos>
>увенчается успехом. Это
p::apply<s, pos>
Иначе.
#include <boost/metaparse/look_ahead.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/get_remaining.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( get_result< look_ahead<int_>::apply<BOOST_METAPARSE_STRING("13"), start> >::type::value == 13, "it should return the same result as the wrapped parser" ); static_assert( std::is_same< BOOST_METAPARSE_STRING("13"), get_remaining< look_ahead<int_>::apply<BOOST_METAPARSE_STRING("13"), start> >::type >::type::value, "it should not consume any input" ); static_assert( is_error< look_ahead<int_>::apply<BOOST_METAPARSE_STRING("six"), start> >::type::value, "it should fail when the wrapped parser fails" );
Класс метафункции шаблонапредставляет собой тип с публичной вложеннойметафункцией шаблонапод названием<apply
>. Поскольку это тип, он может передаваться шаблонным метафункциям в качестве аргументов, а метафункции могут возвращать его в качестве результата. Это позволяет реализоватьметафункции шаблонов более высокого порядка, которые являются метафункциями шаблонов, принимающими метафункции шаблонов в качестве аргументов или возвращающими метафункции шаблонов в качестве их результата.
Например, это класс метафункции шаблона идентичности:
struct identity { template <class T> struct apply { using type = T; }; using type = identity; };
Этот класс метафункций называется<identity
>. Один из них<T
>. Результатом наименования этого класса метафункций является его аргумент<T
>. Обратите внимание, что класс метафункций<identity
>также является значением метапрограммированияшаблона, поэтому он может быть аргументом или результатом метафункции шаблона.
Чтобы назвать эту метафункцию, нужно назвать метафункцию вложенного шаблона. Например:
identity::apply<std::integral_constant<int, 13>>::type
Вышеприведенный пример называет класс метафункции<identity
>с<std::integral_constant<int,13>
>в качестве аргумента.
Метафункция шаблонапредставляет собой функцию над типами, которая оценивается во время компиляции. Он реализуется классом шаблонов.
Аргументы шаблонов этого класса должны быть типами<class
>или<typename
>. Они представляют собой аргументы метафункции.
Случаи класса шаблонов, как ожидается, будут иметь публичный вложенный тип под названием<type
>. Этот тип является типом возвращения метафункции.
Предполагается, что метафункция шаблона будет называтьсязначениями метапрограммирования шаблонатолько в качестве аргументов.
Предполагается, что метафункции шаблонов возвращают значения метапрограммирования шаблонов.
Например, это метафункция шаблона идентичности:
template <class T> struct identity { using type = T; };
Эта метафункция называется<identity
>. Это требует одного аргумента<T
>. Результатом вызова этой метафункции является ее аргумент<T
>.
Чтобы назвать эту метафункцию, нужно создать класс шаблонов. Аргументы шаблона, с которыми он инстанцируется, являются аргументами, с которыми называется метафункция. Например:
identity<std::integral_constant<int, 13>>::type
Приведенный выше пример называет метафункцию<identity
>аргументом<std::integral_constant<int,13>
>.
Значение метапрограммирования шаблонаявляетсянулевой метафункцией шаблона, возвращающейся сама. Например:
struct void_ { using type = void_; };
Это значение метапрограммирования шаблона называется<void_
>. Это нулевая метафункция, возвращающаяся в результате. Из-за этого его можно рассматривать как нулевую метафункцию и оценивать любое количество раз. Например,<void_::type::type::type
>остается<void_
>.
template <class P1, class P2, class P3> struct middle_of;
<middle_of
>применяется<P1
>,<P2
>и<P3
>в последовательности. Он принимает ввод, когда все эти три парсера принимают его. Результатом анализа является результат<P2
>.
#include <boost/metaparse/middle_of.hpp>
Для любых<p1
>,<p2
>и<p3
>парсеров
middle_of<p1, p2, p3>
является эквивалентным
nth_of<1, p1, p2, p3>
#include <boost/metaparse/middle_of.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; using int_token = token<int_>; using left_paren_token = token<lit_c<'('>>; using right_paren_token = token<lit_c<')'>>; using int_in_parens = middle_of<left_paren_token, int_token, right_paren_token>; static_assert( get_result< int_in_parens::apply<BOOST_METAPARSE_STRING("(13)"), start> >::type::value == 13, "it should return the result of the middle parser" ); static_assert( is_error< int_in_parens::apply<BOOST_METAPARSE_STRING("13"), start> >::type::value, "it should reject the input when there are no parens" ); static_assert( is_error< int_in_parens::apply<BOOST_METAPARSE_STRING("(13"), start> >::type::value, "it should reject the input when there is no closing paren" );
template <class SourcePosition, class Ch> struct next_char;
Этоленивая шаблонная метафункция.
Table 22.60. Arguments
Имя |
Тип |
---|---|
< |
|
< |
упакованноезначение символа. Персонаж< |
Возвращает новую исходную позицию, указывая на следующий характер той же линии.
#include <boost/metaparse/next_char.hpp>
Для любого<s
>исходного положения и<c
>завернутого символа следующие эквивалентны:
get_col<next_char<s, c>> boost::mpl::plus<get_col<s>::type, boost::mpl::int_<1>> get_line<next_char<s, c>> get_line<s> get_prev_char<next_char<s, c>>::type c
#include <boost/metaparse/next_char.hpp> #include <boost/metaparse/source_position.hpp> #include <boost/metaparse/get_col.hpp> #include <boost/metaparse/get_line.hpp> #include <boost/metaparse/get_prev_char.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_source_position { using type = source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >; }; struct returns_char { using type = std::integral_constant<char, 'x'>; }; static_assert( get_col< next_char< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >, std::integral_constant<char, 'x'> > >::type::value == 14, "it should increase the column component of the source position" ); static_assert( get_line< next_char< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >, std::integral_constant<char, 'x'> > >::type::value == 11, "it should not increase the line component of the source position" ); static_assert( get_prev_char< next_char< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >, std::integral_constant<char, 'x'> > >::type::value == 'x', "it should update the prev char component of the source position" ); static_assert( get_col<next_char<returns_source_position, returns_char>>::type::value == 14, "it should support lazy evaluation" );
template <class SourcePosition, class Ch> struct next_line;
Этоленивая шаблонная метафункция.
Table 22.61. Arguments
Имя |
Тип |
---|---|
< |
|
< |
упакованноезначение символа. Персонаж< |
Возвращает новую исходную позицию, указывая на начало следующей строки.
#include <boost/metaparse/next_line.hpp>
Для любого<s
>исходного положения и<c
>завернутого символа следующие эквивалентны:
get_col<next_line<s, c>>::type boost::mpl::int_<1> get_line<next_line<s, c>> boost::mpl::plus<get_line<s>::type, boost::mpl::int_<1>> get_prev_char<next_line<s, c>>::type c
#include <boost/metaparse/next_line.hpp> #include <boost/metaparse/source_position.hpp> #include <boost/metaparse/get_col.hpp> #include <boost/metaparse/get_line.hpp> #include <boost/metaparse/get_prev_char.hpp> #include <type_traits> using namespace boost::metaparse; struct returns_source_position { using type = source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >; }; struct returns_char { using type = std::integral_constant<char, '\n'>; }; static_assert( get_col< next_line< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >, std::integral_constant<char, '\n'> > >::type::value == 1, "it should set the column to 1" ); static_assert( get_line< next_line< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >, std::integral_constant<char, '\n'> > >::type::value == 12, "it should increase the line component of the source position" ); static_assert( get_prev_char< next_line< source_position< std::integral_constant<int, 11>, std::integral_constant<int, 13>, std::integral_constant<char, 'a'> >, std::integral_constant<char, '\n'> > >::type::value == '\n', "it should update the prev char component of the source position" ); static_assert( get_col<next_line<returns_source_position, returns_char>>::type::value == 1, "it should support lazy evaluation" );
namespace error { struct none_of_the_expected_cases_found; }
Класс, представляющий ошибку, что ни один из списка парсеров не может разобрать вход.
#include <boost/metaparse/error/none_of_the_expected_cases_found.hpp>
template <int N, class P0, /* ... */, class Pk> struct nth_of_c;
<nth_of_c
>применяет парсеры<P0
>...<Pk
>в последовательности. Он принимает ввод, когда все эти парсеры принимают его. Результатом разбора является результат<N
>.
Максимальное количество принимаемых парсеров<nth_of_c
>может быть определено с помощью макроса<BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
>. Его значение по умолчанию<5
>.
#include <boost/metaparse/nth_of.hpp>
Для любых<p0
>, ...,<pn
>парсеров и<k
>целых чисел, где<0<=
k<
n
>следующие эквивалентны:
nth_of_c<k, p0, ..., pn> transform<sequence<p0, ..., pn>, boost::mpl::at_c<boost::mpl::_1, k>>
#include <boost/metaparse/nth_of_c.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; using int_token = token<int_>; using left_paren_token = token<lit_c<'('>>; using right_paren_token = token<lit_c<')'>>; using int_in_parens = nth_of_c<1, left_paren_token, int_token, right_paren_token>; static_assert( get_result< int_in_parens::apply<BOOST_METAPARSE_STRING("(13)"), start> >::type::value == 13, "it should return the result of the second parser" ); static_assert( is_error< int_in_parens::apply<BOOST_METAPARSE_STRING("13"), start> >::type::value, "it should reject the input when there are no parens" ); static_assert( is_error< int_in_parens::apply<BOOST_METAPARSE_STRING("(13"), start> >::type::value, "it should reject the input when there is no closing paren" );
template <class N, class P0, /* ... */, class Pk> struct nth_of;
<nth_of
>применяет парсеры<P0
>..<Pk
>в последовательности. Он принимает ввод, когда все эти парсеры принимают его. Результатом разбора является результат<N
>.
Максимальное количество принимаемых парсеров<nth_of
>может быть определено макросом<BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
>. Его значение по умолчанию<5
>.
#include <boost/metaparse/nth_of.hpp>
Для любых<p0
>, ...,<pn
>парсеров и<k
>упакованных целых чисел следующие эквивалентны:
nth_of<k, p0, ..., pn> nth_of_c<k::type::value, p0, ..., pn>
#include <boost/metaparse/nth_of.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using int_token = token<int_>; using left_paren_token = token<lit_c<'('>>; using right_paren_token = token<lit_c<')'>>; using int_in_parens = nth_of< std::integral_constant<int, 1>, left_paren_token, int_token, right_paren_token >; static_assert( get_result< int_in_parens::apply<BOOST_METAPARSE_STRING("(13)"), start> >::type::value == 13, "it should return the result of the second parser" ); static_assert( is_error< int_in_parens::apply<BOOST_METAPARSE_STRING("13"), start> >::type::value, "it should reject the input when there are no parens" ); static_assert( is_error< int_in_parens::apply<BOOST_METAPARSE_STRING("(13"), start> >::type::value, "it should reject the input when there is no closing paren" );
нулевой шаблон метафункцииявляетсяшаблон метафункциипринимая 0 аргументов. Это тип с вложенным типом<type
>, который является обратным значением нулевой метафункции. Например:
struct always13 { using type = std::integral_constant<int, 13>; };
Эта метафункция называется 1833. Это нулевая метафункция, потому что она не требует никаких аргументов. Он всегда возвращается (1834).
Чтобы назвать эту метафункцию, нужно получить доступ к ней<::type
>. Например:
always13::type
Вышеприведенный пример называет метафункцию получать<std::integral_constant<int,13>
>.
template <char C1, char C2, /* ... */, char Cn> struct one_char_except_c;
Этопарсер.
<one_char_except_c
>принимает один символ, кроме любого из<C1
>...<Cn
>. Когда вход пуст или начинается с одного из непринятых символов,<one_char_except_c
>отвергает вход. В противном случае он принимает ввод, и результатом разбора является значение символа.
Максимальное количество аргументов шаблона, которое может иметь этот класс, — это значение, к которому расширяется макрос<BOOST_METAPARSE_LIMIT_ONE_CHAR_EXCEPT_SIZE
>. Его значение по умолчанию составляет 10.
#include <boost/metaparse/one_char_except_c.hpp>
Для любой<s
>строки времени компиляции и<c1
>, ...,<cn
>символы являются эквивалентными:
one_char_except_c<c1, ..., cn>::apply<s, pos> boost::metaparse::one_char::apply<s, pos>
Когда<s
>пуст или начинается с иного персонажа, чем<c1
>, ...,<cn
>. В противном случае<one_char_except_c<c1,...,cn>::appl<s,pos>
>возвращает ошибку разбора.
#include <boost/metaparse/one_char_except_c.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/middle_of.hpp> #include <boost/metaparse/repeated.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/char.hpp> #include <boost/mpl/equal.hpp> using namespace boost::metaparse; using string_literal_parser = middle_of<lit_c<'"'>, repeated<one_char_except_c<'"'>>, lit_c<'"'>>; static_assert( boost::mpl::equal< boost::mpl::vector< boost::mpl::char_<'h'>, boost::mpl::char_<'e'>, boost::mpl::char_<'l'>, boost::mpl::char_<'l'>, boost::mpl::char_<'o'> >, get_result< string_literal_parser::apply<BOOST_METAPARSE_STRING("\"hello\""), start> >::type >::type::value, "it should return the content of the string literal" );
template <class C1, class C2, /* ... */, class Cn> struct one_char_except;
Этопарсер.
<one_char_except
>принимает один символ, кроме любого из<C1
>...<Cn
>. Когда вход пуст или начинается с одного из непринятых символов,<one_char_except
>отклоняет вход. В противном случае он принимает ввод, и результатом разбора является значение символа.
Максимальное количество аргументов шаблона, которое может иметь этот класс, — это значение, к которому расширяется макрос<BOOST_METAPARSE_LIMIT_ONE_CHAR_EXCEPT_SIZE
>. Его значение по умолчанию составляет 10.
#include <boost/metaparse/one_char_except.hpp>
Для любых<c1
>, ...,<cn
>упакованных символов следующие эквивалентны:
one_char_except<c1, ..., cn> one_char_except_c<c1::type::value, ..., cn::type::value>
#include <boost/metaparse/one_char_except.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/middle_of.hpp> #include <boost/metaparse/repeated.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/char.hpp> #include <boost/mpl/equal.hpp> #include <type_traits> using namespace boost::metaparse; using string_literal_parser = middle_of< lit_c<'"'>, repeated<one_char_except<std::integral_constant<char, '"'>>>, lit_c<'"'> >; static_assert( boost::mpl::equal< boost::mpl::vector< boost::mpl::char_<'h'>, boost::mpl::char_<'e'>, boost::mpl::char_<'l'>, boost::mpl::char_<'l'>, boost::mpl::char_<'o'> >, get_result< string_literal_parser::apply<BOOST_METAPARSE_STRING("\"hello\""), start> >::type >::type::value, "it should return the content of the string literal" );
struct one_char;
Этопарсер.
<one_char
>Принимает один характер. Результатом разбора является принятый характер. Отказывается от пустого ввода.
#include <boost/metaparse/one_char.hpp>
Для любой<s
>непустой строки времени компиляции и<pos
>позиции источника следующие эквивалентны:
get_result<one_char::apply<s, pos>> boost::mpl::front<s> get_remaining<one_char::apply<s, pos>> boost::mpl::pop_front<s>
Значение<get_position<one_char::apply<s,pos>>
>зависит от первого характера последовательности и значения той, которая была проанализирована до этого (которая хранится в исходном положении).<one_char
>обновляет значения исходной позиции<col
>и<line
>на основе новых линейных символов. Он обнаруживает окончания строк Linux<\n
>, Windows<\r\n
>и Mac<\r
>.
<one_char::apply<BOOST_METAPARSE_STRING(""),
pos>
>возвращает ошибку для каждой позиции источника<pos
>.
#include <boost/metaparse/one_char.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/get_remaining.hpp> #include <boost/metaparse/is_error.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( get_result< one_char::apply<BOOST_METAPARSE_STRING("foo"), start> >::type::value == 'f', "the result of parsing should be the first character of the input" ); static_assert( std::is_same< BOOST_METAPARSE_STRING("oo"), get_remaining<one_char::apply<BOOST_METAPARSE_STRING("foo"), start>>::type >::type::value, "one_char should consume the first character of the input" ); static_assert( is_error<one_char::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "it should return an error for empty input" );
template <long P1, long P2, /* ... */ long Pn> struct one_of_c;
Этопарсер.
Он принимает входы, начинающиеся с любого из символов<P1
>, ...,<Pn
>. Результатом разбора является первый характер ввода.
Максимальное количество символов, которое может быть предоставлено, определяется макросом<BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
>. Его значение по умолчанию<20
>.
#include <boost/metaparse/one_of_c.hpp>
Для любых<c1
>, ...,<cn
>символов
one_of_c<c1, ..., cn>
является эквивалентным
one_of<lit_c<c1>, /* ... */, lit_c<cn>>
#include <boost/metaparse/one_of_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> using namespace boost::metaparse; using whitespace = one_of_c<' ', '\n', '\r', '\t', '\v'>; static_assert( get_result< whitespace::apply<BOOST_METAPARSE_STRING(" "), start> >::type::value == ' ', "the result of parsing should be the first character of the input" ); static_assert( is_error<whitespace::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "it should return an error when the input does not begin with a whitespace" );
template <class P1, class P2, /* ... */, class Pn> struct one_of;
Он принимает ввод, когда любой из<P1
>,<Pn
>парсеры принимают его. Результатом парсинга является результат применения первого парсера, который принимает ввод. Парсеры проверяются по порядку, поэтому в случае неоднозначных грамматик результат парсеризации зависит от порядка парсеров<P1
>...<Pn
>.
Максимальное количество принятых парсеров определяется макросом<BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
>. Его значение по умолчанию<20
>.
#include <boost/metaparse/one_of.hpp>
Для любых<p1
>, ...,<pn
>парсеров,<s
>струн времени компиляции и<pos
>позиции источника
one_of<p1, ..., pn>::apply<s, pos>
является эквивалентным
pk::apply<s, pos>
Когда есть<k
>, что<pi::apply<s,pos>::type
>возвращает ошибку для каждого<i
>в диапазоне<[1..k)
>и<pk::apply<s,pos>::type
>не возвращает ошибку.
Парсерный комбинатор возвращает ошибку, когда ее нет<k
>.
#include <boost/metaparse/one_of.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> using namespace boost::metaparse; using whitespace = one_of<lit_c<' '>, lit_c<'\n'>, lit_c<'\r'>, lit_c<'\t'>, lit_c<'\v'>>; static_assert( get_result< whitespace::apply<BOOST_METAPARSE_STRING(" "), start> >::type::value == ' ', "the result of parsing should be the first character of the input" ); static_assert( is_error<whitespace::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "it should return an error when the input does not begin with a whitespace" );
template <class P, class Default = /* unspecified */> struct optional;
Он пытается разобрать вход с<P
>. Когда<P
>преуспевает, результат разбора является результатом<P
>. В противном случае никакие символы не потребляются, и результатом разбора является<Default
>.
#include <boost/metaparse/optional.hpp>
Для любого<p
>парсераи<d
>шаблона значение метапрограммирования
optional<p, d>
является эквивалентным
one_of<p, return_<d>>
#include <boost/metaparse/optional.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/middle_of.hpp> #include <boost/metaparse/sequence.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/equal_to.hpp> #include <boost/mpl/vector_c.hpp> using namespace boost::metaparse; using complex_number = sequence< // Real int_, // Imaginary optional< middle_of<lit_c<'+'>, int_, lit_c<'i'>>, boost::mpl::int_<0> > > ; static_assert( boost::mpl::equal< boost::mpl::vector_c<int, 1, 0>, get_result< complex_number::apply<BOOST_METAPARSE_STRING("1"), start> >::type, boost::mpl::equal_to<boost::mpl::_, boost::mpl::_> >::type::value, "No imaginary" ); static_assert( boost::mpl::equal< boost::mpl::vector_c<int, 1, 0>, get_result< complex_number::apply<BOOST_METAPARSE_STRING("1+0i"), start> >::type, boost::mpl::equal_to<boost::mpl::_, boost::mpl::_> >::type::value, "0 as imaginary" ); static_assert( boost::mpl::equal< boost::mpl::vector_c<int, 0, 1>, get_result< complex_number::apply<BOOST_METAPARSE_STRING("0+1i"), start> >::type, boost::mpl::equal_to<boost::mpl::_, boost::mpl::_> >::type::value, "Non-null imaginary" );
парсерный комбинаторпредставляет собой парсер, реализованный как класс шаблонов, принимающий один или несколько парсеров в качестве аргументов.
Парсерпредставляет собой класс метафункций шаблона, который принимает следующие аргументы:
string
>Функция парсирует префикс входной строки. Когда анализ будет успешным, он возвращает значение<accept
>. При погрешности парсер возвращает значение<reject
>. Метафункция<is_error
>может быть использована для определения результата анализатора, если он удался или не удался.
Документация часто ссылается нарезультат парсера. Это означает, что парсер принимает ввод и ссылается на то, что<get_result
>возвращает стоимость, возвращенную парсером.
Aпарсинг сообщения об ошибкеявляетсяшаблон метапрограммирования значениес<static
std::stringget_value()
>член функции. Эта функция возвращает распечатанную версию ошибки, которую представляет класс. Например:
struct example_error { using type = example_error; static std::string get_value() { return "This is a formatted example error." } };
Неудачныйпарсервозвращает парсинг сообщений об ошибках как сообщения об ошибках.
Предикат(или унарный предикат) представляет собой класс метафункций шаблона, принимающий один аргумент и возвращающийупакованное значениетипа<bool
>.
Например, следующий предикат проверяет, является ли его аргумент упакованным<char
>значением<x
>:
struct is_x { template <class C> struct apply { static constexpr bool value = (C::value == 'x'); using type = apply; }; using type = is_x; };
template <char From, char To> struct range_c;
Этопарсер.
<range_c
>принимает одного персонажа в диапазоне<[From..To]
>. Результатом парсера является принятый характер.
#include <boost/metaparse/range_c.hpp>
Для любого<A
>,<B
>символы эквивалентны:
range_c<A, B> accept_when< one_char, util::in_range_c<char, A, B>, errors::unexpected_character >
#include <boost/metaparse/range_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> using namespace boost::metaparse; using one_digit = range_c<'0', '9'>; static_assert( !is_error<one_digit::apply<BOOST_METAPARSE_STRING("0"), start>>::type::value, "one_digit should accept a digit" ); static_assert( is_error<one_digit::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "one_digit should reject a value outside of ['0'..'9']" ); static_assert( get_result< one_digit::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value == '0', "the result of parsing should be the character value" );
template <class From, class To> struct range;
Этопарсер.
<range
>принимает одного персонажа в диапазоне<[From..To]
>. Результатом парсера является принятый характер.
#include <boost/metaparse/range.hpp>
Для любых<A
>,<B
>завернутых символов эквивалентны:
range<A, B> accept_when<one_char, util::in_range<A, B>, errors::unexpected_character>
#include <boost/metaparse/range.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using one_digit = range<std::integral_constant<char, '0'>, std::integral_constant<char, '9'>>; static_assert( !is_error<one_digit::apply<BOOST_METAPARSE_STRING("0"), start>>::type::value, "one_digit should accept a digit" ); static_assert( is_error<one_digit::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "one_digit should reject a value outside of ['0'..'9']" ); static_assert( get_result< one_digit::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value == '0', "the result of parsing should be the character value" );
template <class Msg, class Pos> struct reject;
Это значениешаблонного метапрограммирования.
Ценности, представляющие неудавшееся приложение парсера. Он ведет себя как ленивая метафункция шаблона: Когда его оценивают как метафункцию, он возвращается с оцениваемыми аргументами. Смотрите семантику выражения для более подробной информации.
![]() |
Note |
---|---|
Обратите внимание, что для обратной совместимости, когда< |
Для любого значения метапрограммирования шаблона<m
>и позиции источника<p
>эквивалентны:
reject<m, p>::type reject<m, p::type>
#include <boost/metaparse/reject.hpp>
template <class P> struct repeated1;
Он применяется<P
>на входной строке многократно, пока парсер принимает вход. Результатом разбора является последовательность результатов отдельных применений<P
>.
Когда<P
>впервые отвергает вход,<repeated1
>также отвергает его. По крайней мере, одно успешное приложение<P
>требуется для<repeated1
>, чтобы принять ввод.
#include <boost/metaparse/repeated1.hpp>
Для любого<p
>парсера эквивалентны:
repeated1<p> last_of<look_ahead<p>, repeated<p>>
#include <boost/metaparse/repeated1.hpp> #include <boost/metaparse/digit_val.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/int.hpp> using namespace boost::metaparse; using digits = repeated1<digit_val>; static_assert( boost::mpl::equal< get_result<digits::apply<BOOST_METAPARSE_STRING("1234"), start>>::type, boost::mpl::vector< boost::mpl::int_<1>, boost::mpl::int_<2>, boost::mpl::int_<3>, boost::mpl::int_<4> > >::type::value, "the result of parsing should be the list of digit values" ); static_assert( is_error<digits::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "repeated1 should reject the input when it can't parse anything with digit_val" );
template <class P> struct repeated_reject_incomplete1;
То же самое, что<repeated1
>, но как только<P
>отклоняет вход,<repeated_reject_incomplete1
>проверяет, потребляет ли<P
>какие-либо символы, прежде чем отклонить вход. Если это так,<repeated_reject_incomplete1
>отклоняет ввод с тем же сообщением об ошибке, это последнее приложение<P
>возвращается. В противном случае _reject_incomplete<repeated1
>принимает ввод и дает тот же результат, что и<repeated1
>.
#include <boost/metaparse/repeated_reject_incomplete1.hpp>
Для любого<p
>парсера,<s
>струны времени компиляции и<pos
>положения источника
repeated_reject_incomplete1<p>::apply<s, pos>
является эквивалентным
first_of<repeated1<p>, fail_at_first_char_expected<p> >::apply<s, pos>
#include <boost/metaparse/repeated_reject_incomplete1.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/vector_c.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using ints = repeated_reject_incomplete1<plus_int>; static_assert( boost::mpl::equal< boost::mpl::vector_c<int, 13, 3, 21>, get_result< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 + 21"), start> >::type >::type::value, "ints should parse the numbers" ); static_assert( is_error< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 +"), start> >::type::value, "when the last number is missing, it should be an error" ); static_assert( is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, "when no numbers are provided, it should be an error" );
template <class P> struct repeated_reject_incomplete;
То же самое, что<repeated
>, но как только<P
>отклоняет вход,<repeated_reject_incomplete
>проверяет, потребляет ли<P
>какие-либо символы, прежде чем отклонить вход. Если это так,<repeated_reject_incomplete
>отклоняет ввод с тем же сообщением об ошибке, это последнее приложение<P
>возвращается. В противном случае<repeated_reject_incomplete
>принимает вход и дает тот же результат, что и<repeated
>.
Вот диаграмма, показывающая, как<repeated_reject_incomplete
>работает на примере:
using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
#include <boost/metaparse/repeated_reject_incomplete.hpp>
Для любого<p
>парсера,<s
>струны времени компиляции и<pos
>положения источника
repeated_reject_incomplete<p>::apply<s, pos>
является эквивалентным
first_of<repeated<p>, fail_at_first_char_expected<p> >::apply<s, pos>
#include <boost/metaparse/repeated_reject_incomplete.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/vector_c.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using plus_int = last_of<plus_token, int_token>; using ints = repeated_reject_incomplete<plus_int>; static_assert( boost::mpl::equal< boost::mpl::vector_c<int, 13, 3, 21>, get_result< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 + 21"), start> >::type >::type::value, "ints should parse the numbers" ); static_assert( is_error< ints::apply<BOOST_METAPARSE_STRING("+ 13 + 3 +"), start> >::type::value, "when the last number is missing, it should be an error" );
template <class P1, class P2, /* ... */, class Pn> struct repeated_one_of1;
Он применяет<P1
>...<Pn
>парсеры многократно, пока любой из них принимает ввод. В каждой итерации парсеры испробованы в порядке и используется первый, принимающий ввод, поэтому в случае неоднозначных грамматик результат парсеризации зависит от порядка парсеров<P1
>...<Pn
>. Результатом разбора с этимпарсерным комбинаторомявляется последовательность отдельных результатов разбора.
Когда ни один из парсеров<P1
>...<Pn
>не принимает вход в первой итерации,<repeated_one_of1
>отвергает вход.
Максимальное количество принятых парсеров определяется макросом<BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
>. Его значение по умолчанию составляет 20.
#include <boost/metaparse/repeated_one_of1.hpp>
Для любых<p1
>, ...,<pn
>парсеров
repeated_one_of1<p1, /* ... */, pn>
является эквивалентным
repeated1<one_of<p1, /* ... */, pn>>
#include <boost/metaparse/repeated_one_of1.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/char.hpp> using namespace boost::metaparse; using as_and_bs = repeated_one_of1<lit_c<'a'>, lit_c<'b'>>; static_assert( boost::mpl::equal< get_result<as_and_bs::apply<BOOST_METAPARSE_STRING("abaab"), start>>::type, boost::mpl::vector< boost::mpl::char_<'a'>, boost::mpl::char_<'b'>, boost::mpl::char_<'a'>, boost::mpl::char_<'a'>, boost::mpl::char_<'b'> > >::type::value, "the result of parsing should be the list of results" ); static_assert( is_error<as_and_bs::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "repeated_one_of1 should reject the input when it" " can't parse anything with digit_val" );
template <class P1, class P2, /* ... */, class Pn> struct repeated_one_of1;
Он применяет<P1
>...<Pn
>парсеры многократно, пока любой из них принимает ввод. В каждой итерации парсеры испробованы в порядке и используется первый, принимающий ввод, поэтому в случае неоднозначных грамматик результат парсеризации зависит от порядка парсеров<P1
>...<Pn
>. Результатом разбора с этимпарсерным комбинаторомявляется последовательность отдельных результатов разбора.
Когда ни один из парсеров<P1
>...<Pn
>не принимает вход в первой итерации,<repeated_one_of
>принимает вход, и результатом парсинга является пустая последовательность.
Максимальное количество принятых парсеров определяется макросом<BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
>. Его значение по умолчанию составляет 20.
#include <boost/metaparse/repeated_one_of.hpp>
Для любых<p1
>, ...,<pn
>парсеров
repeated_one_of<p1, /* ... */, pn>
является эквивалентным
repeated<one_of<p1, /* ... */, pn>>
#include <boost/metaparse/repeated_one_of.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/char.hpp> using namespace boost::metaparse; using as_and_bs = repeated_one_of<lit_c<'a'>, lit_c<'b'>>; static_assert( boost::mpl::equal< get_result<as_and_bs::apply<BOOST_METAPARSE_STRING("abaab"), start>>::type, boost::mpl::vector< boost::mpl::char_<'a'>, boost::mpl::char_<'b'>, boost::mpl::char_<'a'>, boost::mpl::char_<'a'>, boost::mpl::char_<'b'> > >::type::value, "the result of parsing should be the list of results" ); static_assert( boost::mpl::equal< get_result<as_and_bs::apply<BOOST_METAPARSE_STRING("x"), start>>::type, boost::mpl::vector<> >::type::value, "repeated_one_of should accept the input when it" " can't parse anything with digit_val" );
template <class P> struct repeated;
Он применяется<P
>на входной строке многократно, пока<P
>принимает вход. Результатом разбора является последовательность результатов отдельных применений<P
>.
Когда<P
>отклоняет вход в первый раз,<repeated
>по-прежнему принимает вход, и результатом разбора является пустая последовательность.
Вот диаграмма, показывающая, как<repeated
>работает на примере:
using int_token = token<int_>;
Более подробную информацию можно найти вПовторениеразделРуководство пользователя.
#include <boost/metaparse/repeated.hpp>
Для любого<p
>парсера эквивалентны:
repeated<p> foldl< p, /* unspecified empty sequence */, boost::mpl::push_back<_2, _1> >
#include <boost/metaparse/repeated.hpp> #include <boost/metaparse/digit_val.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/int.hpp> using namespace boost::metaparse; using digits = repeated<digit_val>; static_assert( boost::mpl::equal< get_result<digits::apply<BOOST_METAPARSE_STRING("1234"), start>>::type, boost::mpl::vector< boost::mpl::int_<1>, boost::mpl::int_<2>, boost::mpl::int_<3>, boost::mpl::int_<4> > >::type::value, "the result of parsing should be the list of digit values" ); static_assert( boost::mpl::equal< get_result<digits::apply<BOOST_METAPARSE_STRING("x"), start>>::type, boost::mpl::vector<> >::type::value, "repeated should accept the input when it can't parse anything with digit_val" );
template <class C> struct return_;
Этопарсер.
<return_
>принимает каждый вход. Результатом разбора является<C
>, оставшаяся строка является входной строкой.
#include <boost/metaparse/return_.hpp>
Для любого класса<c
>,<s
>строки времени компиляции и<pos
>положения источника следующие эквивалентны:
get_result<return_<c>::apply<s, pos>>::type c get_remaining<return_<c>::apply<s, pos>>::type s get_position<return_<c>::apply<s, pos>>::type pos
#include <boost/metaparse/return_.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/one_of.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <type_traits> using namespace boost::metaparse; using default_value = std::integral_constant<int, 13>; using optional_number = one_of<int_, return_<default_value>>; static_assert( get_result< optional_number::apply<BOOST_METAPARSE_STRING("11"), start> >::type::value == 11, "when a number is provided, it is the result of parsing" ); static_assert( get_result< optional_number::apply<BOOST_METAPARSE_STRING(""), start> >::type::value == 13, "when no number is provided, the default value is the result of parsing" );
template <class P1, /* ... */, class Pn> struct sequence;
<sequence
>применяет<P1
>, ...,<Pn
>парсеры последовательно на входе. Он принимает ввод, когда все эти парсеры принимают его. Результатом разбора является последовательность результатов парсеров.
Максимальное количество принимаемых парсеров<sequence
>может быть определено с помощью макроса<BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
>. Его значение по умолчанию<5
>.
#include <boost/metaparse/sequence.hpp>
Для любых<n>
0
>,<p0
>, ...,<pn
>парсеров результат<sequence<p0,...,p1>
>представляет собой последовательность результатов парсеров, применяемых друг за другом в порядке на входной строке, когда ни один из них не возвращает ошибку. Оставшаяся строка — это оставшаяся строка, возвращаемая последним парсером.
Когда один из парсеров возвращает ошибку, комбинатор возвращает эту ошибку.
#include <boost/metaparse/sequence.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/mpl/at.hpp> using namespace boost::metaparse; using int_token = token<int_>; using plus_token = token<lit_c<'+'>>; using a_plus_b = sequence<int_token, plus_token, int_token>; static_assert( boost::mpl::at_c< get_result<a_plus_b::apply<BOOST_METAPARSE_STRING("1 + 2"), start>>::type, 0 >::type::value == 1, "the first element of the sequence should be the first number" ); static_assert( boost::mpl::at_c< get_result<a_plus_b::apply<BOOST_METAPARSE_STRING("1 + 2"), start>>::type, 1 >::type::value == '+', "the second element of the sequence should be the plus" ); static_assert( boost::mpl::at_c< get_result<a_plus_b::apply<BOOST_METAPARSE_STRING("1 + 2"), start>>::type, 2 >::type::value == 2, "the third element of the sequence should be the second number" ); static_assert( is_error<a_plus_b::apply<BOOST_METAPARSE_STRING("1 +"), start>>::type::value, "when not all of the parsers accept the input, sequence should fail" );
template <template <class, ..., class> class T, class P1, ..., class Pn> struct sequence_applyn;
Он применяет<P1
>...<Pn
>парсерна входе в порядке. Когда все они преуспевают, результатом разбора с<sequence_applyn
>является<T
>класс шаблонов, инстанцированный с результатами<P1
>...<Pn
>парсерs. Когда любой из<P1
>...<Pn
>парсеротклоняет вход, ошибка распространяется.
<n
>должен быть в диапазоне<[1..BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE)
>.
#include <boost/metaparse/sequence_apply.hpp>
Для любого<n>
0
>,<p1
>...<pn
>парсераs,<t
>класса шаблонов с<n
><class
>аргументами,<s
>строкой времени компиляции и<pos
>положением источника эквивалентны:
sequence_apply<t, p1, ..., pn>::apply<s, pos>::type
Когда<sequence
><<p1,...,pn>
>принимает ввод:
return_< t< mpl::at_c<0, get_result<sequence<p1,...,pn>::apply<s, pos>>::type>::type, ... mpl::at_c<n, get_result<sequence<p1,...,pn>::apply<s, pos>>::type>::type, > >::apply<s, pos>::type
когда<sequence
><<p1,...,pn>
>отклоняет ввод:
sequence<p1, ..., pn>::apply<s, pos>::type
#include <boost/metaparse/sequence_apply.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/middle_of.hpp> #include <boost/metaparse/lit_c.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/type_traits/is_same.hpp> using namespace boost::metaparse; template <int Real, int Imaginary> struct complex_c { typedef complex_c type; }; template <class Real, class Imaginary> struct complex : complex_c<Real::type::value, Imaginary::type::value> {}; typedef sequence_apply2<complex, int_, middle_of<lit_c<'+'>, int_, lit_c<'i'>>> complex_parser; static_assert( boost::is_same< complex_c<1, 2>, get_result< complex_parser::apply<BOOST_METAPARSE_STRING("1+2i"), start> >::type::type >::type::value, "the result of parsing should be the list of digit values" );
template <class Line, class Col, class PrevChar> struct source_position;
Это значениешаблонного метапрограммирования.
Table 22.81. Arguments
Имя |
Тип |
---|---|
< |
упакованноецелое число |
< |
упакованноецелое число |
< |
упакованноезначение символа |
Структура данных по времени компиляции, описывающая положение входного текста.
Значения этой структуры данных хранят последний символ, который был разобран до достижения позиции входа, описанного значением<source_position
>.
Его имя<source_position_tag
>.
Начало входного текста представлено<start
>.
#include <boost/metaparse/source_position.hpp>
Для любых<l
>,<c
>интегральных значений, упакованных во времени компиляции, и<p
>значений символов, упакованных во времени компиляции, следующие значения эквивалентны:
get_col<source_position<l, c, p>>::type c::type get_line<source_position<l, c, p>>::type l::type get_prev_char<source_position<l, c, p>>::type p::type
boost::mpl::equal_to
>boost::mpl::greater
>boost::mpl::greater_equal
>boost::mpl::less
>boost::mpl::less_equal
>boost::mpl::not_equal_to
>get_col
>get_line
>get_prev_char
>next_char
>next_line
>struct source_position_tag;
Этобирка.
Это тег значений<source_position
>.
#include <boost/metaparse/source_position_tag.hpp>
struct space;
Этопарсер.
<space
>принимает один белый пространственный характер. Результатом парсинга является парсированный характер.
#include <boost/metaparse/space.hpp>
Следующие эквивалентны:
space accept_when<one_char, util::is_whitespace<>, errors::whitespace_expected>
#include <boost/metaparse/space.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_remaining.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( std::is_same< BOOST_METAPARSE_STRING(" foo"), get_remaining<space::apply<BOOST_METAPARSE_STRING(" foo"), start>>::type >::type::value, "it should consume the first space of the input" ); static_assert( is_error<space::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "it should return an error when the input does not begin with a whitespace" );
struct spaces;
Этопарсер.
<spaces
>принимает любое количество символов белого пространства. Требуется хотя бы одно присутствие.
#include <boost/metaparse/spaces.hpp>
spaces
является эквивалентным
repeated1<space>
#include <boost/metaparse/spaces.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_remaining.hpp> #include <type_traits> using namespace boost::metaparse; static_assert( std::is_same< BOOST_METAPARSE_STRING("foo"), get_remaining<spaces::apply<BOOST_METAPARSE_STRING(" foo"), start>>::type >::type::value, "it should consume all whitespaces at the beginning of the input" ); static_assert( is_error<spaces::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "it should return an error when the input does not begin with a whitespace" );
struct start;
Этошаблонное метапрограммное значениетипаисходное положение.
Он представляет собой начало входного текста.
#include <boost/metaparse/start.hpp>
template <char C1, ..., char Cn> struct string;
Это значениешаблонного метапрограммирования.
Структура данных по времени компиляции, описывающая струнный объект. Эти струнные объекты совместимы с<boost::mpl::string
>, но в качестве аргументов они принимают только отдельные символы. Когда<constexpr
>доступен, они могут быть построены с использованием макроса<BOOST_METAPARSE_STRING
>.
Надпись гласит: «<string_tag
>».
C++98: Максимальная длина этих строк контролируется макросом<BOOST_METAPARSE_LIMIT_STRING_SIZE
>.
C++11: Струны используют вариадные шаблоны.
#include <boost/metaparse/string.hpp>
#include <boost/metaparse/string.hpp> #include <type_traits> using namespace boost::metaparse; using hello1 = string<'H','e','l','l','o'>; using hello2 = BOOST_METAPARSE_STRING("Hello"); static_assert( std::is_same< string<'H', 'e', 'l', 'l', 'o'>, BOOST_METAPARSE_STRING("Hello") >::type::value, "The type generated by the macro should be identical to the hand-crafted one." );
struct string_tag;
Этобирка.
Это тег значений<string
>.
#include <boost/metaparse/string_tag.hpp>
Тегпредставляет собойшаблонное значение метапрограммирования, используемое для идентификации групп значений.
template <class P> struct token;
<token
>парсирует вход, используя<P
>, когда это удается,<token
>потребляет все белые пространства после этого. Результатом анализа является результат<P
>.
#include <boost/metaparse/token.hpp>
Для любого<p
>парсера эквивалентны:
token<p> first_of<p, spaces>
#include <boost/metaparse/token.hpp> #include <boost/metaparse/int_.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/get_remaining.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/string.hpp> #include <type_traits> using namespace boost::metaparse; using int_token = token<int_>; static_assert( get_result< int_token::apply<BOOST_METAPARSE_STRING("13 "), start> >::type::value, "the result of int_token is the number" ); static_assert( std::is_same< BOOST_METAPARSE_STRING(""), get_remaining<int_token::apply<BOOST_METAPARSE_STRING("13 "), start>>::type >::type::value, "token consumes whitespaces after the number" ); static_assert( get_result< int_token::apply<BOOST_METAPARSE_STRING("13"), start> >::type::value, "whitespaces after the number are optional" ); static_assert( is_error<int_token::apply<BOOST_METAPARSE_STRING("foo"), start>>::type::value, "when there is no number, token fails" );
template <class P, class F> struct transform_error_message;
Сравнение с<P
>. Когда это удастся, результат разбора с<transform_error_message
>будет результатом разбора с<P
>. Когда он не удается, ошибка<P
>возвращается к абоненту<transform_error_message
>, но сообщение о ней преобразуется с<F
>.
#include <boost/metaparse/transform_error_message.hpp>
Для любого<p
>парсера и<f
>класса метафункций, принимающего один аргумент
transform_error_message<p, f>::apply<s, pos>
<p::apply<s,pos>
>, когда<p
>принимает вход. Это равносильно<reject<f::apply<get_message<p::apply<s,pos>>::type>,get_position<p::apply<s,pos>>>
>.
#include <boost/metaparse/transform_error_message.hpp> #include <boost/metaparse/repeated1.hpp> #include <boost/metaparse/letter.hpp> #include <boost/metaparse/keyword.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_message.hpp> #include <boost/metaparse/define_error.hpp> #include <boost/metaparse/reject.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(name_expected, "Name expected"); struct return_name_expected { typedef return_name_expected type; template <class> struct apply : name_expected {}; }; using keyword_name = token<keyword<BOOST_METAPARSE_STRING("name")>>; using name_token = token<repeated1<letter>>; using name_parser = last_of< keyword_name, transform_error_message<name_token, return_name_expected> >; static_assert( !is_error< name_parser::apply<BOOST_METAPARSE_STRING("name Bela"), start> >::type::value, "name_parser should accept \"name <a name>\"" ); static_assert( is_error< name_parser::apply<BOOST_METAPARSE_STRING("name ?"), start> >::type::value, "name_parser should reject input when name is a question mark" ); static_assert( std::is_same< get_message< name_parser::apply<BOOST_METAPARSE_STRING("name ?"), start> >::type, name_expected >::type::value, "the error message should be the one specified by change_error_message" );
template <class P, class F> struct transform_error;
Он сравнится с<P
>. Когда это удастся, результат разбора с<transform_error
>будет результатом разбора с<P
>. В случае неудачи<F
>оценивается с ошибкой<P
>, возвращенной в качестве аргумента. Сравнение с<transform_error
>не удастся, и ошибка будет то, что<F
>возвращается. Поэтому<F
>, как ожидается, примет и вернет<reject
>значение.
#include <boost/metaparse/transform_error.hpp>
Для любого<p
>парсера и<f
>класса метафункций, принимающего один аргумент
transform_error<p, f>::apply<s, pos>
<p::apply<s,pos>
>, когда<p
>принимает вход. Это равносильно<f::apply<p::apply<s,pos>::type>
>.
#include <boost/metaparse/transform_error.hpp> #include <boost/metaparse/repeated1.hpp> #include <boost/metaparse/letter.hpp> #include <boost/metaparse/keyword.hpp> #include <boost/metaparse/last_of.hpp> #include <boost/metaparse/token.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/get_message.hpp> #include <boost/metaparse/get_position.hpp> #include <boost/metaparse/define_error.hpp> #include <boost/metaparse/reject.hpp> #include <boost/mpl/lambda.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(name_expected, "Name expected"); using keyword_name = token<keyword<BOOST_METAPARSE_STRING("name")>>; using name_token = token<repeated1<letter>>; using name_parser = last_of< keyword_name, transform_error< name_token, boost::mpl::lambda< reject<name_expected, get_position<boost::mpl::_1> > >::type > >; static_assert( !is_error< name_parser::apply<BOOST_METAPARSE_STRING("name Bela"), start> >::type::value, "name_parser should accept \"name <a name>\"" ); static_assert( is_error< name_parser::apply<BOOST_METAPARSE_STRING("name ?"), start> >::type::value, "name_parser should reject input when name is a question mark" ); static_assert( std::is_same< get_message< name_parser::apply<BOOST_METAPARSE_STRING("name ?"), start> >::type, name_expected >::type::value, "the error message should be the one specified by change_error_message" );
template <class P, class T> struct transform;
<transform
>анализирует вход с использованием<P
>и преобразует результат<P
>возвращается с<T
>. Результатом разбора является то, что<T
>возвращается. Когда<P
>терпит неудачу, неудача возвращается неизменной.
#include <boost/metaparse/transform.hpp>
Для любого<p
>парсера,<t
>класса метафункций, принимающего один аргумент,<s
>струны времени компиляции и<pos
>позиции источника
get_result<transform<p, t>::apply<s, pos>>::type
является эквивалентным
t::apply<get_result<p::apply<s, pos>>::type>::type
Когда<p::apply<s,pos>
>не возвращает ошибку. Комбинатор возвращает ошибку.
#include <boost/metaparse/transform.hpp> #include <boost/metaparse/digit.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/is_error.hpp> #include <boost/metaparse/get_result.hpp> #include <boost/metaparse/util/digit_to_int.hpp> using namespace boost::metaparse; using digit_value = transform<digit, util::digit_to_int<>>; static_assert( !is_error< digit_value::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value, "digit_val should accept a digit" ); static_assert( is_error<digit_value::apply<BOOST_METAPARSE_STRING("x"), start>>::type::value, "digit_val should reject a character" ); static_assert( get_result< digit_value::apply<BOOST_METAPARSE_STRING("0"), start> >::type::value == 0, "the result of parsing should be the int value" );
namespace error { struct unexpected_character; }
Класс, представляющий ошибку, которую ожидал другой персонаж, чем то, что было найдено в определенном месте.
#include <boost/metaparse/error/unexpected_character.hpp>
namespace error { struct unexpected_end_of_input; }
Класс, представляющий ошибку, что конец ввода был достигнут, в то время как он должен содержать дополнительные символы.
#include <boost/metaparse/error/unexpected_end_of_input.hpp>
template <class T, class NotErrorCase> struct unless_error;
Этоленивая шаблонная метафункция.
Проверяет, является ли<T
>парсинговой ошибкой или нет. Если это так, то результат<T
>. Если это не так, то результат<NotErrorCase
>.
#include <boost/metaparse/unless_error.hpp>
Для любых<t
>и<c
>классов эквивалентны:
unless_error<t, c> boost::mpl::if_<is_error<t::type>::type, t, c>
#include <boost/metaparse/unless_error.hpp> #include <boost/metaparse/accept.hpp> #include <boost/metaparse/reject.hpp> #include <boost/metaparse/start.hpp> #include <boost/metaparse/string.hpp> #include <boost/metaparse/define_error.hpp> #include <type_traits> using namespace boost::metaparse; BOOST_METAPARSE_DEFINE_ERROR(sample_error, "Sample error message"); using accept1 = accept<std::integral_constant<int, 11>, BOOST_METAPARSE_STRING("foo"), start>; using accept2 = accept<std::integral_constant<int, 13>, BOOST_METAPARSE_STRING("bar"), start>; using reject1 = reject<sample_error, start>; struct returns_accept1 { using type = accept1; }; struct returns_accept2 { using type = accept2; }; static_assert( std::is_same<accept2, unless_error<accept1, accept2>::type>::type::value, "it returns the second argument when the first argument is an accept" ); static_assert( std::is_same<reject1, unless_error<reject1, accept2>::type>::type::value, "it returns the first argument when that is a reject" ); static_assert( std::is_same< accept2, unless_error<returns_accept1, returns_accept2>::type >::type::value, "it supports lazy evaluation" );
namespace error { template <int Line, int Col, class Msg = boost::mpl::na> struct unpaired; }
Класс шаблонов, представляющий ошибку, что закрывающий элемент "открывающий элемент...закрывающий элемент"структура отсутствует. (например, отсутствует закрывающий парен).<Line
>и<Col
>указывают на началооткрывающий элемент(например, открывающий парен).<Msg
>— сообщение об ошибке, которое парсер пытается разобрать.Закрывающий элементвышел из строя.
Он поддерживает карривание:<unpaired<Line,Col>
>являетсяклассом метафункций шаблона, принимая один аргумент: элемент<Msg
>и возвращая соответствующее<unpaired
>значение.
#include <boost/metaparse/error/unpaired.hpp>
namespace error { struct whitespace_expected; }
Класс, представляющий ошибку, что символ белого пространства ожидался в определенном месте.
#include <boost/metaparse/error/whitespace_expected.hpp>
Статья Reference раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 22. Boost.Metaparse может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Chapter 22. Boost.Metaparse ::
реклама |