我应该包括哪些头文件,以便在boost spirit中使用limit_d指令

What header files should i include in order to use limit_d directive in boost spirit?

本文关键字:spirit limit 指令 boost 包括哪 文件 我应该      更新时间:2023-10-16

我是使用boost spirit的初学者。

我要做的就是解析一个具有以下格式的时间的文本:

HH: MM: SS

,这很容易通过使用以下规则(boost文档)

uint_parser<int, 10, 2, 2> uint2_p;
r = lexeme_d
    [
        boost::spirit::limit_d(0u, 23u)[uint2_p] >> ':' 
        >>  boost::spirit::limit_d(0u, 59u)[uint2_p] >> ':' 
        >>  boost::spirit::limit_d(0u, 59u)[uint2_p]           
    ];

问题是,我得到一个编译器错误,说明limit_d不是boost spirit命名空间的成员,即使limit_d指令位于boost::spirit命名空间下:

增加/精神/home/经典/核心/复合/directives.hpp

我已经包含了这个标题。

所以我对我应该包括哪个头感到困惑,以便获得代码编译(我使用VS2013)

注:我的代码在没有limit_d指令的情况下正常工作,所以问题肯定是由limit_d引起的。

您应该在<boost/spirit/include/...>中使用头,以便Boost可以在不影响客户端代码的情况下改变其内部。

include <boost/spirit/include/classic_directives.hpp>仅仅是对使用的的包装,因此除了忽略一层抽象之外,您的头文件没有任何问题。

真正的问题是您使用的命名空间boost::spirit与您应该使用的—boost::spirit::classic

IIRC,他们把以前的boost::spirit变成了boost::spirit::classic几个版本,当新的Spirit v2 API出来的时候,他们试图修复Spirit的"Header Hell"。

#include <boost/spirit/include/classic_directives.hpp>
namespace bspirit = boost::spirit::classic;
int main()
{
    bspirit::limit_d( 0u, 23u );
}

如果您不担心更高的编译时间,并且不想弄清楚使用确切地哪个头文件,您当然可以简单地使用#include <boost/spirit/include/classic.hpp>并完成它。: -)

使用@DevSolar发布的答案,我可以看到limit_d,但这会引入另一个编译错误,说明我们不能使用

boost::spirit::qi::uint_parser<int, 10, 2, 2> uint2_p;

with limit_d所以我把它改成

boost::spirit::classic::uint_parser<uint16, 10, 2, 2> uint2_p;

结果时间解析器规则如下:

boost::spirit::classic::uint_parser<uint16, 10, 2, 2>           uint2_p;
boost::spirit::qi::rule<std::string::const_iterator, Time(), qi::space> Time_;
Time_ = lexeme_d
    [
            boost::spirit::classic::limit_d(0u, 23u)[uint2_p] >> ':'
        >>  boost::spirit::classic::limit_d(0u, 59u)[uint2_p] >> ':'
        >>  boost::spirit::classic::limit_d(0u, 59u)[uint2_p]
    ];

这段代码的问题是我们不能将limit_dBoost::Spirit::QI一起使用,因为您已经注意到QI命名空间的规则。

所以我已经搜索了与Spirit 2.x兼容的limit_d等效

如前所述,在Spirit 2中没有对应的limit_d。X,而你必须使用语义动作,这是我的问题的解决方案。

所以工作代码应该是这样的:
    namespace qi = boost::spirit::qi;
    struct Time
    {
        unsigned Hour;
        unsigned Minute;
        unsigned Second;
    };
    boost::spirit::qi::rule<std::string::const_iterator, Time(), qi::space> Time_;
    Time_ = lexeme_d
        [
                    qi::uint_[qi::_pass = (0 <= qi::_1 && qi::_1 <= 23)] >> ':'
                >>  qi::uint_[qi::_pass = (0 <= qi::_1 && qi::_1 <= 59)] >> ':'
                >>  qi::uint_[qi::_pass = (0 <= qi::_1 && qi::_1 <= 59)]
        ];