Boost X3 使用容器解析结构

Boost X3 parse struct with containers

我试图像下面这样解析以下字符串:

pc_us_ru_2_ua_3_inet(evdev)_capslock(grouplock)

进入以下结构:

struct LayoutSymbols
{
    std::vector<std::string> layouts; // Will contain {us,ru,ua} for example above
    std::vector<std::string> options; // Will contain {inet(evdev), capslock(grouplock)} for example above
};


BOOST_FUSION_ADAPT_STRUCT(LayoutSymbols,
    layouts, options
)

这是我的代码:

std::string test = "pc_us_ru_2_ua_3_inet(evdev)_capslock(grouplock)";
LayoutSymbols layoutSymbols;
x3::phrase_parse(test.begin(), test.end(), "pc_" >> (+x3::char_("a-z") >> -('_' >> +x3::char_("a-z") >> '_' >> x3::omit[x3::alnum]))
                 >> '_' >> (+x3::char_("a-z") >> x3::char_('(') >> +x3::char_("a-z") >> x3::char_(')')) % '_',
        x3::space, layoutSymbols);

但是我有编译错误:

/usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:148: error: static assertion failed: Size of the passed attribute is less than expected.
  148 |             actual_size >= expected_size
      |             ~~~~~~~~~~~~^~~~~~~~~~~~~~~~

是否可以为以下内容指定 >>+x3::char_("a-z") >> '_' >> -(+x3::char_("a-z") >> '_' >> x3::alnum 将任何元素读入 LayoutSymbols 的向量而不是读入它的成员?

我使用规则修复了它:


namespace LayoutSymbolsParser
{
    namespace x3 = boost::spirit::x3;

    x3::rule<class SymbolsRule, LayoutSymbols> const symbolsRule = "symbols";
    x3::rule<class LayoutsRule, std::vector<std::string>> const layoutsRule = "layouts";
    x3::rule<class OptionsRule, std::vector<std::string>> const optionsRule = "options";

    const auto symbolsRule_def = "pc_" >> layoutsRule >> -('_' >> optionsRule);
    const auto layoutsRule_def = +x3::alpha >> *('_' >> +x3::alpha >> '_' >> x3::omit[x3::digit]);
    const auto optionsRule_def = x3::lexeme[+(x3::char_ - ')') >> x3::char_(')')] % '_';

    BOOST_SPIRIT_DEFINE(symbolsRule, layoutsRule, optionsRule);
}

用法:

std::string test = "pc_us_ru_2_ua_3_inet(evdev)_capslock(grouplock)";
LayoutSymbols layoutSymbols;
x3::phrase_parse(test.begin(), test.end(), LayoutSymbolsParser::symbolsRule, x3::space, layoutSymbols);