首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用boost-spirit解析ipv4地址

使用boost-spirit解析ipv4地址
EN

Stack Overflow用户
提问于 2012-07-03 17:19:02
回答 1查看 870关注 0票数 1

我想使用boost::spirit来解析ipv4地址。以下是我尝试做的事情:

代码语言:javascript
复制
#include <string>
#include <string.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

struct Ipv4 { union { uint32_t as_int; uint8_t as_char[4]; } raw; };

Ipv4 make_ipv4(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4) {
    Ipv4 ip;
    ip.raw.as_char[0] = i1; ip.raw.as_char[1] = i2;
    ip.raw.as_char[2] = i3; ip.raw.as_char[3] = i4;
    return ip;
}

namespace qi = boost::spirit::qi;
qi::uint_parser<uint8_t, 10, 1, 3> octet;

struct Ipv4Address : qi::grammar<const char *, Ipv4()> {
    Ipv4Address() : Ipv4Address::base_type(start) {
        start = ( octet >> qi::lit('.') >> octet >> qi::lit('.') >>
                  octet >> qi::lit('.') >> octet
                ) [
                    //qi::_val = make_ipv4(1, 2, 3, 4) // working
                    qi::_val = make_ipv4(qi::_1, qi::_2, qi::_3, qi::_4) // compile error
                ]
        ;
    }
    qi::rule<const char *, Ipv4()> start;
} ipv4_address;

int main() {
    Ipv4 ip;
    const char * s = "1.2.3.4";
    bool r = qi::parse(s, s+strlen(s), ipv4_address, ip);
    std::cout << r << " " << (int)ip.raw.as_char[0] << "." <<
                             (int)ip.raw.as_char[1] << "." <<
                             (int)ip.raw.as_char[2] << "." <<
                             (int)ip.raw.as_char[3] << std::endl;
}

编译这段代码时,我得到了以下编译错误:

/tmp/ip.cxx:在构造函数'Ipv4Address::Ipv4Address()':/tmp/ip.cxx:26:72: error:无法将参数'1‘的'const _1_type {aka const boost::phoenix::actor >}’转换为'uint8_t {aka unsigned char}‘到'Ipv4 make_ipv4(uint8_t,uint8_t)’

有什么提示吗?

这是“正确”的方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-03 21:10:18

您需要使用bind来延迟绑定语义操作中的函数:

代码语言:javascript
复制
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
qi::uint_parser<uint8_t, 10, 1, 3> octet;

struct Ipv4Address : qi::grammar<const char *, Ipv4()> {
    Ipv4Address() : Ipv4Address::base_type(start) {
        start = ( octet >> qi::lit('.') >> octet >> qi::lit('.') >>
                  octet >> qi::lit('.') >> octet
                ) [
                    qi::_val = phx::bind(make_ipv4, qi::_1, qi::_2, qi::_3, qi::_4)
                ]
        ;
    }
    qi::rule<const char *, Ipv4()> start;
} ipv4_address;

完整示例:

代码语言:javascript
复制
#include <string>
#include <string.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

struct Ipv4 { union { uint32_t as_int; uint8_t as_char[4]; } raw; };

Ipv4 make_ipv4(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4) {
    Ipv4 ip;
    ip.raw.as_char[0] = i1; ip.raw.as_char[1] = i2;
    ip.raw.as_char[2] = i3; ip.raw.as_char[3] = i4;
    return ip;
}

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
qi::uint_parser<uint8_t, 10, 1, 3> octet;

struct Ipv4Address : qi::grammar<const char *, Ipv4()> {
    Ipv4Address() : Ipv4Address::base_type(start) {
        start = ( octet >> qi::lit('.') >> octet >> qi::lit('.') >>
                  octet >> qi::lit('.') >> octet
                ) [
                    qi::_val = phx::bind(make_ipv4, qi::_1, qi::_2, qi::_3, qi::_4)
                ]
        ;
    }
    qi::rule<const char *, Ipv4()> start;
} ipv4_address;

int main() {
    Ipv4 ip;
    const char * s = "1.2.3.4";
    bool r = qi::parse(s, s+strlen(s), ipv4_address, ip);
    std::cout << r << " " << (int)ip.raw.as_char[0] << "." <<
                             (int)ip.raw.as_char[1] << "." <<
                             (int)ip.raw.as_char[2] << "." <<
                             (int)ip.raw.as_char[3] << std::endl;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11307940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档