Boost logo

Boost :

From: Jorge Lodos Vigil (lodos_at_[hidden])
Date: 2007-11-23 15:51:04


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

I have to thank you again, this is a better solution than the prepocessing I was thinking about. This solves our problem. The only caveat is that proto is not yet a boost library, but I hope this will imply just a header change when definitely accepted and BOOST_PROTO_AUTO will not change.
So far you came with 2 different ideas, the first one modifying the way we traverse the sequence, now an elegant way of modifying the grammar. There is still the alternative of modiying the algorithm to use an additional skip regex. I wonder, performance wise, what should be the best option for arbitrary texts? Do you (or someone else) could shed some light on this?
Thanks once more!

Cheers
Jorge


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