Introduction
Dans ce tutoriel nous allons présenter
le framework XText et illustrer étape par étape la création d’un simple DSL.
Prérequis
Eclipse : De préférence la
dernière version Eclipse Juno (4.2), j’ai rencontré certains problèmes de
plantages avec des versions antérieurs d’Eclipse.
Présentation
DSL (Domain Specific
Language)
Il s’agit d’un langage destiné à être utilisé dans un domaine
d’application bien précis. Un DSL peut être un langage de programmation à part
entière ou simplement une grammaire permettant de définir une syntaxe bien
précise pour certains fichiers (exemple : fichiers de paramétrage), ce
dernier exemple s’agit de mon cas d’utilisation personnel qui m’a fait
découvrir ce framework.
Framework XText
XText est un framework permettant la
création d’un DSL avec un IDE Eclipse.
L’atout principal de ce framework est la simplicité de son utilisation par
rapport à d’autres, notamment ANTLR qui nécessite beaucoup plus de temps pour
sa prise en main.
XText se base sur ANTLR pour la
parsing et la génération d’artefacts relatifs à la grammaire. Ce qui lui permet
de profiter de la puissance de ce framework tout en restant dans la simplicité.
Il est disponible gratuitement sous
licence « Eclipse Public License ». Permettant son utilisation pour
le développement des produits commerciaux.
Installation
Pour installer XText Framework rapidement,
il suffit d’installer le plugin Eclipse de la manière suivante : Dans Eclipse à Help à Install New Software : saisir
l’adresse de la dernière version du framework comme suit :
Dans les éléments d’installation
proposés, il suffit de cocher la dernière version de XText comme indiqué dans
l’écran ci-dessus. Ceci installera les éléments suivants qui sont
suffisants pour créer et tester notre DSL :
Une fois le plugin est installé, nous
avons tout ce qu’il faut pour commencer la création de notre DSL.
Création de la DSL
Introduction
Ce tutoriel est un exemple simplifié
inspiré de mon cas d’utilisation réel de ce framework : Dans une plateforme MOM (Messaging
Oriented Middleware), on a besoin de plusieurs éléments de paramétrage, notamment
des fichiers de configuration contenant les adresses des machines échangeant
les messages, les noms de piles et d’autres éléments. Ces fichiers sont
utilisés par des applications Java permettant d’assurer cet échange.
Le besoin d’utilisation d’une DSL est
exprimé par le souci d’assurer la validité des fichiers de paramétrage qui sont
saisis manuellement par les administrateurs du MOM.
On prend l’exemple allégé du fichier
de paramétrage suivant qui contiens la liste des machines définis chacune par
une adresse IP et un numéro de port :
Création du projet XText
Maintenant nous allons procéder à la création du projet qui va définir la grammaire du fichier de paramétrage.
Créer un nouveau projet comme suit :
Choisir le nom du projet ainsi que l’extension des fichiers qui doivent respecter la grammaire :
Les projets suivants sont créés :
Dans ce tutoriel nous allons utiliser seulement le projet principal tutodsl.
Création de la grammaire
Le fichier TutoDsl.xtext contenant la grammaire est ouvert automatiquement dans l’éditeur, le fichier contiens par défaut un DSL d’exemple « Hello World » suivant :
Description de la grammaire :
grammar fr.geekplayground.xtext.TutoDsl with org.eclipse.xtext.common.Terminals
grammar : définis le nom de la DSL ainsi que le package.
with : fait appel à un DSL prédéfini dans XText "Terminals", si vous examinez le contenu du fichier et vous allez remarquer qu’il définit des éléments élémentaires tels que INT et STRING ce qui nous épargne de les définir par nous-même.
generate tutoDsl "http://www.geekplayground.fr/xtext/TutoDsl"
Cette ligne sert pour le générateur des classes Java relatifs à la grammaire, donc ne la modifier pas.
Model
greetings+=Greeting*;
Dans l’élément Model, l’élément racine de la DSL "greetings" est déclaré.
greetings += : signifie que dans cet élément ils sont affectés N éléments de type Greeting, il est important d’utiliser
+= et pas = pour que l’élément soit capable de stocker n occurrences de l’objet Greeting, ce qui se traduit après en Java à une Liste d’objets. Dans le cas où on a un seul objet on doit utiliser seulement
=
Greeting* : le
* défini le nombre d’occurrences possibles de Greeting, les occurrences sont définis comme suit dans XText :
* : 0 ou N éléments
+ : 1 ou N éléments
? : 0 ou 1 élément.
Rien : 1 seul élément.
Greeting :
Déclare l’élément Greeting appelé précédemment.
'Hello' name=ID '!';
Contenu de l’élément Greeting : une chaîne en dur ‘Hello’ et un élément "name" de type ID. Type défini dans le fichier Terminals.
Pour apprendre d’avantage la syntaxe ainsi que les différentes possibilités offertes par XText pour définir une grammaire vous pouvez consulter la documentation sur le site XText :
http://www.eclipse.org/Xtext/documentation.html
On édite le fichier par notre grammaire suivante :
L’élément racine de notre grammaire est "File" pour désigner le fichier de paramétrage.
Dans cet élément on définit 2 sous éléments :
comment : élément contenant la chaine de caractères '#Host list'.
hostlist : element contenant 1 ou n elements HOST.
HOST : on declare 2 sous-éléments "address" et "port" séparés par ‘ :’
address : est de type IP : pour obliger les administrateurs a saisir des adresses IP correctes on défini le type IP comme suit :ip=INT'.'INT'.'INT'.'INT;
port : est de type PORT : défini par un simple INT :
port=INT;
Une fois notre grammaire est définie, on génère les classes Java « Artefacts » correspondantes, en cliquant sur le fichier TutoDsl.xtext comme suit :
Dans la console vous verrai le message suivant apparaître :
*ATTENTION*
It is recommended to use the ANTLR 3 parser generator (BSD licence - http://www.antlr.org/license.html).
Do you agree to download it (size 1MB) from 'http://download.itemis.com/antlr-generator-3.2.0.jar'? (type 'y' or 'n' and hit enter)
Ce message vous demande l’installation de parser ANTLR 3, répondez par y. Le composant sera téléchargé et la compilation de la grammaire se poursuivra.
Dans le cas où il y’a des erreurs dans votre grammaire, vous verrez les erreurs dans la console, donc corrigez et répéter l’opération.
Vous verrez toutes les classes Java générés dans le Project Explorer ainsi que les éléments relatifs au Workflow MWE2 :
Une fois que votre grammaire est exempte d’erreurs, lancer l’opération suivante en cliquant sur le fichier GeneratedTutoDsl.mwe2 :
D’autres classes sont générées permettant l’utilisation de votre grammaire dans d’autres projets Java.
Tester la grammaire
Maintenant c’est le moment de tester notre DSL, pour cela sélectionner le projet tutodsl et procéder comme suit :
Une nouvelle instance d’Eclipse s’ouvrira, aucun projet dans l’éditeur pour le moment.
Créer un nouveau projet Java « Sample » comme suit :
Un message vous demande si vous voulez ajouter la nature XText au projet, répondez par Oui.
Dans le projet Sample, créer un nouveau fichier et nommez le sample.tdsl (extension définie lors de la création du projet XText).
Le fichier sample.tdsl est ouvert automatiquement dans l’éditeur, on remarque qu’il y’a une croix rouge au début du fichier, ce qui indique que notre grammaire n’autorise pas un fichier vide.
On copie le contenu suivant de notre fichier de paramétrage dans le fichier :
On remarque que le contenu est accepté parce qu’il respecte bien la syntaxe définie par notre grammaire. Je vous laisse faire joujou avec le contenu du fichier et tester le bon fonctionnement de la grammaire ;)
Conclusion
Ce tutoriel vous a permis de découvrir le framework XText, vous avez remarqué que la syntaxe est dynamique ce qui permet de créer n’importe quelle grammaire.
Perspectives
Le projet généré est un projet Java simple, donc si vous voulez qu’il soit appelé par des projets Maven, vous serez amenés à "maveniser" également le projet XText. Pour cela j’ai trouvé quelque tutoriels sur le net qui sont plus ou moins efficaces, je vais essayer de créer un petit guide dans une prochaine publication.