Boost logo

Boost Users :

Subject: Re: [Boost-users] Spirit: parsing tab separated values and no_skip compilation error.
From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2010-05-13 19:28:19


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

This example compiles fine for me (VC10, g++ 4.5). Is it supposed to fail?

Regards Hartmut

---------------
Meet me at BoostCon
www.boostcon.com


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