我需要将解析后的令牌位置与令牌一起保存。这是简化的示例代码。
#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;
}
答案 0 :(得分:1)
您可以按照以下指南进行操作:
但到目前为止,我首选的方法(最少侵入性)使用on_success
,在使用它的样本之外,遗憾地记录不足: