Boost logo

Boost :

From: Dave Jenkins (david_at_[hidden])
Date: 2007-11-23 15:25:34


"Jorge Lodos Vigil" <lodos_at_[hidden]> wrote in message
news:ECBF993526E3BC47BD232BDC77D6933706A916F588_at_mercurio.segurmatica.cu...
>
> Dave Jenkins wrote:
>>
>> > Hi
>> > We are using xpressive with a grammar to match certain patterns. In
>> > some cases, we have the need to ignore white spaces.
>> > Using dynamic regexes, this can be achieved with the
>> > ignore_white_space constant.
>> > Is there a way to ignore white spaces using a grammar in xpressive
>> > other than modifying the grammar itself?
>>
>> How about using a filter_iterator to skip spaces. Something
>> like the following program:
>
> Thank you for your help. Unfortunately our grammar definition have spaces,
> we can not remove all of them.
> I'll think more about your idea of modifying the way to traverse the
> string, perhaps we may do some sort of preprocessing.

Oh, I see. How about something like this? It allows you to selectively
skip spaces for parts of your regex.

#include <iostream>
#include <string>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/xpressive/xpressive_static.hpp>
#include <boost/xpressive/regex_actions.hpp>
#include <boost/xpressive/proto/proto_typeof.hpp>

static bool skip_spaces = false;

struct not_space {
    inline bool operator()(char ch) const
        { return ' ' != ch || !skip_spaces; }
    static bool disable(std::string const & s)
        { skip_spaces = false; return true; }
    static bool enable(std::string const & s)
        { skip_spaces = true; return true; }
};

typedef boost::filter_iterator<not_space,
    std::string::const_iterator> Iter_Skip;

boost::iterator_range<Iter_Skip> make_range (std::string const& s)
{
    return boost::make_iterator_range(
        boost::make_filter_iterator<not_space>(s.begin(), s.end()),
        boost::make_filter_iterator<not_space>(s.end(), s.end())
        );
}

int main()
{
    using namespace boost::xpressive;

    std::string s = "a ab bc c";

    BOOST_PROTO_AUTO( skip_spaces,
        nil[check(&not_space::enable)]
    );
    BOOST_PROTO_AUTO( normal,
        nil[check(&not_space::disable)]
    );

    typedef basic_regex<Iter_Skip> regex_skip;
    regex_skip rx =
        normal >> as_xpr("a a") >>
        skip_spaces >> "bb" >>
        normal >> "c c";
    match_results<Iter_Skip> what;

    if(!regex_match(make_range(s), what, rx))
        std::cout << "not found\n";
    else
        std::cout << "found\n";
    return 0;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk