Простое семантическое действие уничтожает результат в Spirit X3 - PullRequest
0 голосов
/ 03 мая 2019

У меня есть этот анализатор Spirit X3

    auto xyz_def = 
        x3::omit[x3::int_] >> x3::eol >> 
        (x3::lexeme[+(x3::char_ - x3::eol)]) >> x3::eol >>
        (*(chemical::parser::atom >> x3::eol)
    ;

, который без проблем анализирует что-то вроде этого

2
Comment
H 1.2 3.2 4.5
C 1.1 9.1 8.5

Теперь я хочу использовать (вместо полного игнорирования) первое целое числов качестве подсказки, чтобы помочь построить вектор (из клины *).Для этого я делаю:

    auto xyz_def = 
        x3::omit[x3::int_[([](auto& ctx){x3::_val(ctx).reserve(x3::_attr(ctx));})]] >> x3::eol >> 
        (x3::lexeme[+(x3::char_ - x3::eol)]) >> x3::eol >>
        (*(chemical::parser::atom >> x3::eol)
    ;

Однако, когда я делаю это, хотя функция синтаксического анализа завершается успешно, у меня появляется пустой результат.Это особенно таинственно, потому что семантическое действие, в принципе, не имеет выраженного побочного эффекта.

Я нашел этот обходной путь, который должен был явным образом ввести все семантические действия.

    auto xyz_def = 
        x3::omit[x3::int_[([](auto& ctx){x3::_val(ctx).reserve(x3::_attr(ctx));})]] >> x3::eol >> 
        (x3::lexeme[+(x3::char_ - x3::eol)])[([](auto& ctx){x3::_val(ctx).comment = x3::_attr(ctx);})] >> x3::eol >>
        (*(chemical::parser::atom >> x3::eol)[([](auto& ctx){x3::_val(ctx).atoms.insert(end(x3::_val(ctx).atoms), x3::_attr(ctx));})])
    ;

Это явно перебор. Почему, когда я добавляю только одно семантическое действие в первый элемент, я должен добавить семантическое действие для всех?

Я недавно задал аналогичный вопрос ,но я использовал неправильную версию Spirit (Qi), и теперь я использую атрибуты вместо того, чтобы захватывать лямбды, чтобы я мог определять автономные правила.

Полный код здесь , можно вставить в https://wandbox.org/

1 Ответ

0 голосов
/ 03 мая 2019

Случайно, читая код rule /usr/include/boost/spirit/home/x3/nonterminal/detail/rule.hpp, я заметил, что у него есть третий параметр шаблона, называемый «атрибуты силы».

    template <typename ID, typename Attribute = unused_type, bool force_attribute = false>
    struct rule;

Что ж, получается, что установка true принесла ожидаемый результат.

    x3::rule<class xyz_, chemical::xyz, true> const xyz = "xyz";

(до этого было x3::rule<class xyz_, chemical::xyz> const xyz = "xyz";)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...