Super journal, mais pourquoi n'a-t'il pas déjà été promu en dépêche ;-)
Tombant d'autant plus à pic que Grako vient de sortir une version 3.9.3 le 30 juin dernier.
Personnellement j'avais essayé parcimonious et pyparsing.
Contrairement à Grako qui génère du code python à utiliser dans son application, parsimonious et pyparsing
sont à utiliser comme une lib standard dans laquelle on définie une grammaire chargée à l'exécution.
C'est en fait ce que tu fais via l'intégration de l'outil en ligne de commande Grako à ton code, je pense
même que ça mériterai que tu soumettes une PR pour ajouter cette fonctionnalité à la lib de base.
Pyparsing
Pyparsing (passé en 2.1.5 le 13 juin dernier, décidement c'est le mois !) fourni un moyen pythonique de définir sa grammaire :
On remarque les suppress pour exclure un token de l'ast ainsi que setResultsName qui est l'équivalent de la syntaxe de nommage de Grako.
On peut voir aussi l'utilisation de l'objet Forward permettant de faire référence à un élément avant sa définition.
Une option intéressante est de pouvoir utiliser la méthode setParseAction permettant de déclencher une fonction prenant le nœud du token
en argument. Cela permet de customiser l'ast, voir de faire son évaluation pendant cette phase.
Toutefois d'un point de vu ressenti personnel, je trouve qu'on galère beaucoup pour écrire sa grammaire justement à cause de ce problème de forward.
Dans mon exemple j'utilise des ZeroOrMore pour éviter d'utiliser de la récursion (les forwards donc) qui en général ne
fait rien d'autre que des erreurs de parsing plus ou moins abscons.
De plus on perd la compatibilité avec la syntaxe BNF ce qui rend les choses plus compliqués si on veut réimplémenter dans un autre langage.
Parcimonious
Parcimonious avait une syntaxe plus proche d'une bnf :
Là il faut comprendre qu'on a une liste de nœuds, simplement leurs __repr__ retournent une string contenant un retour à la ligne et pas de séparation claire !
J'aurai préféré un truc du style :
Je devrais leur faire une PR mais vu que le projet n'a pas évolué depuis 2 ans...
Bilan
Je n'ai été qu'à moitié convaincu par ces deux lib, je pense que pyparsing est pas mal pour les petites grammaire
en raison de son API et de sa capacité à évaluer les nœuds tout en les parsants.
Parsimonious de son côté me semble trop simple et son développement semble stoppé (pas de maj depuis 2ans), à éviter donc.
# Pyparsing & Parsimonious
Posté par G.bleu (site web personnel) . En réponse au journal Génération de code (Python) avec Grako. Évalué à 4.
Sommaire
Super journal, mais pourquoi n'a-t'il pas déjà été promu en dépêche ;-)
Tombant d'autant plus à pic que Grako vient de sortir une version 3.9.3 le 30 juin dernier.
Personnellement j'avais essayé parcimonious et pyparsing.
Contrairement à Grako qui génère du code python à utiliser dans son application, parsimonious et pyparsing
sont à utiliser comme une lib standard dans laquelle on définie une grammaire chargée à l'exécution.
C'est en fait ce que tu fais via l'intégration de l'outil en ligne de commande Grako à ton code, je pense
même que ça mériterai que tu soumettes une PR pour ajouter cette fonctionnalité à la lib de base.
Pyparsing
Pyparsing (passé en 2.1.5 le 13 juin dernier, décidement c'est le mois !) fourni un moyen pythonique de définir sa grammaire :
Qui retourne
On remarque les
suppresspour exclure un token de l'ast ainsi quesetResultsNamequi est l'équivalent de la syntaxe de nommage de Grako.On peut voir aussi l'utilisation de l'objet
Forwardpermettant de faire référence à un élément avant sa définition.Une option intéressante est de pouvoir utiliser la méthode
setParseActionpermettant de déclencher une fonction prenant le nœud du tokenen argument. Cela permet de customiser l'ast, voir de faire son évaluation pendant cette phase.
Toutefois d'un point de vu ressenti personnel, je trouve qu'on galère beaucoup pour écrire sa grammaire justement à cause de ce problème de forward.
Dans mon exemple j'utilise des
ZeroOrMorepour éviter d'utiliser de la récursion (les forwards donc) qui en général nefait rien d'autre que des erreurs de parsing plus ou moins abscons.
De plus on perd la compatibilité avec la syntaxe BNF ce qui rend les choses plus compliqués si on veut réimplémenter dans un autre langage.
Parcimonious
Parcimonious avait une syntaxe plus proche d'une bnf :
Le résultat est très verbeux :
Contrairement à pyparsing, pas d'équivalent à
suppressici, mêmes les espaces sont présent dans l'ast(ici sous la forme de la règle
ws).Il faut donc gérer ça dans le visitor parcourant l'ast :
Niveau débuggage, c'est là encore pas très confortable, exemple:
Là il faut comprendre qu'on a une liste de nœuds, simplement leurs
__repr__retournent une string contenant un retour à la ligne et pas de séparation claire !J'aurai préféré un truc du style :
Je devrais leur faire une PR mais vu que le projet n'a pas évolué depuis 2 ans...
Bilan
Je n'ai été qu'à moitié convaincu par ces deux lib, je pense que pyparsing est pas mal pour les petites grammaire
en raison de son API et de sa capacité à évaluer les nœuds tout en les parsants.
Parsimonious de son côté me semble trop simple et son développement semble stoppé (pas de maj depuis 2ans), à éviter donc.