spirit x3 не может распространять атрибуты типа optional ‹vector›

Простой парсер, как на Coliru. Синтаксический анализатор -(+x3::alpha) должен иметь возможность распространять атрибут типа boost::optional<std::string>, как это делает Qi. Но не компилируется.

std::string const input = "abc";
boost::optional<std::string> attr;
if(x3::parse(boost::begin(input),boost::end(input),
    -(+x3::alpha),
    attr)) {
    std::cout<<"match!"<<std::endl;
}
else {
    std::cout<<"NOT match!"<<std::endl;
}

person Han    schedule 29.03.2017    source источник


Ответы (1)


Я не думаю, что нормативное утверждение «должно [...] уметь, как Ци» рубить дрова. X3 не является эволюцией ци по очень веским причинам (таким как эта).

Часто повторяющийся шаблон состоит в том, что подсказки типа требуются в более сложных сценариях распространения. Уродливый многословный способ может быть таким:

    -(x3::rule<struct _, std::string> {} = +x3::alpha),

Live On Coliru

Или вы можете использовать взлом , который я описал ранее:

namespace {
    template <typename T>
    struct as_type {
        template <typename Expr>
            auto operator[](Expr&& expr) const {
                return x3::rule<struct _, T>{"as"} = x3::as_parser(std::forward<Expr>(expr));
            }
    };

    template <typename T> static const as_type<T> as = {};
}

Live On Coliru

person sehe    schedule 29.03.2017
comment
Отличное решение! Но мне все еще интересно, по какой причине x3 не поддерживает такое очевидное распространение составных атрибутов? - person Han; 29.03.2017
comment
Это не очевидно. Он включает в себя два нетривиальных преобразования. Типы контейнеров всегда были сложными (-(a%b) имеет смысл, потому что vector <A>, а -(a*), естественно, эквивалентен просто a*. - person sehe; 29.03.2017
comment
«Достаточно очевидным» в Qi могло быть то, что вспомогательные парсеры внутренне преждевременно удерживали свои атрибуты в явном синтезированном типе, что приводило к большой неэффективности при копировании атрибутов. - person sehe; 29.03.2017