Boost logo

Boost Users :

Subject: [Boost-users] Spirit: parsing tab separated values and no_skip compilation error.
From: Mauricio Gomes (mgpensar_at_[hidden])
Date: 2010-05-13 17:47:28


Hi,

I am a beginner with Spirit. I just read the tutorial and I am playing
around with some examples.
Environment: boost 1.43, Windows Vista, Code::Blocks, mingw, gcc 4.5.

My goal is to build a tab separated values parser.
If you have an example on how to parse something like:
string/t/tdouble/tdouble
it would be great. Contiguous tabs should be considered as one tab, not an
empty field.

To start I just tried to parse a tab separated list of strings but I am
having some difficulties.

Is there another skip parser to be used instead of space (for full code see
the end of the message below) ?
I have changed the commas to tabs in the code below but it failed. I guess
it was because it was skipping them (space skipper).

        bool r = phrase_parse(first, last,

            // Begin grammar
            (
                +(char_ - ',') % ','
            )
            ,
            // End grammar

            space, v);

This code works with commas but it fails with '\t'.

I tried to use no_skip[] but it failed to compile the header #include
<boost/spirit/include/qi_no_skip.hpp>:

C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|30|error:
'no_skip' is not a member of 'boost::spirit::tag'|

For full error message see the end of the message below.

Any suggestions ?

Thank you for your attention,
Mau.

#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_stl.hpp>
//#include <boost/spirit/include/qi_no_skip.hpp>

#include <iostream>
#include <string>
#include <vector>

#define VECTOR_TYPE std::string

namespace client
{
    namespace qi = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;

///////////////////////////////////////////////////////////////////////////
    // Our number list compiler

///////////////////////////////////////////////////////////////////////////
    //[tutorial_numlist4
    template <typename Iterator>
    bool parse_numbers(Iterator first, Iterator last,
std::vector<VECTOR_TYPE>& v)
    {
        using qi::double_;
        using qi::phrase_parse;
        using qi::_1;
        using ascii::space;
        using qi::char_;

        bool r = phrase_parse(first, last,

            // Begin grammar
            (
                +(char_ - ',') % ','
            )
            ,
            // End grammar

            space, v);

        if (first != last) // fail if we did not get a full match
            return false;
        return r;
    }
    //]
}

////////////////////////////////////////////////////////////////////////////
// Main program
////////////////////////////////////////////////////////////////////////////
int
main()
{
    std::cout <<
"/////////////////////////////////////////////////////////\n\n";
    std::cout << "\t\tA comma separated list parser for Spirit...\n\n";
    std::cout <<
"/////////////////////////////////////////////////////////\n\n";

    std::cout << "Give me a comma separated list of numbers.\n";
    std::cout << "The numbers will be inserted in a vector of numbers\n";
    std::cout << "Type [q or Q] to quit\n\n";

    std::string str;
    while (getline(std::cin, str))
    {
        if (str.empty() || str[0] == 'q' || str[0] == 'Q')
            break;

        std::vector<VECTOR_TYPE> v;
        if (client::parse_numbers(str.begin(), str.end(), v))
        {
            std::cout << "-------------------------\n";
            std::cout << "Parsing succeeded\n";
            std::cout << str << " Parses OK: " << std::endl;

            for (std::vector<VECTOR_TYPE>::size_type i = 0; i < v.size();
++i)
                std::cout << i << ": " << v[i] << std::endl;

            std::cout << "\n-------------------------\n";
        }
        else
        {
            std::cout << "-------------------------\n";
            std::cout << "Parsing failed\n";
            std::cout << "-------------------------\n";
        }
    }

    std::cout << "Bye... :-) \n\n";
    return 0;
}

Error messages when compiling with the no_skip include file:
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|30|error:
'no_skip' is not a member of 'boost::spirit::tag'|
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|30|error:
'no_skip' is not a member of 'boost::spirit::tag'|
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|30|error:
template argument 2 is invalid|
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|36|error:
'boost::spirit::no_skip' has not been declared|
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|37|error:
'boost::spirit::no_skip_type' has not been declared|
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|79|error:
'no_skip' is not a member of 'boost::spirit::tag'|
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|79|error:
'no_skip' is not a member of 'boost::spirit::tag'|
C:\boost_1_43_0\boost\spirit\home\qi\directive\no_skip.hpp|79|error:
template argument 1 is invalid|
||=== Build finished: 8 errors, 0 warnings ===|

-- 
Mauricio Gomes
Pensar Digital
55-11-9698-1683 (Brazil - mobile)


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net