Search code examples
c++parsingboostboost-spiritboost-spirit-qi

parsing number with boost spirit qi


I'm parsing a grammar using boost spirit and all the complex parts are working great; however, I'm trying to accept numeric variables and I can't seem to get them to parse properly. I don't want to do anything with the numbers except store them as strings but I can't seem to get a string parser that matches a generic number to work.

Here is code that shows the problem:

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

int main()
{
    std::vector<std::string> testVec;
    testVec.push_back("25.16");
    testVec.push_back("2516");
    std::string result;
    std::string::const_iterator it, endIt;

    for (unsigned int i = 0; i < testVec.size(); ++i)
    {
        it = testVec[i].begin();
        endIt = testVec[i].end();
        result.clear();

        std::cout << "test" << i << "a: ";
        bool r = qi::phrase_parse(
            it,
            endIt,
            +qi::digit >> -(qi::string(".") >> +qi::digit),
            qi::space,
            result
        );

        if (!r || it != endIt)
        {
            std::cout << "failed" << std::endl;
        }
        else
        {
            std::cout << result << std::endl;
        }

        it = testVec[i].begin();
        endIt = testVec[i].end();
        result.clear();

        std::cout << "test" << i << "b: ";
        r = qi::phrase_parse(
            it,
            endIt,
            +qi::digit >> (qi::string(".") >> +qi::digit),
            qi::space,
            result
        );

        if (!r || it != endIt)
        {
            std::cout << "failed" << std::endl;
        }
        else
        {
            std::cout << result << std::endl;
        }
    }

    return 0;
}

And the output is:

test0a: 25.
test0b: 25.16
test1a: 2516
test1b: failed

The second approach is behaving as expected but simply making the decimal part optional changes the result to exclude the numbers after the decimal point.

Any help is appreciated.

EDIT: The reason for wanting to do this is that I'm parsing one grammar to translate into a slightly different grammar. Obviously, both treat numbers the same so I don't care what the number is, just that it is well formed.


Solution

  • Maybe a problem with your boost spirit version ? Here's my output of your program:

    $ ./a.exe
    test0a: 25.16
    test0b: 25.16
    test1a: 2516
    test1b: failed
    

    It is a result I would expect.

    And here is an online compile/run of your code