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

Java Discussion :

[BNF] Parser et colorer la syntaxe d'un fichier d'après une grammaire


Sujet :

Java

  1. #1
    Membre éclairé
    Avatar de iubito
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2003
    Messages : 389
    Par défaut [BNF] Parser et colorer la syntaxe d'un fichier d'après une grammaire
    Bonjour !

    Depuis quelques jours je cherche, je trouve des trucs qui ne fonctionnent pas, ou pas documentés... donc je viens vous demander...

    Je bosse sur une appli java qui manipule des fichiers ABC (notation musicale)
    La grammaire BNF de ce format est ici : http://www.norbeck.nu/abc/bnf/abc20bnf.txt
    Dans cette appli, les définitions des états, tokens, et le parser ont été écrits "à la main" et la maintenance est assez difficile.
    Modifier le BNF est plus facile (par exemple pour accepter les fichiers .ABC qui dépassent un peu de la norme, ou mal écrits...)

    Je cherche donc un programme (java si possible) qui génère les classes nécessaire pour parser les fichiers ABC.

    Exemple de fichier simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    X:1
    T:Fichier ABC tout simple
    C:iubito
    %un commentaire
    M:2/4
    L:1/8
    K:D
    DE FG | A_B cd
    On a un header contenant :
    - X:1 = numéro de morceau
    - T:le titre
    - C:le compositeur
    - M:la métrique
    - L:longueur de note
    - K:la tonalité (ré majeur)
    puis un corps contenant
    - 2 notes (D et E)
    - un espace (ayant une signification)
    - 2 notes (F et G)
    - un espace (mais on s'en fout)
    - une barre de mesure
    - un autre espace sans signification
    - 2 notes (A et B) dont la deuxième est altéré (_ = bémol)
    - un espace (ayant une signification)
    - 2 notes (c et d)

    J'aimerai récupérer ses infos dans une structure arbre du genre
    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
     
    abc-file {
      abc-tune {
        abc-header {
          field-number = "X:1"
          title-fields {
            field-title {
              tex-text = "T:Fichier ABC tout simple"
            }
          }
          other-field {
            field-composer = "C:iubito"
            comment = "%un commentaire"
            field-meter {
              string = "M:"
              time-signature { ... }
            }
            field-length {
              string = "L:"
              note-length-strict { ... }
            }
          }
        }
        abc-music {
          abc-line {
            element {
              stem {
                note {
                  pitch {
                    basenote = "D"
                  }
                }
              }
            }
            element...stem......basenote = "E"
            element { WSP = " " }
    ........................etc......etc........
          }
        }
      }
    }
    Si quelque chose n'est pas reconnu car pas dans la grammaire, plutôt que de mettre un fail général sur le fichier, ignorer l'élément foireux ou le marquer comme "erreur", et continuer à parser la suite...


    J'ai trouvé
    - BNF-for-Java, avec une interface graphique... mais zéro doc, j'en ai rien tiré
    - JavaCC - me semble bien compliqué, pas compris la doc
    - BNF Converter - j'ai beau formater différemment le fichier BNF, ça veut pas
    - AntLR - j'en ai rien tiré
    - SableCC - je lis la doc....
    - beaver - pas assez insisté

    Quelles sont vos expériences en la matière?

  2. #2
    Invité
    Invité(e)
    Par défaut
    Salut,

    Tu as donné une bonne liste de générateur de parser plus ou moins compliqués à utiliser...

    • SableCC parse des grammaires LALR(1) et est assez simple mais il s'arrêtera sur la première erreur lexicale ou syntaxique rencontrée, ce qui ne correspond pas à ton besoin.
    • antlr est pas mal mais c'est du LL(k) (avec ou sans backtracking) ceci dit au premier coup d'oeil, la grammaire semble LL (j'ai pas cherché plus loin pour le moment). L'avantage de antlr est de pouvoir écrire du code Java qui permet de transformer ce qui est parsé, et, si je me souviens bien, d'intercepter les erreurs éventuelles.
    • JavaCC je ne connais pas assez mais ça ne m'a jamais convaincu...
    • Beaver parse des grammaires LALR(1) et permet de faire du "error recovery" (http://beaver.sourceforge.net/recovery.html) j'avais joué avec et le trouvais plus confortable que javacc et antlr...


    Donc je dirais plutôt beaver pour ton cas (en espèrant que ta grammair est LALR, sinon va falloir la manipuler un peu )

    A plus

  3. #3
    Membre éclairé
    Avatar de iubito
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2003
    Messages : 389
    Par défaut
    Salut et merci pour ces quelques éléments de réponse.
    Je débute en grammaire et donc les subtilités LL(k), LALR..., récursif gauche, récursif droite, j'ai pas tout capté

    en gros, y'a pas de récursivité
    unelement ::= unelement / autreschoses
    ça appelle toujours du type
    unelement ::= un_sous_element / ou_un_autre_sous_element
    généralement décris plus bas.

    et donc que dois-je faire pour rendre compatible ce qui semble LL avec Beaver qui prend du LALR?
    Je vais potasser la doc de beaver, c'est ce qui me semble le plus léger, et j'ai pas besoin de code java pour transformer ce qui est parsé... je l'ai déjà, mais à retoucher pour parcourir une belle structure bien propre, et créer l'Objet de mes rêves.

    Et si un terme je veux importer différents type de fichiers, mais dans une structure comparable, je n'aurai qu'à écrire la grammaire pour obtenir la même structure, et réutiliser mon code qui va lire la structure.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Je disais qu'elle me semblait LL car justement je voyais pas de récurisivité, ceci dit le meilleur moyen de savoir si elle est LALR c'est de l'écrire telle quel dans la syntaxe beaver, et tenter de générer le parser, mais a priori je ne vois pas de gros conflit shift/reduce dans cette grammaire qui est assez simple. Si tu as un problème tu peux toujours le poser ici

    Pour ce qui est de ta structure, tu veux surement parler de l'AST que tu vas générer pour le fichier parsé, beaver permet aussi de générer un tel AST avec des classes personnelles (http://beaver.sourceforge.net/asts.html) (ce que ne permet pas SableCC mais permettent les deux autres "monstres" JavaCC et antlr)

  5. #5
    Membre éclairé
    Avatar de iubito
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2003
    Messages : 389
    Par défaut
    sur cette page j'ai trouvé parboiled qui a l'air, d'après la doc, de faire ce dont j'ai besoin.
    ...et la doc est bien mieux que celle de beaver!

  6. #6
    Invité
    Invité(e)
    Par défaut
    Ah oui je l'avais vu passer sur la ML de scala,

    La logique est différente ici, il s'agit d'une DSL pour écrire ses règles directement dans le langage cible (Java ou Scala dans ce cas).
    Il peut y avoir certains avantages notamment pour le debuggage de la grammaire car aucun code n'est généré, c'est simplement une bibliothèque.
    Ceci dit le type de grammaires reconnues et l'efficacité peut en souffrir, et dans un langage comme Java, comme on est contraint d'utiliser la syntaxe Java, la lisibilité peut en souffrir.
    Mais bon je suis un grand fan des parser combinators et j'en utilise régulièrement en scala !
    Cette bibliothèque m'avait attiré et elle vient de se retrouver dans ma liste de choses à investiguer merci

  7. #7
    Membre éclairé
    Avatar de iubito
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2003
    Messages : 389
    Par défaut
    Salut !

    Bon... parboiled fait du bon boulot, après lecture et relecture de doc, les règles ne sont pas si difficiles à écrire, après y'a des astuces pour éviter d'avoir des noeuds tels que "Sequence", "FirstOf" dans l'arbre résultat, bref j'arrive à faire ce que je veux...

    mais y'a un MAIS, un énorme MAIS
    parboiled n'est pas compatible avec Android, et des dev prennent le projet pour notamment son parseur et modèle de données, pour ensuite manipuler dans une appli Android... et là c'est le drame.
    Pour tester je me suis tapé l'install du SDK d'Android, eclipse dernière version et tout le toutim... un premier problème parboiled appelle asm pour analyser le bytecode, et sur Android le bytecode n'est pas dans le même format, donc introuvable... bon, un peu de hacking de code et une méthode crade pour mettre le bytecode .class en "resource" à lire en inputstream... mais ASM plante à son tour, bref compatibilité zéro avec Android... et me voilà reparti de zéro...

  8. #8
    Invité
    Invité(e)
    Par défaut
    Argh...
    Là le plus simple va être de générer un code tout bête utilisant que des choses de base de l'API (SableCC, antlr, beaver surement, ...).
    Ceci dit je serais curieux de savoir à quel moment et pour quoi parboiled manipule du bytecode, le sais-tu ?

    Pourrais tu montrer ton code ? que j'analyse si l'utilisation de ASM est nécessaire ?

  9. #9
    Membre éclairé
    Avatar de iubito
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2003
    Messages : 389
    Par défaut
    Salut,
    je fais rapide...

    J'ai pu rendre compatible avec Android pour une utilisation relativement simple, et au prix d'un peu plus de code (ajouter des .suppressSubnodes() ou .label("xyz") pour construire mon arbre).
    en fait parboiled manipule le bytecode pour
    - éviter les overflow sur du récursif (en gros la règle est mis en cache) -> faut s'en passer pour être compatible Android
    - ajouter les .label("xyz") si on met l'annotation @Label("xyz") devant la règle, idem pour les @SuppressSubnodes -> là facilement contournable

    Je chope une structure de Node que je convertis en ma propre structure de Node qui possède + de méthodes fort sympathiques.

    Bientôt tout cela sera visible et utilisé dans le projet open source abc4j


    Un jour... peut-être... je reprendrai ma plume des anciens temps pour rédiger un article pour la communauté, car c'est vraiment un outil puissant les grammaires. Et dans le monde du dev au boulot ça peut vraiment trouver son utilité... parser le contenu de mails, d'un fichier d'échange avec les administrations....

Discussions similaires

  1. colorer des occurences d'un mot/phrase dans une page web
    Par hicham_alaoui1 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 27/08/2007, 02h47
  2. Réponses: 2
    Dernier message: 27/07/2007, 16h09
  3. Erreurs syntaxe nom de fichier etc
    Par PhiberOptik dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 24/02/2007, 13h46
  4. Vérifiaction de syntaxe d'un fichier
    Par Bayard dans le forum Général Python
    Réponses: 5
    Dernier message: 04/11/2005, 21h46

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