Search code examples
c++parsingboost-spirit

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


I am a beginner in using boost spirit.

What I want to do is just parse a text that has a time in the following format:

HH:MM::SS

and that is pretty easy by using the following rule (boost documentation)

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]           
    ];

The problem is that I am getting a compiler error stating that limit_d is not a member of boost spirit namespace, even though limit_d directive is located under boost::spirit namespace in the following header:

boost/spirit/home/classic/core/composite/directives.hpp

And I have included this header.

So I have got confused about which header should I include in order the get the code compile (I am using VS2013)

P.S. My code is working correctly without limit_d directive so the problem is definitely caused by limit_d.


Solution

  • Using the answer posted by @DevSolar I can see limit_d but that will introduce another compile error stating that we can't use

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

    with limit_d so I changed that to

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

    As a result the time parser rule will be as follow:

    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]
        ];
    

    the problem with this code is that we can't use limit_d with Boost::Spirit::QI as you have noticed that the rule from QI namespace.

    So I have searched for a limit_d equivalent which is compatible with Spirit 2.x

    As stated here, there is no equivalent for limit_din Spirit 2.x and instead you have to use semantic action which is a solution for my problem.

    So the working code should look like this:

        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)]
            ];