I. Introduction▲
Les développements pour cet article ont été faits sous Eclipse-Xtext 2.2.1 avec la version du JDK 1.7.1 (Java 7).
Reprenons le projet Xtext Madsl développé dans : Introduction à Xtext : créer son propre DSL. Ouvrons ce projet dans la version Eclipse-Xtext dont nous disposons.
|
Cette fois, nous ne travaillerons que dans le sous-projet org.xtext.maDsl.ui. C'est dans ce sous-projet qu'il est indiqué d'ajouter tous les éléments graphiques relatifs au DSL.
II. Cahier des charges▲
L'objectif de notre travail dans ce tutoriel reste très académique et est double :
- premièrement, nous voulons développer et embarquer dans Eclipse-Xtext, du code Java permettant d'afficher dans une fenêtre graphique (à développer également) des programmes Madsl dont le fichier a été sélectionné dans la vue Package Explorer d'Eclipse ;
- deuxièmement, nous voulons de même développer et embarquer dans Eclipse-Xtext, du code Java devant exécuter des programmes madsl dont le fichier a été sélectionné dans la vue Package Explorer, et afficher le résultat dans une fenêtre graphique.
Il ressort deux choses principales des objectifs précédents : l'une destinée au développement du code Java pour la manipulation du langage et l'autre destinée au développement d'une interface graphique devant afficher les résultats des exécutions.
Nous choisissons de développer comme interface graphique, une vue, car celle-ci est facilement intégrable dans l'IDE Eclipse via le développement de plugin. Cette vue doit contenir deux boutons :
1) l'un qui lorsqu'il est appuyé déclenche une action permettant d'afficher dans un compartiment de la même vue le programme Madsl, sélectionné dans le package Explorer d'Eclipse ;
2) l'autre qui, lorsqu'il est appuyé déclenche une action permettant d'exécuter et d'afficher dans le compartiment de la même vue, le résultat du programme Madsl sélectionné dans le package Explorer d'Eclipse.
En somme, ce travail demande donc que l'on puisse :
a) premièrement, développer l'interface graphique (vue et boutons) destinée à la manipulation du langage ;
b) deuxièmement, développer un Display (Afficheur) et un Runner (Exécuteur) pour notre langage. Nous nous allégeons du développement d'un compilateur (qui est très lourd à développer) dans ce tutoriel et nous supposons que le programme Madsl sélectionné pour exécution par l'utilisateur ne comporte pas d'erreur (les colorations syntaxiques peuvent aider à détecter les erreurs dans le programme).
III. Développement de la vue MadslView du DSL Madsl▲
Le développement d'interface graphique pour les applications Java peut se faire de manière très rapide en utilisant le plugin WindowBuildertéléchareger Windowbuilder. Ce plugin intégré à Eclipse permet de dessiner des interfaces graphiques et de récupérer le code généré pour personnalisation (customize). Pour installer sa version 3.7 par exemple (celle utilisée pour les développements de cet article), copiez le lien suivant : http://download.eclipse.org/windowbuilder/WB/integration/3.7. Dans le menu help d'eclipse-Xtext, sélectionnez Install New Software. Une fenêtre s'ouvre : recopier ce lien dans le champ work with et appuyez Add et suivre l'installation.
Considérons à présent notre sous-projet plugin org.xtext.maDsl.ui. Dans ce sous-projet, créons un package avec un nom de notre choix (ex. : org.xtext.run) dans lequel nous allons ajouter toutes les classes développées pour la manipulation du langage. Dans ce package, créons la classe MadslView étendant la superclasse Viewpart destinée à la gestion des vues. MadslView a pour but de réaliser la partie graphique de notre travail.
|
Pour la créer via windowbuilder, cliquez droit sur org.xtext.run-->New-->Other-->SWT Designer-->Forms-->ViewPart. Une fenêtre s'ouvre. Dans cette fenêtre, indiquez le nom de votre classe (MadslView). Une fois la classe créée, elle vient avec un squelette de code qu'il faudra compléter. Il se peut qu'elle indique des erreurs dans ce code squelette : supprimer les objets provoquant ces erreurs, car ils ne nous serviront pas. Ouvrir cette classe, en bas à gauche en dessous de l'éditeur Eclipse, cliquez sur Design pour dessiner votre vue et ajouter les boutons. Voici un exemple de vue que nous avons proposée :
Ouvrons maintenant le code source de cette vue. Pour implémenter les actions liées aux boutons de la vue, nous allons compléter la méthode widgetSelected(SelectionEvent e) de chaque bouton. Pour le bouton " Display The Selected Madsl Program", le code proposé doit permettre de détecter le fichier Madsl sélectionné par l'utilisateur dans le Package Explorer et afficher le contenu intégral de ce fichier dans la vue. Pour le bouton " Execute The Selected Madsl Program" le code proposé doit permettre de détecter le fichier Madsl sélectionné par l'utilisateur dans le Package Explorer et faire appel à la classe MadslRunner représentant la classe chargée d'exécuter un programme Madsl.
Nous proposons ci-dessous le code de la classe MadslView que nous avons développé :
package
org.xtext.run;
import
java.io.BufferedReader;
import
java.io.FileReader;
import
java.io.IOException;
import
java.net.URI;
import
org.eclipse.core.resources.IWorkspaceRoot;
import
org.eclipse.core.resources.ResourcesPlugin;
import
org.eclipse.jface.action.IMenuManager;
import
org.eclipse.jface.action.IToolBarManager;
import
org.eclipse.jface.viewers.ISelection;
import
org.eclipse.swt.SWT;
import
org.eclipse.swt.widgets.Composite;
import
org.eclipse.ui.IWorkbenchPage;
import
org.eclipse.ui.part.ViewPart;
import
org.eclipse.swt.widgets.Button;
import
org.eclipse.swt.widgets.Display;
import
org.eclipse.swt.widgets.Label;
import
org.eclipse.swt.widgets.Shell;
import
org.eclipse.swt.custom.ScrolledComposite;
import
org.eclipse.swt.events.SelectionEvent;
import
org.eclipse.swt.events.SelectionListener;
import
org.eclipse.wb.swt.SWTResourceManager;
public
class
MadslView extends
ViewPart {
public
static
final
String ID =
"run.maDslView"
; //$NON-NLS-1$
Label resultLabel;
String[] relativeUriOfTheSelectedFile;
public
MadslView
(
) {
}
/**
* Create contents of the view part.
*
@param
parent
*/
//@Override
public
void
createPartControl
(
Composite parent) {
parent.setLayout
(
null
);
ScrolledComposite scrolledComposite =
new
ScrolledComposite
(
parent, SWT.BORDER |
SWT.H_SCROLL |
SWT.V_SCROLL);
scrolledComposite.setBounds
(
197
, 0
, 580
, 170
);
scrolledComposite.setExpandHorizontal
(
true
);
scrolledComposite.setExpandVertical
(
true
);
resultLabel =
new
Label
(
scrolledComposite, SWT.NONE);
resultLabel.setBackground
(
SWTResourceManager.getColor
(
SWT.COLOR_WHITE));
scrolledComposite.setContent
(
resultLabel);
scrolledComposite.setMinSize
(
resultLabel.computeSize
(
SWT.DEFAULT, SWT.DEFAULT));
Button btnDisplayCurrentMadsl =
new
Button
(
parent, SWT.NONE);
btnDisplayCurrentMadsl.setAlignment
(
SWT.RIGHT);
btnDisplayCurrentMadsl.setBounds
(
0
, 10
, 198
, 32
);
btnDisplayCurrentMadsl.setText
(
"Display The Selected Madsl Program"
);
btnDisplayCurrentMadsl.addSelectionListener
(
new
SelectionListener
(
) {
//@Override
public
void
widgetSelected
(
SelectionEvent e) {
// Add
//IWorkbench workbench = PlatformUI.getWorkbench();
//IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IWorkbenchPage page =
getSite
(
).getPage
(
); //recupération de la page active de la fenêtre eclipse
//récupération de l'objet sélectionné dans la vue Package Explorer; l'objet est tracé par un chemin relatif le localisant, indiquant
//si c'est un fichier ou un dossier
ISelection currentSelectedFile =
page.getSelection
(
"org.eclipse.jdt.ui.PackageExplorer"
);
int
relativePathLength =
currentSelectedFile.toString
(
).length
(
);
relativeUriOfTheSelectedFile =
currentSelectedFile.toString
(
).substring
(
1
, relativePathLength -
1
).split
(
"/"
);
if
(
relativeUriOfTheSelectedFile[0
].equals
(
"P"
)){
//si l'élément sélectionné est un dossier
Display display =
new
Shell
(
).getDisplay
(
);
resultLabel.setForeground
(
display.getSystemColor
(
SWT.COLOR_RED)); // afficher le texte avec la couleur rouge
resultLabel.setText
(
""
);
resultLabel.setText
(
"Un projet ou un package a été sélectionné. Veuillez plutôt sélectionner un fichier .madsl"
);
}
else
{
if
(
relativeUriOfTheSelectedFile[0
].equals
(
"L"
)){
//si l'élément sélectionné est un fichier
IWorkspaceRoot workspaceRoot =
ResourcesPlugin.getWorkspace
(
).getRoot
(
);
//récupération du projet auquel appartient le fichier sélectionné
//IProject currentSelectedProject =
// workspaceRoot.getProject(relativeUriOfTheSelectedFile[relativeUriOfTheSelectedFile.length - 1]);
URI absoluteUriWorkspace =
workspaceRoot.getLocationURI
(
);
String absoluteUriOfTheSelectedFile =
absoluteUriWorkspace.toString
(
);
for
(
int
i =
1
; i<
relativeUriOfTheSelectedFile.length; i++
){
absoluteUriOfTheSelectedFile +=
"/"
+
relativeUriOfTheSelectedFile[i];
}
int
absoluteUriOfSelectedFileLength =
absoluteUriOfTheSelectedFile.length
(
);
// le préfixe constitué des 6 premiers caractères ne font pas partie du chemin considéré
absoluteUriOfTheSelectedFile =
absoluteUriOfTheSelectedFile.substring
(
6
, absoluteUriOfSelectedFileLength);
String absolutePathOfTheSelectedFile =
absoluteUriOfTheSelectedFile.replace
(
'/'
, '
\\
'
);
//lecture du fichier .madsl sélectionné et affichage dans la vue
String sourceCode =
""
;
try
{
BufferedReader bfr =
new
BufferedReader (
new
FileReader
(
absolutePathOfTheSelectedFile));
String line =
bfr.readLine
(
);
while
(
line !=
null
){
sourceCode +=
line +
"
\n
"
;
line =
bfr.readLine
(
);
}
Display display =
new
Shell
(
).getDisplay
(
);
resultLabel.setForeground
(
display.getSystemColor
(
SWT.COLOR_BLACK)); // afficher le texte avec la couleur noire
resultLabel.setText
(
""
); //effacer ce qui était déjà écrit dans la vue
resultLabel.setText
(
sourceCode);
}
catch
(
IOException ex){
Display display =
new
Shell
(
).getDisplay
(
);
resultLabel.setForeground
(
display.getSystemColor
(
SWT.COLOR_RED)); // afficher le texte avec la couleur rouge
resultLabel.setText
(
""
);
resultLabel.setText
(
"Impossible de lire le fichier sélectionné"
);
}
}
}
}
//@Override
public
void
widgetDefaultSelected
(
SelectionEvent e) {
}
}
);
Button btnExecuteCurrentMadsl =
new
Button
(
parent, SWT.NONE);
btnExecuteCurrentMadsl.setBounds
(
0
, 60
, 198
, 32
);
btnExecuteCurrentMadsl.setText
(
"Execute The Selected Madsl Program"
);
btnExecuteCurrentMadsl.addSelectionListener
(
new
SelectionListener
(
) {
//@Override
public
void
widgetSelected
(
SelectionEvent se) {
// Add
IWorkbenchPage page =
getSite
(
).getPage
(
); //récupération de la page active de la fenêtre eclipse
//récupération de l'objet sélectionné dans la vue Package Explorer; l'objet est tracé par un chemin relatif le localisant,
//indiquant si c'est un fichier ou un dossier
ISelection currentSelectedFile =
page.getSelection
(
"org.eclipse.jdt.ui.PackageExplorer"
);
int
relativePathLength =
currentSelectedFile.toString
(
).length
(
);
relativeUriOfTheSelectedFile =
currentSelectedFile.toString
(
).substring
(
1
, relativePathLength -
1
).split
(
"/"
);
if
(
relativeUriOfTheSelectedFile[0
].equals
(
"P"
)){
Display display =
new
Shell
(
).getDisplay
(
);
// afficher le texte avec la couleur rouge
resultLabel.setForeground
(
display.getSystemColor
(
SWT.COLOR_RED));
resultLabel.setText
(
""
);
resultLabel.setText
(
"Un projet ou un package a été sélectionné.
Veuillez plutôt sélectionner un fichier .madsl");
}
else
{
if
(
relativeUriOfTheSelectedFile[0
].equals
(
"L"
)){
//IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
//URI absoluteUriWorkspace = workspaceRoot.getLocationURI();
String UriOfTheSelectedFile =
currentSelectedFile.toString
(
).substring
(
2
, relativePathLength -
1
);
MadslRunner madslrunner =
new
MadslRunner
(
);
double
result =
madslrunner.runMadslProgram
(
UriOfTheSelectedFile);
Display display =
new
Shell
(
).getDisplay
(
);
// afficher le résultat avec la couleur noire
resultLabel.setForeground
(
display.getSystemColor
(
SWT.COLOR_BLACK));
resultLabel.setText
(
""
);
resultLabel.setText
(
" "
+
result);
}
}
}
//@Override
public
void
widgetDefaultSelected
(
SelectionEvent e) {
}
}
);
Label oneLabel =
new
Label
(
parent, SWT.NONE);
oneLabel.setBackground
(
SWTResourceManager.getColor
(
SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
oneLabel.setBounds
(
0
, 0
, 198
, 170
);
createActions
(
);
initializeToolBar
(
);
initializeMenu
(
);
}
/**
* Create the actions.
*/
private
void
createActions
(
) {
// Create the actions
}
/**
* Initialize the toolbar.
*/
private
void
initializeToolBar
(
) {
IToolBarManager toolbarManager =
getViewSite
(
).getActionBars
(
)
.getToolBarManager
(
);
}
/**
* Initialize the menu.
*/
private
void
initializeMenu
(
) {
IMenuManager menuManager =
getViewSite
(
).getActionBars
(
)
.getMenuManager
(
);
}
//@Override
public
void
setFocus
(
) {
// Set the focus
}
}
Pour intégrer cette vue à l'éditeur eclipse-Xtext, ouvrez le fichier plugin.xml du sous-projet org.xtext.maDsl.ui. Sélectionnez l'onglet Extensions. Dans cette fenêtre nous allons lier notre vue MadslView au projet. Cliquez sur Add. La fenêtre New Extension s'ouvre. Dans cette fenêtre, saisissez org.eclipse.ui.view dans le champ texte Extension Point Filter et sélectionnez le plugin correspondant. Puis terminez en cliquant sur Finish.
Le plugin est alors ajouté dans la fenêtre Extensions :
Cliquez droit sur ce plugin, puis New, puis View. Complétez en suite les champs texte comme sur la capture d'écran :
Le développement et l'intégration de la vue sont désormais terminés. Il ne nous reste plus qu'à proposer le code du Runner de notre DSL.
IV. IV-Développement de l'exécuteur MadslRunner des programmes du DSL Madsl▲
Revenons dans le package org.xtext.run créé précédemment. Ajoutons une classe Java nommée MadslRunner à ce package.
|
Pour exécuter une à une les instructions du programme de notre DSL, nous devons utiliser les classes Java qui avaient été générées pour l'occasion dans le sous-projet org.xtext.maDsl, lors de la création du langage.
Ces classes implémentent généralement les méthodes getters/setters permettant de récupérer les données incluses dans les instructions du programme de la DSL. Ces données suivent le format de ce qui est indiqué dans la grammaire du DSL.
Pour le cas du DSL Madsl, nous voulions écrire de petits programmes permettant de récupérer des données statistiques dans des instructions dédiées et de renvoyer sa moyenne, sa variance\x{0085} Ce sont ces fonctions que nous devons coder dans le Runner.
La spécificité de ce Runner est qu'il doit d'abord pouvoir fonctionner en mode standalone. C'est-à-dire indépendamment de l'exécution du projet Xtext en question. La classe permettant de réaliser cela est générée par Xtext. Le Runner doit pouvoir récupérer le fichier contenant le code Madsl à exécuter, sous forme de ressource unique situé sur le disque dur de votre machine. Pour cela, l'URI (Uniform Resource Identifier) indiquant le chemin du fichier doit être indiqué à l'objet Java ResourceSet. Cet objet renvoie un autre objet EObject représentant l'arbre syntaxique du programme contenu dans le fichier sélectionné. Pour se placer à la racine de l'arbre (correspondant à la première règle de production de la grammaire du DSL), nous utilisons la méthode get(0) de ResourceSet. Voici l'entête de la classe MadslRunner réalisant tout le processus sus-cité :
new
MaDslStandaloneSetup
(
);
MaDslStandaloneSetup.doSetup
(
);
ResourceSet resourceSet =
new
ResourceSetImpl
(
);
Resource resource =
resourceSet.getResource
(
URI.createURI
(
uri, true
), true
);
// récupération de la racine de l'arbre syntaxique du programme
EObject eobject =
resource.getContents
(
).get
(
0
);
Nous proposons maintenant le code complet de la classe MadslRunner :
package
org.xtext.run;
import
java.util.Iterator;
import
java.util.Vector;
import
org.xtext.MaDslStandaloneSetup;
import
org.xtext.maDsl.EFFECTIFS;
import
org.xtext.maDsl.MODALITES;
import
org.xtext.maDsl.PROGRAMME;
import
org.xtext.maDsl.REEL;
import
org.xtext.maDsl.RETURN;
import
org.eclipse.emf.common.util.EList;
import
org.eclipse.emf.common.util.URI;
import
org.eclipse.emf.ecore.EObject;
import
org.eclipse.emf.ecore.resource.Resource;
import
org.eclipse.emf.ecore.resource.ResourceSet;
import
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
public
class
MadslRunner {
public
MadslRunner
(
){
}
public
double
runMadslProgram
(
String uri){
double
result =
0.0
;
new
MaDslStandaloneSetup
(
);
MaDslStandaloneSetup.doSetup
(
);
ResourceSet resourceSet =
new
ResourceSetImpl
(
);
Resource resource =
resourceSet.getResource
(
URI.createURI
(
uri, true
), true
);
EObject eobject =
resource.getContents
(
).get
(
0
); // récupération de la racine de l'arbre syntaxique du programme
PROGRAMME madslProgram =
(
PROGRAMME) eobject;
// récupération de la classe contenant les effectifs de la série statistique saisie dans le programme madsl
EFFECTIFS effClass =
madslProgram.getEff
(
);
// récupération du premier effectif de la série statistique
REEL firstEff =
effClass.getPremierEffectif
(
);
// récupération des autres effectifs de la série statistique
EList<
REEL>
otherEffs =
effClass.getAutreEffectif
(
);
Vector<
Double>
listOfEffs =
new
Vector<
Double>(
);
listOfEffs.add
(
firstEff.getReel
(
));
for
(
REEL eff : otherEffs){
listOfEffs.add
(
eff.getReel
(
));
}
// récupération de la classe contenant les modalités de la série statistique saisie dans le programme madsl
MODALITES modClass =
madslProgram.getMod
(
);
// récupération de la première modalité de la série statistique
REEL firstMod =
modClass.getPremiereModalite
(
);
// récupération des autres modalités de la série statistique
EList<
REEL>
otherModalitiesClasses =
modClass.getAutreModalite
(
);
Vector<
Double>
listOfModalities =
new
Vector<
Double>(
);
listOfModalities.add
(
firstMod.getReel
(
));
for
(
REEL mod : otherModalitiesClasses){
listOfModalities.add
(
mod.getReel
(
));
}
// récupération de la class RETURN, pour savoir quelle opération statistique l'utilisateur veut effectuer
RETURN ret =
madslProgram.getRet
(
);
String operation =
ret.getResultat
(
);
int
op =
0
;
if
(
operation.equals
(
"moyenne"
)) op =
1
;
if
(
operation.equals
(
"variance"
)) op =
2
;
if
(
operation.equals
(
"ecarttype"
)) op =
3
;
if
(
operation.equals
(
"mode"
)) op =
4
;
switch
(
op){
//java 7 permet aussi de faire du switch avec des strings
case
1
:
result =
this
.moyenne
(
listOfEffs, listOfModalities);
break
;
case
2
:
result =
this
.variance
(
listOfEffs, listOfModalities);
break
;
case
3
:
result =
this
.ecarttype
(
listOfEffs, listOfModalities);
break
;
case
4
:
result =
this
.mode
(
listOfEffs, listOfModalities);
break
;
}
return
result;
}
private
double
moyenne
(
Vector<
Double>
eff, Vector<
Double>
mod){
double
totalEff =
0.0
;
double
e =
0.0
, m =
0.0
;
Vector<
Double>
v =
new
Vector<
Double>(
);
Iterator<
Double>
itEff =
eff.iterator
(
);
Iterator<
Double>
itMod =
mod.iterator
(
);
while
(
itEff.hasNext
(
) &&
itMod.hasNext
(
)){
// la taille des deux vecteurs est sensée être la même
e =
itEff.next
(
);
m =
itMod.next
(
);
totalEff +=
e;
v.add
(
e*
m);
}
Iterator<
Double>
it =
v.iterator
(
);
double
sum =
0.0
;
while
(
it.hasNext
(
)){
sum +=
it.next
(
);
}
return
(
sum/
totalEff);
}
private
double
variance
(
Vector<
Double>
eff, Vector<
Double>
mod){
double
totalEff =
0.0
;
double
x =
0.0
, m =
0.0
;
double
moyenne =
this
.moyenne
(
eff, mod);
Vector<
Double>
v =
new
Vector<
Double>(
);
Iterator<
Double>
itEff =
eff.iterator
(
);
Iterator<
Double>
itMod =
mod.iterator
(
);
while
(
itEff.hasNext
(
) &&
itMod.hasNext
(
)){
// la taille des deux vecteurs est sensée être la même
totalEff +=
itEff.next
(
);
x =
itMod.next
(
);
m =
(
x -
moyenne)*(
x -
moyenne);
v.add
(
m);
}
Iterator<
Double>
it =
v.iterator
(
);
double
sum =
0.0
;
while
(
it.hasNext
(
)){
sum +=
it.next
(
);
}
return
(
sum/
totalEff);
}
private
double
ecarttype
(
Vector<
Double>
eff, Vector<
Double>
mod){
double
variance =
this
.variance
(
eff, mod);
return
Math.sqrt
(
variance);
}
private
double
mode
(
Vector<
Double>
eff, Vector<
Double>
mod){
int
i =
0
;
double
tampon =
0.0
, effMax =
0.0
, mode =
0.0
;
Iterator<
Double>
itEff =
eff.iterator
(
);
effMax =
itEff.next
(
);
mode =
mod.get
(
i);
while
(
itEff.hasNext
(
)){
tampon =
itEff.next
(
);
if
(
effMax <=
tampon){
effMax =
tampon;
i++
;
mode =
mod.get
(
i);
}
}
return
mode;
}
}
V. Tests▲
Il a été montré dans l'article précédent comment embarquer dans Eclipse, sous forme de plugins, le projet Xtext de notre DSL. Une fois les plugins du projet intégrés dans Eclipse-Xtext, redémarrons l'IDE. Pour afficher la vue MadslView dans la perspective Java, allez dans Window --> Show view --> Other --> Other --> MadslView.
Pour créer un projet Madsl, créons un general project dans lequel nous insérons un fichier test.madsl. Saisissons ensuite du code Madsl dans ce fichier.
Si nous sélectionnons le fichier test.madsl, puis cliquons sur le bouton "Display The Selected Madsl Program" de la vue MadslView, alors on voit afficher dans la vue, le code du fichier sélectionné :
Si nous appuyons sur le bouton "Execute The Selected Madsl Program" de la vue MadslView, alors on voit afficher dans cette vue, la moyenne de la série statistique exposée par le code Madsl du fichier test.madsl :
Modifions un peu le code Madsl du fichier test.madsl pour calculer la variance de cette série statistique. Nous obtenons le résultat suivant :
VI. Conclusion et perspectives▲
Au terme de cet enseignement, nous avons montré par un exemple, une procédure à suivre pour rendre un langage que nous avons développé, exploitable sur un IDE existant et en l'occurrence eclipse-Xtext. Nous n'avons fait que développer des besoins très basiques dans l'optique de montrer cette possibilité. Les développeurs ayant des besoins plus complexes peuvent suivre cette piste pour réaliser leur projet.
Comme perspectives à ce travail, il est aussi possible d'ajouter à eclipse-Xtext, des composants tels que des menus et des toolbars, dédiés à la manipulation du langage (nous l'avons réalisé et l'on peut remarquer l'onglet "Madsl" sur les captures d'écran précédentes). Puis, d'attacher à ces composants, des Commandes et des Handlers leur permettant de réagir aux actions qu'ils proposent.
VII. Remerciements▲
Je tiens à remercier keulkeul pour sa relecture technique, ainsi qu'à ClaudeLELOUP pour sa relecture orthographique.