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

C++ Discussion :

Parsing de fichier texte


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Parsing de fichier texte
    Hello,

    J'aimerais implémenter un parser de fichiers texte, dont voici un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    my_int = 1;   // ceci est un commentaire
    my_float_1 = 3.14;
    my_float_2 = 1.00e5;
    my_string = "bonjour";
    my_vector = (1.2, 3,  // comment
    5.46);
    // encore un commentaire
    my_text = ("a", "b", "c");
    En parcourant caractère à caractère mon flux, je pense y arriver, mais je me demandais si je n'avais pas intérêt à utiliser une librairie d'expressions régulière, ou s'il n'existait pas un librairie permettant de faire du parsing à moindre cout.

    Merci pour vos conseils.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Boost.Regex pour les expressions régulières.
    Boost.Spirit pour une grammaire un peu plus riche.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Merci pour ces 2 liens.
    J'ai retenu la solution Boost.Spirit qui semblait bien remplir mon besoin.

    Malheureusement, sur des gros fichiers (50Mo), le parsing peine un peu. Il peut prendre 20 fois plus de temps qu'une ancienne librairie (entièrement codée à la main) que j'utilisais.

    Du coup j'ai 2 questions :
    1- J'utilise Spirit.Classics, or j'ai vu qu'une nouvelle version majeure Spirit V2 existait à présent : est-ce réellement plus rapide?
    2- S'il faut que je code le parsing à la main, existe-t-il des "bases" à respecter, des méthodes qui ont fait leurs preuves?
    3- Je n'ai pas testé les regexp encore, mais j'imagine que ça sera aussi poussif sur les gros fichiers non ?

    Merci encore pour votre aide

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Donc finalement, j'ai codé le parser à la main. Du coup c'est vraiment très rapide. Attention juste aux std::string pour lesquels les std::string::push_back caractère à caractère sont très consommateurs. J'ai tout mis dans des char* bufferisés à l'avance que j'assigne à la fin.

  5. #5
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bonjour,
    1- J'utilise Spirit.Classics, or j'ai vu qu'une nouvelle version majeure Spirit V2 existait à présent : est-ce réellement plus rapide?
    Oui, spirit2 est bien plus rapide que spirit classic, car selon les auteurs un gros travail d'optimisation a été fait sur la V2. D'ailleurs je serais curieux de pouvoir le vérifier, donc si tu peux poster ta grammaire spirit.classic et un exemple d'utilisation, j'aimerais bien essayer de faire le portage.
    Donc finalement, j'ai codé le parser à la main. Du coup c'est vraiment très rapide.
    Certes, mais par exemple est-ce que tu gères correctement les erreurs ? C'est un cas qui m'est arrivé : j'avais besoin il y a quelques temps de parser un document très simple (beaucoup plus simple que ton exemple) et j'avais fait le comparatif entre quelques règles spirit vs une petite machine à état codé à la main. La machine à état était en effet largement plus rapide, par contre il fallait que le document soit formaté à la perfection, car à la moindre erreur ma MaE partait en vrille et produisait un résultat complètement loufoque

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Hello, voici ma grammaire, merci pour ton aide

    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
     
                definition(Syntax const &self)
                {
                    myNumeric   = real_p;
                    myString    = '"' >> *( ~ch_p( '"' ) ) >> '"';
                    myVector    = '(' >> *( myNumeric >> *( "," >> myNumeric ) ) >> ')';
                    myText      = '(' >> *( myString >> *( "," >> myString ) ) >> ')';
                    myVariant   = myNumeric | myString | myVector | myText;
                    myLetter    = alpha_p | ch_p( '_' );
                    myAlphaNum  = myLetter | digit_p;
                    myObject    = myLetter >> *( myAlphaNum );
                    myAttribute = +myAlphaNum;
                    myKey       = myObject >> *( ch_p( '.' ) >> myAttribute );
                    myLine      = myKey >> str_p( "=" ) >> myVariant >> str_p( ";" );
                    root         = * myLine;
                }

  7. #7
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    J'aurais tendance à proposer Coco/R, qui génère parseur et lexers qui sont relativement efficaces à partir d'une grammaire LL1.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  8. #8
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Oui, spirit2 est bien plus rapide que spirit classic, car selon les auteurs un gros travail d'optimisation a été fait sur la V2. D'ailleurs je serais curieux de pouvoir le vérifier, donc si tu peux poster ta grammaire spirit.classic et un exemple d'utilisation, j'aimerais bien essayer de faire le portage.
    Y'a des benchs un peu partout (bien que j'ai rien sous la main :p) mais c'est le jour et la nuit... (vraiment!).


    De toute façon :
    http://boost-spirit.com/home/2010/11...rs-37-seconds/

    donc bon, je pense que ton fichier de 50 mo c'est pas un soucis... (j'en suis même sur pour l'avoir déjà fait :' )


    Citation Envoyé par Emmanuel Deloget Voir le message
    J'aurais tendance à proposer Coco/R, qui génère parseur et lexers qui sont relativement efficaces à partir d'une grammaire LL1.
    Et moi j'ai tendance à préféré avoir un DSEL plutôt qu'un fichier généré... comme quoi :>
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  9. #9
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    J'aurais aussi tendance à te conseiller spirit V2 même si je ne suis pas vraiment expérimenté avec.

    Citation Envoyé par gege2009 Voir le message
    Attention juste aux std::string pour lesquels les std::string::push_back caractère à caractère sont très consommateurs. J'ai tout mis dans des char* bufferisés à l'avance que j'assigne à la fin.
    Si tu conserves ta solution maison, tu peux utiliser des stringstream pour régler ce souci sans avoir à gérer des char* à la mano.
    Find me on github

  10. #10
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Goten Voir le message
    Et moi j'ai tendance à préféré avoir un DSEL plutôt qu'un fichier généré... comme quoi :>
    Le résultat est plus ou moins équivalent. Après, certaines grammaires ne peuvent être parsées par un DSEL. Pour une grammaire LL1 simple, le DSEL est effectivement une solution correcte.

    Pour ma part, désolidariser la définition de ma grammaire du reste du code me semble être une bonne chose - d'autant plus que certains générateurs de parseurs produisent un code tout à fait acceptable au niveau des performances, avec un learning step assez léger.

    Au final, le résultat est censé être équivalent voire assez proche d'identique, donc c'est plus une question de goût
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  11. #11
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Un avantage d'un generateur, c'est que si la grammaire ne lui convient pas, il va te le dire. Un DSEL, tu as des chances qu'il ait un comportement exponentiel ou meme parte en boucle infinie face a une entree qui ne lui convient pas.

    Et en particulier face a une grammaire stable si la qualite des messages d'erreur a de l'importance, ecrire le parseur a la main est aussi une option.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

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

Discussions similaires

  1. parsing de fichier texte log
    Par shalfat dans le forum Langage
    Réponses: 16
    Dernier message: 19/06/2014, 11h00
  2. parsing de fichiers texte
    Par karaudrey88 dans le forum Langage
    Réponses: 8
    Dernier message: 30/03/2012, 17h42
  3. Parsing de fichiers texte
    Par ChristopheD dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 29/07/2010, 03h50
  4. parsing de fichier texte
    Par robert_trudel dans le forum Access
    Réponses: 4
    Dernier message: 03/06/2006, 18h45
  5. Parsing d'un fichier texte
    Par anibal dans le forum C
    Réponses: 2
    Dernier message: 18/04/2006, 15h33

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