2016-11-29 1 views
2

J'ai essayé d'utiliser qi::uint_parser<int>(). Mais c'est la même chose comme qi::uint_. Ils correspondent tous à des nombres entiers allant de 0 à std::numeric_limits<unsigned int>::max().Comment écrire un boost :: spirit :: qi parser pour analyser un entier de 0 à std :: numeric_limits <int> :: max()?

Est-ce que qi::uint_parser<int>() est conçu pour être comme ça? Quel analyseur dois-je utiliser pour faire correspondre un nombre entier compris entre 0 et std::numeric_limits<int>::max()? Merci.

+0

double possible de [Contraindre le existin g Boost.Spirit réel \ _parser (avec une politique)] (http://stackoverflow.com/questions/30375750/constraining-the-boisting-boost-spirit-real-parser-with-a-policy) – sehe

Répondre

4

Simplest demo, attacher une action sémantique pour faire la vérification de la gamme:

uint_ [ _pass = (_1>=0 && _1<=std::numeric_limits<int>::max()) ]; 

Live On Coliru

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

template <typename It> 
struct MyInt : boost::spirit::qi::grammar<It, int()> { 
    MyInt() : MyInt::base_type(start) { 
     using namespace boost::spirit::qi; 
     start %= uint_ [ _pass = (_1>=0 && _1<=std::numeric_limits<int>::max()) ]; 
    } 
    private: 
    boost::spirit::qi::rule<It, int()> start; 
}; 

template <typename Int> 
void test(Int value, char const* logical) { 
    MyInt<std::string::const_iterator> p; 

    std::string const input = std::to_string(value); 
    std::cout << " ---------------- Testing '" << input << "' (" << logical << ")\n"; 

    auto f = input.begin(), l = input.end(); 
    int parsed; 
    if (parse(f, l, p, parsed)) { 
     std::cout << "Parse success: " << parsed << "\n"; 
    } else { 
     std::cout << "Parse failed\n"; 
    } 

    if (f!=l) { 
     std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n"; 
    } 
} 

int main() { 
    unsigned maxint = std::numeric_limits<int>::max(); 

    MyInt<std::string::const_iterator> p; 

    test(maxint , "maxint"); 
    test(maxint-1, "maxint-1"); 
    test(maxint+1, "maxint+1"); 
    test(0  , "0"); 
    test(-1  , "-1"); 
} 

Prints

---------------- Testing '2147483647' (maxint) 
Parse success: 2147483647 
---------------- Testing '2147483646' (maxint-1) 
Parse success: 2147483646 
---------------- Testing '2147483648' (maxint+1) 
Parse failed 
Remaining unparsed: '2147483648' 
---------------- Testing '0' (0) 
Parse success: 0 
---------------- Testing '-1' (-1) 
Parse failed 
Remaining unparsed: '-1' 
+0

Merci! Et je pense que '_1> = 0' dans l'action sémantique n'est pas nécessaire parce que' uint_' a déjà fait le travail. Je suis toujours curieux de savoir s'il existe des différences entre 'qi :: uint_parser ' et 'qi :: uint_parser '? Il semble que 'std :: numeric_limits :: max()' requis pour le type de base numérique 'T' n'est pas utilisé ici. – Han