Я пытаюсь проанализировать символьную строку в атрибуте пользовательского типа symbol
, который содержит член std::string
. Я думал, что могу использовать здесь BOOST_FUSION_ADAPT_STRUCT
, но это не работает.Класс Adapt, содержащий член строки как синтезированный атрибут
Если я объявляю правило как rule<It, std::string(), space_type>
, он работает. Если я определяю его как rule<It, symbol(), space_type>
, он терпит неудачу с ошибкой «no type name value_type
in symbol
». Я думаю, что Spirit пытается добавить значение character-for-character к атрибуту, который не соответствует ожидаемому. Но нет ли способа сделать эту работу, без, добавив дополнительное промежуточное правило, которое захватывает атрибут std::string
?
Вот полный MWE:
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
struct symbol
{
std::string repr;
};
BOOST_FUSION_ADAPT_STRUCT(symbol, (std::string, repr))
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct test_grammar : qi::grammar<Iterator, symbol(), qi::ascii::space_type> {
test_grammar() : test_grammar::base_type{start} {
start = qi::lexeme[+qi::char_("a-z")];
}
qi::rule<Iterator, symbol(), qi::ascii::space_type> start;
};
#include <iostream>
auto main() -> int {
test_grammar<std::string::iterator> grammar{};
auto input = std::string{"test"};
auto output = symbol{};
auto e = end(input);
if (qi::phrase_parse(begin(input), e, grammar, qi::ascii::space, output))
std::cout << output.repr;
}
Это известное ограничение/ошибка в Духе. Я считаю, что это происходит, когда вы адаптируете структуры, которые имеют один элемент, и этот элемент является «контейнером». Обычным обходным решением является 'start% = eps >> lexeme [+ char _ ('a', 'z')];', по-видимому, это заставляет атрибут правой стороны быть «tuple», и это отлично работает с вашим адаптированная структура. Я попытаюсь найти дубликат. –
llonesmiz
@cv_and_he Да, это [работает] (http://coliru.stacked-crooked.com/a/0634b0eb16d67e46) с этим обходным решением – P0W
@cv_and_he Скопируйте это в ответ, чтобы я мог его принять. –