2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-19 04:22:13 +00:00

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.
This commit is contained in:
Zach Laine
2024-12-09 02:25:01 -06:00
parent 35a7bd3c09
commit 974154c578
4 changed files with 57 additions and 40 deletions

View File

@@ -263,17 +263,14 @@ namespace boost { namespace parser { namespace detail {
std::ostream & os,
int components = 0);
template<typename Context, typename StrIter, typename StrSentinel>
template<
typename Context,
typename StrIter,
typename StrSentinel,
typename ParserMods>
void print_parser(
Context const & context,
string_parser<StrIter, StrSentinel> const & parser,
std::ostream & os,
int components = 0);
template<typename Context, typename StrIter, typename StrSentinel>
void print_parser(
Context const & context,
omit_parser<string_parser<StrIter, StrSentinel>> const & parser,
string_parser<StrIter, StrSentinel, ParserMods> const & parser,
std::ostream & os,
int components = 0);

View File

@@ -660,37 +660,30 @@ namespace boost { namespace parser { namespace detail {
os << "upper";
}
template<typename Context, typename StrIter, typename StrSentinel>
template<
typename Context,
typename StrIter,
typename StrSentinel,
typename ParserMods>
void print_parser(
Context const & context,
string_parser<StrIter, StrSentinel> const & parser,
string_parser<StrIter, StrSentinel, ParserMods> const & parser,
std::ostream & os,
int components)
{
os << "string(\"";
if constexpr (!parser.mods_.omit_attr) {
os << "string(";
}
os << "\"";
for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE(
parser.expected_first_, parser.expected_last_) |
text::as_utf8) {
detail::print_char(os, c);
}
os << "\")";
}
template<typename Context, typename StrIter, typename StrSentinel>
void print_parser(
Context const & context,
omit_parser<string_parser<StrIter, StrSentinel>> 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);
if constexpr (!parser.mods_.omit_attr) {
os << ")";
}
os << "\"";
}
template<typename Context, typename Quotes, typename Escapes>

View File

@@ -7161,10 +7161,13 @@ namespace boost { namespace parser {
#ifndef BOOST_PARSER_DOXYGEN
template<typename StrIter, typename StrSentinel>
template<typename StrIter, typename StrSentinel, typename ParserMods>
struct string_parser
{
constexpr string_parser() : expected_first_(), expected_last_() {}
using attribute_type = std::
conditional_t<ParserMods::omit_attr, detail::nope, std::string>;
constexpr string_parser() = default;
#if BOOST_PARSER_USE_CONCEPTS
template<parsable_range_like R>
@@ -7179,12 +7182,16 @@ namespace boost { namespace parser {
expected_last_(detail::make_view_end(r))
{}
constexpr string_parser(StrIter f, StrSentinel l, ParserMods mods) :
expected_first_(f), expected_last_(l), mods_(mods)
{}
template<
typename Iter,
typename Sentinel,
typename Context,
typename SkipParser>
std::string call(
attribute_type call(
Iter & first,
Sentinel last,
Context const & context,
@@ -7192,7 +7199,7 @@ namespace boost { namespace parser {
detail::flags flags,
bool & success) const
{
std::string retval;
attribute_type retval;
call(first, last, context, skip, flags, success, retval);
return retval;
}
@@ -7238,8 +7245,13 @@ namespace boost { namespace parser {
return;
}
detail::append(
retval, first, mismatch.first, detail::gen_attrs(flags));
if constexpr (!ParserMods::omit_attr) {
detail::append(
retval,
first,
mismatch.first,
detail::gen_attrs(flags));
}
first = mismatch.first;
} else {
@@ -7254,15 +7266,28 @@ namespace boost { namespace parser {
return;
}
detail::append(
retval, first, mismatch.first, detail::gen_attrs(flags));
if constexpr (!ParserMods::omit_attr) {
detail::append(
retval,
first,
mismatch.first,
detail::gen_attrs(flags));
}
first = mismatch.first;
}
}
template<typename ParserMods2>
constexpr auto with_parser_mods(ParserMods2 mods)
{
return string_parser<StrIter, StrSentinel, ParserMods2>{
expected_first_, expected_last_, std::move(mods)};
}
StrIter expected_first_;
StrSentinel expected_last_;
[[no_unique_address]] ParserMods mods_;
};
#if BOOST_PARSER_USE_CONCEPTS
@@ -7271,8 +7296,9 @@ namespace boost { namespace parser {
template<typename R>
#endif
string_parser(R r) -> string_parser<
decltype(detail::make_view_begin(r)),
decltype(detail::make_view_end(r))>;
decltype(detail::make_view_begin(r)),
decltype(detail::make_view_end(r)),
parser_modifiers<>>;
#endif
@@ -7602,7 +7628,8 @@ namespace boost { namespace parser {
#endif
constexpr auto lit(R && str) noexcept
{
return omit[parser::string(str)];
return parser_interface{parser::string(str).parser_.with_parser_mods(
parser_modifiers<true>{})};
}
#ifndef BOOST_PARSER_DOXYGEN

View File

@@ -384,7 +384,7 @@ namespace boost { namespace parser {
/** Matches a particular string, delimited by an iterator sentinel pair;
produces no attribute. */
template<typename StrIter, typename StrSentinel>
template<typename StrIter, typename StrSentinel, typename ParserMods>
struct string_parser;
/** Matches a string delimited by quotation marks; produces a