[JAVA] Développement de DSL avec ANTLR 4.7.1

Préface

Cette fois, de la part de l'utilisateur qui utilise le [outil de génération de code automatique, Damas] créé par Java (https://github.com/yasuflatland-lf/damascus) que je suis en train de créer, il suffit d'utiliser le modèle pour la génération automatique. Au lieu de cela, il y avait une demande pour générer un modèle à partir du code source et créer un modèle personnalisé.

Je ne pouvais pas le gérer correctement avec les expressions régulières seules, et lorsque je cherchais une solution, je l'ai résolu en créant un DSL simple en utilisant le compilateur / compilateur ANTLR.

Après quelques essais et erreurs, j'ai pu implémenter DSL, donc je vais exposer mon flux de développement cette fois. Comme exemple de projet, cette fois je vais utiliser mon travail Damas.

Comprendre le fonctionnement de base d'ANTLR

ANTLR est un outil Java pour créer votre propre système de traitement (langage de programmation). L'analyseur de phrases (Lexer) et l'analyseur de syntaxe (Parser) sont automatiquement générés à partir du fichier `` * .g4 '' décrit dans le BNF étendu.

Je ne sais pas à droite ou à gauche, mais je me suis référé au livre de commentaires "[The Definitive ANTLR 4 Reference](https://pragprog.com/book/tpantlr2/the-definitive]" écrit par le professeur Terence Parr, l'auteur de ANTLR. -antlr-4-référence) ". (Ci-après le livre ANTLR) Le nombre de pages est d'environ 300 pages, ce qui est assez épais, mais il est écrit en anglais simple, avec de nombreux exemples de code dans le texte et Exemple de code sur Github Puisqu'il y a remenska / Grammars), j'ai en fait essayé de le déplacer en le regardant, et j'ai pu le lire en touchant l'exemple de code en environ 2 semaines.

Au début, je regardais simplement l'exemple de code et je jouais avec, mais après tout je n'étais pas sûr, j'ai donc lu le livre ANTLR depuis le début Après tout, je pensais que c'était le moyen le plus rapide. Il y a beaucoup d'informations sur le site Web et le référentiel Github d'Antlr, mais elles sont fragmentées et pas toutes couvertes, donc [ANTLR Book](https://pragprog.com/book/tpantlr2/the-definitive- Il est fortement recommandé de lire d'abord tous les chapitres de antlr-4-reference).

Environnement de développement

J'utilise habituellement IntelliJ, mais j'ai senti que le plug-in Antler d'Eclipse était le plus utilisable. Moi aussi

Je développais le même projet en l'ouvrant dans deux IDE. Depuis janvier 2018, Oxygen est la dernière version, voici donc comment installer le plug Antrl avec.

  1. Recherchez Antlr dans Aide-> Eclipse Market place.
  2. Installez ANTLR 4 IDE 0.3.6
  3. Eclipse redémarre après l'installation
  4. Dans le menu supérieur, Fenêtre-> Afficher la vue-> autres-> ANTLR 4
  5. Sélectionnez à la fois Parse Tree et Syntax Diagram.
  6. Ouvrez Parse Tree dans Eclipse (un volet doit apparaître)
  7. Importez Damascus dans Eclipse en tant que projet et ouvrez DmscSrcParser.g4```.
  8. Double-cliquez sur la règle `file``` en haut de` DmscSrcParser.g4``` pour afficher `` `DmscSrcParser :: file``` dans le volet Analyser l'arborescence et afficher le diagramme. Est affiché

Flux de développement

Conception Lexer / Parser

Dans Damas, il y a deux fichiers, `DmscSrcParser.g4 '' et` `DmscSrcLexer.g4 ''. Il a été développé dans le cycle suivant.

Conception Lexer

En utilisant la notation BNF étendue, j'ai créé une définition de jeton dans `` DmscSrcLexer.g4 '' tout en vérifiant le diagramme de syntaxe du plug Antrl installé. Si la syntaxe est incorrecte, un message d'erreur s'affiche. Comme il est difficile de créer une définition de jeton à partir de zéro, reportez-vous à Sample in ANTLR book, et dans ce cas, Island Language in ANTLR book. ) Il était prévu d'être créé à l'aide de balises, alors reportez-vous à ModeTagsLexer.g4 etc. , Créé la base.

Conception d'analyseur

En utilisant la définition de jeton conçue ci-dessus, j'ai défini une règle d'analyse syntaxique dans DmscSrcParser.g4```. Il peut être difficile de bien définir une règle depuis le début, mais si vous devez définir une règle très compliquée dans Parser, ou si vous vous retrouvez coincé dans une situation où la règle n'est pas bien appliquée, revoyez la définition du token de Reexer. S'il vous plaît essayez. Si Lexer est bien conçu, Parser doit être concis.

Ici, je pense qu'il est nécessaire de répéter les essais et erreurs tout en répétant les ajustements fins, en se référant à l'échantillon du livre ANTLR. Il est difficile de faire une grande règle depuis le début, donc dans ce langage insulaire, créez une petite règle qui peut d'abord juger s'il s'agit d'une balise de début DSL ou non, et si cette opération fonctionne, balisez Je pense que le point est la conscience de tester localement de petites règles, comme tester les règles des attributs à l'intérieur, et les combiner pour créer une grande règle.

DmscSrcParser.Règle de niveau supérieur dans g4 (fichier pour Damas))Cliquez pour coller la syntaxe qui vous intéresse et vérifiez visuellement qu'elle est correctement décomposée en schémas fonctionnels dans l'arborescence d'analyse. En outre, tout en regardant l'erreur de syntaxe, Parser/Nous ajusterons Lexer.



### Développement de l'auditeur
 Maintenant que Lexer et Parser peuvent gérer la syntaxe presque correctement, il est temps d'implémenter le Listener. ANTLR peut générer la méthode Listner et l'interface / l'implémentation de la méthode Visitor. La méthode Visitor convient au traitement séquentiel comme un interpréteur, mais cette fois nous allons tout traiter en même temps, nous l'avons donc développée en utilisant Listner.

 Le `` `` build.gradle``` de [Damascus](https://github.com/yasuflatland-lf/damascus) a une tâche `` generateGrammarSource '' définie, et elle est utilisée comme racine du projet. Lorsque vous exécutez `` gradle generateGrammarSource`` sur, il générera un Lexer / Parser à partir du fichier `` `` * .g4```. Nous allons concevoir l'implémentation en héritant du `` DmscSrcParserBaseListener '' généré.

 À ce stade, nous mettrons en œuvre le test unitaire. JUnit est très bien, mais comme le framework de test appelé Spock vous permet de créer des tests de manière flexible, [Damascus](https://github.com/yasuflatland-lf/damascus) utilise les tests Spock.

## Résumé
 J'ai appris que la conception de Lexer et de Paser est la plus difficile, en particulier lors de la conception de Paser, et que la conception de Lexer est mauvaise et que la réécriture de Lexer à plusieurs reprises rend Parser simple. C'était une grande surprise de pouvoir gérer facilement une syntaxe compliquée qui ne peut pas être gérée par des expressions régulières en utilisant le moteur d'analyse syntaxique généré par ANTLR.

 C'est un article qui ressemble à un poème, mais j'espère que cela aide quelqu'un!

 Tips
### Si vous changez de Lexer et qu'il ne se recharge pas correctement
 Le plug Antlr d'Eclipse fonctionne bien, mais lorsque je change fréquemment de Lexer, il ne charge parfois pas bien la syntaxe modifiée. Je l'ai résolu par la méthode suivante, je vais donc l'écrire pour référence.

 1. Exécutez `` `gradle generateGrammarSource```, puis exécutez` `` `gradle eclipse```
 2. Si cela fonctionne toujours, dans le répertoire où se trouve `` `* .g4``` (` `/ src / main / antlr```)` `ʻantlr4 DmscSrcLexer.g4; antlr4 DmscSrcParser.g4; javac Exécutez Dms * .java``` et convertissez les `` * .tokens '' et `` * .interp '' générés en `` `` src / main / java / com / liferay / damascus / antlr / Copier dans le modèle```, exécutez `` `` gradle eclipse```, double-cliquez sur` `` fichier``` dans `` DmscSrcParser.g4```, `` Parse Tree`` `Revérifiez le volet.
 3. Si cela ne fonctionne pas, essayez de redémarrer Eclipse.


Recommended Posts

Développement de DSL avec ANTLR 4.7.1
Développement d'équipe avec Git (édition eclipse)
Développement de Flink à l'aide de l'API DataStream
[Rails 6] Développement d'API à l'aide de GraphQL (Query)
Développement HTML5 par Java avec TeaVM
Notes de développement MOD à l'aide de l'API Minecraft 14.4 Fabric # 1
Création d'un environnement de développement Kotlin à l'aide de SDKMAN
Développement de jeux avec deux personnes utilisant java 2
Développement de jeux avec deux personnes utilisant java 1
Développement de jeux avec deux personnes utilisant java 3