Boost logo

Boost :

Subject: [boost] Boost 1.44.0 - Problem with optional matching
From: programmer1 (ebenezer.hailemariam_at_[hidden])
Date: 2011-07-21 19:08:51


I'm attempting to match a floating point literal which can contain several
optional tokens. Even though the rule succeeds, it doesn't return all the
symbols which make up the token.

Example

Consider the following. Even though the parser succeeds, it returns only
"Km" in the match string. Why is that? I expect "-666.0e-45km".

std::string phrase = "-666.0e-45km";
std::string val;
std::cout << "res: " << parse_number(phrase.begin(), phrase.end(), val) <<
std::endl; /* prints "1" */
std::cout << val << std::endl; /* prints "km" */

grammar

Here is the grammar which I'm trying to express in Spirit. Notice how it is
slightly different from the built-in rule "double_"

<number> := <decimal> | "INF" | "-INF" | "NaN"
<decimal> := ["-"] <digits> ["." <digits>] [<exp>] [<unit>]
<exp> := ("e"|"E") ["+"|"-"] <digits>
<digits> := <digit> (<digit> | "_")*
<digit> := ('0' - '9')
<unit> := <unitChar>*
<unitChar> := <alpha> | "%" | "_" | "/" | "$" | any char > 128 // see
sys::Unit

Code

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;

template <typename Iterator>
struct number_grammar : qi::grammar&lt;Iterator, std::string(),
ascii::space_type&gt;
{
        number_grammar() : number_grammar::base_type(number, "number")
        {
                using qi::lit;
                using ascii::char_;
                using qi::digit;
                using ascii::string;
                using qi::alpha;
        
                using qi::on_error;
                using qi::fail;
        
                using phoenix::construct;
                using phoenix::val;
        
                unitChar = alpha | char_('%') | char_('_') | char_('/') | char_('$') ; //
| any char > 128 // see sys::Unit
        
                unit = *unitChar ;
        
                digits = digit > *( digit | lit('_') ) ;
                        
                exp = ( char_('e') | char_('E') ) > -( char_('+') | char_('-') ) > digits
;
        
                decimal = -char_('-') > digits > -( char_('.') > digits ) > -exp > -unit
;
        
                number = string("INF") | string("-INF") | string("NaN") | decimal ;
                        
                on_error<fail>
                (
                        number,
                        std::cout
                        << val("Error! Expecting ")
                        << qi::_4 // what failed?
                        << val(" here: \"")
                        << construct<std::string>(qi::_3, qi::_2) // iterators to error-pos, end
                        << val("\"")
                        << std::endl
                );

        }

        qi::rule< Iterator, std::string(), ascii::space_type > number;
        qi::rule< Iterator, std::string() > decimal;
        qi::rule< Iterator, std::string() > exp;
        qi::rule< Iterator, std::string() > digits;
        qi::rule< Iterator, std::string() > unit;
        qi::rule< Iterator, char() > unitChar;

};

template <typename Iterator>
bool parse_number(Iterator first, Iterator last, const std::string& val)
{
        using qi::phrase_parse;
        using ascii::space;
        
        number_grammar<Iterator> grammar;

        bool r = phrase_parse (
                                        first, /*< start iterator >*/
                                        last, /*< end iterator >*/
                                        grammar, /*< the parser >*/
                                        space, /*< the skip-parser >*/
                                        val
                                );

        std::cout << val << std::endl;

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

        return r;
}

--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-1-44-0-Problem-with-optional-matching-tp3685445p3685445.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

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