【问题标题】:Save token position保存令牌位置
【发布时间】: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;
}

Coliru link

【问题讨论】:

    标签: c++ boost boost-spirit boost-spirit-qi


    【解决方案1】:

    您可以遵循以下指南:

    但到目前为止,我最喜欢的方法(侵入性最小)使用 on_success,在使用它的示例之外,遗憾的是记录不足:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-19
      • 2019-09-27
      • 2018-02-28
      • 2019-10-25
      • 2015-12-13
      • 1970-01-01
      • 2018-08-05
      相关资源
      最近更新 更多