Увеличить структуру разбора X3 с контейнерами - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь разобрать следующие строки, например:

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 вместо чтения в него членов?

1 Ответ

0 голосов
/ 12 апреля 2020

Я исправил это, используя правила:


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);
...