В foo_def.hpp
файле для проекта Boost.Spirit X3 у меня есть парсеры:
auto const identifier_component_unrestricted =
lexeme[(alpha | '_') >> *(alnum | '_')];
auto const identifier_component_def =
((identifier_component_unrestricted - reserved_words) |
lexeme['"' >> identifier_component_unrestricted >> '"']);
identifier_component
анализируется как variant
, но затем сворачивается в один std::string
.
Как я могу автоматически преобразовать проанализированный identifier_component
во ВСЕ ЗАГЛАВКИ, когда он не заключен в кавычки (первый тип в варианте), но сохранить регистр без изменений, когда он заключен в кавычки (второй тип в варианте)?
Я пытался использовать семантические действия, но не смог получить что-то, что работает / компилируется.
Редактировать : Благодаря rmawatson для следующего решения.
Добавить файл to_upper.hpp
:
#pragma once
#include <boost/algorithm/string.hpp>
namespace parser {
using namespace boost::spirit::x3;
template <typename Subject>
struct ToUpperDirective : unary_parser<Subject, ToUpperDirective<Subject>> {
using base_type = unary_parser<Subject, ToUpperDirective<Subject>>;
using attribute_type = typename extension::as_parser<Subject>::value_type;
static bool const has_attribute = true;
using subject_type = Subject;
ToUpperDirective(Subject const& subject) : base_type(subject) {}
template <typename Iterator, typename Context, typename RContext,
typename Attribute>
bool parse(Iterator& first,
Iterator const& last,
Context const& context,
RContext& rcontext,
Attribute& attr) const {
auto result = this->subject.parse(first, last, context, rcontext, attr);
boost::to_upper(attr);
return result;
}
};
struct ToUpper {
template <typename Subject>
ToUpperDirective<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const {
return {as_parser(subject)};
}
};
ToUpper const to_upper;
} // namespace parser
В исходном foo_def.hpp
просто добавить #include "to_upper.hpp"
и:
// Convert unquoted identifier_components to upper case; keep quoted unchanged.
auto const identifier_component_def =
to_upper[identifier_component_unrestricted - reserved_words] |
lexeme['"' >> identifier_component_unrestricted >> '"'];