boost::spirit::multi_pass 谓词和替代项崩溃
boost::spirit::multi_pass crash with predicate and alternative
运行 以下代码导致崩溃。为什么?
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
using namespace boost::spirit;
typedef multi_pass<
std::string::const_iterator,
iterator_policies::default_policy<
iterator_policies::first_owner,
iterator_policies::no_check,
iterator_policies::buffering_input_iterator,
iterator_policies::split_std_deque>>
string_mp_iterator;
int main() {
std::string input = "234";
string_mp_iterator input_begin(input.begin()),
input_end((string_mp_iterator()));
qi::rule<string_mp_iterator, boost::variant<int, double>()> r =
&qi::lit('1') >> qi::int_ | qi::double_;
qi::parse(input_begin, input_end, r);
return 0;
}
为了重现崩溃,我似乎需要同时拥有谓词和后续替代方案,使用 multi_pass
迭代器,并且输入不满足谓词。
我觉得我在这里使用 multi_pass
不正确,但我不明白问题到底是什么。
看来你不能用 multi_pass 迭代器包装 std::string,至少不能用 iterator_policies::buffering_input_iterator
std::string 有一个基于指针的 end
,不是空值。这就是迭代器不兼容的原因。如果你打算只解析一个std::string
,直接使用满足multi_pass要求的迭代器。如果您打算更改为流 (code sorta from here):
typedef std::istreambuf_iterator<char> base_iterator_type;
typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type;
main( )
{
std::istringstream input( "234" );
base_iterator_type in_begin(input);
base_iterator_type in_end;
forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin);
forward_iterator_type fwd_end = boost::spirit::make_default_multi_pass(in_end);
qi::rule<forward_iterator_type, boost::variant<int, double>()> r =
&qi::lit('1') >> qi::int_ | qi::double_;
qi::parse(fwd_begin, fwd_end, r);
return 0;
}
简单地修复结束迭代器的初始值设定项。
string_mp_iterator input_end(input.end());
由于它不是输入迭代器,因此您不能合法地使用默认构造的迭代器。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
using namespace boost::spirit;
typedef multi_pass<
std::string::const_iterator,
iterator_policies::default_policy<
iterator_policies::first_owner, iterator_policies::no_check,
iterator_policies::buffering_input_iterator,
iterator_policies::split_std_deque>>
string_mp_iterator;
int main() {
std::string input = "234";
string_mp_iterator input_begin(input.begin()),
input_end(input.end());
qi::rule<string_mp_iterator, boost::variant<int, double>()> r = &qi::lit('1') >> qi::int_ | qi::double_;
qi::parse(input_begin, input_end, r);
}
运行 以下代码导致崩溃。为什么?
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
using namespace boost::spirit;
typedef multi_pass<
std::string::const_iterator,
iterator_policies::default_policy<
iterator_policies::first_owner,
iterator_policies::no_check,
iterator_policies::buffering_input_iterator,
iterator_policies::split_std_deque>>
string_mp_iterator;
int main() {
std::string input = "234";
string_mp_iterator input_begin(input.begin()),
input_end((string_mp_iterator()));
qi::rule<string_mp_iterator, boost::variant<int, double>()> r =
&qi::lit('1') >> qi::int_ | qi::double_;
qi::parse(input_begin, input_end, r);
return 0;
}
为了重现崩溃,我似乎需要同时拥有谓词和后续替代方案,使用 multi_pass
迭代器,并且输入不满足谓词。
我觉得我在这里使用 multi_pass
不正确,但我不明白问题到底是什么。
看来你不能用 multi_pass 迭代器包装 std::string,至少不能用 iterator_policies::buffering_input_iterator
std::string 有一个基于指针的 end
,不是空值。这就是迭代器不兼容的原因。如果你打算只解析一个std::string
,直接使用满足multi_pass要求的迭代器。如果您打算更改为流 (code sorta from here):
typedef std::istreambuf_iterator<char> base_iterator_type;
typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type;
main( )
{
std::istringstream input( "234" );
base_iterator_type in_begin(input);
base_iterator_type in_end;
forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin);
forward_iterator_type fwd_end = boost::spirit::make_default_multi_pass(in_end);
qi::rule<forward_iterator_type, boost::variant<int, double>()> r =
&qi::lit('1') >> qi::int_ | qi::double_;
qi::parse(fwd_begin, fwd_end, r);
return 0;
}
简单地修复结束迭代器的初始值设定项。
string_mp_iterator input_end(input.end());
由于它不是输入迭代器,因此您不能合法地使用默认构造的迭代器。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
using namespace boost::spirit;
typedef multi_pass<
std::string::const_iterator,
iterator_policies::default_policy<
iterator_policies::first_owner, iterator_policies::no_check,
iterator_policies::buffering_input_iterator,
iterator_policies::split_std_deque>>
string_mp_iterator;
int main() {
std::string input = "234";
string_mp_iterator input_begin(input.begin()),
input_end(input.end());
qi::rule<string_mp_iterator, boost::variant<int, double>()> r = &qi::lit('1') >> qi::int_ | qi::double_;
qi::parse(input_begin, input_end, r);
}