簡體   English   中英

使用boost Spirit解析為STL向量

[英]Parsing using boost Spirit into STL vector

我正在學習Boost Spirit 2,我無法弄清楚為什么我無法將兩個整數的序列解析為int的STL向量。 從>> operator的文檔( 這里 )我知道語法int_ >> int_的屬性應該是vector<int> 屬性符號文檔中我知道“ vector<A>符號vector<A>代表任何持有A類元素的STL容器 ”。

然而,當我嘗試向int_ >> int_添加一個動作時,它將std::vector作為其屬性,編譯失敗。

在其他錯誤消息中,它說: /usr/include/boost/bind/mem_fn_template.hpp:163:7: note: no known conversion for argument 2 from 'boost::fusion::vector<int, int>' to 'const std::vector<int>&' : /usr/include/boost/bind/mem_fn_template.hpp:163:7: note: no known conversion for argument 2 from 'boost::fusion::vector<int, int>' to 'const std::vector<int>&'

我知道這個問題 (“讓boost :: spirit :: qi使用stl容器”),但那里的解決方案 - 包括std_tuple.hpp - 沒有改變任何東西。

為什么是這樣?

#include <iostream>
#include <string>
#include <vector>

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/bind.hpp>

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

    class ParserActions
    {
    public:
        void printivec (std::vector<int> const& ivec)
        {
            std::cout << "We see " << ivec.size() << " integers" << std::endl;
        }
    };

    template <typename Iterator>
    bool parse_ivec(Iterator first, Iterator last)
    {
        using ascii::space;

        ParserActions actionContainer;

        auto two_ints = (qi::int_ >> qi::int_);

        bool r = qi::parse(
            first,                          /*< start iterator >*/
            last,                           /*< end iterator >*/
            two_ints[boost::bind(&ParserActions::printivec,&actionContainer,_1)]
            );

        return first == last && r;
    }
}

int main()
{
    std::string str = "12 13";

    if (client::parse_ivec(str.begin(),str.end()))
        std::cout << "Parsing succeeded\n";
    else
        std::cout << "Parsing failed!\n";

    return 0;
}

int_ >> int_合成int,int.¹的元組

如果你想強制合成一個容器,讓它repeat(2) [ int_ ]來表達它。

旁注 :正如您將在下面看到的,即使綁定屬性是cotainer,也存在屬性兼容性的空間,因此您不需要。

旁注 :帶解析器表達式的auto會詢問未定義的行為: 將解析器分配給自動變量

旁注 :您的輸入使用空格分隔符,但解析器不使用。 那永遠不會奏效。

您的代碼示例似乎與目標沒什么關系,所以這是我的小例子:

1. vector<int>

住在Coliru

#include <boost/spirit/include/qi.hpp>
using Vec = std::vector<int>;
namespace qi = boost::spirit::qi;

template <typename It> Vec parse_ivec(It first, It last) {
    Vec v;
    if (qi::phrase_parse(first, last,  qi::int_ >> qi::int_ >> qi::eoi, qi::space, v))
        return v;
    throw std::runtime_error("Parse failed");
}

Vec parse_ivec(std::string const& r) { return parse_ivec(begin(r), end(r)); }

int main() {
    for (int i : parse_ivec("12 13")) {
        std::cout << i << "\n";
    }
}

打印

12
13

2.改編結構

或者,如果你想要一個結構,而不是std::vector<>

住在Coliru

#include <boost/fusion/adapted/struct.hpp>
struct Vec { int a, b; };
BOOST_FUSION_ADAPT_STRUCT(Vec, a, b)

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;

template <typename It> Vec parse_ivec(It first, It last) {
    Vec v;
    if (qi::phrase_parse(first, last,  qi::int_ >> qi::int_ >> qi::eoi, qi::space, v))
        return v;
    throw std::runtime_error("Parse failed");
}

Vec parse_ivec(std::string const& r) { return parse_ivec(begin(r), end(r)); }

int main() {
    Vec vec = parse_ivec("12 13");
    std::cout << vec.a << " " << vec.b << "\n";
}

打印

12 13

3. std::tuple<int, int>

住在Coliru

#include <boost/fusion/adapted/std_tuple.hpp>
using Vec = std::tuple<int, int>;

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;

template <typename It> Vec parse_ivec(It first, It last) {
    Vec v;
    if (qi::phrase_parse(first, last,  qi::int_ >> qi::int_ >> qi::eoi, qi::space, v))
        return v;
    throw std::runtime_error("Parse failed");
}

Vec parse_ivec(std::string const& r) { return parse_ivec(begin(r), end(r)); }

int main() {
    Vec vec = parse_ivec("12 13");
    std::cout << std::get<0>(vec) << " " << std::get<1>(vec) << "\n";
}

打印

12 13

¹從技術上講,Fusion序列可以與std :: pair等類型的東西兼容,或者適合您自己的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM