2014-10-16 1 views
1

Я учусь использовать boost :: spirit library. Я взял этот пример http://www.boost.org/doc/libs/1_56_0/libs/spirit/example/qi/num_list1.cpp и скомпилировал его на своем компьютере - он отлично работает.неопределенное поведение где-то в boost :: spirit :: qi :: phrase_parse

Однако, если я изменить его немного - если я инициализировать сам анализатор

auto parser = qi::double_ >> *(',' >> qi::double_); 

где-то в качестве глобальной переменной и передать его phrase_parse, все сходит с ума. Вот полный модифицированный код (только одна строка изменена и добавлена ​​1). http://pastebin.com/5rWS3pMt

Если я запустил исходный код и передал «3.14, 3.15» в stdin, он говорит, что Parsing преуспел, но с моей измененной версией он не работает , Я пробовал много модификаций одного и того же типа - назначение парсера глобальной переменной - в некоторых вариантах на некоторых компиляторах он segfaults.

Я не понимаю, почему и как это так. Вот другой, более простой вариант, который печатает верно и то ошибку сегментации на лязгом ++ и просто ошибки сегментации на г ++

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

#include <iostream> 
#include <string> 

namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 

const auto doubles_parser_global = qi::double_ >> *(',' >> qi::double_); 

int main() { 
    const auto doubles_parser_local = qi::double_ >> *(',' >> qi::double_); 

    const std::string nums {"3.14, 3.15, 3.1415926"}; 

    std::cout << std::boolalpha; 

    std::cout 
     << qi::phrase_parse(
      nums.cbegin(), nums.cend(), doubles_parser_local, ascii::space 
     ) 
     << std::endl;        // works fine 

    std::cout 
     << qi::phrase_parse(
      nums.cbegin(), nums.cend(), doubles_parser_global, ascii::space 
     )           // this segfaults 
     << std::endl; 
} 

ответ

2

Вы не можете использовать auto в магазин анализатор expressions¹

Либо вы должны оценить из временного выражения непосредственно, или вам нужно присвоить правило/грамматике:

const qi::rule<std::string::const_iterator, qi::space_type> doubles_parser_local = qi::double_ >> *(',' >> qi::double_); 

вы можете иметь свой кусок пирога и съесть его на самый последний бустер VERSI Дополнения (возможно DEV филиал) должен быть BOOST_SPIRIT_AUTO макрос

Это становится немного Справка элемента:

¹ Я считаю, что это на самом деле ограничение базовой библиотеки Proto. Существует версия Proto-0x lib на github (Эрик Ниблер), которая обещает решить эти проблемы, полностью переработанную, чтобы быть в курсе ссылок. Я думаю, для этого потребовались некоторые возможности C++ 11, которые Boost Proto в настоящее время не может использовать.