Quelle technologie d’parsing Haskell est la plus agréable à utiliser et pourquoi?

“Agréable” signifiant, par exemple: vous pouvez écrire des grammaires de manière “naturelle” sans avoir à les réécrire de manière compliquée et sans avoir à introduire un passe-partout ennuyeux.

Disons aux fins de cette question que, à moins que les performances d’une technologie ne soient pathologiquement mauvaises, la performance n’est pas le plus gros problème ici.

Bien que cela soit dit, vous voudrez peut-être mentionner si une technologie tombe en panne pour devoir réécrire une grammaire pour des raisons de performance.

S’il vous plaît, donnez-moi une idée de la taille et de la complexité des grammaires avec lesquelles vous avez travaillé lorsque vous répondez à cette question. Aussi, si vous avez utilisé des fonctionnalités “avancées” notables de la technologie en question et quelles sont vos impressions.

Bien sûr, la réponse à cette question peut dépendre du domaine, auquel cas, je serais heureux d’apprendre ce fait.

Cela dépend vraiment de ce que vous commencez et de ce que vous voulez faire. Il n’y a pas de taille unique.

Si vous avez une grammaire LR (par exemple, vous travaillez à partir d’une grammaire Yacc), il est difficile de la transformer en version LL adaptée à Parsec ou à uu-parsinglib. Cependant, les nombreux parsingurs sepBy, etc. sont très utiles, mais l’parsingur doit être plus lent que Happy + Alex.

Pour l’parsing syntaxique des combinateurs LL, uu-parsinglib et ses prédécesseurs uu-parsing sont bien mais ils manquent de quelque chose comme les modules Token et Language de Parsec, ils sont peut-être moins pratiques. Certaines personnes aiment Parselib de Malcolm Wallace parce qu’elles ont un modèle différent de celui de Parsec pour le backtracking mais je n’en ai aucune expérience.

Si vous décodez un fichier formaté plutôt que quelque chose comme un langage de programmation, Attoparsec ou similaire pourrait être meilleur que Parsec ou uu-parsinglib. Mieux dans ce contexte étant plus rapide – pas seulement ByteSsortingng vs. Char, mais je pense qu’Attoparsec fait moins de travail en ce qui concerne la gestion des erreurs et le suivi des emplacements sources afin que les parsingurs s’exécutent plus rapidement.

De plus, gardez à l’esprit que les formats de fichiers texte n’ont pas toujours des grammaires en tant que telles, vous devrez peut-être définir des combinateurs personnalisés pour réaliser des astuces lexicales spéciales plutôt que de simplement définir des “combinateurs d’parsingurs” pour chaque élément.

Pour l’parsing syntaxique, j’ai trouvé que Frown de Ralf Hinze était plus beau que Happy – un meilleur support des erreurs et un format plus agréable pour les fichiers de grammaire, mais Frown n’est pas activement maintenu et n’est pas sur Hackage. Je pense que c’est LR (k) plutôt que LR (1) ce qui signifie qu’il est plus puissant qu’il ne l’est.

La performance n’est pas vraiment une préoccupation majeure pour une grammaire. Les langages de programmation ont des grammaires complexes, mais vous pouvez vous attendre à des fichiers assez petits. En ce qui concerne les formats de fichiers de données, il incombe au concepteur du format de le concevoir de manière à permettre une parsing efficace. Pour les parsingurs de combinateur, vous ne devriez pas avoir besoin de nombreuses fonctionnalités avancées pour un fichier de format de données – si vous le faites, le format est mal conçu (cela arrive parfois malheureusement) ou votre parsingur est.

Pour la petite histoire, j’ai écrit un parsingur C avec Frown, un langage d’ombrage GL avec Happy, un parsingur C inachevé avec UU_Parsing, et beaucoup d’autres choses avec Parsec. Le choix pour moi était ce que je commençais par, la grammaire LR – Frown ou Happy (maintenant Happy as Frown n’est pas maintenue), sinon d’habitude Parsec (comme je l’ai dit, uu_parse est bien mais manque la commodité de LanguageDef). Pour les formats binarys, je roule moi-même, mais j’ai généralement des exigences particulières.

Nous avons eu beaucoup de succès avec ‘uu-parsinglib’ – nous sums passés à Parsec car il est un peu plus flexible et puissant – par exemple, il peut prendre en charge l’parsing paresseuse si nécessaire, et vous n’avez pas besoin d’utiliser explicitement combinator (comme «try» dans Parsec) pour marquer les éventuels points de back-tracking.

Il est vrai qu’à l’heure actuelle, il faut faire un peu plus en ce qui concerne la tokenisation, mais pour nous, c’est un petit point par rapport aux forces fondamentales de la bibliothèque.

Récemment, j’ai refait un parsingur DSL dans uu-parsinglib qui avait été écrit en parsec. J’ai trouvé que cela simplifiait grandement le programme. Ma principale motivation était d’obtenir l’aspect correcteur automatique. Cela fonctionne juste. C’est pratiquement gratuit! Aussi, j’ai beaucoup préféré écrire mon parsingur dans un style applicatif par opposition au style monadique de Parsec.