i am trying to make sense of the following result. The test case code is
#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_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/spirit/home/support/context.hpp>
#include <boost/spirit/home/phoenix.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
using namespace boost::spirit::ascii;
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
using phoenix::at_c;
using phoenix::push_back;
using phoenix::bind;
template <typename P>
void test_parser(
char const* input, P const& p, bool full_match = true)
{
using boost::spirit::qi::parse;
char const* f(input);
char const* l(f + strlen(f));
if (parse(f, l, p) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
int main() {
test_parser("+12345", qi::int_ ); //Ok
test_parser("+12345", qi::double_ - qi::int_ ); //failed, as expected
test_parser("+12345.34", qi::int_ ); // failed, as expected
test_parser("+12345.34", qi::double_ - qi::int_ ); //failed but it should be Ok!
};
the motivation here is that i want to match numbers '12345' as integers and NEVER as floating points. '12345.34' will match double_ and never int_ but the reciprocal case is not true; '12345' matches both integers (int_ ) and floating point (double_ ). I tried double_ - int_ and it successfully failed to match '12345'. However my hope was that the last test case '12345.34' would positively match double_ - int_, but the result i get is fail to match.
Why this is so, and how do i get a parser that only matches integers and another that only matches floating points (like in c, 5.0 would be interpreted as floating point)
For your specific example, I think it's actually described in the Boost Spirit documentation under RealPolicies
Specialization. To make things a bit easier for you, I whipped out a quick "real" parser, that only parses real numbers and not integers(or at least it worked with your simplified examples):
template <typename T>
struct strict_real_policies : qi::real_policies<T>
{
static bool const expect_dot = true;
};
qi::real_parser< double, strict_real_policies<double> > real;
And you can use this just like any other parser(like int_ and double_). You might have to add:
#include <boost/spirit/include/qi_numeric.hpp>
To get it to compile.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With