Compilateurs, Python
     

Commencer avec ANTLR pour Python

ANTLR est un outil d’écriture compilateur, similaire Lex / Yacc ou Flex / Bison, mais beaucoup plus capable, moderne, et généralement moins frustrant. Je lis actuellement The Definitive ANTLR 4 Reference du créateur d’ANTLR, Terence Parr. C’est un merveilleux reasource sur le fonctionnement et l’utilisation d’ANTLR, mais il est écrit en Java – l’une de mes langues les moins préférées. Heureusement ANTLR cible plusieurs langues, alors j’ai pensé que je suivrais le long en Python – aussi l’une de mes langues les moins préférées.

ANTLR lui-même est écrit en Java, donc considère quelle langue vous allez écrire dans (Python dans ce cas) vous aurez besoin d’avoir Java installé, le fichier JAR ANTLR téléchargé, et une configuration Java Classpath dans votre environnement shell. En supposant que vous utilisez Fish, cela ressemble à ceci:

Avec cela à l’extérieur de la route, nous sommes à peu près fini avec Java. Nous pouvons passer à des étapes plus spécifiques python, et la première est d’installer le temps d’exécution Python ANTLR. C’est aussi simple que l’installation pip en cours d’exécution:

Le dernier morceau de configuration est de configurer un alias pour invoquer l’outil ANTLR lui-même. Bien que ce soit purement facultatif, je trouve qu’il permet d’économiser beaucoup de dactylographie. Ceci est similaire au script à la page 5 du livre ANTLR, mais adapté pour Python.

Remarque : Assurez-vous de chmod +x le script ci-dessus et placez-le quelque part dans votre chemin.

Maintenant, nous pouvons revenir à profiter d’apprendre sur ANTLR. Pour la plupart suivant avec le livre est un processus de traduction simple, avec les noms de classe Java référencés dans le livre étant très similaires (sinon identiques) à ceux exposés par le cadre Python ANTLR.

Par exemple, voici un exemple de fichier « principal » pour invoquer votre grammaire :

Vous échangez simplement « YourLexer » et « YourParser » pour les noms appropriés de votre lexer et parser.

Même la création de visiteurs et d’auditeurs est à peu près une traduction 1:1 de leurs exemples Java du livre. Par exemple, un plan pour un auditeur peut ressembler à :

C’est en fait très agréable que les convetions utilisées par le temps d’exécution Java sont si similaires à ceux utilisés par le Python. Je soupçonne que c’est intentionnel, afin de réduire la quantité de travail nécessaire pour ajouter de nouvelles cibles linguistiques et réduire la complexité de leur documentation.

Toutefois, tout cela a un inconvénient.

Malgré le langage qui implique à la contaire dans le livre ANTLR lui-même, grammaires ANTLR ne sont pas agnostiques de langue. Il est tout à fait possible de contretraire une grammaire ANTLR qui ne peut pas être compilée telle quelle à un certain nombre de langues cibles. En fait, nous nous sommes aperçus de cette situation assez tôt dans le livre à la page 43 où nous sommes exposés au modèle de l’auditeur.

La grammaire Java.g4 ne fonctionne pas lorsque vous ciblez Python, ANTLR génère les erreurs suivantes :

C’est beaucoup d’erreurs!

Retirons la première erreur réelle et regardons de plus près.

Il se plaint que la règle « type » nous cause des problèmes. Pour mieux comprendre pourquoi, examinons la partie applicable de la grammaire :

Et aussi le parser Java généré par ce peu de grammaire:

Et, si ce n’est pas 100% clair, regardons le code Java que nous devrions passer à Python pour utiliser cette grammaire:

Essentiellement, la grammaire définit une règle appelée « type », mais « type » est un mot réservé en Python. ANTLR lui-même produit alors un parser qui définit littéralement une fonction appelée « type », qui est apparemment très bien en Java, mais échoue merveilleusement dans Python.

Ce problème aurait pu facilement être évité en utilisant un préfixe commun pour les règles, ou avoir des règles être quelque chose levé dans un dictionnaire. Au lieu de cela, en prenant des noms de règles littérales et en s’attendant à ce que chacun d’eux puisse être défini comme fonction du même nom exact dans la langue cible, ANTLR n’est, par définition, pas un langage agnostique. Pour toute grammaire, il y a probablement plusieurs backends réels ou hypothétiques pour qui une telle grammaire ne peut pas être compilée.

Par exemple, voici une grammaire qui fonctionne parfaitement bien dans Python, mais ne peut pas être compilée pour Java :

Malheureusement, cette question github implique qu’il s’agit également d’une question connue par l’auteur, et celui qu’ils ne considèrent pas la peine de fixer.

Bien que beaucoup, sinon la plupart, grammaires ne sont probablement pas un problème, il est plutôt triste que:

  1. Un tel problème se produit assez tôt dans le livre
  2. Le livre implique fortement, et d’autres ressources sur Internet disent carrément, que ANTLR est agnostique langue – non, il n’est pas
  3. L’auteur ne semble pas enclin à corriger plus largement ni ce bug, ni cette idée fausse sur son outil.

Cela mis à part, ANTLR est en fait un outil merveilleux, surtout si vous y allez avec la connaissance et la conscience de ses verrues. Je suis heureux de voir ce que les choses merveilleuses que je peux créer avec cet outil étonnant.

About Jason

Jason est un entrepreneur expérimenté et développeur de logiciels qualifié dans le leadership, le développement mobile, la synchronisation des données et l’architecture SaaS. Il a obtenu son baccalauréat ès sciences (B.S.) en informatique de l’Université d’État de l’Arkansas.
View all posts by Jason →

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *