【发布时间】:2014-08-06 11:40:08
【问题描述】:
我需要将解析后的令牌位置与令牌一起保存。这是简化的示例代码。
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
struct double_w_pos
{
double_w_pos() : d(-1.0), pos(0) {}
double_w_pos(double d, size_t p) : d(d), pos(p) {}
double d;
size_t pos;
};
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::vector<double_w_pos>& v)
{
using qi::double_;
using qi::phrase_parse;
using qi::_1;
using ascii::space;
using phoenix::at_c;
using phoenix::push_back;
bool r = phrase_parse(first, last,
(
double_[push_back(phoenix::ref(v), phoenix::construct<double_w_pos>(qi::_1, 0))] % ','
)
,
space);
if (first != last)
return false;
return r;
}
}
int main()
{
std::vector<client::double_w_pos> v;
std::string str = "2.0, 3.45, 5.67, 2.08";
client::parse_numbers(str.begin(), str.end(), v);
for(auto i : v)
std::cout << i.d << " at " << i.pos << ", ";
std::cout << std::endl;
return 0;
}
您可以在Coliru 上实时运行它 现在 0 被保存为令牌位置。我怎样才能得到实际的解析位置。它不必是 size_t。它可以是迭代器或任何东西,可以用来识别文本中的位置,在哪个标记被发现。 谢谢。
更新 我没有设法直接从解析中获得 size_t 的位置,但我设法获得了迭代器的位置。这不完全是我需要的,但总比没有好。 这是代码
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/repository/include/qi_iter_pos.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
struct double_w_pos
{
double_w_pos(double d, std::string::iterator p) : d(d), pos(p) {}
double d;
std::string::iterator pos;
};
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::vector<double_w_pos>& v)
{
using qi::double_;
using qi::phrase_parse;
using qi::_1;
using ascii::space;
using phoenix::at_c;
using phoenix::push_back;
using phoenix::begin;
using boost::spirit::repository::qi::iter_pos;
bool r = phrase_parse(first, last,
(
(iter_pos >> qi::double_)[push_back(phoenix::ref(v), phoenix::construct<double_w_pos>(qi::_2, qi::_1))] % ","
)
,
space);
if (first != last)
return false;
return r;
}
}
int main()
{
std::vector<client::double_w_pos> v;
std::string str = "2.0, 3.45, 5.67, 2.08";
client::parse_numbers(str.begin(), str.end(), v);
for(auto i : v)
std::cout << i.d << " at " << std::distance(str.begin(), i.pos) << ", ";
std::cout << std::endl;
return 0;
}
【问题讨论】:
标签: c++ boost boost-spirit boost-spirit-qi