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 - Parser pour listes énumérées


Sujet :

Boost C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 3
    Par défaut Boost::Spirit - Parser pour listes énumérées
    Salut à tous,

    J'essaye d'écrire une moteur wiki en C++ et pour cela j'ai besoin d'écrire un parser compatible avec le format de "trac" ...

    Voici mon problème : Je n'arrive pas à trouver la bonne grammaire pour reconnaitre le format suivant pour les listes énumérées :

    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
     
     
    The wiki supports both ordered/numbered and unordered lists.
     
    Example:
     
     * Item 1
       * Item 1.1
          * Item 1.1.1   
          * Item 1.1.2
          * Item 1.1.3
       * Item 1.2
     * Item 2
     
     1. Item 1
       a. Item 1.a
       a. Item 1.b
          i. Item 1.b.i
          i. Item 1.b.ii
     1. Item 2
    And numbered lists can also be given an explicit number:
     3. Item 3
     
    Display:
     
        * Item 1
              o Item 1.1
                    + Item 1.1.1
                    + Item 1.1.2
                    + Item 1.1.3 
              o Item 1.2 
        * Item 2 
     
       1. Item 1
             1. Item 1.a
             2. Item 1.b
                   1. Item 1.b.i
                   2. Item 1.b.ii 
       2. Item 2 
     
    And numbered lists can also be given an explicit number:
     
       3. Item 3
    Voici ma tentative d'élaboration de la grammaire, mais impossible de savoir comment définir les "sublist" ... car pour cela, il faudrai être capable de savoir si la ligne commence par plus d'espaces (blank_p) que la ligne précédente !


    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
     
    class WikiParser : public grammar<WikiParser> 
    {
    public:
    	template <typename ScannerT> struct definition {
     
            definition(WikiParser const& /*self*/)
            {
     
    			document = *element ;
    			element = title[&onTitle] | tab[&onTable] | para[&onPara] | list | eol_p   ;
     
     
    			// Definition des regles pour les listes :
    			list = item >> !list  >> !eol_p;
    			item = bullet; 
    			bullet = "*" >> +(word | FormatedSequence)>> (lexeme_d[sublist]) >>!eol_p ;
    			sublist=  ???  ....
    Autre effet bizarre : la directive lexeme_d semble être sans effet ... le parser continu à "skipper" les blancs (puisque invoqué comme suit dans le main) ce qui ne facilite pas le comptage des blancs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parse_info<> info = parse(str.c_str(), p, blank_p);
    Merci d'avance pour votre aide !

    Pat

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Salut, et bienvenue sur le forum.

    En fait, tu ne dois pas te baser sur les espaces pour déterminer à quel niveau se trouve un objet de ta liste, mais de préférence sur un symbole de début (en HTML, il s'agit de <ul>) et un symbole de fin (</ul> en HTML).

    Et tu fais en sorte que ta grammaire accepte un nombre quelconque de symboles étant soit un objet de la liste (l'équivalent de <li> en HTML) soit... un nouveau début de liste, l'indentation (et le cas échéant, le type de puce utilisée) étant calculée en fonction du nombre de "sous liste" présente
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

    Informations forums :
    Inscription : Mars 2008
    Messages : 3
    Par défaut
    Merci pour ta réponse koala01.

    C'est vrai que dans l'absolu, il faudrait se baser sur des balises différentes pour déterminer le niveau des objets ... mais dans mon cas, j'ai besoin de connaitre le niveau des puces en fonction de l'indentation (et donc du nombre de blank_p présent en début de ligne, relativement au précédent rencontré). La fin d'un élément de la liste étant déterminé par un eop_p.

    Du coup j'ai réussi à m'en sortir en revenant à un parsing plus atomique et en invoquant l'objet WikiParser comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parse_info<> info = parse(str.c_str(), p);
    Par contre, du coup, j'ai du mal à comprendre l'idée des directives telles que : lexeme_d ...

    Pour info, la grammaire que j'ai utilisé est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // Definition des regles pour les listes :
    list = item >> !list  >> !eol_p;
    item = bullet[&onBulletList] ; 
    bullet = +indent[&onIndentFound] >> "*" >> *blank_p >>  +((word| FormatedSequence) >> *blank_p )>> eol_p ;
    indent = blank_p ;
    Et la gestion des sous-listes (et autre) étant gérée au niveau des call back :

    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
     
    void onList(char const* first, char const* last){
     
    	elementList.append(currentList->root());
    	currentList = NULL ; 
    }	
     
    void onBulletList(char const* first, char const* last){
    	if ( currentList == NULL)
    		currentList = new List( NULL,bulletIndent) ; 
    	else if ( bulletIndent > currentList->getIndent())  // on a trouvé une subList
    	{
    		List * subList = new List( currentList,bulletIndent); 
    		currentList->append(subList) ;
    		currentList = subList ;		
    	}
    	else if( bulletIndent < currentList->getIndent())// on doit revenir à la list mere 
    	{
    		if ( currentList->up() != NULL)
    			currentList = currentList->up(); 
    	}
     
    	currentList->append(new Bullet(QString(string(first+bulletIndent+1,  last-2).c_str()))); 
    	bulletIndent = 0 ;
    }	
     
    void onIndentFound(char const* first, char const* last){
    	bulletIndent ++ ; 
    }
    En tout cas, vraiment sympa ce Forum ! C'est vivant, constructif, et rempli de développeurs très compétents et de ressources pertinentes !

    Encore merki !

    Pat

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

Discussions similaires

  1. Boost Spirit: Grammaire pour les équations en math
    Par darkman19320 dans le forum C++
    Réponses: 3
    Dernier message: 17/04/2012, 18h30
  2. Boost::Spirit classic (Parser)
    Par Melloz dans le forum Boost
    Réponses: 2
    Dernier message: 03/03/2012, 15h56
  3. Liste énuméré pour le texte contenu dans un noeud XML ?
    Par lightstring4 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 01/05/2011, 23h50
  4. Utiliser un parser pour extraire des formules
    Par EpOnYmE187 dans le forum C++
    Réponses: 2
    Dernier message: 15/03/2005, 23h55
  5. Réponses: 8
    Dernier message: 08/05/2004, 13h58

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