...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
See the Repetition section of the User Manual for a detailed comparison of the most common repetition combinators.
Cheat-sheet
for choosing among the fold*
parsers.
Metaparse uses a number of general purpose metafunctions and metafunction classes.
template <class Result, class Remaining, class Pos> struct accept;
This is a template metaprogramming value.
Values representing a successful parser application. It behaves as a lazy template metafunction: when it is evaluated as a metafunction, it returns itself with its arguments evaluated. See expression semantics for further details.
Note | |
---|---|
Note that for backward compatibility when |
For any r
template metaprogramming
value, s
compile-time string
and p
source position the
following are equivalent:
accept<r, s, p>::type accept<r, s::type, p::type>
#include <boost/metaparse/accept.hpp>
struct accept_tag;
This is a tag.
This is the tag of the values returned by a parser when parsing was successful.
#include <boost/metaparse/accept_tag.hpp>
template <class P, class Pred, class Msg> struct accept_when;
This is a parser combinator.
It parses the input with P
.
When P
rejects the input,
accept_when
rejects it
as well. When P
accepts
it, accept_when
evaluates
Pred
with the result of
parsing the input with P
.
When Pred
returns true
, accept_when
accepts the input and the result of parsing will be what P
returned. Otherwise accept_when
rejects the input and Msg
is used as the error reason.
#include <boost/metaparse/accept_when.hpp>
For any p
parser, pred
predicate, msg
parsing error message, s
compile-time string and pos
source position
accept_when<p, pred, msg>i::apply<s, pos>::type
is equivalent to
p::apply<s, pos>::type
when p::apply<s, pos>
doesn't return an error and pred::apply<get_result<p::apply<s, pos>>>::type
is true
. Otherwise it is equivalent
to
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;
This is a parser.
It accepts one character in the range a-z
,
A-Z
or 0-9
. The result
of the parser is the accepted character.
#include <boost/metaparse/alphanum.hpp>
The following are equivalent:
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;
This is a parser combinator.
It accepts inputs beginning with the C
character. It consumes that character and the result of parsing is T
. Other inputs as rejected.
#include <boost/metaparse/always_c.hpp>
For any c
character and
t
class the following are
equivalent:
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;
This is a parser combinator.
It accepts an input if and only if P
accepts it, but the result of parsing will be T
instead of the result P
returned.
#include <boost/metaparse/always.hpp>
For any p
parser and t
class the following are equivalent:
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
This is a macro.
Macro for defining a parsing error
message class. name
is the name of the class representing the error message and msg
is a string literal containing the
description of the error.
#include <boost/metaparse/define_error.hpp>
For any n
name and m
string literal, given the following
is defined:
BOOST_METAPARSE_DEFINE_ERROR(n, m);
the following pairs of expressions are equivalent:
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
This is a macro.
Macro for defining string
values. s
is expected to
be a string literal. The macro requires C++11.
The maximal length of the string is limited. This limit is defined by the
BOOST_METAPARSE_LIMIT_STRING_SIZE
macro.
On platforms where BOOST_METAPARSE_STRING
is not supported, the string.hpp
header defines the BOOST_METAPARSE_V1_CONFIG_NO_BOOST_METAPARSE_STRING
macro. Defining this macro before including the header disables the BOOST_METAPARSE_STRING
macro.
The upper limit for the maximum length, which can be used is 2048. The
implementation of the BOOST_METAPARSE_STRING
macro is generated using tools/string_headers.py
and
can be regenerated to extend this upper limit. Note that for Oracle Developer
Studio the string length limit is 127.
Metaparse supports changing the string length limit within a compilation
unit. To change the length limit, redefine the BOOST_METAPARSE_LIMIT_STRING_SIZE
macro.
You can find benchmarks of this macro here.
#include <boost/metaparse/string.hpp>
The semantics of this macro is demonstrated by an example. The following
BOOST_METAPARSE_STRING("hello")
is equivalent to
string<'h','e','l','l','o'>
#define BOOST_METAPARSE_LIMIT_STRING_SIZE 8 #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." ); #undef BOOST_METAPARSE_LIMIT_STRING_SIZE #define BOOST_METAPARSE_LIMIT_STRING_SIZE 32 static_assert( std::is_same< string< 'A', ' ', 'l', 'o', 'n', 'g', 'e', 'r', ' ', 's', 't', 'r', 'i', 'n', 'g' >, BOOST_METAPARSE_STRING("A longer string") >::type::value, "The type generated by the macro should be identical to the hand-crafted one." );
#define BOOST_METAPARSE_VERSION \\ unspecified
This is a macro.
Macro containing the version number of Boost.Metaparse.
#include <boost/metaparse/version.hpp>
It has major, minor and release components:
major == BOOST_METAPARSE_VERSION / 10000000 minor == (BOOST_METAPARSE_VERSION % 10000000) / 100000 release == BOOST_METAPARSE_VERSION % 100000
A boxed value is a type representing a constant value.
It has a public static const
or constexpr
member called
value
. The class represents
that value as a type, so it can be manipulated by template
metafunctions. It has to be a template
metaprogramming value.
For example the following struct
represents the true
value
of type bool
:
struct true_type { static constexpr bool value = true; using type = true_type; };
The value
member is the
wrapped value. true_type::type
is an alias of true_type
which makes it a template metaprogramming value.
template <class P> struct build_parser;
This is a template metafunction.
It generates a simple interface for parser. It returns a metafunction class
that takes an input string, parses it with P
and returns the result of parsing. It generates a compilation error when
parsing fails.
It returns a template metafunction class:
struct { template <class S> struct apply; };
#include <boost/metaparse/build_parser.hpp>
For any p
parser and s
compile-time string
build_parser<p>::type::apply<s>
is equivalent to
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;
This is a parser combinator.
It applies P
on the input.
When P
succeeds, change_error_message
returns the result
P
returns, otherwise change_error_message
rejects the input
and the reason will be Msg
.
#include <boost/metaparse/change_error_message.hpp>
For any p
parser and m
parsing error message, s
compile-time string and pos
source position
change_error_message<p, msg>::apply<s, pos>
is equivalent to p::apply<s, pos>
when p
accepts the input. It is equivalent to fail<msg>::apply<s, pos>
otherwise.
#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" );
A template metafunction supports currying when it accepts less arguments than it normally expects. When less arguments are provided, then it returns a template metafunction class expecting the remaining arguments. That template metafunction class is also expected to support currying.
For example assuming the following metafunction is given:
template <class A, class B> struct plus;
It takes two values, adds them and returns their result. For example:
static_assert( plus< std::integral_constant<int, 11>, std::integral_constant<int, 2> >::type::value == 13, "This should work" );
If it supports currying, then the following should also work:
using inc = plus<std::integral_constant<int, 1>>; static_assert( inc::apply<std::integral_constant<int, 12>>::type::value == 13, "This should work" );
The above example defines the inc
template metafunction class by calling plus
with just one argument: the boxed 1
value.
template <class P, class S> struct debug_parsing_error { debug_parsing_error(); };
This is a template class.
Utility to debug errors generated by a compile-time parser. An instance
of the instantiated template class has to be created and initialised using
the default constructor. When parsing the input string using the parser
generates an error, the default constructor of debug_parsing_error
prints the error message to the standard output at run-time and calls
exit
.
Note | |
---|---|
Note that more powerful debugging utilities, like Metashell are also available. |
#include <boost/metaparse/debug_parsing_error.hpp>
For any p
compile-time
parser and s
compile-time
string
debug_parsing_error<p, s>()
Tries to parse s
using
p
at compile-time. At run-time
the constructor prints the result of parsing to the standard output and
calls 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() {}
By running the compiled executable you get the following:
Compile-time parsing results ---------------------------- Input text: not an int
Parsing failed: line 1, col 1: Digit expected
namespace error { struct digit_expected; }
This is a parsing error message.
Class representing the error that a digit character was expected at a specific location.
#include <boost/metaparse/error/digit_expected.hpp>
struct digit;
This is a parser.
Parser accepting one character in the range 0-9
. The result
of the parser is the accepted character.
#include <boost/metaparse/digit.hpp>
The following are equivalent:
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; }
This is a template class similar to a template
metafunction but taking a char
value as argument.
Converts a character containing a value in the range ['0'..'9']
to an integer.
It returns a boxed integer value.
#include <boost/metaparse/util/digit_to_int_c.hpp>
The following pairs of expressions are equivalent
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; }
This is a lazy template metafunction that supports currying.
Converts a boxed character containing a value in the range ['0'..'9']
to an
integer.
It returns a boxed integer value.
#include <boost/metaparse/util/digit_to_int.hpp>
For any C
boxed character
value in the range ['0'..'9']
the following expressions are equivalent
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;
This is a parser.
It accepts one character in the range 0-9
. The result
of the parser is the value represented by the accepted character.
#include <boost/metaparse/digit_val.hpp>
The following are equivalent:
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;
This is a parser.
It accepts empty input only. The result of parsing is the Result
argument.
#include <boost/metaparse/empty.hpp>
For any c
class the following
are equivalent:
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; }
This is a parsing error message.
Class representing the error that the input contains more characters than it should.
#include <boost/metaparse/error/end_of_input_expected.hpp>
template <class P, class Msg = error::end_of_input_expected> struct entire_input;
This is a parser combinator.
It parses the input using P
and checks if it consumes the entire input. If P
fails or doesn't consume the entire input, entire_input
fails. Otherwise entire_input
returns the result of P
.
When P
does not consume
the entire input, the error message returned by entire_input
is Msg
.
#include <boost/metaparse/entire_input.hpp>
For any p
parser and e
parsing error message the following
are equivalent
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;
This is a parser combinator.
except
accepts the input
when P
rejects it and the
result of parsing is the Result
argument. When P
accepts
the input, except
rejects
it and the reason is ErrorMsg
.
#include <boost/metaparse/except.hpp>
For any p
parser, c
class, msg
parsing error message, s
compile-time string and pos
source position the following are equivalent
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
when p
rejects the input.
The result of the parser is an error with the error message msg
otherwise.
#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; }
This is a parsing error message.
Class representing the error that a parser was expected to fail but it did not fail.
#include <boost/metaparse/error/expected_to_fail.hpp>
template <class P> struct fail_at_first_char_expected;
This is a parser combinator.
It tries to parse the input using P
.
When P
rejects the input
without consuming any character, fail_at_first_char_expected
accepts the input. Otherwise (when P
accepts the input or when it consumes characters before rejecting the input)
fail_at_first_char_expected
rejects the input.
#include <boost/metaparse/fail_at_first_char_expected.hpp>
For any p
parser, s
compile-time string and pos
source position:
When is_error<p::apply<s, pos>>::type
is false, the following are equivalent:
fail_at_first_char_expected<p>::apply<s, pos>::type reject<error::expected_to_fail, pos>
When is_error<p::apply<s, pos>>::type
is true and boost::mpl::equal_to<pos, get_position<p::apply<s, pos>>::type>::type
is also true, the following are equivalent:
get_remaining<except<p, c, msg>, s, pos>::type accept</* unspecified */, s, pos>
Otherwise the following are equivalent:
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;
This is a parser.
Parser rejecting every input.
#include <boost/metaparse/fail.hpp>
For any msg
parsing error
message, s
compile-time
string and pos
source position
fail<msg>::apply<s, pos>::type
returns an error with msg
as the error message.
#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;
This is a tag.
This is the tag of the values returned by a parser when parsing was not successful.
#include <boost/metaparse/fail_tag.hpp>
template <class... Ps> struct first_of;
This is a parser combinator.
first_of
applies the Ps...
parsers in sequence. It accepts an input when all parsers accept it. The
result of parsing is the result of the first parser.
On compilers, which are not C++11-compliant, the maximum number of parsers
first_of
accepts can be
specified with the BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
macro. Its default value is 5
.
#include <boost/metaparse/first_of.hpp>
For any p1
, ... pn
parsers
first_of<p1, ..., pn>
is equivalent to
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;
This is a parser combinator.
foldl1
applies P
on the input string repeatedly as long
as P
accepts the input.
The result of parsing is equivalent to boost::mpl::fold<Sequence, State, ForwardOp>
, where Sequence
is the sequence of the results of the applications of P
.
When P
rejects the input
for the first time, foldl1
rejects it as well. At least one successful application of P
is required for foldl1
to accept the input.
#include <boost/metaparse/foldl1.hpp>
For any p
parser, t
class, f
metafunction class taking two arguments the following are equivalent:
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;
This is a parser combinator.
The same as foldl
,
but once P
rejects the
input, foldl_reject_incomplete
checks if P
consumes any
characters before rejecting the input. If so, foldl_reject_incomplete
rejects the input with the same error message this last application of
P
returned. Otherwise
foldl_reject_incomplete
accepts the input and gives the same result as foldl
.
Here is a diagram showing how foldl_reject_incomplete
works by example:
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>
For any p
parser, t
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldl_reject_incomplete<p, t, f>::apply<s, pos>
is equivalent to
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;
This is a parser combinator.
The same as foldl1
,
but once P
rejects the
input, foldl_reject_incomplete1
checks if P
consumes any
characters before rejecting the input. If so, foldl_reject_incomplete1
rejects the input with the same error message this last application of
P
returned. Otherwise
foldl_reject_incomplete1
accepts the input and gives the same result as foldl1
.
#include <boost/metaparse/foldl_reject_incomplete1.hpp>
For any p
parser, t
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldl_reject_incomplete1<p, t, f>::apply<s, pos>
is equivalent to
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;
This is a parser combinator.
Table 24.23. Arguments
Name |
Type |
---|---|
|
|
|
|
|
template metafunction class taking two arguments |
The same as foldl_start_with_parser
,
but once P
rejects the
input, foldl_reject_incomplete_start_with_parser
checks if P
consumes any
characters before rejecting the input. If so, foldl_reject_incomplete_start_with_parser
rejects the input with the same error message this last application of
P
returned. Otherwise
foldl_reject_incomplete_start_with_parser
accepts the input and gives the same result as foldl_start_with_parser
.
Here is a diagram showing how foldl_reject_incomplete_start_with_parser
works by example:
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;
Further details can be found in the Introducing foldl_reject_incomplete_start_with_parser section of the User Manual.
#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp>
For any p
parser, pt
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldl_reject_incomplete_start_with_parser<p, pt, f>::apply<s, pos>
is equivalent to
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;
This is a parser combinator.
Table 24.24. Arguments
Name |
Type |
---|---|
|
|
|
|
|
template metafunction class taking two arguments |
The same as foldl
,
but before folding it applies a parser, StateP
on the input. If it fails, foldl_start_with_parser
fails. If it succeeds, foldl_start_with_parser
works as foldl
taking the
result of StateP
as the
initial state.
Here is a diagram showing how foldl_start_with_parser
works by example:
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;
Further details can be found in the Introducing foldl_start_with_parser section of the User Manual.
#include <boost/metaparse/foldl_start_with_parser.hpp>
For any p
parser, pt
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldl_start_with_parser<p, pt, f>::apply<s, pos>
is equivalent to
pt::apply<s, pos>
when the above expression returns a parsing error. It is
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 >
otherwise.
#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;
This is a parser combinator.
foldl
applies P
on the input string repeatedly as long
as P
accepts the input.
The result of parsing is equivalent to boost::mpl::fold<Sequence, State, ForwardOp>
, where Sequence
is the sequence of the results of the applications of P
.
When P
rejects the input
for the first time, foldl
still accepts the input and the result of parsing is State
.
Here is a diagram showing how foldl
works by example:
using int_token = token<int_>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Further details can be found in the Introducing foldl section of the User Manual.
#include <boost/metaparse/foldl.hpp>
For any p
parser, t
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldl<p, t, f>::apply<s, pos>
is equivalent to
return_<t>::apply<s, pos>
when p::apply<s, pos>
returns an error. It is
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>> >
otherwise.
#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;
This is a parser combinator.
Table 24.26. Arguments
Name |
Type |
---|---|
|
|
|
|
|
template metafunction class taking two arguments |
foldr1
applies P
on the input string repeatedly as long
as P
accepts the input.
The result of parsing is equivalent to boost::reverse_fold<Sequence, State, BackwardOp>
, where Sequence
is the sequence of the results of the applications of P
.
When P
rejects the input
for the first time, foldr1
rejects it as well. At least one successful application of P
is required for foldr1
to accept the input.
#include <boost/metaparse/foldr1.hpp>
For any p
parser, t
class, f
metafunction class taking two arguments the following are equivalent:
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;
This is a parser combinator.
Table 24.27. Arguments
Name |
Type |
---|---|
|
|
|
|
|
template metafunction class taking two arguments |
The same as foldr
,
but once P
rejects the
input, foldr_reject_incomplete
checks if P
consumes any
characters before rejecting the input. If so, foldr_reject_incomplete
rejects the input with the same error message this last application of
P
returned. Otherwise
foldr_reject_incomplete
accepts the input and gives the same result as foldr
.
Here is a diagram showing how foldr_reject_incomplete
works by example:
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;
Note that foldr_reject_incomplete
folds from right to left and therefore does not start folding until it
reaches the end of the sequence. Since at the end of the sequence it finds
an error, folding does not happen at all.
#include <boost/metaparse/foldr_reject_incomplete.hpp>
For any p
parser, t
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldr_reject_incomplete<p, t, f>::apply<s, pos>
is equivalent to
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;
This is a parser combinator.
Table 24.28. Arguments
Name |
Type |
---|---|
|
|
|
|
|
template metafunction class taking two arguments |
The same as foldr1
,
but once P
rejects the
input, foldr_reject_incomplete1
checks if P
consumes any
characters before rejecting the input. If so, foldr_reject_incomplete1
rejects the input with the same error message this last application of
P
returned. Otherwise
foldr_reject_incomplete1
accepts the input and gives the same result as foldr1
.
#include <boost/metaparse/foldr_reject_incomplete1.hpp>
For any p
parser, t
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldr_reject_incomplete1<p, t, f>::apply<s, pos>
is equivalent to
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;
This is a parser combinator.
Table 24.29. Arguments
Name |
Type |
---|---|
|
|
|
|
|
template metafunction class taking two arguments |
The same as foldr
,
but after folding it applies a parser, StateP
on the input. If StateP
fails, foldr_start_with_parser
fails. If it succeeds, the result of parsing is equivalent to boost::reverse_fold<Sequence, State, BackwardOp>
,
where Sequence
is the sequence
of the results of the applications of P
and State
is the result
StateP
returned after
the repeated application of P
on the input.
Here is a diagram showing how foldr_start_with_parser
works by example:
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;
Further details can be found in the Introducing foldr_start_with_parser section of the User Manual.
#include <boost/metaparse/foldr_start_with_parser.hpp>
For any p
parser, pt
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position let pos_
be the position where the repeated application of p
on s
fails for the first
time. Let s_
be the postfix
of s
starting at that position.
foldr_start_with_parser<p, pt, f>::apply<s, pos>
is equivalent to
pt::apply<s_, pos_>
when the above expression returns a parsing error. It is
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 >
otherwise.
#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;
This is a parser combinator.
Table 24.30. Arguments
Name |
Type |
---|---|
|
|
|
|
|
template metafunction class taking two arguments |
foldr
applies P
on the input string repeatedly as long
as P
accepts the input.
The result of parsing is equivalent to boost::reverse_fold<Sequence, State, BackwardOp>
, where Sequence
is the sequence of the results of the applications of P
.
When P
rejects the input
for the first time, foldr
still accepts the input and the result of parsing is State
.
Here is a diagram showing how foldr
works by example:
using int_token = token<int_>; using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type;
Further details can be found in the Introducing foldr section of the User Manual.
#include <boost/metaparse/foldr.hpp>
For any p
parser, t
class, f
metafunction class taking two arguments, s
compile-time string and pos
source position
foldr<p, t, f>::apply<s, pos>
is equivalent to
return_<t>::apply<s, pos>
when p::apply<s, pos>
returns an error. It is
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 >
otherwise.
#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;
This is a lazy template metafunction.
Returns the column of a source position.
#include <boost/metaparse/get_col.hpp>
For any l
, c
compile-time wrapped integral values
and ch
compile-time wrapped
character the following are equivalent
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;
This is a lazy template metafunction.
Returns the line of a source position.
#include <boost/metaparse/get_line.hpp>
For any l
, c
compile-time wrapped integral values
and ch
compile-time wrapped
character the following are equivalent
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;
This is a lazy template metafunction.
Returns the error message of a parsing failure.
#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;
This is a lazy template metafunction.
Returns the source position information of a parsing result.
#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;
This is a lazy template metafunction.
Returns the last character the source position was updated with. The value
it returns for start
is unspecified.
#include <boost/metaparse/get_prev_char.hpp>
For any l
, c
compile-time wrapped integral values
and ch
compile-time wrapped
character the following are equivalent
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;
This is a lazy template metafunction.
Returns the remaining string information of a parsing result.
#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;
This is a lazy template metafunction.
Returns the result information of a parsing 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 | |
---|---|
Note that using this adds a significant overhead to your builds. When someone uses your parser, the compiler will have to build your grammar parser, use it to parse your grammar and build your parser and then it can parse the input the user would like to parse with your parser. You might consider using the parser combinators the library provides. |
Parser combinator for constructing parsers based on an embedded DSL similar to EBNF. It can be used the following way:
grammar<> // definitions
where a definition can be a rule or an import command.
Rules look like on of the following:
::rule<BOOST_METAPARSE_STRING("name ::= def")> ::rule<BOOST_METAPARSE_STRING("name ::= def"), semantic_action>
name
consists of letters,
digits and the _
character.
It is the name of the symbol being defined. def
describes the rule. It can be
\
can be used for escaping. The following
are accepted: \n
,
\r
,
\t
,
\\
, \'
*
character, which means repetition accepting 0 match
+
character, which means repetition expecting at least one match
Rules take an optional semantic_action
argument. It is a placeholder expression taking one argument. When this
is given, this is used to transform the result of the rule.
Imports can be used to turn an arbitrary parser into a symbol available for the rules. Import definitions look like the following:
::import<BOOST_METAPARSE_STRING("name"), parser>
name
is the name of the
symbol, parser
is the parser
to bind the name to.
The start symbol of the grammar is specified by the template argument of
the grammar
template. This
is optional, the default value is S
.
Note that the current implementation "inlines" the referenced symbols while parsing the grammar and recursion is not supported because of this.
#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_;
This is a parser combinator.
if_
always accepts the
input string. The result of parsing is T
,
when P
accepts the input
and F
otherwise.
#include <boost/metaparse/if_.hpp>
For any p
parser, t
and f
classes the following are equivalent:
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; }
This is a parsing error message.
Table 24.39. Arguments
Name |
Type |
---|---|
|
|
|
|
|
|
Template class representing an over or under indexing error. From
and To
represent the range and N
is the value outside of the range.
#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; }; }
This is a template metafunction class.
Table 24.40. Arguments
Name |
Type |
---|---|
|
integral type |
|
value of type |
|
value of type |
|
Metafunction class verifying that U
is in the [LowerBound..UpperBound]
range or not.
#include <boost/metaparse/util/in_range_c.hpp>
For any T
integral type,
A
, B
values of type T
and C
wrapped value the following are equivalent:
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; }
This is a template metafunction supporting currying.
It returns a boxed boolean value. The value is true
when Item
is in the range
[LowerBound..UpperBound]
and false
otherwise. boost::mpl::less_equal
is used for comparison.
#include <boost/metaparse/util/in_range.hpp>
For any L
, U
and T
classes the following are equivalent:
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_;
This is a parser.
It accepts a non-empty sequence of characters in the range 0-9
.
The result of the parser is the decimal value represented by the accepted
character sequence.
#include <boost/metaparse/int_.hpp>
The following are equivalent:
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; }
This is a template class similar to a template
metafunction but taking an int
value as argument.
Converts an integer value in the range [0-9]
to a character representing that decimal
value.
#include <boost/metaparse/util/int_to_digit_c.hpp>
The following pairs of expressions are equivalent
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; }
This is a lazy template metafunction that supports currying.
Converts a boxed integer value in the range [0-9]
to a character representing that decimal
value.
#include <boost/metaparse/util/int_to_digit.hpp>
The following pairs of expressions are equivalent
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; }
This is a lazy template metafunction that supports currying.
Checks if C
is a digit
value or not. Returns a boxed boolean value.
#include <boost/metaparse/util/is_digit.hpp>
The following expressions are equivalent:
is_digit<boost::mpl::char_<'0'>>::type is_digit<>::apply<boost::mpl::char_<'0'>>::type boost::mpl::true_
The following expressions are also equivalent:
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;
This is a lazy template metafunction that supports currying.
Determines if C
is a parsing
error or not. Returns a boxed boolean
value.
#include <boost/metaparse/is_error.hpp>
For any e
parsing error
is_error<c>::type
is a wrapped compile-time true
value, for any other c
class is_error<c>::type
is a wrapped compile-time false
value.
#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; }
This is a lazy template metafunction that supports currying.
Checks if C
is a lower
case letter. Returns a boxed boolean value.
#include <boost/metaparse/util/is_lcase_letter.hpp>
The following expressions are equivalent:
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; }
This is a lazy template metafunction that supports currying.
Checks if C
is a letter.
Returns a boxed boolean value.
#include <boost/metaparse/util/is_letter.hpp>
The following expressions are equivalent:
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; }
This is a lazy template metafunction that supports currying.
Checks if C
is an upper
case letter. Returns a boxed boolean value.
#include <boost/metaparse/util/is_ucase_letter.hpp>
The following expressions are equivalent:
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; }
This is a template class similar to a template
metafunction but taking a char
value as argument.
Checks if C
is a whitespace
character. Returns a boxed boolean value.
#include <boost/metaparse/util/is_whitespace_c.hpp>
The following expressions are equivalent:
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_
For any c
character other
than the above listed ones the following are equivalent:
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; }
This is a lazy template metafunction that supports currying.
Checks if C
is a whitespace
character. Returns a boxed boolean value.
#include <boost/metaparse/util/is_whitespace.hpp>
For any C
nullary template
metafunction returning a wrapped character value the following are equivalent:
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;
This is a parser combinator.
It applies P
on the input
string N
times. The result
of parsing is a sequence of the results of the individual applications
of P
. P
has to accept the input N
times for iterate_c
to
accept it.
#include <boost/metaparse/iterate_c.hpp>
For any p
parser, n
integer value the following are equivalent:
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;
This is a parser combinator.
It applies P
on the input
string N
times. The result
of parsing is a sequence of the results of the individual applications
of P
. P
has to accept the input N
times for iterate
to accept
it.
#include <boost/metaparse/iterate.hpp>
For any p
parser, n
wrapped integer the following are equivalent:
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;
This is a parser.
Parser accepting the keyword S
.
The result of parsing is ResultType
,
which is optional; when not given, the result of successful parsing is
undefined.
#include <boost/metaparse/keyword.hpp>
For any r
class and s
compile-time string that is built from
the characters c1
...
cn
the following are equivalent:
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... Ps> struct last_of;
This is a parser combinator.
last_of
applies the Ps...
parsers in sequence. It accepts an input when all parsers accept it. The
result of parsing is the result of the last parser.
On compilers, which are not C++11-compliant, the maximum number of parsers
last_of
accepts can be
specified with the BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
macro. Its default value is 5
.
#include <boost/metaparse/last_of.hpp>
For any p1
, ... pn
parsers
first_of<p1, ..., pn>
is equivalent to
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" );
A lazy template metafunction is a template metafunction that accepts nullary metafunctions as arguments, that need to be evaluated first to get the value of the argument.
For example here is a plus
metafunction for int
values:
template <class A, class B> struct plus : std::integral_constant<int, A::value + B::value> {};
This metafunction takes two boxed numbers as arguments, unboxes them, adds their values and boxed the result again.
It works when it is called with boxed numbers. For example:
static_assert( plus< std::intgeral_constant<int, 2>, std::integral_constant<int, 2> >::type::value == 4, "This should work" );
However, when it is called with a nullary metafunction returning the boxed value, it breaks:
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
So plus
is not
a lazy template metafunction. To make it lazy, it has to evaluate its arguments
before using them:
template <class A, class B> struct lazy_plus : std::integral_constant<int, A::type::value + B::type::value> {};
Note that it uses A::type::value
and B::type::value
instead of A::value
and B::value
.
It works when it is called with nullary metafunctions as well:
static_assert( plus< nullary_metafunction_returning_2, nullary_metafunction_returning_2 >::type::value == 4, "This should work" );
Because it works with nullary metafunctions as arguments, it is a lazy template metafunction.
namespace error { struct letter_expected; }
This is a parsing error message.
Class representing the error that a letter character was expected at a specific location.
#include <boost/metaparse/error/letter_expected.hpp>
struct letter;
This is a parser.
Parser accepting one character in the range a-z
or
A-Z
. The result of the parser is the accepted
character.
#include <boost/metaparse/letter.hpp>
The following are equivalent:
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;
This is a parser.
Parser accepting only the C
character. The result of parsing is the accepted character.
#include <boost/metaparse/lit_c.hpp>
For any c
character the
following are equivalent:
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; }
This is a parsing error message.
Template class representing the error that a specific literal was expected.
C
is the literal that was
expected but not found.
#include <boost/metaparse/error/literal_expected.hpp>
template <class C> struct lit;
This is a parser.
Parser accepting only the C
character. The result of parsing is the accepted character.
#include <boost/metaparse/lit.hpp>
For any c
boxed character
the following are equivalent:
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;
This is a parser combinator.
Parses the input using parser P
.
When P
returns an error,
look_ahead
returns the
error. When P
returns a
result, look_ahead
returns
the result without consuming anything from the input string.
#include <boost/metaparse/look_ahead.hpp>
For any p
parser, s
compile-time string and pos
source position
look_ahead<p>::apply<s, pos>
is equivalent to
return_<get_result<p::apply<s, pos>>::type>::apply<s, pos>
when p::apply<s, pos>
succeeds. It is
p::apply<s, pos>
otherwise.
#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" );
A template metafunction class is a type with a public
nested template metafunction called
apply
. Since it is a type,
it can be passed to template metafunctions as arguments and metafunctions
can return it as their result. This makes it possible to implement higher-order
template metafunctions, which are template metafunctions taking
template metafunctions as arguments or returning template metafunctions
as their result.
For example this is the identity template metafunction class:
struct identity { template <class T> struct apply { using type = T; }; using type = identity; };
This metafunction class is called identity
.
It takes one argument, T
.
The result of calling this metafunction class is its argument, T
. Note that the identity
metafunction class is also a template
metaprogramming value, so it can be an argument or the result of
a template metafunction.
To call this metafunction, one has to call the nested template metafunction. For example:
identity::apply<std::integral_constant<int, 13>>::type
The above example calls the metafunction class identity
with std::integral_constant<int, 13>
as its argument.
A template metafunction represents a function over types that is evaluated at compile-time. It is implemented by a template class.
The template arguments of that class are expected to be types (class
or typename
template arguments). They represent the arguments of the metafunction.
Instances of the template class are expected to have a public nested type
called type
. This type
is the type the metafunction returns.
Template metafunction are expected to be called with template metaprogramming values as arguments only.
Template metafunctions are expected to return template metaprogramming values.
For example this is the identity template metafunction:
template <class T> struct identity { using type = T; };
This metafunction is called identity
.
It takes one argument, T
.
The result of calling this metafunction is its argument, T
.
To call this metafunction, one has to instantiate the template class. The template arguments it is instantiated with are the arguments the metafunction is called with. For example:
identity<std::integral_constant<int, 13>>::type
The above example calls the metafunction identity
with std::integral_constant<int, 13>
as its argument.
A template metaprogramming value is a nullary template metafunction returning itself. For example:
struct void_ { using type = void_; };
This template metaprogramming value is called void_
.
It is a nullary metafunction returning itself as its result. Because of
this, it can be treated as a nullary metafunction and evaluated any number
of times. For example void_::type::type::type
is still void_
.
template <class P1, class P2, class P3> struct middle_of;
This is a parser combinator.
middle_of
applies P1
, P2
and P3
in sequence. It
accepts an input when all of these three parsers accept it. The result
of parsing is the result of P2
.
#include <boost/metaparse/middle_of.hpp>
For any p1
, p2
and p3
parsers
middle_of<p1, p2, p3>
is equivalent to
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;
This is a lazy template metafunction.
Table 24.60. Arguments
Name |
Type |
---|---|
|
|
|
boxed character value. The
character |
Returns a new source position, pointing to the next character of the same line.
#include <boost/metaparse/next_char.hpp>
For any s
source position
and c
wrapped character
the following are equivalent
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;
This is a lazy template metafunction.
Table 24.61. Arguments
Name |
Type |
---|---|
|
|
|
boxed character value. The
character |
Returns a new source position, pointing to the beginning of the next line.
#include <boost/metaparse/next_line.hpp>
For any s
source position
and c
wrapped character
the following are equivalent
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; }
This is a parsing error message.
Class representing the error that none of a list of parsers could parse the input.
#include <boost/metaparse/error/none_of_the_expected_cases_found.hpp>
template <int N, class... Ps> struct nth_of_c;
This is a parser combinator.
nth_of_c
applies the Ps...
parsers in sequence. It accepts an input when all of these parsers accept
it. The result of parsing is the result of the N
.
parser.
On compilers, which are not C++11-compliant, the maximum number of parsers
nth_of_c
accepts can be
specified with the BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
macro. Its default value is 5
.
#include <boost/metaparse/nth_of.hpp>
For any p0
, ..., pn
parsers and k
integer value, where 0 <=
k <
n
the following are equivalent
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... Ps> struct nth_of;
This is a parser combinator.
nth_of
applies the Ps...
parsers in sequence. It accepts an input when all of these parsers accept
it. The result of parsing is the result of the N
.
parser.
On compilers, which are not C++11-compliant, the maximum number of parsers
nth_of
accepts can be specified
with the BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
macro. Its default value is 5
.
#include <boost/metaparse/nth_of.hpp>
For any p0
, ..., pn
parsers and k
boxed integer value the following are equivalent
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" );
A nullary template metafuncion is a template
metafunction taking 0 arguments. It is a type with a nested type
called type
, which is the
return value of the nullary metafunction. For example:
struct always13 { using type = std::integral_constant<int, 13>; };
This metafunction is called always13
.
It is a nullary metafunction, because it takes no arguments. It always
returns std::integral_constant<int, 13>
.
To call this metafunction, one has to access its ::type
. For example:
always13::type
The above example calls the metafunction to get std::integral_constant<int, 13>
.
template <char... Cs> struct one_char_except_c;
This is a parser.
one_char_except_c
accepts
one character except any of Cs
.
When the input is empty or begins with one of the non-accepted characters,
one_char_except_c
rejects
the input. Otherwise it accepts the input and the result of parsing is
the character value.
On compilers, which are not C++11-compliant, the maximum number of characters
this class can have is the value the macro BOOST_METAPARSE_LIMIT_ONE_CHAR_EXCEPT_SIZE
expands to. Its default value is 10.
#include <boost/metaparse/one_char_except_c.hpp>
For any s
compile-time
string and c1
, ..., cn
characters the following are equivalent
one_char_except_c<c1, ..., cn>::apply<s, pos> boost::metaparse::one_char::apply<s, pos>
when s
is empty or it begins
with a character other than c1
,
..., cn
. Otherwise one_char_except_c<c1, ..., cn>::appl<s, pos>
returns a parsing error.
#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... Cs> struct one_char_except;
This is a parser.
one_char_except
accepts
one character except any of Cs
.
When the input is empty or begins with one of the non-accepted characters,
one_char_except
rejects
the input. Otherwise it accepts the input and the result of parsing is
the character value.
On compilers, which are not C++11-compliant, the maximum number of characters
this class can have is the value the macro BOOST_METAPARSE_LIMIT_ONE_CHAR_EXCEPT_SIZE
expands to. Its default value is 10.
#include <boost/metaparse/one_char_except.hpp>
For any c1
, ..., cn
boxed characters the following are
equivalent
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;
This is a parser.
one_char
accepts one character.
The result of parsing is the accepted character. It fails for empty input.
#include <boost/metaparse/one_char.hpp>
For any s
non-empty compile-time
string and pos
source position
the following are equivalent
get_result<one_char::apply<s, pos>> boost::mpl::front<s> get_remaining<one_char::apply<s, pos>> boost::mpl::pop_front<s>
The value of get_position<one_char::apply<s, pos>>
depends on the first character
of the sequence and the value of the one parsed before that (which is stored
in the source position). one_char
updates the source position's col
and line
values based on
the new line characters. It detects Linux (\n
), Windows (\r\n
)
and Mac (\r
)
line endings.
one_char::apply<BOOST_METAPARSE_STRING(""),
pos>
returns an error for every pos
source position.
#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 <char... Cs> struct one_of_c;
This is a parser.
It accepts inputs beginning with any of the Cs...
characters. The result of parsing is
the first character of the input.
On compilers, which are not C++11-compliant, the maximum number of characters
that can be provided is defined by the BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
macro. Its default value is 20
.
#include <boost/metaparse/one_of_c.hpp>
For any c1
, ..., cn
characters
one_of_c<c1, ..., cn>
is equivalent to
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... Ps> struct one_of;
This is a parser combinator.
It accepts an input when any of the Ps...
parsers accept it. The result of parsing
is the result of applying the first parser that accepts the input. The
parsers are tried in order, therefore in case of ambiguous grammars the
result of parsing depends on the order of the Ps...
parsers.
On compilers, which are not C++11-compliant, the maximum number of accepted
parsers is defined by the BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
macro. Its default value is 20
.
#include <boost/metaparse/one_of.hpp>
For any p1
, ..., pn
parsers, s
compile-time string and pos
source position
one_of<p1, ..., pn>::apply<s, pos>
is equivalent to
pk::apply<s, pos>
when there is a k
, that
pi::apply<s, pos>::type
returns an error for every i
in the range [1..k)
and pk::apply<s, pos>::type
doesn't return an error.
The parser combinator returns an error when there is no such 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;
This is a parser combinator.
It tries parsing the input with P
.
When P
succeeds, the result
of parsing is the result of P
.
Otherwise no characters are consumed and the result of parsing is Default
.
#include <boost/metaparse/optional.hpp>
For any p
parser
and d
template
metaprogramming value
optional<p, d>
is equivalent to
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" );
A parser combinator is a parser implemented as a template class taking one or more parsers as arguments.
A parser is a template metafunction class that takes the following arguments:
string
The function parses a prefix of the input string. When the parsing is successful,
it returns an accept
value. When there is a parsing error, the parser returns a reject
value. The is_error
metafunction can be used
to determine about the result of a parser if it succeeded or failed.
The documentation refers often to the result of a parser.
This means that the parser accepts the input and refers to what get_result
returns for the value
returned by the parser.
A parsing error message is a template
metaprogramming value with a static
std::string get_value()
member function. This function returns
the pretty-printed version of the error the class represents. For example:
struct example_error { using type = example_error; static std::string get_value() { return "This is a formatted example error." } };
Failing parsers return parsing error messages as error messages.
A predicate (or unary predicate) is a template
metafunction class taking one argument and returning a boxed
value of type bool
.
For example the following predicate checks if its argument is the boxed
char
value 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;
This is a parser.
range_c
accepts one character
in the range [From..To]
. The result of the parser is the accepted
character.
#include <boost/metaparse/range_c.hpp>
For any A
, B
characters the following are equivalent:
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;
This is a parser.
range
accepts one character
in the range [From..To]
. The result of the parser is the accepted
character.
#include <boost/metaparse/range.hpp>
For any A
, B
wrapped characters the following are
equivalent:
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;
This is a template metaprogramming value.
Values representing a failed parser application. It behaves as a lazy template metafunction: when it is evaluated as a metafunction, it returns itself with its arguments evaluated. See expression semantics for further details.
Note | |
---|---|
Note that for backward compatibility when |
For any m
template metaprogramming
value and p
source position
the following are equivalent:
reject<m, p>::type reject<m, p::type>
#include <boost/metaparse/reject.hpp>
template <class P> struct repeated1;
This is a parser combinator.
It applies P
on the input
string repeatedly as long as the parser accepts the input. The result of
parsing is a sequence of the results of the individual applications of
P
.
When P
rejects the input
for the first time, repeated1
rejects it as well. At least one successful application of P
is required for repeated1
to accept the input.
#include <boost/metaparse/repeated1.hpp>
For any p
parser the following
are equivalent:
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;
This is a parser combinator.
The same as repeated1
,
but once P
rejects the
input, repeated_reject_incomplete1
checks if P
consumes any
characters before rejecting the input. If so, repeated_reject_incomplete1
rejects the input with the same error message this last application of
P
returned. Otherwise _reject_incompleterepeated1
accepts the input and gives
the same result as repeated1
.
#include <boost/metaparse/repeated_reject_incomplete1.hpp>
For any p
parser, s
compile-time string and pos
source position
repeated_reject_incomplete1<p>::apply<s, pos>
is equivalent to
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;
This is a parser combinator.
The same as repeated
,
but once P
rejects the
input, repeated_reject_incomplete
checks if P
consumes any
characters before rejecting the input. If so, repeated_reject_incomplete
rejects the input with the same error message this last application of
P
returned. Otherwise
repeated_reject_incomplete
accepts the input and gives the same result as repeated
.
Here is a diagram showing how repeated_reject_incomplete
works by example:
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>
For any p
parser, s
compile-time string and pos
source position
repeated_reject_incomplete<p>::apply<s, pos>
is equivalent to
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... Ps> struct repeated_one_of1;
This is a parser combinator.
It applies the Ps...
parsers repeatedly as long as any of them accepts the input. In each iteration
the parsers are tried in order and the first one accepting the input is
used, therefore in case of ambiguous grammars the result of parsing depends
on the order of the Ps...
parsers. The result of parsing with
this parser combinator is a sequence
of the individual parsing results.
When none of the Ps...
parsers accept the input in the first iteration, repeated_one_of1
rejects the input.
On compilers, which are not C++11-compliant, the maximum number of accepted
parsers is defined by the BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
macro. Its default value is 20.
#include <boost/metaparse/repeated_one_of1.hpp>
For any p1
, ..., pn
parsers
repeated_one_of1<p1, /* ... */, pn>
is equivalent to
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... Ps> struct repeated_one_of1;
This is a parser combinator.
It applies the Ps...
parsers repeatedly as long as any of them accepts the input. In each iteration
the parsers are tried in order and the first one accepting the input is
used, therefore in case of ambiguous grammars the result of parsing depends
on the order of the Ps...
parsers. The result of parsing with
this parser combinator is a sequence
of the individual parsing results.
When none of the Ps...
parsers accept the input in the first iteration, repeated_one_of
accepts the input and the result of parsing is an empty sequence.
On compilers, which are not C++11-compliant, the maximum number of accepted
parsers is defined by the BOOST_METAPARSE_LIMIT_ONE_OF_SIZE
macro. Its default value is 20.
#include <boost/metaparse/repeated_one_of.hpp>
For any p1
, ..., pn
parsers
repeated_one_of<p1, /* ... */, pn>
is equivalent to
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;
This is a parser combinator.
It applies P
on the input
string repeatedly as long as P
accepts the input. The result of parsing is a sequence of the results of
the individual applications of P
.
When P
rejects the input
for the first time, repeated
still accepts the input and the result of parsing is an empty sequence.
Here is a diagram showing how repeated
works by example:
using int_token = token<int_>;
Further details can be found in the Repetition section of the User Manual.
#include <boost/metaparse/repeated.hpp>
For any p
parser the following
are equivalent:
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_;
This is a parser.
return_
accepts every input.
The result of parsing is C
,
the remaining string is the input string.
#include <boost/metaparse/return_.hpp>
For any c
class, s
compile-time string and pos
source position the following are
equivalent
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... Ps> struct sequence;
This is a parser combinator.
sequence
applies the Ps...
parsers in sequence on the input. It accepts an input when all of these
parsers accept it. The result of parsing is a sequence of the results of
the parsers.
On compilers, which are not C++11-compliant, the maximum number of parsers
sequence
accepts can be
specified with the BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE
macro. Its default value is 5
.
#include <boost/metaparse/sequence.hpp>
For any n >
0
, p0
,
..., pn
parsers the result
of sequence<p0, ..., p1>
is a compile-time sequence of the results
of the parsers, applied after each other in order on the input string when
none of them returns an error. The remaining string is the remaining string
the last parser returns.
When one of the parsers returns an error, the combinator returns that error.
#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;
This is a parser combinator.
It applies the P1
...
Pn
parsers
on the input in order. When all of them succeed, the result of parsing
with sequence_applyn
is
the T
template class instantiated
with the results of the P1
... Pn
parsers.
When any of the P1
...
Pn
parsers
reject the input, the error is propagated.
n
has to be in the [1..BOOST_METAPARSE_LIMIT_SEQUENCE_SIZE)
range.
#include <boost/metaparse/sequence_apply.hpp>
For any n >
0
, p1
... pn
parsers,
t
template class with
n
class
arguments, s
compile-time
string and pos
source position
the following are equivalent:
sequence_apply<t, p1, ..., pn>::apply<s, pos>::type
when sequence
<p1, ..., pn>
accepts the input:
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
when sequence
<p1, ..., pn>
rejects the input:
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;
This is a template metaprogramming value.
Compile-time data-structure describing a position of the input text.
The values of this data-structure store the last character that was parsed
before reaching the position of the input described by the source_position
value.
Its tag is source_position_tag
.
The beginning of the input text is represented by start
.
#include <boost/metaparse/source_position.hpp>
For any l
, c
compile-time boxed integral values
and p
compile-time boxed
character value, the following are equivalent
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;
This is a tag.
This is the tag of the source_position
values.
#include <boost/metaparse/source_position_tag.hpp>
struct space;
This is a parser.
space
accepts one white
space character. The result of parsing is the parsed character.
#include <boost/metaparse/space.hpp>
The following are equivalent:
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;
This is a parser.
spaces
accepts any number
of whitespace characters. It requires at least one to be present.
#include <boost/metaparse/spaces.hpp>
spaces
is equivalent to
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;
This is a template metaprogramming value of type source position.
It represents the beginning of an input text.
#include <boost/metaparse/start.hpp>
template <char C1, ..., char Cn> struct string;
This is a template metaprogramming value.
Compile-time data-structure describing a string object. These string objects
are compatible with boost::mpl::string
,
but they accept only individual characters as arguments. When constexpr
is available, they can be constructed
using the BOOST_METAPARSE_STRING
macro.
The tag of the strings is string_tag
.
C++98: The maximum length of these strings
is controlled by the BOOST_METAPARSE_LIMIT_STRING_SIZE
macro.
C++11: The strings use variadic templates.
#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;
This is a tag.
This is the tag of the string
values.
#include <boost/metaparse/string_tag.hpp>
A tag is a template metaprogramming value used to identify groups of values.
template <class P> struct token;
This is a parser combinator.
token
parses the input
using P
when it succeeds,
token
consumes all whitespaces
afterwards. The result of parsing is the result of P
.
#include <boost/metaparse/token.hpp>
For any p
parser the following
are equivalent:
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;
This is a parser combinator.
It parses the input with P
.
When this succeeds, the result of parsing with transform_error_message
will be the result of parsing with P
.
When it fails, the error P
returns is forwarded to the caller of transform_error_message
,
but the message of it is transformed with F
.
#include <boost/metaparse/transform_error_message.hpp>
For any p
parser and f
metafunction class accepting one argument
transform_error_message<p, f>::apply<s, pos>
is equivalent to p::apply<s, pos>
when p
accepts the input. It is equivalent to reject<f::apply<get_message<p::apply<s, pos>>::type>, get_position<p::apply<s, pos>>>
otherwise.
#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;
This is a parser combinator.
It parses the input with P
.
When this succeeds, the result of parsing with transform_error
will be the result of parsing with P
.
When it fails, F
is evaluated
with the error P
returned
as argument. Parsing with transform_error
will fail and the error will be what F
returns. Therefore, F
is
expected to accept and return a reject
value.
#include <boost/metaparse/transform_error.hpp>
For any p
parser and f
metafunction class accepting one argument
transform_error<p, f>::apply<s, pos>
is equivalent to p::apply<s, pos>
when p
accepts the input. It is equivalent to f::apply<p::apply<s, pos>::type>
otherwise.
#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;
This is a parser combinator.
transform
parses the input
using P
and transforms
the result P
returns with
T
. The result of parsing
is what T
returns. When
P
fails, the failure is
returned unchanged.
#include <boost/metaparse/transform.hpp>
For any p
parser, t
metafunction class accepting one argument,
s
compile-time string and
pos
source position
get_result<transform<p, t>::apply<s, pos>>::type
is equivalent to
t::apply<get_result<p::apply<s, pos>>::type>::type
When p::apply<s, pos>
doesn't return an error. The combinator
returns the error otherwise.
#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; }
This is a parsing error message.
Class representing the error that a different character was expected than what was found at a specific location.
#include <boost/metaparse/error/unexpected_character.hpp>
namespace error { struct unexpected_end_of_input; }
This is a parsing error message.
Class representing the error that the end of input has been reached while it should contain further characters.
#include <boost/metaparse/error/unexpected_end_of_input.hpp>
template <class T, class NotErrorCase> struct unless_error;
This is a lazy template metafunction.
Checks if T
is a parsing
error or not. When it is, the result is T
.
When it is not, the result is NotErrorCase
.
#include <boost/metaparse/unless_error.hpp>
For any t
and c
classes the following are equivalent:
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; }
This is a parsing error message.
Template class representing the error that the closing element of an "opening
element ... closing element" structure
is missing. (eg. a closing paren is missing). Line
and Col
point to the beginning
of the opening element (eg. the opening paren). Msg
is the error message the parser trying
to parse the closing element failed with.
It supports currying: unpaired<Line, Col>
is a template
metafunction class taking one argument: the Msg
element and returning the corresponding unpaired
value.
#include <boost/metaparse/error/unpaired.hpp>
namespace error { struct whitespace_expected; }
This is a parsing error message.
Class representing the error that a whitespace character was expected at a specific location.
#include <boost/metaparse/error/whitespace_expected.hpp>