2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-21 17:12:16 +00:00

6 Commits

Author SHA1 Message Date
Zach Laine
88abb615aa Add pre_- and post_parser members to parser_modifiers; these are used as
look-ahead/-behind positive or negative assertions.

When combining parsers using op>> and op>, if either side is an expect_parser
and the other side has an open pre_-/post_parser slot, take the subparser out
of the expect_parser, and use it directly in the pre_-/post_parser slot.

See #160.
2024-12-16 19:24:39 -06:00
Zach Laine
54f8eecfe6 Change the no_case[] directive to use the parser_modifiers struct, like omit[]
does; remove no_case_parser.

See #160.
2024-12-16 19:24:39 -06:00
Zach Laine
fcd257abca Generalize with_parser_mods(), so that some functions can be recursive, and
others can be non-recursive.

See #160.
2024-12-16 19:24:39 -06:00
Zach Laine
2f7e5964a6 Apply the same sort of change as the previous two commits, but to all the
parsers not already modified.  Generalize with_parser_mods().  Remove
omit_parser, since it is now moot.

See #160.
2024-12-16 19:24:39 -06:00
Zach Laine
2fff00b3e1 Change string_parser to support the use of parser_modifiers, and change lit()
to return a parameterized string_parser instead of string_parser wrapped in an
omit_parser.

See #160.
2024-12-16 19:24:39 -06:00
Zach Laine
28e9b61735 Add a new template, parser_modifiers, that will hold common modifications to
parsers, like turning off attribute generation (replacing omit_parser).
Change char_parser to support the use of parser_modifiers, and change lit() to
return a parameterized char_parser instead of char_parser wrapped in an
omit_parser.

See #160.
2024-12-16 19:24:39 -06:00
10 changed files with 3003 additions and 1244 deletions

View File

@@ -52,110 +52,118 @@ namespace boost { namespace parser { namespace detail {
typename Parser, typename Parser,
typename DelimiterParser, typename DelimiterParser,
typename MinType, typename MinType,
typename MaxType> typename MaxType,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
repeat_parser<Parser, DelimiterParser, MinType, MaxType> const & parser, repeat_parser<
Parser,
DelimiterParser,
MinType,
MaxType,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
opt_parser<Parser> const & parser, opt_parser<Parser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename ParserTuple> template<typename Context, typename ParserTuple, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
or_parser<ParserTuple> const & parser, or_parser<ParserTuple, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename ParserTuple> template<typename Context, typename ParserTuple, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
perm_parser<ParserTuple> const & parser, perm_parser<ParserTuple, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template< template<
typename Context, typename Context,
typename ParserTuple, typename ParserTuple,
typename BacktrackingTuple, typename BacktrackingTuple,
typename CombiningGroups> typename CombiningGroups,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups> const & seq_parser<
parser, ParserTuple,
BacktrackingTuple,
CombiningGroups,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser, typename Action> template<
void print_parser( typename Context,
typename Parser,
typename Action,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
action_parser<Parser, Action> const & parser, action_parser<Parser, Action, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser, typename F> template<typename Context, typename Parser, typename F, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
transform_parser<Parser, F> const & parser, transform_parser<Parser, F, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
omit_parser<Parser> const & parser, raw_parser<Parser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser>
void print_parser(
Context const & context,
raw_parser<Parser> const & parser,
std::ostream & os,
int components = 0);
#if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS #if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
string_view_parser<Parser> const & parser, string_view_parser<Parser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
#endif #endif
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
lexeme_parser<Parser> const & parser, lexeme_parser<Parser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser> template<
void print_parser( typename Context,
typename Parser,
typename SkipParser,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
no_case_parser<Parser> const & parser, skip_parser<Parser, SkipParser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser, typename SkipParser> template<
void print_parser( typename Context,
typename Parser,
expect_match_t ExpectMatch,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
skip_parser<Parser, SkipParser> const & parser, expect_parser<Parser, ExpectMatch, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Parser, bool FailOnMatch>
void print_parser(
Context const & context,
expect_parser<Parser, FailOnMatch> const & parser,
std::ostream & os,
int components = 0);
template< template<
typename Context, typename Context,
@@ -163,143 +171,147 @@ namespace boost { namespace parser { namespace detail {
typename Parser, typename Parser,
typename Attribute, typename Attribute,
typename LocalState, typename LocalState,
typename ParamsTuple> typename ParamsTuple,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
rule_parser< rule_parser<
UseCallbacks, UseCallbacks,
Parser, Parser,
Attribute, Attribute,
LocalState, LocalState,
ParamsTuple> const & parser, ParamsTuple,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename T> template<typename Context, typename T, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
symbol_parser<T> const & parser, symbol_parser<T, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Predicate> template<typename Context, typename Predicate, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
eps_parser<Predicate> const & parser, eps_parser<Predicate, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
eps_parser<nope> const & parser, eps_parser<nope, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
eoi_parser const & parser, eoi_parser<ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Atribute> template<typename Context, typename Atribute, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
attr_parser<Atribute> const & parser, attr_parser<Atribute, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Expected, typename AttributeType> template<
void print_parser( typename Context,
typename Expected,
typename AttributeType,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
char_parser<Expected, AttributeType> const & parser, char_parser<Expected, AttributeType, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
digit_parser const & parser, digit_parser<ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_subrange_parser<hex_digit_subranges> const & parser, char_subrange_parser<hex_digit_subranges, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_subrange_parser<control_subranges> const & parser, char_subrange_parser<control_subranges, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_set_parser<punct_chars> const & parser, char_set_parser<punct_chars, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_set_parser<lower_case_chars> const & parser, char_set_parser<lower_case_chars, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_set_parser<upper_case_chars> const & parser, char_set_parser<upper_case_chars, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Expected, typename AttributeType> template<
void print_parser( typename Context,
typename StrIter,
typename StrSentinel,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
omit_parser<char_parser<Expected, AttributeType>> const & parser, string_parser<StrIter, StrSentinel, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename StrIter, typename StrSentinel> template<
void print_parser( typename Context,
typename Quotes,
typename Escapes,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
string_parser<StrIter, StrSentinel> const & parser, quoted_string_parser<Quotes, Escapes, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename StrIter, typename StrSentinel> template<
void print_parser( typename Context,
bool NewlinesOnly,
bool NoNewlines,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
omit_parser<string_parser<StrIter, StrSentinel>> const & parser, ws_parser<NewlinesOnly, NoNewlines, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename Quotes, typename Escapes> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
quoted_string_parser<Quotes, Escapes> const & parser, bool_parser<ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, bool NewlinesOnly, bool NoNewlines>
void print_parser(
Context const & context,
ws_parser<NewlinesOnly, NoNewlines> const & parser,
std::ostream & os,
int components = 0);
template<typename Context>
void print_parser(
Context const & context,
bool_parser const & parser,
std::ostream & os,
int components = 0);
template< template<
typename Context, typename Context,
@@ -307,12 +319,19 @@ namespace boost { namespace parser { namespace detail {
int Radix, int Radix,
int MinDigits, int MinDigits,
int MaxDigits, int MaxDigits,
typename Expected> typename Expected,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
uint_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser, uint_parser<
T,
Radix,
MinDigits,
MaxDigits,
Expected,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template< template<
typename Context, typename Context,
@@ -320,38 +339,51 @@ namespace boost { namespace parser { namespace detail {
int Radix, int Radix,
int MinDigits, int MinDigits,
int MaxDigits, int MaxDigits,
typename Expected> typename Expected,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
int_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser, int_parser<T, Radix, MinDigits, MaxDigits, Expected, ParserMods> const &
parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename T> template<typename Context, typename T, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
float_parser<T> const & parser, float_parser<T, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
float_parser<float> const & parser, float_parser<float, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
float_parser<double> const & parser, float_parser<double, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components);
template<typename Context, typename SwitchValue, typename OrParser> template<
typename Context,
typename SwitchValue,
typename OrParser,
typename ParserMods>
void print_parser_impl(
Context const & context,
switch_parser<SwitchValue, OrParser, ParserMods> const & parser,
std::ostream & os,
int components);
template<bool SuppressOmit = false, typename Context, typename Parser>
void print_parser( void print_parser(
Context const & context, Context const & context,
switch_parser<SwitchValue, OrParser> const & parser, Parser const & parser,
std::ostream & os, std::ostream & os,
int components = 0); int components = 0);

View File

@@ -43,36 +43,44 @@ namespace boost { namespace parser { namespace detail {
typename Parser, typename Parser,
typename DelimiterParser, typename DelimiterParser,
typename MinType, typename MinType,
typename MaxType> typename MaxType,
typename ParserMods>
struct n_aray_parser< struct n_aray_parser<
repeat_parser<Parser, DelimiterParser, MinType, MaxType>> repeat_parser<Parser, DelimiterParser, MinType, MaxType, ParserMods>>
: std::true_type : std::true_type
{}; {};
template<typename Parser, typename MinType, typename MaxType> template<
struct n_aray_parser<repeat_parser<Parser, detail::nope, MinType, MaxType>> typename Parser,
typename MinType,
typename MaxType,
typename ParserMods>
struct n_aray_parser<
repeat_parser<Parser, detail::nope, MinType, MaxType, ParserMods>>
: std::false_type : std::false_type
{}; {};
template<typename Parser, typename DelimiterParser> template<typename Parser, typename DelimiterParser, typename ParserMods>
struct n_aray_parser<delimited_seq_parser<Parser, DelimiterParser>> struct n_aray_parser<
delimited_seq_parser<Parser, DelimiterParser, ParserMods>>
: std::true_type : std::true_type
{}; {};
template<typename ParserTuple> template<typename ParserTuple, typename ParserMods>
struct n_aray_parser<or_parser<ParserTuple>> : std::true_type struct n_aray_parser<or_parser<ParserTuple, ParserMods>> : std::true_type
{}; {};
template<typename ParserTuple> template<typename ParserTuple, typename ParserMods>
struct n_aray_parser<perm_parser<ParserTuple>> : std::true_type struct n_aray_parser<perm_parser<ParserTuple, ParserMods>> : std::true_type
{}; {};
template< template<
typename ParserTuple, typename ParserTuple,
typename BacktrackingTuple, typename BacktrackingTuple,
typename CombiningGroups> typename CombiningGroups,
typename ParserMods>
struct n_aray_parser< struct n_aray_parser<
seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups>> seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups, ParserMods>>
: std::true_type : std::true_type
{}; {};
@@ -101,10 +109,16 @@ namespace boost { namespace parser { namespace detail {
typename Parser, typename Parser,
typename DelimiterParser, typename DelimiterParser,
typename MinType, typename MinType,
typename MaxType> typename MaxType,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
repeat_parser<Parser, DelimiterParser, MinType, MaxType> const & parser, repeat_parser<
Parser,
DelimiterParser,
MinType,
MaxType,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -116,7 +130,7 @@ namespace boost { namespace parser { namespace detail {
os << "*"; os << "*";
if (n_ary_child) if (n_ary_child)
os << "("; os << "(";
detail::print_parser( detail::print_parser_impl(
context, parser.parser_, os, components + 1); context, parser.parser_, os, components + 1);
if (n_ary_child) if (n_ary_child)
os << ")"; os << ")";
@@ -124,7 +138,7 @@ namespace boost { namespace parser { namespace detail {
os << "+"; os << "+";
if (n_ary_child) if (n_ary_child)
os << "("; os << "(";
detail::print_parser( detail::print_parser_impl(
context, parser.parser_, os, components + 1); context, parser.parser_, os, components + 1);
if (n_ary_child) if (n_ary_child)
os << ")"; os << ")";
@@ -141,22 +155,22 @@ namespace boost { namespace parser { namespace detail {
detail::print(os, max_); detail::print(os, max_);
os << ")["; os << ")[";
} }
detail::print_parser( detail::print_parser_impl(
context, parser.parser_, os, components + 1); context, parser.parser_, os, components + 1);
os << "]"; os << "]";
} }
} else { } else {
detail::print_parser(context, parser.parser_, os, components + 1); detail::print_parser_impl(context, parser.parser_, os, components + 1);
os << " % "; os << " % ";
detail::print_parser( detail::print_parser_impl(
context, parser.delimiter_parser_, os, components + 2); context, parser.delimiter_parser_, os, components + 2);
} }
} }
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
opt_parser<Parser> const & parser, opt_parser<Parser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -164,7 +178,7 @@ namespace boost { namespace parser { namespace detail {
constexpr bool n_ary_child = n_aray_parser_v<Parser>; constexpr bool n_ary_child = n_aray_parser_v<Parser>;
if (n_ary_child) if (n_ary_child)
os << "("; os << "(";
detail::print_parser(context, parser.parser_, os, components + 1); detail::print_parser_impl(context, parser.parser_, os, components + 1);
if (n_ary_child) if (n_ary_child)
os << ")"; os << ")";
} }
@@ -189,16 +203,16 @@ namespace boost { namespace parser { namespace detail {
} }
if (i) if (i)
os << ws_or; os << ws_or;
detail::print_parser(context, parser, os, components); detail::print_parser_impl(context, parser, os, components);
++components; ++components;
++i; ++i;
}); });
} }
template<typename Context, typename ParserTuple> template<typename Context, typename ParserTuple, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
or_parser<ParserTuple> const & parser, or_parser<ParserTuple, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -206,10 +220,10 @@ namespace boost { namespace parser { namespace detail {
context, parser, os, components, " | ...", " | "); context, parser, os, components, " | ...", " | ");
} }
template<typename Context, typename ParserTuple> template<typename Context, typename ParserTuple, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
perm_parser<ParserTuple> const & parser, perm_parser<ParserTuple, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -221,11 +235,15 @@ namespace boost { namespace parser { namespace detail {
typename Context, typename Context,
typename ParserTuple, typename ParserTuple,
typename BacktrackingTuple, typename BacktrackingTuple,
typename CombiningGroups> typename CombiningGroups,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups> const & seq_parser<
parser, ParserTuple,
BacktrackingTuple,
CombiningGroups,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -264,14 +282,18 @@ namespace boost { namespace parser { namespace detail {
os << ']'; os << ']';
} }
template<typename Context, typename Parser, typename Action> template<
void print_parser( typename Context,
typename Parser,
typename Action,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
action_parser<Parser, Action> const & parser, action_parser<Parser, Action, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
detail::print_parser(context, parser.parser_, os, components); detail::print_parser_impl(context, parser.parser_, os, components);
os << "[<<action>>]"; os << "[<<action>>]";
} }
@@ -287,14 +309,14 @@ namespace boost { namespace parser { namespace detail {
if (++components == parser_component_limit) if (++components == parser_component_limit)
os << "..."; os << "...";
else else
detail::print_parser(context, parser, os, components + 1); detail::print_parser_impl(context, parser, os, components + 1);
os << "]"; os << "]";
} }
template<typename Context, typename Parser, typename F> template<typename Context, typename Parser, typename F, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
transform_parser<Parser, F> const & parser, transform_parser<Parser, F, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -302,21 +324,10 @@ namespace boost { namespace parser { namespace detail {
context, "transform(<<f>>)", parser.parser_, os, components); context, "transform(<<f>>)", parser.parser_, os, components);
} }
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
omit_parser<Parser> const & parser, raw_parser<Parser, ParserMods> const & parser,
std::ostream & os,
int components)
{
detail::print_directive(
context, "omit", parser.parser_, os, components);
}
template<typename Context, typename Parser>
void print_parser(
Context const & context,
raw_parser<Parser> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -324,10 +335,10 @@ namespace boost { namespace parser { namespace detail {
} }
#if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS #if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
string_view_parser<Parser> const & parser, string_view_parser<Parser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -336,10 +347,10 @@ namespace boost { namespace parser { namespace detail {
} }
#endif #endif
template<typename Context, typename Parser> template<typename Context, typename Parser, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
lexeme_parser<Parser> const & parser, lexeme_parser<Parser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -347,21 +358,14 @@ namespace boost { namespace parser { namespace detail {
context, "lexeme", parser.parser_, os, components); context, "lexeme", parser.parser_, os, components);
} }
template<typename Context, typename Parser> template<
void print_parser( typename Context,
typename Parser,
typename SkipParser,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
no_case_parser<Parser> const & parser, skip_parser<Parser, SkipParser, ParserMods> const & parser,
std::ostream & os,
int components)
{
detail::print_directive(
context, "no_case", parser.parser_, os, components);
}
template<typename Context, typename Parser, typename SkipParser>
void print_parser(
Context const & context,
skip_parser<Parser, SkipParser> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -370,7 +374,7 @@ namespace boost { namespace parser { namespace detail {
context, "skip", parser.parser_, os, components); context, "skip", parser.parser_, os, components);
} else { } else {
os << "skip("; os << "skip(";
detail::print_parser( detail::print_parser_impl(
context, parser.skip_parser_.parser_, os, components); context, parser.skip_parser_.parser_, os, components);
os << ")"; os << ")";
detail::print_directive( detail::print_directive(
@@ -378,21 +382,25 @@ namespace boost { namespace parser { namespace detail {
} }
} }
template<typename Context, typename Parser, bool FailOnMatch> template<
void print_parser( typename Context,
typename Parser,
expect_match_t ExpectMatch,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
expect_parser<Parser, FailOnMatch> const & parser, expect_parser<Parser, ExpectMatch, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
if (FailOnMatch) if constexpr (ExpectMatch == expect_match_t::yes)
os << "!";
else
os << "&"; os << "&";
else
os << "!";
constexpr bool n_ary_child = n_aray_parser_v<Parser>; constexpr bool n_ary_child = n_aray_parser_v<Parser>;
if (n_ary_child) if (n_ary_child)
os << "("; os << "(";
detail::print_parser(context, parser.parser_, os, components + 1); detail::print_parser_impl(context, parser.parser_, os, components + 1);
if (n_ary_child) if (n_ary_child)
os << ")"; os << ")";
} }
@@ -403,15 +411,17 @@ namespace boost { namespace parser { namespace detail {
typename Parser, typename Parser,
typename Attribute, typename Attribute,
typename LocalState, typename LocalState,
typename ParamsTuple> typename ParamsTuple,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
rule_parser< rule_parser<
UseCallbacks, UseCallbacks,
Parser, Parser,
Attribute, Attribute,
LocalState, LocalState,
ParamsTuple> const & parser, ParamsTuple,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -428,10 +438,10 @@ namespace boost { namespace parser { namespace detail {
} }
} }
template<typename Context, typename T> template<typename Context, typename T, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
symbol_parser<T> const & parser, symbol_parser<T, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -441,40 +451,40 @@ namespace boost { namespace parser { namespace detail {
os << parser.diagnostic_text_; os << parser.diagnostic_text_;
} }
template<typename Context, typename Predicate> template<typename Context, typename Predicate, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
eps_parser<Predicate> const & parser, eps_parser<Predicate, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "eps(<<pred>>)"; os << "eps(<<pred>>)";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
eps_parser<nope> const & parser, eps_parser<nope, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "eps"; os << "eps";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
eoi_parser const & parser, eoi_parser<ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "eoi"; os << "eoi";
} }
template<typename Context, typename Atribute> template<typename Context, typename Atribute, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
attr_parser<Atribute> const & parser, attr_parser<Atribute, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -527,7 +537,7 @@ namespace boost { namespace parser { namespace detail {
} }
template<typename Context, typename T> template<typename Context, typename T>
struct char_print_parser_impl struct char_print_parser_impl_impl
{ {
static void call(Context const & context, std::ostream & os, T expected) static void call(Context const & context, std::ostream & os, T expected)
{ {
@@ -536,7 +546,7 @@ namespace boost { namespace parser { namespace detail {
}; };
template<typename Context, typename T, typename U> template<typename Context, typename T, typename U>
struct char_print_parser_impl<Context, char_pair<T, U>> struct char_print_parser_impl_impl<Context, char_pair<T, U>>
{ {
static void call( static void call(
Context const & context, Context const & context,
@@ -550,7 +560,7 @@ namespace boost { namespace parser { namespace detail {
}; };
template<typename Context, typename Iter, typename Sentinel, bool B> template<typename Context, typename Iter, typename Sentinel, bool B>
struct char_print_parser_impl<Context, char_range<Iter, Sentinel, B>> struct char_print_parser_impl_impl<Context, char_range<Iter, Sentinel, B>>
{ {
static void call( static void call(
Context const & context, Context const & context,
@@ -566,13 +576,25 @@ namespace boost { namespace parser { namespace detail {
} }
}; };
template<typename Context, typename Expected, typename AttributeType> template<
void print_parser( typename Context,
typename Expected,
typename AttributeType,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
char_parser<Expected, AttributeType> const & parser, char_parser<Expected, AttributeType, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
if constexpr (parser.mods_.omit_attr == parser::omit_attr_t::yes) {
if constexpr (is_nope_v<Expected>) {
os << "char_";
} else {
char_print_parser_impl_impl<Context, Expected>::call(
context, os, parser.expected_);
}
} else {
if (std::is_same_v<AttributeType, uint32_t>) if (std::is_same_v<AttributeType, uint32_t>)
os << "cp"; os << "cp";
else if (std::is_same_v<AttributeType, char>) else if (std::is_same_v<AttributeType, char>)
@@ -581,124 +603,107 @@ namespace boost { namespace parser { namespace detail {
os << "char_"; os << "char_";
if constexpr (!is_nope_v<Expected>) { if constexpr (!is_nope_v<Expected>) {
os << "("; os << "(";
char_print_parser_impl<Context, Expected>::call( char_print_parser_impl_impl<Context, Expected>::call(
context, os, parser.expected_); context, os, parser.expected_);
os << ")"; os << ")";
} }
} }
}
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
digit_parser const & parser, digit_parser<ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "digit"; os << "digit";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_subrange_parser<hex_digit_subranges> const & parser, char_subrange_parser<hex_digit_subranges, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "hex_digit"; os << "hex_digit";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_subrange_parser<control_subranges> const & parser, char_subrange_parser<control_subranges, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "control"; os << "control";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_set_parser<punct_chars> const & parser, char_set_parser<punct_chars, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "punct"; os << "punct";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_set_parser<lower_case_chars> const & parser, char_set_parser<lower_case_chars, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "lower"; os << "lower";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
char_set_parser<upper_case_chars> const & parser, char_set_parser<upper_case_chars, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "upper"; os << "upper";
} }
template<typename Context, typename Expected, typename AttributeType> template<
void print_parser( typename Context,
typename StrIter,
typename StrSentinel,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
omit_parser<char_parser<Expected, AttributeType>> const & parser, string_parser<StrIter, StrSentinel, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
if constexpr (is_nope_v<Expected>) { if constexpr (parser.mods_.omit_attr == parser::omit_attr_t::no) {
os << "omit[char_]"; os << "string(";
} else {
char_print_parser_impl<Context, Expected>::call(
context, os, parser.parser_.expected_);
} }
} os << "\"";
template<typename Context, typename StrIter, typename StrSentinel>
void print_parser(
Context const & context,
string_parser<StrIter, StrSentinel> const & parser,
std::ostream & os,
int components)
{
os << "string(\"";
for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE( for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE(
parser.expected_first_, parser.expected_last_) | parser.expected_first_, parser.expected_last_) |
text::as_utf8) { text::as_utf8) {
detail::print_char(os, c); detail::print_char(os, c);
} }
os << "\")"; os << "\"";
if constexpr (parser.mods_.omit_attr == parser::omit_attr_t::no) {
os << ")";
}
} }
template<typename Context, typename StrIter, typename StrSentinel> template<
void print_parser( typename Context,
typename Quotes,
typename Escapes,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
omit_parser<string_parser<StrIter, StrSentinel>> const & parser, quoted_string_parser<Quotes, Escapes, ParserMods> const & parser,
std::ostream & os,
int components)
{
os << "\"";
for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE(
parser.parser_.expected_first_,
parser.parser_.expected_last_) |
text::as_utf8) {
detail::print_char(os, c);
}
os << "\"";
}
template<typename Context, typename Quotes, typename Escapes>
void print_parser(
Context const & context,
quoted_string_parser<Quotes, Escapes> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -716,10 +721,14 @@ namespace boost { namespace parser { namespace detail {
os << ')'; os << ')';
} }
template<typename Context, bool NewlinesOnly, bool NoNewlines> template<
void print_parser( typename Context,
bool NewlinesOnly,
bool NoNewlines,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
ws_parser<NewlinesOnly, NoNewlines> const & parser, ws_parser<NewlinesOnly, NoNewlines, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -731,10 +740,10 @@ namespace boost { namespace parser { namespace detail {
os << "ws"; os << "ws";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
bool_parser const & parser, bool_parser<ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -747,10 +756,17 @@ namespace boost { namespace parser { namespace detail {
int Radix, int Radix,
int MinDigits, int MinDigits,
int MaxDigits, int MaxDigits,
typename Expected> typename Expected,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
uint_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser, uint_parser<
T,
Radix,
MinDigits,
MaxDigits,
Expected,
ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -791,27 +807,29 @@ namespace boost { namespace parser { namespace detail {
int Radix, int Radix,
int MinDigits, int MinDigits,
int MaxDigits, int MaxDigits,
typename Expected> typename Expected,
void print_parser( typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
int_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser, int_parser<T, Radix, MinDigits, MaxDigits, Expected, ParserMods> const &
parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
if (Radix == 10 && MinDigits == 1 && MaxDigits == -1) { if (Radix == 10 && MinDigits == 1 && MaxDigits == -1) {
if (std::is_same_v<T, short>) { if constexpr (std::is_same_v<T, short>) {
os << "short_"; os << "short_";
detail::print_expected(context, os, parser.expected_); detail::print_expected(context, os, parser.expected_);
return; return;
} else if (std::is_same_v<T, int>) { } else if constexpr (std::is_same_v<T, int>) {
os << "int_"; os << "int_";
detail::print_expected(context, os, parser.expected_); detail::print_expected(context, os, parser.expected_);
return; return;
} else if (std::is_same_v<T, long>) { } else if constexpr (std::is_same_v<T, long>) {
os << "long_"; os << "long_";
detail::print_expected(context, os, parser.expected_); detail::print_expected(context, os, parser.expected_);
return; return;
} else if (std::is_same_v<T, long long>) { } else if constexpr (std::is_same_v<T, long long>) {
os << "long_long"; os << "long_long";
detail::print_expected(context, os, parser.expected_); detail::print_expected(context, os, parser.expected_);
return; return;
@@ -822,60 +840,30 @@ namespace boost { namespace parser { namespace detail {
detail::print_expected(context, os, parser.expected_); detail::print_expected(context, os, parser.expected_);
} }
template<typename Context> template<typename Context, typename T, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
int_parser<short> const & parser, float_parser<T, ParserMods> const & parser,
std::ostream & os,
int components)
{
os << "short_";
}
template<typename Context>
void print_parser(
Context const & context,
int_parser<long> const & parser,
std::ostream & os,
int components)
{
os << "long_";
}
template<typename Context>
void print_parser(
Context const & context,
int_parser<long long> const & parser,
std::ostream & os,
int components)
{
os << "long_long";
}
template<typename Context, typename T>
void print_parser(
Context const & context,
float_parser<T> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "float<" << detail::type_name<T>() << ">"; os << "float<" << detail::type_name<T>() << ">";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
float_parser<float> const & parser, float_parser<float, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
os << "float_"; os << "float_";
} }
template<typename Context> template<typename Context, typename ParserMods>
void print_parser( void print_parser_impl(
Context const & context, Context const & context,
float_parser<double> const & parser, float_parser<double, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -886,10 +874,11 @@ namespace boost { namespace parser { namespace detail {
typename Context, typename Context,
typename ParserTuple, typename ParserTuple,
typename BacktrackingTuple, typename BacktrackingTuple,
typename CombiningGroups> typename CombiningGroups,
typename ParserMods>
void print_switch_matchers( void print_switch_matchers(
Context const & context, Context const & context,
seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups> const & seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups, ParserMods> const &
parser, parser,
std::ostream & os, std::ostream & os,
int components) int components)
@@ -901,15 +890,15 @@ namespace boost { namespace parser { namespace detail {
detail::resolve( detail::resolve(
context, parser::get(parser.parsers_, 0_c).pred_.value_)); context, parser::get(parser.parsers_, 0_c).pred_.value_));
os << ", "; os << ", ";
detail::print_parser( detail::print_parser_impl(
context, parser::get(parser.parsers_, 1_c), os, components); context, parser::get(parser.parsers_, 1_c), os, components);
os << ")"; os << ")";
} }
template<typename Context, typename ParserTuple> template<typename Context, typename ParserTuple, typename ParserMods>
void print_switch_matchers( void print_switch_matchers(
Context const & context, Context const & context,
or_parser<ParserTuple> const & parser, or_parser<ParserTuple, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -928,10 +917,14 @@ namespace boost { namespace parser { namespace detail {
}); });
} }
template<typename Context, typename SwitchValue, typename OrParser> template<
void print_parser( typename Context,
typename SwitchValue,
typename OrParser,
typename ParserMods>
void print_parser_impl(
Context const & context, Context const & context,
switch_parser<SwitchValue, OrParser> const & parser, switch_parser<SwitchValue, OrParser, ParserMods> const & parser,
std::ostream & os, std::ostream & os,
int components) int components)
{ {
@@ -942,6 +935,123 @@ namespace boost { namespace parser { namespace detail {
context, parser.or_parser_, os, components); context, parser.or_parser_, os, components);
} }
template<typename Context, typename Parser>
struct scoped_print_parser_mods
{
using parser_mods = decltype(std::declval<Parser>().mods_);
scoped_print_parser_mods(
Context const & context,
Parser const & parser,
std::ostream & os,
int & components,
bool suppress_omit) :
context_(context),
parser_(parser),
os_(os),
components_(components),
skip_omit_(suppress_omit)
{
if constexpr (parser_mods::omit_attr == parser::omit_attr_t::yes) {
if (!skip_omit_ && !skip_omit(parser_))
os_ << "omit[";
}
if constexpr (
parser_mods::ignore_case == parser::ignore_case_t::yes) {
os_ << "no_case[";
}
if constexpr (!is_nope_v<typename parser_mods::pre_parser_type>) {
print_expected_operator<
typename parser_mods::pre_parser_type>();
detail::print_parser<true>(
context_,
parser_.mods_.pre_parser.parser,
os_,
components_);
os_ << " >> ";
}
}
~scoped_print_parser_mods()
{
if constexpr (!is_nope_v<typename parser_mods::post_parser_type>) {
os_ << " >> ";
print_expected_operator<
typename parser_mods::post_parser_type>();
detail::print_parser<true>(
context_,
parser_.mods_.post_parser.parser,
os_,
components_);
}
if constexpr (
parser_mods::ignore_case == parser::ignore_case_t::yes) {
os_ << "]";
}
if constexpr (parser_mods::omit_attr == parser::omit_attr_t::yes) {
if (!skip_omit_ && !skip_omit(parser_))
os_ << "]";
}
}
template<typename ExpectedParser>
void print_expected_operator()
{
if constexpr (ExpectedParser::expect_match == expect_match_t::yes) {
os_ << "&";
} else {
os_ << "!";
}
}
template<typename T>
static bool skip_omit(T const &)
{
return false;
}
template<typename Expected, typename AttributeType, typename ParserMods>
static bool
skip_omit(char_parser<Expected, AttributeType, ParserMods> const &)
{
return !std::is_same_v<Expected, detail::nope>;
}
template<typename StrIter, typename StrSentinel, typename ParserMods>
static bool
skip_omit(string_parser<StrIter, StrSentinel, ParserMods> const &)
{
return true;
}
template<
typename Parser2,
expect_match_t ExpectMatch,
typename ParserMods>
static bool
skip_omit(expect_parser<Parser2, ExpectMatch, ParserMods> const &)
{
return true;
}
Context const & context_;
Parser const & parser_;
std::ostream & os_;
int & components_;
bool skip_omit_;
};
// TODO: Document how recursive directives like 'omit[]' and
// `no_case[]`will reappear for subparsers sometimes, as in
// omt[*omit[char_]] (see test/tracing.cpp).
template<bool SuppressOmit, typename Context, typename Parser>
void print_parser(
Context const & context,
Parser const & parser,
std::ostream & os,
int components)
{
scoped_print_parser_mods _(
context, parser, os, components, SuppressOmit);
detail::print_parser_impl(context, parser, os, components);
}
}}} }}}
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -149,6 +149,35 @@ namespace boost { namespace parser {
{}; {};
} }
enum struct omit_attr_t { no, yes };
enum struct ignore_case_t { no, yes };
enum struct expect_match_t { no, yes };
template<typename Parser, expect_match_t ExpectMatch>
struct expected_parser
{
static constexpr expect_match_t expect_match = ExpectMatch;
Parser parser;
};
template<
omit_attr_t OmitAttr = omit_attr_t::no,
ignore_case_t IgnoreCase = ignore_case_t::no,
typename PreParser = detail::nope,
typename PostParser = detail::nope>
struct parser_modifiers
{
using pre_parser_type = PreParser;
using post_parser_type = PostParser;
static constexpr omit_attr_t omit_attr = OmitAttr;
static constexpr ignore_case_t ignore_case = IgnoreCase;
[[no_unique_address]] PreParser pre_parser;
[[no_unique_address]] PostParser post_parser;
};
/** Repeats the application of another parser `p` of type `Parser`, /** Repeats the application of another parser `p` of type `Parser`,
optionally applying another parser `d` of type `DelimiterParser` in optionally applying another parser `d` of type `DelimiterParser` in
between each pair of applications of `p`. The parse succeeds if `p` between each pair of applications of `p`. The parse succeeds if `p`
@@ -159,20 +188,21 @@ namespace boost { namespace parser {
typename Parser, typename Parser,
typename DelimiterParser = detail::nope, typename DelimiterParser = detail::nope,
typename MinType = int64_t, typename MinType = int64_t,
typename MaxType = int64_t> typename MaxType = int64_t,
typename ParserMods = parser_modifiers<>>
struct repeat_parser; struct repeat_parser;
/** Repeats the application of another parser `p` of type `Parser`, `[0, /** Repeats the application of another parser `p` of type `Parser`, `[0,
Inf)` times. The parse always succeeds. The attribute produced is a Inf)` times. The parse always succeeds. The attribute produced is a
sequence of the type of attribute produced by `Parser`. */ sequence of the type of attribute produced by `Parser`. */
template<typename Parser> template<typename Parser, typename ParserMods>
struct zero_plus_parser; struct zero_plus_parser;
/** Repeats the application of another parser `p` of type `Parser`, `[1, /** Repeats the application of another parser `p` of type `Parser`, `[1,
Inf)` times. The parse succeeds iff `p` succeeds at least once. The Inf)` times. The parse succeeds iff `p` succeeds at least once. The
attribute produced is a sequence of the type of attribute produced by attribute produced is a sequence of the type of attribute produced by
`Parser`. */ `Parser`. */
template<typename Parser> template<typename Parser, typename ParserMods>
struct one_plus_parser; struct one_plus_parser;
/** Repeats the application of another parser `p` of type `Parser`, `[1, /** Repeats the application of another parser `p` of type `Parser`, `[1,
@@ -181,14 +211,14 @@ namespace boost { namespace parser {
succeeds at least once, and `d` succeeds each time it is applied. The succeeds at least once, and `d` succeeds each time it is applied. The
attribute produced is a sequence of the type of attribute produced by attribute produced is a sequence of the type of attribute produced by
`Parser`. */ `Parser`. */
template<typename Parser, typename DelimiterParser> template<typename Parser, typename DelimiterParser, typename ParserMods>
struct delimited_seq_parser; struct delimited_seq_parser;
/** Repeats the application of another parser of type `Parser`, `[0, 1]` /** Repeats the application of another parser of type `Parser`, `[0, 1]`
times. The parse always succeeds. The attribute produced is a times. The parse always succeeds. The attribute produced is a
`std::optional<T>`, where `T` is the type of attribute produced by `std::optional<T>`, where `T` is the type of attribute produced by
`Parser`. */ `Parser`. */
template<typename Parser> template<typename Parser, typename ParserMods>
struct opt_parser; struct opt_parser;
/** Applies each parser in `ParserTuple`, in order, stopping after the /** Applies each parser in `ParserTuple`, in order, stopping after the
@@ -196,7 +226,7 @@ namespace boost { namespace parser {
one of the sub-parsers succeeds. The attribute produced is a one of the sub-parsers succeeds. The attribute produced is a
`std::variant` over the types of attribute produced by the parsers in `std::variant` over the types of attribute produced by the parsers in
`ParserTuple`. */ `ParserTuple`. */
template<typename ParserTuple> template<typename ParserTuple, typename ParserMods>
struct or_parser; struct or_parser;
/** Applies each parsers in `ParserTuple`, an any order, stopping after /** Applies each parsers in `ParserTuple`, an any order, stopping after
@@ -207,7 +237,7 @@ namespace boost { namespace parser {
`ParserTuple`, not the order of the parsers' matches. It is an error `ParserTuple`, not the order of the parsers' matches. It is an error
to specialize `perm_parser` with a `ParserTuple` template parameter to specialize `perm_parser` with a `ParserTuple` template parameter
that includes an `eps_parser`. */ that includes an `eps_parser`. */
template<typename ParserTuple> template<typename ParserTuple, typename ParserMods>
struct perm_parser; struct perm_parser;
/** Applies each parser in `ParserTuple`, in order. The parse succeeds /** Applies each parser in `ParserTuple`, in order. The parse succeeds
@@ -220,14 +250,15 @@ namespace boost { namespace parser {
template< template<
typename ParserTuple, typename ParserTuple,
typename BacktrackingTuple, typename BacktrackingTuple,
typename CombiningGroups> typename CombiningGroups,
typename ParserMods>
struct seq_parser; struct seq_parser;
/** Applies the given parser `p` of type `Parser` and an invocable `a` of /** Applies the given parser `p` of type `Parser` and an invocable `a` of
type `Action`. `Action` shall model `semantic_action`, and `a` will type `Action`. `Action` shall model `semantic_action`, and `a` will
only be invoked if `p` succeeds. The parse succeeds iff `p` succeeds. only be invoked if `p` succeeds. The parse succeeds iff `p` succeeds.
Produces no attribute. */ Produces no attribute. */
template<typename Parser, typename Action> template<typename Parser, typename Action, typename ParserMods>
struct action_parser; struct action_parser;
/** Applies the given parser `p` of type `Parser`. The attribute produced /** Applies the given parser `p` of type `Parser`. The attribute produced
@@ -235,21 +266,14 @@ namespace boost { namespace parser {
only be invoked if `p` succeeds and sttributes are currently being only be invoked if `p` succeeds and sttributes are currently being
generated. The parse succeeds iff `p` succeeds. The attribute generated. The parse succeeds iff `p` succeeds. The attribute
produced is the the result of the call to `f`. */ produced is the the result of the call to `f`. */
template<typename Parser, typename F> template<typename Parser, typename F, typename ParserMods>
struct transform_parser; struct transform_parser;
/** Applies the given parser `p` of type `Parser`. This parser produces
no attribute, and suppresses the production of any attributes that
would otherwise be produced by `p`. The parse succeeds iff `p`
succeeds. */
template<typename Parser>
struct omit_parser;
/** Applies the given parser `p` of type `Parser`; regardless of the /** Applies the given parser `p` of type `Parser`; regardless of the
attribute produced by `Parser`, this parser's attribute is equivalent attribute produced by `Parser`, this parser's attribute is equivalent
to `_where(ctx)` within a semantic action on `p`. The parse succeeds to `_where(ctx)` within a semantic action on `p`. The parse succeeds
iff `p` succeeds. */ iff `p` succeeds. */
template<typename Parser> template<typename Parser, typename ParserMods>
struct raw_parser; struct raw_parser;
#if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS #if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
@@ -262,34 +286,30 @@ namespace boost { namespace parser {
non-contiguous, code using `string_view_parser` is ill-formed. The non-contiguous, code using `string_view_parser` is ill-formed. The
parse succeeds iff `p` succeeds. This parser is only available in parse succeeds iff `p` succeeds. This parser is only available in
C++20 and later. */ C++20 and later. */
template<typename Parser> template<typename Parser, typename ParserMods>
struct string_view_parser; struct string_view_parser;
#endif #endif
/** Applies the given parser `p` of type `Parser`, disabling the current /** Applies the given parser `p` of type `Parser`, disabling the current
skipper in use, if any. The parse succeeds iff `p` succeeds. The skipper in use, if any. The parse succeeds iff `p` succeeds. The
attribute produced is the type of attribute produced by `Parser`. */ attribute produced is the type of attribute produced by `Parser`. */
template<typename Parser> template<typename Parser, typename ParserMods>
struct lexeme_parser; struct lexeme_parser;
/** Applies the given parser `p` of type `Parser`, enabling
case-insensitive matching, based on Unicode case folding. The parse
succeeds iff `p` succeeds. The attribute produced is the type of
attribute produced by `Parser`. */
template<typename Parser>
struct no_case_parser;
/** Applies the given parser `p` of type `Parser`, using a parser of type /** Applies the given parser `p` of type `Parser`, using a parser of type
`SkipParser` as the skipper. The parse succeeds iff `p` succeeds. `SkipParser` as the skipper. The parse succeeds iff `p` succeeds.
The attribute produced is the type of attribute produced by The attribute produced is the type of attribute produced by
`Parser`. */ `Parser`. */
template<typename Parser, typename SkipParser = detail::nope> template<
typename Parser,
typename SkipParser = detail::nope,
typename ParserMods = parser_modifiers<>>
struct skip_parser; struct skip_parser;
/** Applies the given parser `p` of type `Parser`, producing no attributes /** Applies the given parser `p` of type `Parser`, producing no attributes
and consuming no input. The parse succeeds iff `p`'s success is and consuming no input. The parse succeeds iff `p`'s success is equal
unequal to `FailOnMatch`. */ to `ExpectMatch == expect_match_t::yes`. */
template<typename Parser, bool FailOnMatch> template<typename Parser, expect_match_t ExpectMatch, typename ParserMods>
struct expect_parser; struct expect_parser;
/** Matches one of a set S of possible inputs, each of which is associated /** Matches one of a set S of possible inputs, each of which is associated
@@ -298,7 +318,7 @@ namespace boost { namespace parser {
from S dynamically, during parsing; any such changes are reverted at from S dynamically, during parsing; any such changes are reverted at
the end of parsing. The parse succeeds iff an element of S is the end of parsing. The parse succeeds iff an element of S is
matched. \see `symbols` */ matched. \see `symbols` */
template<typename T> template<typename T, typename ParserMods>
struct symbol_parser; struct symbol_parser;
/** Applies another parser `p`, associated with this parser via `TagType`. /** Applies another parser `p`, associated with this parser via `TagType`.
@@ -317,22 +337,24 @@ namespace boost { namespace parser {
typename TagType, typename TagType,
typename Attribute, typename Attribute,
typename LocalState, typename LocalState,
typename ParamsTuple> typename ParamsTuple,
typename ParserMods>
struct rule_parser; struct rule_parser;
/** Matches anything, and consumes no input. If `Predicate` is anything /** Matches anything, and consumes no input. If `Predicate` is anything
other than `detail::nope` (which it is by default), and `pred_(ctx)` other than `detail::nope` (which it is by default), and `pred_(ctx)`
evaluates to false, where `ctx` is the parser context, the parse evaluates to false, where `ctx` is the parser context, the parse
fails. */ fails. */
template<typename Predicate> template<typename Predicate, typename ParserMods>
struct eps_parser; struct eps_parser;
/** Matches only the end of input. Produces no attribute. */ /** Matches only the end of input. Produces no attribute. */
template<typename ParserMods>
struct eoi_parser; struct eoi_parser;
/** Matches anything, consumes no input, and produces an attribute of type /** Matches anything, consumes no input, and produces an attribute of type
`RESOLVE(Attribute)`. */ `RESOLVE(Attribute)`. */
template<typename Attribute> template<typename Attribute, typename ParserMods>
struct attr_parser; struct attr_parser;
/** A tag type that can be passed as the first parameter to `char_()` when /** A tag type that can be passed as the first parameter to `char_()` when
@@ -349,7 +371,10 @@ namespace boost { namespace parser {
parse fails only if the parser is constructed with a specific set of parse fails only if the parser is constructed with a specific set of
expected code point values that does not include the matched code expected code point values that does not include the matched code
point. */ point. */
template<typename Expected, typename AttributeType = void> template<
typename Expected,
typename AttributeType = void,
typename ParserMods = parser_modifiers<>>
struct char_parser; struct char_parser;
/** Matches a single code point that is equal to one of the code points /** Matches a single code point that is equal to one of the code points
@@ -357,7 +382,7 @@ namespace boost { namespace parser {
characters for matching Unicode character classes like punctuation or characters for matching Unicode character classes like punctuation or
lower case. Attribute type is the attribute type of the character lower case. Attribute type is the attribute type of the character
being matched. */ being matched. */
template<typename Tag> template<typename Tag, typename ParserMods>
struct char_set_parser; struct char_set_parser;
/** Matches a single code point that falls into one of the subranges of /** Matches a single code point that falls into one of the subranges of
@@ -365,22 +390,26 @@ namespace boost { namespace parser {
sets of characters for matching Unicode character classes like hex sets of characters for matching Unicode character classes like hex
digits or control characters. Attribute type is the attribute type of digits or control characters. Attribute type is the attribute type of
the character being matched. */ the character being matched. */
template<typename Tag> template<typename Tag, typename ParserMods>
struct char_subrange_parser; struct char_subrange_parser;
/** Matches a single decimal digit code point, using the Unicode character /** Matches a single decimal digit code point, using the Unicode character
class Hex_Digit. Attribute type is the attribute type of the class Hex_Digit. Attribute type is the attribute type of the
character being matched. */ character being matched. */
template<typename ParserMods>
struct digit_parser; struct digit_parser;
/** Matches a particular string, delimited by an iterator sentinel pair; /** Matches a particular string, delimited by an iterator sentinel pair;
produces no attribute. */ produces no attribute. */
template<typename StrIter, typename StrSentinel> template<typename StrIter, typename StrSentinel, typename ParserMods>
struct string_parser; struct string_parser;
/** Matches a string delimited by quotation marks; produces a /** Matches a string delimited by quotation marks; produces a
`std::string` attribute. */ `std::string` attribute. */
template<typename Quotes = detail::nope, typename Escapes = detail::nope> template<
typename Quotes = detail::nope,
typename Escapes = detail::nope,
typename ParserMods = parser_modifiers<>>
struct quoted_string_parser; struct quoted_string_parser;
/** Matches an end-of-line (`NewlinesOnly == true`), whitespace /** Matches an end-of-line (`NewlinesOnly == true`), whitespace
@@ -388,11 +417,12 @@ namespace boost { namespace parser {
but not newline) code point, based on the Unicode definitions of each but not newline) code point, based on the Unicode definitions of each
(also matches the two code points `"\r\n"`). Produces no (also matches the two code points `"\r\n"`). Produces no
attribute. */ attribute. */
template<bool NewlinesOnly, bool NoNewlines> template<bool NewlinesOnly, bool NoNewlines, typename ParserMods>
struct ws_parser; struct ws_parser;
/** Matches the strings "true" and "false", producing an attribute of /** Matches the strings "true" and "false", producing an attribute of
`true` or `false`, respectively, and fails on any other input. */ `true` or `false`, respectively, and fails on any other input. */
template<typename ParserMods>
struct bool_parser; struct bool_parser;
/** Matches an unsigned number of radix `Radix`, of at least `MinDigits` /** Matches an unsigned number of radix `Radix`, of at least `MinDigits`
@@ -406,7 +436,8 @@ namespace boost { namespace parser {
int Radix = 10, int Radix = 10,
int MinDigits = 1, int MinDigits = 1,
int MaxDigits = -1, int MaxDigits = -1,
typename Expected = detail::nope> typename Expected = detail::nope,
typename ParserMods = parser_modifiers<>>
struct uint_parser; struct uint_parser;
/** Matches a signed number of radix `Radix`, of at least `MinDigits` and /** Matches a signed number of radix `Radix`, of at least `MinDigits` and
@@ -420,12 +451,13 @@ namespace boost { namespace parser {
int Radix = 10, int Radix = 10,
int MinDigits = 1, int MinDigits = 1,
int MaxDigits = -1, int MaxDigits = -1,
typename Expected = detail::nope> typename Expected = detail::nope,
typename ParserMods = parser_modifiers<>>
struct int_parser; struct int_parser;
/** Matches a floating point number, producing an attribute of type /** Matches a floating point number, producing an attribute of type
`T`. */ `T`. */
template<typename T> template<typename T, typename ParserMods>
struct float_parser; struct float_parser;
/** Applies at most one of the parsers in `OrParser`. If `switch_value_` /** Applies at most one of the parsers in `OrParser`. If `switch_value_`
@@ -433,7 +465,10 @@ namespace boost { namespace parser {
first such parser is applied, and the success or failure and attribute first such parser is applied, and the success or failure and attribute
of the parse are those of the applied parser. Otherwise, the parse of the parse are those of the applied parser. Otherwise, the parse
fails. */ fails. */
template<typename SwitchValue, typename OrParser = detail::nope> template<
typename SwitchValue,
typename OrParser = detail::nope,
typename ParserMods = parser_modifiers<>>
struct switch_parser; struct switch_parser;
/** A wrapper for parsers that provides the operations that must be /** A wrapper for parsers that provides the operations that must be

View File

@@ -451,7 +451,7 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
template< template<
typename V, typename V,
@@ -469,7 +469,7 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
namespace detail { namespace detail {
template< template<
@@ -571,7 +571,8 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>> parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>>
[[nodiscard]] constexpr auto operator()( [[nodiscard]] constexpr auto operator()(
R && r, R && r,
parser_interface<Parser, GlobalState, ErrorHandler> const & parser_interface<Parser, GlobalState, ErrorHandler> const &
@@ -582,7 +583,8 @@ namespace boost::parser {
return (*this)( return (*this)(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
(ReplacementR &&)replacement, (ReplacementR &&)replacement,
trace_mode); trace_mode);
} }
@@ -625,7 +627,8 @@ namespace boost::parser {
return impl( return impl(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
(SkipParser &&)skip, (SkipParser &&)skip,
replacement); replacement);
} else { } else {

View File

@@ -116,7 +116,9 @@ namespace boost::parser {
return BOOST_PARSER_SUBRANGE(first, first); return BOOST_PARSER_SUBRANGE(first, first);
auto const search_parser = omit[*(char_ - parser)] >> -raw[parser]; auto const search_parser = omit[*(char_ - parser)] >> -raw[parser];
if constexpr (std::is_same_v<SkipParser, eps_parser<phony>>) { if constexpr (std::is_same_v<
SkipParser,
eps_parser<phony, parser_modifiers<>>>) {
auto result = parser::prefix_parse( auto result = parser::prefix_parse(
first, last, search_parser, trace_mode); first, last, search_parser, trace_mode);
if (*result) if (*result)
@@ -257,7 +259,7 @@ namespace boost::parser {
return parser::search( return parser::search(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<eps_parser<detail::phony, parser_modifiers<>>>{},
trace_mode); trace_mode);
} }
@@ -292,7 +294,7 @@ namespace boost::parser {
return parser::search( return parser::search(
BOOST_PARSER_SUBRANGE(first, last), BOOST_PARSER_SUBRANGE(first, last),
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<eps_parser<detail::phony, parser_modifiers<>>>{},
trace_mode); trace_mode);
} }
@@ -483,7 +485,7 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
template< template<
typename V, typename V,
@@ -496,7 +498,7 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
namespace detail { namespace detail {
template< template<
@@ -569,7 +571,8 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>> parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>>
[[nodiscard]] constexpr auto operator()( [[nodiscard]] constexpr auto operator()(
R && r, R && r,
parser_interface<Parser, GlobalState, ErrorHandler> const & parser_interface<Parser, GlobalState, ErrorHandler> const &
@@ -579,7 +582,8 @@ namespace boost::parser {
return (*this)( return (*this)(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
trace_mode); trace_mode);
} }
@@ -590,8 +594,8 @@ namespace boost::parser {
typename Parser, typename Parser,
typename GlobalState, typename GlobalState,
typename ErrorHandler, typename ErrorHandler,
typename SkipParser = typename SkipParser = parser_interface<
parser_interface<eps_parser<detail::phony>>, eps_parser<detail::phony, parser_modifiers<>>>,
typename Trace = trace, typename Trace = trace,
typename Enable = std::enable_if_t<is_parsable_range_v<R>>> typename Enable = std::enable_if_t<is_parsable_range_v<R>>>
[[nodiscard]] constexpr auto operator()( [[nodiscard]] constexpr auto operator()(
@@ -609,7 +613,8 @@ namespace boost::parser {
return impl( return impl(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
skip); skip);
} else if constexpr ( } else if constexpr (
detail::is_parser_iface<SkipParser> && detail::is_parser_iface<SkipParser> &&

View File

@@ -193,14 +193,13 @@ namespace boost::parser {
typename Parser, typename Parser,
typename GlobalState, typename GlobalState,
typename ErrorHandler> typename ErrorHandler>
split_view( split_view(V &&, parser_interface<Parser, GlobalState, ErrorHandler>, trace)
V &&, parser_interface<Parser, GlobalState, ErrorHandler>, trace)
-> split_view< -> split_view<
detail::text::detail::all_t<V>, detail::text::detail::all_t<V>,
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
template< template<
typename V, typename V,
@@ -213,7 +212,7 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
namespace detail { namespace detail {
template< template<
@@ -286,7 +285,8 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>> parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>>
[[nodiscard]] constexpr auto operator()( [[nodiscard]] constexpr auto operator()(
R && r, R && r,
parser_interface<Parser, GlobalState, ErrorHandler> const & parser_interface<Parser, GlobalState, ErrorHandler> const &
@@ -296,7 +296,8 @@ namespace boost::parser {
return (*this)( return (*this)(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
trace_mode); trace_mode);
} }
@@ -307,8 +308,8 @@ namespace boost::parser {
typename Parser, typename Parser,
typename GlobalState, typename GlobalState,
typename ErrorHandler, typename ErrorHandler,
typename SkipParser = typename SkipParser = parser_interface<
parser_interface<eps_parser<detail::phony>>, eps_parser<detail::phony, parser_modifiers<>>>,
typename Trace = trace, typename Trace = trace,
typename Enable = std::enable_if_t<is_parsable_range_v<R>>> typename Enable = std::enable_if_t<is_parsable_range_v<R>>>
[[nodiscard]] constexpr auto operator()( [[nodiscard]] constexpr auto operator()(
@@ -326,7 +327,8 @@ namespace boost::parser {
return impl( return impl(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
skip); skip);
} else if constexpr ( } else if constexpr (
detail::is_parser_iface<SkipParser> && detail::is_parser_iface<SkipParser> &&

View File

@@ -254,7 +254,9 @@ namespace boost::parser {
BOOST_PARSER_SUBRANGE(first, first), parse_result{}); BOOST_PARSER_SUBRANGE(first, first), parse_result{});
} }
if constexpr (std::is_same_v<SkipParser, eps_parser<phony>>) { if constexpr (std::is_same_v<
SkipParser,
eps_parser<phony, parser_modifiers<>>>) {
auto result = parser::prefix_parse( auto result = parser::prefix_parse(
first, last, search_parser, trace_mode); first, last, search_parser, trace_mode);
if (*result) { if (*result) {
@@ -578,7 +580,7 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
template< template<
typename V, typename V,
@@ -594,7 +596,7 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>>; parser_interface<eps_parser<detail::phony, parser_modifiers<>>>>;
namespace detail { namespace detail {
template< template<
@@ -697,7 +699,8 @@ namespace boost::parser {
Parser, Parser,
GlobalState, GlobalState,
ErrorHandler, ErrorHandler,
parser_interface<eps_parser<detail::phony>>> parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>>
[[nodiscard]] constexpr auto operator()( [[nodiscard]] constexpr auto operator()(
R && r, R && r,
parser_interface<Parser, GlobalState, ErrorHandler> const & parser_interface<Parser, GlobalState, ErrorHandler> const &
@@ -708,7 +711,8 @@ namespace boost::parser {
return (*this)( return (*this)(
(R &&)r, (R &&)r,
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
(F &&)f, (F &&)f,
trace_mode); trace_mode);
} }
@@ -755,7 +759,8 @@ namespace boost::parser {
return impl( return impl(
to_range<R>::call((R &&)r), to_range<R>::call((R &&)r),
parser, parser,
parser_interface<eps_parser<detail::phony>>{}, parser_interface<
eps_parser<detail::phony, parser_modifiers<>>>{},
(SkipParser &&)skip, (SkipParser &&)skip,
f); f);
} else { } else {

View File

@@ -39,7 +39,7 @@ constexpr auto double_s = u8"sS"; // U+0073 U+0073
// basic) // basic)
{ {
constexpr auto char_p = no_case[char_('a') | char_('B')]; auto char_p = no_case[char_('a') | char_('B')];
{ {
auto const result = parse("a", char_p); auto const result = parse("a", char_p);
@@ -461,12 +461,12 @@ constexpr auto double_s = u8"sS"; // U+0073 U+0073
{ {
constexpr auto mixed_sharp_s1 = U"ẞs"; constexpr auto mixed_sharp_s1 = U"ẞs";
constexpr auto mixed_sharp_s2 = U"sẞ"; constexpr auto mixed_sharp_s2 = U"sẞ";
auto const result = detail::no_case_aware_string_mismatch( auto const result =
detail::no_case_aware_string_mismatch<ignore_case_t::yes>(
mixed_sharp_s1, mixed_sharp_s1,
detail::text::null_sentinel, detail::text::null_sentinel,
mixed_sharp_s2, mixed_sharp_s2,
detail::text::null_sentinel, detail::text::null_sentinel);
true);
BOOST_TEST(result.first == detail::text::null_sentinel); BOOST_TEST(result.first == detail::text::null_sentinel);
BOOST_TEST(result.second == detail::text::null_sentinel); BOOST_TEST(result.second == detail::text::null_sentinel);
} }

View File

@@ -144,7 +144,7 @@ int main()
std::cout << "\n\n" std::cout << "\n\n"
<< "----------------------------------------\n" << "----------------------------------------\n"
<< "| transform)f_[] |\n" << "| transform(f)[] |\n"
<< "----------------------------------------\n"; << "----------------------------------------\n";
auto f = [](auto x) { return x; }; auto f = [](auto x) { return x; };
@@ -156,6 +156,8 @@ int main()
<< "----------------------------------------\n"; << "----------------------------------------\n";
PARSE(omit[char_]); PARSE(omit[char_]);
PARSE(omit[omit[char_]]);
PARSE(omit[*omit[char_]]);
std::cout << "\n\n" std::cout << "\n\n"
<< "----------------------------------------\n" << "----------------------------------------\n"
@@ -188,6 +190,15 @@ int main()
PARSE(skip[char_]); PARSE(skip[char_]);
PARSE(skip(ws)[char_]); PARSE(skip(ws)[char_]);
std::cout << "\n\n"
<< "----------------------------------------\n"
<< "| no_case[] |\n"
<< "----------------------------------------\n";
PARSE(no_case[char_]);
PARSE(no_case[no_case[char_]]);
PARSE(no_case[*no_case[char_]]);
std::cout << "\n\n" std::cout << "\n\n"
<< "----------------------------------------\n" << "----------------------------------------\n"
<< "| merge[] |\n" << "| merge[] |\n"
@@ -218,6 +229,16 @@ int main()
PARSE(!char_); PARSE(!char_);
PARSE(!(*char_ >> char_)); PARSE(!(*char_ >> char_));
PARSE(!char_ >> char_);
PARSE(*char_ >> !char_);
PARSE(!char_ >> *char_ >> char_ >> !char_);
try {
PARSE((!char_) > char_);
} catch (...) {
}
PARSE(*char_ > !char_);
PARSE((!char_) > *char_ >> char_ > !char_);
std::cout << "\n\n" std::cout << "\n\n"
<< "----------------------------------------\n" << "----------------------------------------\n"
<< "| operator& |\n" << "| operator& |\n"
@@ -226,6 +247,16 @@ int main()
PARSE(&char_); PARSE(&char_);
PARSE(&(*char_ >> char_)); PARSE(&(*char_ >> char_));
PARSE(&char_ >> char_);
PARSE(*char_ >> &char_);
PARSE(&char_ >> *char_ >> char_ >> &char_);
try {
PARSE(&char_ > char_);
} catch (...) {
}
PARSE(*char_ > &char_);
PARSE(&char_ >>*char_ >> char_ > &char_);
std::cout << "\n\n" std::cout << "\n\n"
<< "----------------------------------------\n" << "----------------------------------------\n"
<< "| symbols<T> |\n" << "| symbols<T> |\n"