IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Boost C++ Discussion :

[Boost.Spirit] Ignorer la case


Sujet :

Boost C++

  1. #1
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut [Boost.Spirit] Ignorer la case
    Bonjour,

    Je me trouve face à un problème très simple (à expliquer), j'ai fait un petit programme compilable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/lex_lexertl.hpp>
    #include <boost/spirit/include/phoenix_operator.hpp>
    #include <boost/spirit/include/phoenix_core.hpp>
    #include <boost/spirit/include/phoenix_object.hpp>
     
    #include <iostream>
    #include <fstream>
    #include <string>
     
    using namespace boost::spirit;
    using boost::phoenix::val;
     
    // Token definition base, defines all tokens for the base grammar below
    template <typename Lexer>
    struct sql_tokens : lex::lexer<Lexer>
    {
    public:
        // Tokens with no attributes.
        lex::token_def<lex::omit> kw_unique;
     
        sql_tokens()
        {
            kw_unique = "unique";
     
            // The token must be added in priority order.
            this->self += kw_unique;
        }
    };
     
    // Grammar definition, define a little part of the SQL language.
    template <typename Iterator, typename Lexer>
    struct sql_grammar 
      : qi::grammar<Iterator, qi::in_state_skipper<Lexer> >
    {
        template <typename TokenDef>
        sql_grammar(TokenDef const& tok)
          : sql_grammar::base_type(program, "program")
        {
            program = keywords.alias();
            keywords = tok.kw_unique;
        }
     
        typedef qi::in_state_skipper<Lexer> skipper_type;
     
        qi::rule<Iterator, skipper_type> program, keywords;
    };
     
    int main(int argc, char* argv[])
    {
        if(argc != 2)
            exit(1);
        // iterator type used to expose the underlying input stream
        typedef std::string::iterator base_iterator_type;
        typedef lex::lexertl::token<base_iterator_type> token_type;
     
        // Here we use the lexertl based lexer engine.
        typedef lex::lexertl::lexer<token_type> lexer_type;
     
        // This is the token definition type (derived from the given lexer type).
        typedef sql_tokens<lexer_type> sql_tokens;
     
        // this is the iterator type exposed by the lexer 
        typedef sql_tokens::iterator_type iterator_type;
     
        // this is the type of the grammar to parse
        typedef sql_grammar<iterator_type, sql_tokens::lexer_def> sql_grammar;
     
        // now we use the types defined above to create the lexer and grammar
        // object instances needed to invoke the parsing process
        sql_tokens tokens;                         // Our lexer
        sql_grammar sql(tokens);                  // Our parser
     
        std::string str(argv[1]);
     
        // At this point we generate the iterator pair used to expose the
        // tokenized input stream.
        std::string::iterator it = str.begin();
        iterator_type iter = tokens.begin(it, str.end());
        iterator_type end = tokens.end();
     
        // Parsing is done based on the the token stream, not the character 
        // stream read from the input.
        // Note how we use the lexer defined above as the skip parser. It must
        // be explicitly wrapped inside a state directive, switching the lexer 
        // state for the duration of skipping whitespace.
        std::string ws("WS");
        bool r = qi::phrase_parse(iter, end, sql, qi::in_state(ws)[tokens.self]);
     
     
        if (r && iter == end)
        {
            std::cout << "-------------------------\n";
            std::cout << "Parsing succeeded\n";
            std::cout << "-------------------------\n";
        }
        else
        {
            std::cout << "-------------------------\n";
            std::cout << "Parsing failed\n";
            std::cout << "-------------------------\n";
        }
        return 0;
    }
    J'ai testé ces différentes possibilités pour ignorer la case :

    Encapsuler toute la grammaire dans le "no_case".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool r = qi::phrase_parse(iter, end, qi::ascii::no_case[sql], qi::in_state(ws)[tokens.self]);
    Seulement quelques règles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    program = qi::ascii::no_case[keywords];
            keywords = tok.kw_unique;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    program = keywords.alias();
            keywords = qi::ascii::no_case[tok.kw_unique];
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    program = qi::ascii::no_case[keywords];
            keywords = qi::ascii::no_case[tok.kw_unique];
    Rien ne marche, j'ai même essayé de modifié les expressions régulières avec "(?i)" pour activer la non-sensibilité à la case mais cette option n'est pas supportée.

    Et j'ai pas très envie de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    kw_unique = "(unique|UNIQUE)";
    Ou encore plus énervant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    kw_unique = "([uU][nN][iI]...";
    Vous pouvez tester le programme en le lançant comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    .\sql_parser unique
    .\sql_parser UNIQUE
    Merci pour l'aide !

  2. #2
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Bon en fait j'utilisais mal l'option des regex (?i), j'essayais de l'activer en faisant :

    alors que ce n'est pas comme ça mais plutôt :

    Et ça marche. Ça m'apprendra à lire la doc de travers et à me baser sur des expressions régulières d'autres personnes

    Après je trouve que ça reste moyennement satisfaisant pour une grammaire qui est entièrement non sensible à la case, ici le SQL. Mais bon j'ai pas trouvé de meilleur moyen "global" pour le faire alors je vais m'en contenter

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. boost.lambda et comparaison case insensitive
    Par nikko34 dans le forum Boost
    Réponses: 2
    Dernier message: 27/03/2008, 19h23
  2. displaytag - tris en ignorant a case
    Par anaon dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 29/11/2007, 13h42
  3. recherche en ignorant la case
    Par Chonchon dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/08/2007, 13h25
  4. ignorer la case dans DbLookUpComboBox?
    Par gregcat dans le forum Bases de données
    Réponses: 3
    Dernier message: 11/09/2006, 17h19
  5. Ignorer la case dans une requete sql ?
    Par gregcat dans le forum Bases de données
    Réponses: 2
    Dernier message: 27/03/2006, 11h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo