Avantages d'Antlr (par rapport, par exemple, lex / yacc / bison) [fermé]

143

J'ai utilisé lex et yacc (plus généralement bison) dans le passé pour divers projets, généralement des traducteurs (comme un sous-ensemble d'EDIF diffusé dans une application EDA). De plus, j'ai dû prendre en charge du code basé sur des grammaires lex / yacc datant de plusieurs décennies. Je connais donc bien les outils, même si je ne suis pas un expert.

J'ai vu des commentaires positifs sur Antlr dans divers forums dans le passé, et je suis curieux de savoir ce qui me manque peut-être. Donc, si vous avez utilisé les deux, dites-moi ce qui est meilleur ou plus avancé dans Antlr. Mes contraintes actuelles sont que je travaille dans une boutique C ++, et tout produit que nous livrons n'inclura pas Java, donc les analyseurs résultants devront suivre cette règle.

Don Wakefield
la source

Réponses:

145

Mise à jour / avertissement: Cette réponse n'est peut-être pas à jour!


Une différence majeure est que ANTLR génère un analyseur LL (*), alors que YACC et Bison génèrent tous deux des analyseurs LALR. Il s'agit d'une distinction importante pour un certain nombre d'applications, les plus évidentes étant les opérateurs:

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

ANTLR est totalement incapable de gérer cette grammaire telle quelle. Pour utiliser ANTLR (ou tout autre générateur d'analyseur LL), vous devez convertir cette grammaire en quelque chose qui n'est pas récursif à gauche. Cependant, Bison n'a aucun problème avec les grammaires de cette forme. Vous auriez besoin de déclarer «+» et «-» comme des opérateurs associatifs à gauche, mais ce n'est pas strictement requis pour la récursivité gauche. Un meilleur exemple pourrait être la répartition:

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

Notez que exprles actualsrègles et les règles sont récursives à gauche. Cela produit un AST beaucoup plus efficace au moment de la génération de code car cela évite le besoin de registres multiples et de débordements inutiles (un arbre de gauche peut être réduit alors qu'un arbre de droite ne le peut pas).

En termes de goût personnel, je pense que les grammaires LALR sont beaucoup plus faciles à construire et à déboguer. L'inconvénient est que vous devez faire face à des erreurs quelque peu cryptiques comme la réduction de décalage et la réduction (redoutée). Ce sont des erreurs que Bison détecte lors de la génération de l'analyseur, donc cela n'affecte pas l'expérience de l'utilisateur final, mais cela peut rendre le processus de développement un peu plus intéressant. ANTLR est généralement considéré comme plus facile à utiliser que YACC / Bison précisément pour cette raison.

Daniel Spiewak
la source
2
Donc, le grand avantage, peut-être unique, d'Antlr dans votre perception est qu'il génère moins d'erreurs comme sr et rr pendant la phase de construction? Je pense que je vais essayer, mais je finirai probablement par m'en tenir à ce que je sais ...
Don Wakefield
1
Ouais, c'est à peu près tout. :-) Je ne suis pas vraiment d'accord non plus avec l'opinion populaire selon laquelle ANTLR est plus facile que Bison, donc je pense que je serais d'accord avec votre décision.
Daniel Spiewak
2
La règle des «réels» a-t-elle besoin d'une deuxième règle pour indiquer qu'un simple «expr» est un réel? Sinon, belle explication.
Jonathan Leffler
8
Un autre commentaire que j'ai trouvé récemment, bien que vieux de dix ans, fait une observation raisonnable de la sortie : compilers.iecc.com/comparch/article/98-11-040 : "ANTLR / PCCTS sont LL, ce qui rend l'écriture grammaticale plus difficile, mais le le code généré est lisible. Yacc étant LALR (bien sûr vous le savez) facilite l'écriture de la grammaire, mais le code généré pourrait tout aussi bien être des hiéroglyphes. "
Don Wakefield
72
Je viens de terminer la prise en charge immédiate de la récursivité gauche pour la prochaine version d'ANTLR v3.4. Gère les règles d'expression LR et des éléments similaires comme les règles du déclarateur C. :)
Terence Parr
117

La différence la plus significative entre YACC / Bison et ANTLR est le type de grammaires que ces outils peuvent traiter. YACC / Bison gère les grammaires LALR, ANTLR gère les grammaires LL.

Souvent, les personnes qui ont travaillé avec les grammaires LALR pendant une longue période, trouveront plus difficile de travailler avec les grammaires LL et vice versa. Cela ne veut pas dire que les grammaires ou les outils sont intrinsèquement plus difficiles à utiliser. L'outil que vous trouvez le plus facile à utiliser dépendra principalement de la familiarité avec le type de grammaire.

En ce qui concerne les avantages, il y a des aspects où les grammaires LALR ont des avantages par rapport aux grammaires LL et il y a d'autres aspects où les grammaires LL ont des avantages par rapport aux grammaires LALR.

YACC / Bison génèrent des analyseurs basés sur des tables, ce qui signifie que la "logique de traitement" est contenue dans les données du programme parseur, pas tellement dans le code de l'analyseur. L'avantage est que même un analyseur pour un langage très complexe a une empreinte de code relativement faible. Cela était plus important dans les années 1960 et 1970, lorsque le matériel était très limité. Les générateurs d'analyseurs basés sur des tables remontent à cette époque et une faible empreinte de code était une exigence principale à l'époque.

ANTLR génère des analyseurs de descente récursifs, ce qui signifie que la "logique de traitement" est contenue dans le code de l'analyseur, car chaque règle de production de la grammaire est représentée par une fonction dans le code de l'analyseur. L'avantage est qu'il est plus facile de comprendre ce que fait l'analyseur en lisant son code. En outre, les analyseurs de descente récursifs sont généralement plus rapides que ceux pilotés par table. Cependant, pour les langages très complexes, l'empreinte du code sera plus importante. C'était un problème dans les années 60 et 70. À l'époque, seuls des langages relativement petits comme Pascal par exemple étaient implémentés de cette façon en raison de limitations matérielles.

Les analyseurs générés par ANTLR sont généralement à proximité de 10 000 lignes de code et plus. Les analyseurs de descente récursifs manuscrits sont souvent dans la même situation. Le compilateur Oberon de Wirth est peut-être le plus compact avec environ 4000 lignes de code, y compris la génération de code, mais Oberon est un langage très compact avec seulement environ 40 règles de production.

Comme quelqu'un l'a déjà souligné, un gros plus pour ANTLR est l'outil graphique IDE, appelé ANTLRworks. C'est un laboratoire complet de conception de grammaire et de langage. Il visualise vos règles de grammaire au fur et à mesure que vous les tapez et s'il trouve des conflits, il vous montrera graphiquement ce qu'est le conflit et ce qui le cause. Il peut même automatiquement refactoriser et résoudre des conflits tels que la récursivité à gauche. Une fois que vous avez une grammaire sans conflit, vous pouvez laisser ANTLRworks analyser un fichier d'entrée de votre langue et créer un arbre d'analyse et AST pour vous et afficher l'arborescence graphiquement dans l'EDI. C'est un très gros avantage car cela peut vous faire gagner de nombreuses heures de travail: vous trouverez des erreurs conceptuelles dans la conception de votre langage avant de commencer à coder! Je n'ai pas trouvé un tel outil pour les grammaires LALR, il semble qu'il n'y en ait pas.

Même pour les personnes qui ne souhaitent pas générer leurs analyseurs mais les coder à la main, ANTLRworks est un excellent outil de conception / prototypage de langage. Très probablement le meilleur outil disponible. Malheureusement, cela ne vous aide pas si vous souhaitez créer des analyseurs LALR. Passer de LALR à LL simplement pour profiter de ANTLRworks peut bien valoir la peine, mais pour certaines personnes, changer de type de grammaire peut être une expérience très pénible. En d'autres termes: YMMV.

trijezdci
la source
4
l'aime parce qu'il explique l'histoire derrière les différents mécanismes qui font comprendre
immédiatement les
35

Quelques avantages pour ANTLR:

  • peut générer des analyseurs dans différents langages - Java n'est pas requis pour exécuter l'analyseur généré.
  • Une interface graphique impressionnante facilite le débogage de la grammaire (par exemple, vous pouvez voir les AST générés directement dans l'interface graphique, aucun outil supplémentaire n'est requis)
  • Le code généré est en fait lisible par l'homme (c'est l'un des objectifs d'ANTLR) et le fait qu'il génère des analyseurs LL aide sûrement à cet égard.
  • la définition des terminaux est également indépendante du contexte (par opposition à regex dans (f) lex) - permettant ainsi, par exemple, la définition de terminaux contenant des parenthèses correctement fermées

Mon 0,02 $

Cristian Diaconescu
la source
9

Un autre avantage d'ANTRL est que vous pouvez utiliser ANTLRWORKS , même si je ne peux pas dire que c'est un avantage strict, car il peut y avoir des outils similaires pour d'autres générateurs.

John avec gaufre
la source
9
  • Bison et Flex entraînent une plus petite empreinte mémoire, mais vous n'avez pas d'IDE graphique.
  • antlr utilise plus de mémoire, mais vous avez antlrworks, un IDE graphique.

L'utilisation de la mémoire Bison / Flex est généralement d'environ un Mo. Comparez cela avec antlr - en supposant qu'il utilise 512 octets de mémoire pour chaque jeton du fichier que vous souhaitez analyser. 4 millions de jetons et vous n'avez plus de mémoire virtuelle sur un système 32 bits.

Si le fichier que vous souhaitez analyser est volumineux, antlr peut manquer de mémoire, donc si vous souhaitez simplement analyser un fichier de configuration, ce serait une solution viable. Sinon, si vous souhaitez analyser un fichier contenant beaucoup de données, essayez Bison.

juste moi
la source
7
Je suis curieux. Pouvez-vous faire référence à la documentation décrivant la consommation de 512 octets de mémoire par jeton? Je ne me souviens pas avoir vu cette discussion. Mon choix de mots-clés Google ne me donne pas non plus satisfaction ...
Don Wakefield
2
Parlez-vous de l'empreinte mémoire du générateur d'analyseur lors de la génération d'un analyseur, ou parlez-vous de l'empreinte mémoire de l'analyseur généré lors de l'analyse de l'entrée pour la langue source? Des millions de jetons dans une grammaire seraient absolument insensés. Vous devriez être enfermé dans un établissement psychiatrique si vous avez sérieusement tenté de vendre une telle idée. En ce qui concerne les fichiers d'entrée pour l'analyseur lui-même, il peut y avoir des cas où ceux-ci peuvent avoir un très grand nombre de jetons, mais la plupart des langages sont modulaires, vous n'analysez pas toute l'entrée dans un seul fichier, les modules individuels sont plus petits.
trijezdci