2014-10-16 1 views
3

Я пытаюсь передать семантическое действие в унаследованном аргументе грамматики.Boost :: spirit, передающий семантические действия в унаследованных атрибутах

В самом базовом примере ниже грамматика анализирует два числа, и я передаю семантическое действие (в форме C++ лямбда), и я хотел бы, чтобы это действие вызывалось при разборе первого числа. Однако он не называется, но молча игнорируется, и я хотел бы знать, почему это так, и как правильно это сделать.

#include <iostream> 
#include <boost/spirit/include/qi.hpp> 

using namespace std; 
using namespace boost; 

namespace qi = spirit::qi; 
namespace phx = phoenix; 

template <typename Iterator, typename Action> 
struct two_numbers : qi::grammar<Iterator, void (Action const&)> 
{ 
    two_numbers() : two_numbers::base_type(start) 
    { 
    using namespace qi; 
    start = int_ [ _r1 ] >> ' ' >> int_; 
    } 
    qi::rule<Iterator, void (Action const&)> start; 
}; 

int main() 
{ 
    string input { "42 21" }; 
    auto first=std::begin (input), last=std::end(input); 

    static const auto my_action = [] (auto&& p) { 
    cout << "the meaning of life is " << p << "\n"; 
    }; 

    static const two_numbers <decltype(first), decltype (my_action)> p; 

    if (qi::parse (first, last, p(phx::ref(my_action)))) 
    cout << "parse ok\n"; 
} 

Ожидаемый результат:

the meaning of life is 42 
parse ok 

И реальный выход:

parse ok 
+0

Обязательная ссылка: [Boost Spirit: «Семантические действия злы»?] (http://stackoverflow.com/questions/8259440/boost-spirit-semantic-actions-are -evil) – sehe

ответ

4

Во-первых, непосредственное ответ:

«Я пытаюсь передать семантическое действие в унаследованном аргументе грамматики ».

мгновенный травматический удар. Ты ... ты ... что ?!

C++ не очень хорош для программирования более высокого порядка, конечно, не со статическим полиморфизмом, основанным на шаблонах выражений. На самом деле это так, но в моем предыдущем ответе я уже предостерег от UB при хранении шаблонов выражений в именованных объектах (переменные ≅).

Это время было UB, что вы заметили. Мне повезло, на мой взгляд.

В последнее время я уже столкнулся с другим вопросом о подобных целях:

Обратите особое внимание на комментарий резьбу. Я не думаю, что это разумный путь, по крайней мере, до тех пор, пока Boost Mpl не будет выполнен с полной добротой C++ 11 (Boost Hana, возможно?) И Proto-0x.

К тому времени, Spirit X3, вероятно, зрелый, и мы просто остаемся с разрывом Boost Phoenix. Я не уверен, что это на повестке дня.

Вкратце: мы будем застрять в этой «полупустой» земле, где у нас могут быть приятные вещи, но с некоторыми довольно ограниченными ограничениями. Вероятно, нам следует избегать увлечения и притворяться, что мы можем написать Haskell на C++.

Актуально: Есть предложение (N4221, pdf) для обобщенного продления срока службы ссылок в C++. Он поставляется с некоторыми хорошими примерами простых приложений, например, адаптеров Boost Range, которые тихо UB в текущем C++. Например. из § 2.3 Универсальное наблюдение:

std::vector<int> vec; 
for (int val : vec | boost::adaptors::reversed 
        | boost::adaptors::uniqued) 
{ 
     // Error: result of (vec | boost::adaptors::reversed) died. 
} 

Решение

Тем не менее, поскольку унаследовали аргумент был бы функтор (не ленивый актер), вы должны связать его:

start = int_ [ phx::bind(phx::cref(_r1), qi::_1) ] >> ' ' >> int_; 

Это делает работу: Live On Coliru

Howev er, Я не рекомендую это

+0

Добавлена ​​ссылка на предложение N4221 (спасибо @AndyProwl) – sehe

+0

Спасибо за ответ. Я изменил свой пример и теперь передаю ленивый актер, но он все еще не работает должным образом: [COLIRU Link] (http://coliru.stacked-crooked.com/a/7790ff05a15f234c) Кроме того, если неопределенное поведение происходит из-за раннего уничтожено prvalue и болтаться ссылкой, можете ли вы показать, что проблема ссылка именно в коде? –

+0

@ НиккиЧумаков Я не могу (на данный момент). И я, вероятно, не найду мотивацию. Там ** ** что-то в Boost Phoenix, тем не менее, указывает, является ли шаблон выражения Phoenix «безстоящим» (возможно, я помню, что это тот случай, если тип выражения по умолчанию является конструктивным?). Если это так, то нет проблем с его хранением. В противном случае все ставки отключены. Есть сообщение Эрика Ниблера, подробно описывающего это, IIRC. – sehe

 Смежные вопросы

  • Нет связанных вопросов^_^