ch-outils.tex 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438
  1. % vim:spell spelllang=fr
  2. \chapter{Outils pour exprimer une transformation de modèles en Tom}
  3. \label{ch:outils}
  4. %15p
  5. Dans ce chapitre, nous traitons de notre contribution au langage {\tom} et de
  6. la manière dont notre approche de transformation de modèles par réécriture est
  7. implémentée. Dans un premier temps, nous donnons le mode opératoire concret
  8. pour utiliser nos outils en nous appuyant sur l'exemple de transformation vu
  9. précédemment. Nous présentons ensuite l'extension du langage {\tom} dédiée aux
  10. transformations de modèles, puis nous expliquons son implémentation technique
  11. au sein du compilateur, ainsi que l'implémentation du générateur d'ancrages
  12. formels.
  13. %%Réorganisation du chapitre :
  14. % 1. Exemple pratique super concret (ex 3)
  15. % 2. Extension du langage mais en présentant resolve+tracelink ensemble (ex1)
  16. % 3. Implémentation (ex2)
  17. % 4. Synthèse
  18. \section{Exemple d'utilisation des outils}
  19. %\todo{ici : j'écris une version pour l'exemple en couleurs ? Je me suis appuyé
  20. %dessus avant, cette section a-t-elle du sens ? ou alors c'est avant que je
  21. %n'aurais pas dû parler des constructions ?\\
  22. %Non, en fait ici on parle d'utilisation concrète, le déroulé d'une
  23. %implémentation vient dans le chapitre suivant sur le cas d'étude SimplePDL, etc.}
  24. Cette section présente l'utilisation de nos outils d'un point de vue concret.
  25. Nous expliquons le processus d'écriture d'une transformation de modèles avec
  26. eux. Pour cela, nous proposons de nous appuyer sur la transformation de texte
  27. en formes géométriques colorées présentée dans un chapitre précédent et que
  28. nous rappelons dans la section~\ref{ch:outils:subsec:ex} ci-après. L'objectif
  29. de cette transformation est purement pédagogique et sert uniquement à illustrer
  30. l'utilisation de nos outils pour ensuite introduire notre extension du langage.
  31. Nous ne nous intéressons donc pas à sa pertinence ni à son utilité dans le
  32. cadre d'un développement en contexte industriel.
  33. \subsection{Exemple support}
  34. \label{ch:outils:subsec:ex}
  35. Le principe général de cette transformation de modèle est de transformer un
  36. modèle sous forme de texte en une représentation graphique, comme l'illustre la
  37. figure~\ref{fig:rappelSimpleTransfo}.
  38. \begin{figure}[h]
  39. \begin{center}
  40. \input{figures/simpleApproachExample}
  41. \caption{Exemple de transformation de texte en formes géométriques colorées.}
  42. \label{fig:rappelSimpleTransfo}
  43. \end{center}
  44. \end{figure}
  45. Les figures~\ref{fig:textmmodel} et~\ref{fig:picturemmodel} sont deux
  46. métamodèles que nous proposons et auxquels les modèles source et cible de la
  47. figure~\ref{fig:rappelSimpleTransfo} se conforment respectivement.
  48. \begin{figure}[h]
  49. \begin{center}
  50. \input{figures/textmmodel}
  51. \caption{Un métamodèle pouvant décrire le formalisme textuel (source)
  52. utilisé dans l'exemple support.}
  53. \label{fig:textmmodel}
  54. \end{center}
  55. \end{figure}
  56. Un texte (\emph{Text}) est composé de lettres (\emph{Letter}) et de symboles
  57. (\emph{Symbol}). Dans notre exemple, les lettres peuvent être soit des A
  58. (\emph{AText}), soit des B (\emph{BText}) ; tandis que les symboles sont des
  59. points-virgules (\emph{SemiColon}).
  60. \begin{figure}[h]
  61. \begin{center}
  62. \input{figures/picturemmodel}
  63. \caption{Un métamodèle pouvant décrire le formalisme graphique (cible)
  64. utilisé dans l'exemple support.}
  65. \label{fig:picturemmodel}
  66. \end{center}
  67. \end{figure}
  68. Une image \emph{GeoPicture} est composée de formes (\emph{Shape}) caractérisées
  69. par une couleur (\emph{Color}, pouvant prendre les valeurs \emph{red},
  70. \emph{green} et \emph{blue}). \emph{Shape} est abstraite, et plusieurs formes
  71. concrètes en héritent (\emph{Triangle}, \emph{Pentagon}, \emph{Hexagon},
  72. \emph{Square}, \emph{Circle}). Les formes géométriques sont reliées entre elles
  73. par des segments (\emph{Segmen}).
  74. \FloatBarrier
  75. \subsection{Mode opératoire}
  76. Concrètement, un utilisateur souhaitant implémenter une transformation de
  77. modèle devra opérer par étapes, obtenues en fonction de l'outil principal à
  78. utiliser :
  79. \begin{enumerate}
  80. \item {\eclipse} : modélisation et génération des structures de données
  81. {\java-\emf} ;
  82. \item {\tomemf} : génération des ancrages formels pour représenter les
  83. modèles comme des termes (passerelle opérant le changement d'espace
  84. technologique) ;
  85. \item {\tomjava} : écriture effective de la transformation.
  86. \end{enumerate}
  87. \paragraph{Étape 1 :} La première étape consiste à modéliser le problème,
  88. c'est-à-dire à définir les métamodèles source et cible, en utilisant {\eclipse}
  89. ou tout autre outil capable de générer un métamodèle au format \texttt{.ecore}.
  90. Supposons que ces métamodèles source et cible s'appellent respectivement
  91. \texttt{text.ecore} et \texttt{picture.ecore}.
  92. Depuis ces métamodèles, le générateur de code de {\emf} (\emph{GenModel})
  93. permet de générer les structures de données {\java} correspondantes qui
  94. permettent d'instancier et de manipuler les modèles. L'utilisateur souhaitant
  95. implémenter la transformation n'a pas forcément besoin de se plonger dans ce
  96. code, étant donné que par la suite il ne manipulera pas directement les
  97. modèles en {\java+\emf}, mais plutôt des termes algébriques. Une fois le
  98. code des métamodèles source et cible généré, il suffit de l'exporter sous la
  99. forme d'archives \texttt{.jar} (par exemple \texttt{text.jar} et
  100. \texttt{picture.jar} dans notre cas). Une fois cette opération accomplie,
  101. {\eclipse} n'est plus nécessaire.
  102. \paragraph{Étape 2 :} La seconde étape de la mise en œuvre d'une transformation
  103. consiste à générer les ancrages algébriques à partir de la représentation
  104. {\emf} des métamodèles. Cette étape est réalisée en utilisant un outil nommé
  105. {\tomemf}. L'utilisateur applique {\tomemf} sur l'archive (ou les archives) en
  106. spécifiant le nom complet de l'\emph{EPackage} (ou des \emph{EPackages})
  107. concerné(s).
  108. Concrètement, la commande suivante permet d'effectuer l'opération (nous
  109. supposons que les archives \texttt{.jar} sont dans le répertoire courant noté
  110. \texttt{.} et nous ne les nommons donc pas explicitement :
  111. \begin{verbatim}
  112. $> emf-generate-mappings -cp . text.TextEPackage picture.PictureEPackage
  113. \end{verbatim}
  114. Un mécanisme de préfixe a aussi été prévu pour résoudre les conflits de noms.
  115. Nous supposons dans notre exemple qu'il n'y en a pas et que l'utilisateur n'a
  116. pas à spécifier des préfixes.
  117. %
  118. %Pour éviter les conflits de noms, l'utilisateur peut définir un préfixe à
  119. %utiliser lors d'une application de {\tomemf}. Concrètement, avec les noms de
  120. %fichiers de notre exemple, les commandes suivantes conviendraient :
  121. %
  122. %\begin{verbatim}
  123. %$> emf-generate-mappings -cp ./text.jar -prefix Text_ text.TextPackage
  124. %
  125. %$> emf-generate-mappings -cp ./picture.jar -prefix Pic_ picture.PicturePackage
  126. %\end{verbatim}
  127. %
  128. %Dans les deux cas, les commandes précédentes entraînent la génération de deux
  129. La commande précédente entraîne la génération de deux fichiers d'ancrages
  130. ---~un par \emph{EPackage} spécifié~--- nommés respectivement
  131. \texttt{text.TextEPackage.tom} et \texttt{picture.PictureEPackage.tom}. %Dans le
  132. %premier cas, les types et opérateurs ne sont pas préfixés, dans le second,
  133. %chaque \emph{mapping} a un préfixe (les types primitifs et {\ecore} sont
  134. %exclus).
  135. Dans notre exemple, les types et opérateurs ne sont pas préfixés. Si
  136. l'utilisateur avait choisi de spécifier un préfixe, chaque \emph{mapping}
  137. aurait eu un préfixe (les types primitifs et {\ecore} sont exclus).
  138. %Il est aussi possible d'intégrer le sous-typage au moment de la génération des
  139. %ancrages algébriques
  140. La passerelle permettant d'opérer le changement d'espace technologique étant
  141. générée, l'outil {\tomemf} n'est plus utile pour le reste du développement.
  142. \paragraph{Étape 3 :} Il s'agit de l'écriture en {\tomjava} de la
  143. transformation à proprement parler. Cette étape consiste en un développement
  144. {\java} classique intégrant des constructions {\tom} en son sein, notamment
  145. \lex{\%transformation} pour spécifier la transformation. Pour pouvoir manipuler
  146. les modèles comme des termes algébriques, il est nécessaire d'inclure les
  147. fichiers d'ancrages que nous venons de générer avec {\tomemf}. Dans notre
  148. exemple, les inclusions (îlot formel \texttt{\%include}) et la transformation
  149. (îlot formel \texttt{\%transformation}) apparaissent comme illustré dans le
  150. listing~\ref{code:exInclude}.
  151. \begin{figure}[H]
  152. \centering
  153. \input{code/exInclude}
  154. % \caption{<+caption text+>}
  155. % \label{fig:<+label+>}
  156. \end{figure}
  157. Dans ce programme, un modèle peut être soit chargé en utilisant les services
  158. {\emf} (chargement d'un modèle sérialisé dans un fichier \texttt{.xmi}), soit
  159. créé avec la construction \emph{backquote} de {\tom} (\lex{`}), comme tout
  160. autre terme. Quelle que soit la méthode choisie, le modèle peut ensuite être
  161. manipulé en tant que terme. À ce titre, il est possible de filtrer des motifs
  162. et d'appliquer des stratégies de réécriture (donc des transformations {\tom}).
  163. Une fois le développement terminé, le programme doit être compilé en deux
  164. temps. Il faut procéder à une compilation {\tom} pour \emph{dissoudre} les
  165. îlots formels {\tom} dans le langage hôte, puis compiler normalement le code
  166. {\java} généré en intégrant les bibliothèques générées par {\emf}. L'exécution
  167. du programme est identique à toute exécution de programme {\java}.
  168. \begin{verbatim}
  169. $> tom TestText2Picture.t
  170. $> javac -cp ./text.jar:./picture.jar:${CLASSPATH} TestText2Picture.java
  171. $> java -cp ./text.jar:./picture.jar:${CLASSPATH} TestText2Picture
  172. \end{verbatim}
  173. %%%%%%%
  174. \section{Extension du langage}
  175. Nous avons vu le mode opératoire pour écrire une transformation de modèles avec
  176. nos outils dans la section précédente, sans détailler le langage lui-même. Nous
  177. décrivons nos constructions dans cette section. Nous avons vu dans le
  178. chapitre~\ref{ch:approach} que nous décomposons les transformations de modèles
  179. en transformations élémentaires (\emph{Letter2Shape} par exemple), encodées par
  180. des stratégies de réécriture. Nous formons ensuite une stratégie en les
  181. composant avec d'autres combinateurs élémentaires tels que \texttt{Sequence} ou
  182. \texttt{TopDown}. Nous avons aussi vu que cela constitue la première phase
  183. d'une transformation suivant notre approche et qu'il faut procéder à une
  184. seconde phase ---~\emph{résolution}~---, elle aussi encodée par une stratégie
  185. de réécriture.
  186. Pour mettre en œuvre la méthode générale de transformation que nous
  187. proposons~\cite{Bach2012}, nous avons ajouté trois constructions principales au
  188. langage {\tom} :
  189. %\begin{itemize}
  190. % \item exprimer une transformation ;
  191. % \item intégrer et créer les éléments \emph{resolve} ;
  192. % \item assurer la traçabilité de la transformation.
  193. %\end{itemize}
  194. %
  195. \begin{itemize}
  196. \item \lex{\%transformation} pour exprimer une transformation
  197. (listing~\ref{transformationConstructSyntax}) ;
  198. \item \lex{\%resolve} pour intégrer et créer les éléments \emph{resolve}
  199. (listing~\ref{resolveConstructSyntax}) ;
  200. \item \lex{\%tracelink} pour assurer la résolution des liens ainsi que la
  201. traçabilité de la transformation (listing~\ref{tracelinkConstructSyntax}).
  202. \end{itemize}
  203. \begin{figure}[H]
  204. \centering
  205. \input{code/transformationSyntax}
  206. % \caption{Syntaxe concrète de la construction \%transformation}
  207. % \label{transformationConstructSyntax}
  208. \end{figure}
  209. \begin{figure}[H]
  210. \begin{center}
  211. \input{code/resolveSyntax}
  212. \end{center}
  213. %\caption{Syntaxe concrète de la construction \%resolve}
  214. %\label{resolveConstructSyntax}
  215. \end{figure}
  216. \begin{figure}[H]
  217. \begin{center}
  218. \input{code/tracelinkSyntax}
  219. \end{center}
  220. %\caption{Syntaxe concrète de la construction \%tracelink}
  221. %\label{tracelinkConstructSyntax}
  222. \end{figure}
  223. Ces constructions nous permettent d'implémenter des transformations avec les
  224. caractéristiques suivantes, selon des critères proposés par
  225. Czarnecki~\cite{Czarnecki2003,ibm06} :
  226. %portée de la transformation
  227. %\ttodo{reprendre les critères de Czarnecki~\cite{Czarnecki2003,ibm06} et les
  228. %mettre en relation avec ce que je fais ? :
  229. \begin{itemize}
  230. \item \textbf{règles de transformation :} une règle contient des
  231. \emph{patterns} et des variables, et bénéficie de typage. L'application
  232. des règles peut être contrôlée par le paramétrage des transformations
  233. élémentaires que l'utilisateur averti peut faire varier ;
  234. \item \textbf{ordonnancement des règles :} nos règles ne sont pas ordonnées
  235. ni interactives. Par défaut, et si le flot d'exécution n'est pas interrompu
  236. (par des instructions du type \texttt{break} ou \texttt{return}), les règles
  237. sont appliquées sur tous les motifs filtrés du modèle source. Ce
  238. comportement peut toutefois être modifié par le paramétrage de la
  239. \emph{définition} en cours {\via} une stratégie {\adhoc}. L'ordre
  240. d'écriture des \emph{définitions} et des règles n'a pas d'impact sur le
  241. résultat final ;
  242. \item \textbf{découpage en phases :} nos transformations sont constituées de
  243. deux phases, l'une pour transformer, l'autre pour \emph{résoudre} les
  244. liens ;
  245. \item \textbf{sens des règles et des transformations :} nos règles sont
  246. unidirectionnelles, nos transformations ne sont pas naturellement
  247. bidirectionnelles ;
  248. \item \textbf{modularité et mécanismes de réutilisation :} nos
  249. transformations reposent sur le langage de stratégies de réécriture de
  250. {\tom} dont l'une des caractéristiques est la modularité. Si une règle ne
  251. peut être directement réutilisée ailleurs, une \emph{définition} (un
  252. ensemble de règles) peut en revanche l'être ;
  253. \item \textbf{relation entre l'entrée et la sortie :} le modèle cible est
  254. différent du modèle source, même dans le cas d'une transformation endogène
  255. (transformation \emph{out-place}) ;
  256. \item \textbf{portée de la transformation :} tout ou partie du modèle peut
  257. être transformé, en fonction des \emph{patterns} dans les règles définies
  258. par l'utilisateur ;
  259. \item \textbf{traçabilité :} durant une transformation, nous maintenons des
  260. liens entre les éléments sources et cibles.
  261. \end{itemize}%}
  262. La syntaxe des nouvelles constructions du langage ainsi que les
  263. caractéristiques des transformations de notre approche étant établies,
  264. détaillons précisément ces constructions. Pour illustrer notre propos, nous
  265. nous appuierons sur la transformation proposée en exemple précédemment. Cette
  266. transformation consiste à transformer le modèle texte \texttt{A;B} en une
  267. figure constituée de formes géométriques
  268. (figure~\ref{fig:rappelSimpleTransfo}).
  269. Afin d'illustrer concrètement l'extension du langage, nous nous appuierons sur
  270. l'extrait de code donné par le listing~\ref{code:transformationText2Picture}.
  271. Les points de suspension dénotent le fait qu'il est parcellaire dans le but de
  272. mettre en avant les nouvelles constructions du langage et de rendre plus
  273. lisible l'extrait de code ainsi que son explication. Nous adoptons en outre le
  274. code visuel suivant : les nouvelles constructions du langage apparaissent en
  275. \colcode{blue}{bleu } tandis que le texte souligné et coloré marque les
  276. correspondances dans la transformation entre les éléments des constructions. Ce
  277. code visuel permet de comprendre clairement les relations entre les termes
  278. créés par les nouvelles constructions du langage.
  279. %et \myul{magenta}{pour} \myul{black}{les} nouvelles constructions du langage.
  280. %Nous adoptons aussi le code visuel bleu pour les nouvelles constructions du langage.
  281. \begin{figure}[h]
  282. \begin{center}
  283. \input{code/transformationText2Picture}
  284. \end{center}
  285. % \caption{Extrait de code de la transformation \emph{Text2Picture} illustrant les nouvelles constructions {\tom} dédiées aux transformations de modèles}
  286. % \label{code:transformationText2Picture}
  287. \end{figure}
  288. \FloatBarrier
  289. \subsection{Expression d'une transformation}
  290. Une transformation prend un modèle source en paramètre et renvoie un modèle
  291. cible. L'encodant sous la forme d'une stratégie de réécriture composée, nous
  292. proposons une construction haut niveau gérant automatiquement sa combinaison.
  293. Elle est composée de transformations élémentaires ---~\emph{définitions}~---,
  294. représentées par des blocs \texttt{definition}. Une \emph{définition} opère une
  295. transformation sur des éléments d'un type unique : deux
  296. éléments ayant des types différents (et sans surtype commun) ne peuvent être
  297. transformés dans une même \emph{définition}. Une transformation comporte donc
  298. au moins autant de \emph{définitions} qu'il y a de types d'éléments que
  299. l'utilisateur souhaite transformer. Chaque \emph{définition} est constituée
  300. d'un ensemble de règles de réécriture composées d'un \emph{pattern} (membre
  301. gauche) ainsi que d'une action (membre droit). Une action est un bloc pouvant
  302. contenir du code hôte et du code {\tom}. De plus, chaque \emph{définition}
  303. ---~encodée par une stratégie~--- est nommée et paramétrée par une stratégie de
  304. parcours que l'utilisateur averti peut faire varier.
  305. Chacune de ces \emph{définitions} est écrite sans notion d'ordre par rapport
  306. aux autres \emph{définitions} et elles n'entretiennent aucune dépendance dans
  307. le sens où l'entrée de l'une n'est pas la sortie d'une autre. La transformation
  308. est de type \emph{out-place} (la source n'est jamais modifiée) et la source de
  309. chaque \emph{définition} est le modèle source. Le résultat de la
  310. transformation ne dépend donc pas de l'ordre d'écriture des \emph{définitions}
  311. adopté par l'utilisateur. La transformation finale est encodée par une
  312. stratégie qui est une séquence de ces \emph{définitions}.
  313. %Le
  314. %listing~\ref{code:formeSyntaxeTransfo} illustre la forme générale d'une
  315. %transformation de modèle écrite selon notre approche.
  316. %
  317. %\begin{figure}[H]
  318. % \begin{center}
  319. % \input{code/formeSyntaxeTransfo}
  320. % \end{center}
  321. % %\caption{Schéma global d'une transformation de modèle avec {\tom}}
  322. % %\label{code:formeSyntaxeTransfo}
  323. %\end{figure}
  324. %
  325. %Cette transformation \texttt{MyTransfo} donnera lieu à une stratégie $MyTransfo
  326. %= Sequence(TopDown(Nom1),TopDown(Nom2))$.
  327. Dans l'exemple, la transformation nommée \texttt{Text2Picture} est introduite
  328. par le lexème \lex{\%transformation} (ligne 1). Elle sert à transformer un
  329. modèle conforme au métamodèle \texttt{text.ecore} en un modèle conforme au
  330. métamodèle \texttt{picture.ecore}, ce qui est symbolisé par les noms de
  331. fichiers des deux métamodèles de part et d'autre du lexème \lex{\texttt{->}}
  332. (ligne 2). %On peut donner des chemins absolus ou relatifs,
  333. %mais en l'absence de tout élément de chemin, seul le répertoire courant est
  334. %considéré.
  335. Cette transformation prend deux arguments : \texttt{link} qui est le
  336. modèle de lien qui sera peuplé durant la transformation, et \texttt{gp} qui est
  337. le modèle cible qui sera construit au fur et à mesure de l'avancée des pas
  338. d'exécution.
  339. Cette transformation est constituée d'au moins deux \emph{définitions} nommées
  340. \texttt{Letter2Shape} (ligne 4) et \texttt{Symbol2Shape} (ligne 20). Elles sont
  341. toutes deux paramétrées par une stratégie introduite par le mot-clef
  342. \texttt{traversal} pouvant être différente pour chaque définition (bien que
  343. cela n'ait pas d'impact dans cet exemple, nous avons utilisé deux stratégies
  344. différentes ---~\texttt{TopDown} et \texttt{BottomUp}~--- pour illustrer cette
  345. possibilité). C'est cette stratégie qui est utilisée pour appliquer les
  346. transformations élémentaires. Il est à noter que les paramètres de la
  347. transformation sont aussi les paramètres de ces stratégies. Les
  348. \emph{définitions} sont constituées de règles de réécriture à l'image des
  349. stratégies {\tom}. Le fait que la \emph{définition} qui traduit les lettres en
  350. formes géométriques soit écrite avant ou après celle qui transforme les
  351. symboles n'a aucune importance. La \emph{définition} \texttt{Letter2Shape}
  352. comprend deux règles : l'une pour transformer les éléments de type \emph{BText}
  353. (lignes 5 à 10) et l'autre pour transformer les éléments de type \emph{AText}
  354. (lignes 11 à 16). La \emph{définition} \texttt{Symbol2Shape} est quant à elle
  355. constituée d'une seule règle qui transforme les éléments de type
  356. \emph{SemiColon} (lignes 21 à 28). Une fois définie, une transformation peut
  357. être utilisée (appelée) comme toute autre stratégie {\tom} {\via} la fonction
  358. \texttt{visit()}.
  359. Seule, la construction \lex{\%transformation} permet d'exprimer la première
  360. phase de la transformation en générant une stratégie composée.
  361. \subsection{Résolution}
  362. La seconde phase de la transformation (résolution) est exprimée grâce à deux
  363. autres constructions.
  364. Pour intégrer et créer des éléments intermédiaires \emph{resolve}, nous avons
  365. introduit une nouvelle construction : \lex{\%resolve} (syntaxe donnée dans le
  366. listing~\ref{resolveConstructSyntax}). Elle permet de créer les termes
  367. intermédiaires pour représenter les éléments censés être créés dans une autre
  368. \emph{définition}. Cette construction correspond à une spécialisation de la
  369. construction \emph{backquote} (\lex{`}), en ce sens qu'elle crée un terme tout
  370. en déclenchant un autre traitement, à savoir la génération d'un \emph{mapping}
  371. dédié.
  372. %\begin{figure}[h]
  373. % \begin{center}
  374. % \input{code/resolveSyntax}
  375. % \end{center}
  376. % %\caption{Syntaxe de la construction \%resolve}
  377. % %\label{resolveConstructSyntax}
  378. %\end{figure}
  379. La construction \lex{\%resolve} prend deux paramètres : l'élément source en
  380. cours de transformation et le nom de l'élément de l'image d'un élément
  381. transformé dans une autre définition que ce terme est censé représenter.
  382. %\ttodo{$\leftarrow$ incompréhensible en français, faire un schéma / dessin pour
  383. %expliquer qqch du genre : $r_1 = Img(Source_1).x$ insert schéma.} C'est ce
  384. %mécanisme qu'illustre la figure\needcite.
  385. Cet élément transformé dans une autre \emph{définition} est quant à lui marqué
  386. comme pouvant être résolu {\via} la construction \lex{\%tracelink} (syntaxe
  387. donnée dans le listing~\ref{tracelinkConstructSyntax}). Elle est le pendant de
  388. \lex{\%resolve} et apparaît obligatoirement dans le code si l'utilisation
  389. d'éléments intermédiaires est nécessaire. Elle correspond elle aussi à une
  390. spécialisation de la construction \emph{backquote} : elle permet de créer un
  391. terme tout en mettant à jour la structure de données qui maintient les liens de
  392. traçabilité \emph{interne} (pour la résolution).
  393. %elle permet de créer un terme tout en mettant à jour une structure qui rend la
  394. %résolution possible.
  395. La construction \lex{\%tracelink} prend deux paramètres : le nom du terme
  396. marqué (accompagné de son type) ainsi que le terme lui-même (\emph{terme
  397. backquote}).
  398. %Si l'on considère deux \emph{définitions} $d_1$ et $d_2$, et deux sources
  399. %$s_{i_1}$ et $s_{i_2}$
  400. %
  401. %Soient $s_i$ les $i$ éléments du modèle source à transformer. Soit $t_i =
  402. %Img(s_i)$ l'image de $s_i$ par la transformation. $t_i$ est un ensemble de $j$
  403. %éléments cibles : $t_i = Img(s_i) = \{ t_{i,j} \}$. Si une règle de cette
  404. %\emph{définition} nécessite un élément temporaire, un élément \emph{resolve}
  405. %$r_{i,j}$ doit être créé. Il représente un élément $t_{i',j'}$ obtenu lors de
  406. %la transformation d'un autre élément source $s_{i'}$. L'image d'une source
  407. %$s_i$ est donc un ensemble d'éléments cibles $t_{i,j}$ dont certains sont des
  408. %éléments intermédiaires $r_{i,j}$ jouant le rôle d'éléments $t_{i',j'} \in
  409. %Img(s_{i'})$.
  410. Dans notre exemple support, la transformation d'un élément \textsf{B} en la
  411. forme constituée d'un pentagone bleu et d'un connecteur nécessite
  412. l'introduction d'un élément \emph{resolve}. En effet, le connecteur carré est
  413. créé dans une autre \emph{définition} ---~\texttt{Symbol2Shape}~--- et nous
  414. devons utiliser le mécanisme de création d'éléments intermédiaires
  415. \emph{resolve}. À la ligne 6, nous instancions donc un terme \emph{resolve} qui
  416. remplacera temporairement l'élément \texttt{target\_right} de l'image de la
  417. transformation du symbole \emph{SemiColon} (\texttt{;}). Outre le fait de jouer
  418. le rôle de \emph{placeholder} et de pouvoir être manipulé comme s'il s'agissait
  419. d'un élément classique du modèle cible, l'élément \emph{resolve} maintient aussi
  420. un lien entre l'élément source (\texttt{b}, de type \texttt{BText}) qui a
  421. provoqué sa création et la cible représentée.
  422. Dans notre exemple, ce mécanisme est réitéré dans la \emph{définition}
  423. suivante (ligne 25) et peut être utilisé autant de fois que nécessaire dans la
  424. transformation.
  425. %%\ttodo{+ bloc de code pour expliquer ?, reprendre l'exemple graphique, par
  426. %%exemple resolveB2Forme -> nope, on réutilise le bloc de code d'avant où on met
  427. %%tout, sinon c'est incompréhensible}
  428. %%\input{code/resolveB2Forme}
  429. %\ttodo{déplacer DISCUSSION / Nous remarquons que la phase de résolution n'apparaît pas dans l'extrait de
  430. %code présenté, ce qui est tout à fait normal. En effet, elle est entièrement
  431. %générée, en fonction de l'utilisation des constructions \lex{\%resolve} au sein
  432. %de la transformation. Ainsi, une transformation ne nécessitant pas d'éléments
  433. %\emph{resolve} (donc sans utilisation du lexème \lex{\%resolve}) n'a pas de
  434. %phase de résolution.}
  435. %
  436. %\ttodo{ déplacer UTILISATION / À l'inverse, l'utilisation de la construction provoque la
  437. %génération du bloc de résolution dédié au type traité. Dans la version
  438. %actuellement publiée de l'outil ({\tom-2.10}), cette phase est encodée par une
  439. %unique stratégie que l'utilisateur n'écrit qu'indirectement par l'usage
  440. %judicieux des constructions de résolution. L'application de la stratégie de
  441. %résolution est néanmoins à la charge de l'utilisateur au sein de son programme.
  442. %Il doit appeler la stratégie en l'appliquant sur le modèle intermédiaire créé
  443. %lors de la première phase.}
  444. %
  445. %\ttodo{déplacer EXPÉRIMENTATION / Nous avons aussi expérimenté une version modulaire de la phase de résolution.
  446. %Plutôt que de générer une stratégie monolithique effectuant toute la
  447. %résolution, nous avons écrit une solution alternative générant plusieurs
  448. %stratégies de résolution partielle, chacune de ces stratégies n'effectuant la
  449. %réconciliation que sur un type de termes donné. Dans notre exemple, cette
  450. %alternative générerait deux stratégies distinctes, ainsi qu'une stratégie
  451. %combinant les deux. L'inconvénient de cette solution est qu'elle est plus
  452. %complexe à prendre en main pour l'utilisateur. Cependant, elle a l'avantage
  453. %d'offrir un plus grande modularité en décomposant la seconde phase. Ainsi, le
  454. %code généré pour une \emph{définition} peut être réutilisé dans une autre
  455. %transformation, et l'utilisateur averti prendra soin d'accompagner la
  456. %définition de la (ou des) stratégie(s) de résolution correspondante(s).
  457. %Pour des raisons d'utilisabilité de nos outils , nous avons fait le choix de
  458. %diffuser la version du générateur de phase de résolution monolithique dans la
  459. %version stable de {\tom}.}
  460. \subsection{Traçabilité}
  461. \label{ch:outils:trace}
  462. %\ttodo{traçabilité on demand}
  463. Nous avons également étendu le langage afin d'ajouter la traçabilité aux
  464. transformations. Une possibilité eût été de tracer systématiquement les termes
  465. créés, puis de mettre en œuvre un mécanisme de requête pour retrouver les
  466. informations intéressantes. Cependant, cette approche aurait donnée des traces
  467. extrêmement verbeuses et donc peu exploitables. Pour éviter cet écueil, nous
  468. avons fait le choix d'une \emph{traçabilité à la demande}, implémentée par la
  469. construction \lex{\%tracelink} dont la syntaxe a été donnée en début de section
  470. dans le listing~\ref{tracelinkConstructSyntax}.
  471. %\begin{figure}[h]
  472. % \begin{center}
  473. % \input{code/tracelinkSyntax}
  474. % \end{center}
  475. % %\caption{Syntaxe concrète de la construction \%tracelink}
  476. % %\label{tracelinkConstructSyntax}
  477. %\end{figure}
  478. Bien que techniquement implémentée par un unique lexème, la notion de
  479. traçabilité est double. Ce lexème a donc actuellement deux usages ---~pour deux
  480. types de traçabilité~--- à savoir :
  481. \begin{itemize}
  482. \item assurer la traçabilité \emph{interne} (ou \emph{technique}) : pour
  483. spécifier les éléments correspondant aux éléments \emph{resolve} créés lors
  484. de la transformation, afin que la phase de résolution puisse effectuer le
  485. traitement (nous pouvons parler de \emph{resolveLink}) ;
  486. \item assurer la traçabilité au sens de la qualification logicielle :
  487. construire d'une part le métamodèle de lien à la compilation de la
  488. transformation, et d'autre part peupler la trace à l'exécution (nous
  489. parlons dans ce cas de \emph{trace}).
  490. \end{itemize}
  491. Quelle que soit la traçabilité voulue, nous souhaitons spécifier à la demande
  492. quels sont les éléments que nous créons que nous souhaitons tracer.
  493. L'utilisateur doit donc explicitement désigner les termes {\tom} à tracer.
  494. Chaque terme traçable appartenant à une \emph{définition} de la transformation,
  495. l'élément du modèle source dont il est issu est implicite. Du point de vue de
  496. l'utilisateur, tracer un terme revient simplement à utiliser la construction
  497. dédiée en spécifiant son nom, son type et en écrivant le terme {\via} la
  498. construction \emph{backquote}.
  499. Dans le cadre d'une traçabilité \emph{interne}, la construction correspond au
  500. pendant des éléments \emph{resolve} (\emph{resolveLink}). La création
  501. d'éléments \emph{resolve} dans la transformation implique alors l'utilisation
  502. d'au moins un marquage de ce type. Cette utilisation est celle présentée dans
  503. la section précédente.
  504. Dans le cadre d'une traçabilité de transformation au sens de la qualification
  505. logicielle, la construction de trace peut être utilisée de manière indépendante
  506. de la construction pour la résolution. Une transformation peut donc comporter
  507. des constructions de trace sans qu'aucune construction de résolution ne soit
  508. utilisée. Dans notre approche, l'utilisateur ne fournit pas de métamodèle de
  509. lien \emph{a priori}. La construction de trace permet de générer le métamodèle
  510. de lien de la transformation lors de la compilation, c'est-à-dire de générer
  511. les structures liant sources et cibles en fonction des termes tracés. À
  512. l'exécution, ces structures sont peuplées pour maintenir les relations entre
  513. les sources et les cibles de la transformation. La construction de trace lie un
  514. élément cible créé à la source en cours de transformation, ce qui permet
  515. d'établir un ensemble de relations \texttt{1..N} (une source associée à
  516. plusieurs cibles).
  517. Dans notre exemple support, l'utilisateur a décidé d'opérer une trace minimale,
  518. c'est-à-dire que les éléments tracés sont ceux qui doivent impérativement être
  519. tracés pour que la résolution s'opère correctement. C'est donc la traçabilité
  520. technique qui est essentiellement utilisée ici. Les traces sont activées par
  521. les lexèmes \lex{\%tracelink} (lignes 12 et 23). Celui de la ligne 23
  522. correspond à l'élément \emph{resolve} de la ligne 6 (souligné en magenta),
  523. tandis que celui de la ligne 12 à celui de la ligne 25 (souligné en noir).
  524. L'utilisateur aurait bien évidemment pu tracer les autres éléments créés (par
  525. exemple \texttt{bluePentagon} à ligne 7). Même si l'usage de \lex{\%tracelink}
  526. dans cet exemple fait transparaître la volonté de l'utilisateur d'avoir
  527. uniquement une traçabilité \emph{technique}, un modèle de lien minimal de la
  528. transformation est néanmoins créé. La transformation spécifie un modèle de lien
  529. (\texttt{link} dans notre cas) dans lequel nous stockons les associations
  530. établies entre les éléments sources et les éléments cibles tracés tout au long
  531. de la transformation. En fin de transformation, cette trace peut être
  532. sérialisée pour un usage ultérieur.
  533. En expérimentant nos outils, nous nous sommes aperçus que l'utilisation d'une
  534. construction unique pour deux usages distincts pouvait perturber l'utilisateur.
  535. Nous projetons donc à terme de séparer cette construction en deux constructions
  536. distinctes, chacune adaptée à une des traçabilités.
  537. \section{Travaux d'implémentation}
  538. % rappel
  539. %\usepackage{float}
  540. %...
  541. %\begin{figure}[H]
  542. % ou
  543. %\begin{figure}[!htbp]
  544. % ou
  545. %\usepackage{placeins}
  546. %...
  547. %\FloatBarrier
  548. %\begin{figure}[H]
  549. %\todo{utile ? vient de la réorganisation du premier jet ; refaire, le projet a
  550. %un peu évolué\\}
  551. %D'un point de vue plus macroscopique, le projet {\tom} compte environ 60000
  552. %lignes de code, réparties dans les sous-projets suivants : le compilateur
  553. %{\tom} lui-même (\texttt{engine}), le générateur d'ancrages algébriques et de
  554. %structures de données {\java} à partir d'une signature (\texttt{gom}), les
  555. %bibliothèques (\texttt{library}), le générateur d'ancrages algébriques à partir
  556. %d'un métamodèle EMF Ecore (\texttt{emf}), ainsi que la plateforme
  557. %(\texttt{platform}) qui mutualise une partie du code de {\tom} et de {\gom}
  558. %(gestion des phases). La Table~\ref{table:stats} résume cela avec quelques
  559. %valeurs chiffrées \ttodo{Mettre à jour}.
  560. %
  561. %\begin{table}[H]
  562. % \begin{center}
  563. % \input{figures/tomstats}
  564. % \caption{Nombre de lignes de code dans le compilateur Tom}
  565. % \label{table:stats}
  566. % \end{center}
  567. %\end{table}
  568. Les travaux d'implémentation pour étendre le langage ont concerné deux parties
  569. du projet {\tom} : d'une part le compilateur {\tom}, d'autre part l'outil
  570. {\tomemf}.
  571. Avant de détailler la manière dont nous avons mis en œuvre notre extension du
  572. projet, nous décrivons l'architecture du projet {\tom} ainsi que le processus
  573. de compilation dans le contexte de {\java}.
  574. %le projet {\tom} d'un point de vue technique et nous
  575. %expliquons son architecture ainsi que le processus de compilation dans le
  576. %contexte de {\java}.
  577. Cela nous permettra ensuite d'expliquer comment nous nous
  578. sommes intégrés dans l'existant.
  579. \subsection{Architecture du projet Tom et chaîne de compilation}
  580. %\subsection{\todo{Architecture actuelle} vs \todo{Chaîne de compilation et architecture du compilateur Tom}}
  581. %\section{Langages supportés : \emph{backends}}
  582. Le projet {\tom} s'articule autour de trois outils distincts utilisables
  583. indépendamment : le compilateur lui-même, {\gom} et l'outil de génération
  584. d'ancrages formels {\tomemf}.
  585. %Le projet {\tom} s'articule autour de trois outils distincts : le compilateur
  586. %lui-même, {\gom} que nous ne détaillerons pas ici et l'outil de génération
  587. %d'ancrages formels {\tomemf}.
  588. Le projet {\tom} comprend aussi un ensemble de bibliothèques (notamment la
  589. bibliothèque de stratégies \texttt{sl}, des ancrages algébriques, un outil de
  590. conversion {DOM \xml} vers {\gom} et inverse, une bibliothèque de
  591. \emph{bytecode} {\java}, etc.) ainsi que de très nombreux exemples et tests
  592. unitaires. La gestion des phases de compilation est assurée par la plateforme
  593. sur laquelle s'appuient {\tom} et {\gom}.
  594. %D'un point de vue plus macroscopique, le projet {\tom} compte environ 60000
  595. %lignes de code, réparties dans les sous-projets suivants : le compilateur
  596. %{\tom} lui-même (\texttt{engine}), le générateur d'ancrages algébriques et de
  597. %structures de données {\java} à partir d'une signature (\texttt{gom}), les
  598. %bibliothèques (\texttt{library}), le générateur d'ancrages algébriques à partir
  599. %d'un métamodèle EMF Ecore (\texttt{emf}), ainsi que la plateforme
  600. %(\texttt{platform}) qui mutualise une partie du code de {\tom} et de {\gom}
  601. %(gestion des phases). La Table~\ref{table:stats} résume cela avec quelques
  602. %valeurs chiffrées \ttodo{Mettre à jour}.
  603. L'ensemble du projet compte environ \num{60000} lignes de code, réparties dans les
  604. sous-projets \texttt{engine} (compilateur {\tom} lui-même), \texttt{gom},
  605. \texttt{library}, \texttt{emf}, ainsi que \texttt{platform}. L'essentiel du
  606. code source est écrit en {\tom} (+{\java}) ainsi qu'en {\java} pur. La
  607. Table~\ref{table:stats} résume cette répartition par projet et par langage.
  608. \begin{table}[H]
  609. \begin{center}
  610. \input{figures/tomstats}
  611. \caption{Nombre de lignes de code dans le projet {\tom}, par sous-projet et par langage}
  612. \label{table:stats}
  613. \end{center}
  614. \end{table}
  615. %\subsection{Backends}
  616. Le langage {\tom} a été conçu pour étendre des langages hôtes. La chaîne de
  617. compilation (figure~\ref{fig:tomArchi}) a été pensée de manière à minimiser le
  618. code spécifique à chaque langage hôte. Le compilateur ne traitant que la partie
  619. {\tom} et n'analysant pas le code hôte, seules les constructions {\tom} sont
  620. \emph{parsées} puis traitées par chaque phase du compilateur, jusqu'à la
  621. compilation à proprement parler. Durant cette phase, plutôt que de compiler
  622. directement vers le langage cible, {\tom} compile vers un langage intermédiaire
  623. (IL) qui sert de langage pivot. Les constructions de ce langage sont ensuite
  624. traduites dans le langage cible lors de la dernière phase de compilation.
  625. Ainsi, l'extension à un nouveau langage passe par l'écriture d'un nouveau
  626. \emph{backend} sans forcément avoir à réécrire ou adapter la chaîne complète du
  627. compilateur.
  628. Nos exemples sont centrés sur {\java} étant donné que son \emph{backend} est
  629. le plus avancé. Cependant {\tom} supporte d'autres langages : {\ada}, {\C},
  630. {\caml}, {\csharp}, {\python}. Le tableau ~\ref{table:backends} donne
  631. l'implémentation des fonctionnalités en fonction des \emph{backends}.
  632. \begin{table}[H]
  633. \begin{center}
  634. \input{figures/tomFeatures}
  635. \end{center}
  636. \caption{Implémentation de fonctionnalités de {\tom} par langage cible.}
  637. \label{table:backends}
  638. \end{table}
  639. %\subsection{Vue d'ensemble du compilateur}
  640. Un programme est écrit en {\tom}+langage hôte, accompagné d'ancrages pour faire
  641. le lien avec les structures de données hôtes. Le compilateur analyse les
  642. constructions {\tom} et génère le code hôte correspondant qui, couplé aux
  643. structures de données hôtes, constitue un programme écrit dans le langage hôte
  644. que l'on compile avec le compilateur adéquat. La
  645. figure~\ref{fig:wholeTomProcess}
  646. %~\ref{fig:tomGomCompiler}
  647. explique ce fonctionnement global des outils du projet {\tom} dans
  648. l'environnement {\java}. La partie haute décrit le processus de compilation
  649. d'un programme {\tom} couplé à {\gom}, tandis que la partie basse se concentre
  650. sur le processus dans le cadre des transformations de modèles, c'est-à-dire en
  651. utilisant l'outil {\tomemf} pour générer les ancrages algébriques. Ces outils
  652. peuvent bien évidemment être utilisés indépendamment.
  653. %\todo{[ancienne version (manque EMF):]}
  654. %\input{figures/bckp.tomGomCompiler}
  655. %\input{figures/tomGomCompiler}
  656. %\todo{[version en cours de modification : ajout de EMF : wholeTomProcess]}
  657. %\todo{[test, première version]}
  658. \begin{figure}[H]
  659. \begin{center}
  660. \input{figures/wholeTomProcess}
  661. \end{center}
  662. \caption{Diagramme d'activité décrivant le processus de compilation d'un programme {\tom}.}
  663. \label{fig:wholeTomProcess}
  664. \end{figure}
  665. %\todo{[test, ou autre version~\ref{fig:wholeTomProcess2} :]}
  666. %\input{figures/wholeTomProcess2}
  667. %\todo{[TEST schéma, en faire un plus simple pour expliquer Tom-EMF ; et un plus
  668. %complexe pour expliquer toute l'archi du projet (à la place de la figure
  669. %au-dessus]}
  670. %\input{figures/tomEMFCompiler}
  671. %Figure~\ref{fig:tomEMFCompiler}
  672. %\subsection{Architecture du compilateur Tom}
  673. Le compilateur {\tom} se décompose en phases -- écrites en {\tomjava} -- qui
  674. sont chaînées les unes après les autres. Chacune procède à une transformation
  675. bien définie sur l'entrée, et fournit une sortie à la phase suivante. Nous
  676. décrivons brièvement chacune de ces phases ci-après, et nous représentons
  677. l'architecture du compilateur {\tom} avec la figure~\ref{fig:tomArchi}. Les
  678. blocs marqués en traits pointillés indiquent les phases où nos travaux
  679. d'implémentation se sont essentiellement concentrés tandis que la phase colorée
  680. était inexistante avant ce travail de thèse. C'est le cœur de
  681. l'implémentation permettant de traiter l'extension du langage dédiée aux
  682. transformations de modèles.
  683. \begin{figure}[h]
  684. \begin{center}
  685. \input{figures/tomArchi}
  686. \end{center}
  687. \caption{Phases du compilateur {\tom}.}
  688. \label{fig:tomArchi}
  689. \end{figure}
  690. \begin{description}
  691. \item[Parser :] Le \emph{parser} produit un arbre de syntaxe abstraite (AST,
  692. \emph{Abstract-Syntax Tree}) à partir du code d'entrée. Les constructions
  693. {\tom} sont représentées par des nœuds particuliers tandis que les blocs de
  694. code hôte sont stockés dans l'arbre comme des chaînes de caractères. Dans
  695. le cas d'une construction \lex{\%gom} (ou de l'utilisation d'un fichier
  696. \texttt{.gom}), l'outil {\gom} est appelé et son \emph{parser} prend le
  697. relais pour l'analyse du bloc.
  698. \item[Transformer :] Le \emph{transformer} est une phase qui a été ajoutée
  699. durant cette thèse afin de traiter les constructions du langage dédiées aux
  700. transformations de modèles. Il traite en particulier les constructions
  701. \lex{\%transformation}, \lex{\%resolve} et \lex{\%tracelink}, les AST issus
  702. de ces deux dernières étant des sous-arbres de l'AST issu de
  703. \lex{\%transformation}. La mise en œuvre de cette phase est détaillée dans
  704. la section~\ref{subsec:meoExt}.
  705. \item[Syntax checker :] Le \emph{syntax checker} effectue des vérifications
  706. syntaxiques sur l'{\AST}. Par exemple, il vérifie que chaque symbole de
  707. fonction a été déclaré et qu'il n'y a pas de dépendance circulaire entre
  708. les conditions de filtrage.
  709. \item[Desugarer :] Le \emph{desugarer} simplifie l'{\AST} en transformant les
  710. différents types de nœuds représentant des constructeurs de langage hôte en
  711. nœuds génériques. De plus, les variables anonymes y sont nommées avec des
  712. noms \emph{frais} (noms qui n'ont jamais été utilisés précédemment).
  713. \item[Typer :] Le \emph{typer} effectue l'inférence de type et propage les
  714. types inférés dans l'{\AST}.
  715. \item[Typer checker :] Le \emph{type checker} vérifie les types et les rangs
  716. des symboles. Il vérifie par exemple que les occurrences d'une même
  717. variable sont du même type.
  718. \item[Expander :] L'\emph{expander} transforme une dernière fois l'{\AST}
  719. avant la compilation : il traite les nœuds issus des constructions
  720. \lex{\%strategy} et génère les introspecteurs (structures pour parcourir un
  721. terme).
  722. \item[Compiler :] Le \emph{compiler} transforme les nœuds {\tom} en
  723. instructions du langage intermédiaire (IL, pour \emph{Intermediate
  724. Language}) qui sert de langage pivot.
  725. \item[Optimizer :] L'\emph{optimizer} est responsable de l'optimisation du
  726. code écrit dans le langage intermédiaire. Il limite par exemple le nombre
  727. d'assignations de variables.
  728. \item[Backend :] Le \emph{backend} est le générateur de code cible. Durant
  729. cette phase, le langage intermédiaire est traduit en instructions du
  730. langage cible.
  731. \end{description}
  732. \subsection{Générateur d'ancrages algébriques}
  733. \label{ch:outils:subsec:tomemf}
  734. %\ttodo{Tom-EMF ; traitement de gros MM : UML2, Ecore}
  735. Dans cette partie, nous décrivons techniquement le générateur d'ancrages
  736. formels {\tomemf}. Il a été écrit pour répondre au besoin de représentation des
  737. modèles {\emf} sous la forme de termes {\tom}. Il est lui-même écrit en
  738. {\tomjava} et fonctionne de manière complètement indépendante de l'extension du
  739. langage dédiée aux transformations de modèles. Il est utilisé de manière
  740. \emph{stand-alone}, c'est-à-dire comme un logiciel à part entière, exécuté sans
  741. être appelé par un programme {\tom} externe. La figure~\ref{fig:tomEMF} décrit
  742. le principe général de fonctionnement que nous expliquons ci-après :
  743. %\ttodo{supprimer ces interlignes pourris}
  744. \begin{enumerate}
  745. %\compresslist
  746. \item {\eclipse} : métamodélisation et génération des structures {java}
  747. \begin{enumerate}
  748. %\compresslist
  749. \item L'utilisateur écrit un métamodèle {\ecore} manuellement, ou en
  750. utilisant les \emph{modeling tools} de {\eclipse} ;
  751. \item Il génère ensuite le générateur de code {\java} (\emph{GenModel})
  752. à partir de ce métamodèle via {\eclipse} ;
  753. \item Il génère ensuite les structures {\java} correspondantes et les exporte
  754. sous la forme d'une archive (\texttt{.jar}) ;
  755. \end{enumerate}
  756. \item {\tomemf} : génération des ancrages algébriques
  757. %\compresslist
  758. \begin{enumerate}
  759. %\compresslist
  760. \item L'utilisateur charge les structures {\java} générées et spécifie à
  761. {\tomemf} le(s) \emph{EPackage(s)} pour le(s)quel(s) il souhaite générer des
  762. ancrages ;
  763. \item Un fichier de \emph{mappings} (\texttt{<nom.complet.du.paquet>.tom})
  764. est généré par paquet ;
  765. \end{enumerate}
  766. \item {\tom} et {\java} : transformation de modèles
  767. %\compresslist
  768. \begin{enumerate}
  769. %\compresslist
  770. \item L'utilisateur inclut les ancrages dans sa transformation via la
  771. construction \lex{\%include} et importe les structures de données {\java}
  772. (\texttt{import}) ;
  773. \item L'utilisateur peut alors utiliser les types apparaissant dans le
  774. métamodèle et écrire la transformation en {\tomjava}, en utilisant ou non
  775. l'extension du langage, dédiée aux transformations de modèles ;
  776. \item La suite du processus est identique à une utilisation classique de
  777. {\tom} (compilation du code {\tom}, puis du code {\java}).
  778. \end{enumerate}
  779. \end{enumerate}
  780. %\ttodo{insérer schéma de fonctionnement {\tomemf} (comme dans les
  781. %présentations)}
  782. \begin{figure}[h]
  783. \begin{center}
  784. \input{figures/tomEMF}
  785. \end{center}
  786. \caption{Processus de compilation d'une transformation de modèles {\tomemf}.}
  787. \label{fig:tomEMF}
  788. \end{figure}
  789. %\todo{[tests schéma idée Marion v1]}
  790. %\input{figures/tests_marion/v1_myTomGomCompiler}
  791. %\todo{[tests schéma idée Marion v2]}
  792. %\input{figures/tests_marion/v2_tomGomCompiler}
  793. Ce générateur extrait une signature algébrique utilisable par {\tom} à partir
  794. du code {\java-\emf} représentant le métamodèle.
  795. %traduit le code du métamodèle sous la forme d'une signature
  796. %algébrique utilisable par {\tom}.
  797. %\ttodo{fonctionnalités : gestion des paquestmultiples, gestion des doublons,
  798. %des types builtin, des types venus de Ecore et de UML2, gestion des préfixes}
  799. %Le générateur d'ancrages {\tomemf} était au départ un \emph{proof of concept}
  800. Au départ en tant que \emph{proof of concept}, nous avons adapté et étendu le
  801. générateur d'ancrages {\tomemf} afin de construire un générateur pleinement
  802. opérationnel dédié aux modèles. Compte tenu de la forte utilisation de {\java}
  803. dans le développement logiciel ainsi que de celle de {\eclipse} et de {\emf}
  804. dans la communauté de l'ingénierie dirigée par les modèles, nous avons fait le
  805. choix de nous concentrer dans un premier temps sur ces technologies pour
  806. obtenir un outil fonctionnel. Cependant, nous ne nous limitons pas à ces choix
  807. et n'excluons pas une ouverture de {\tomemf} à d'autres technologies et
  808. langages. Notamment, certaines expériences ont été menées dans le but d'étendre
  809. l'outil au langage {\ada} et au \emph{framework} {\gms}. Une autre piste
  810. d'extension envisagée est l'utilisation de {\kmf}~\footnote{\emph{Kevoree
  811. Modeling Framework} : \url{http://www.kevoree.org/kmf}}. Le développement d'une
  812. transformation en {\java-\emf} nécessitant de toute manière de générer la
  813. structure de données du métamodèle pour l'utiliser au sein du programme, nous
  814. avons choisi de conserver dans un premier temps ce fonctionnement de génération
  815. de signature algébrique à partir du code. Cependant, si l'outil devait être
  816. étendu à d'autres langages et technologies, nous pourrions revoir nos choix
  817. afin de générer la signature directement à partir du métamodèle au format
  818. \texttt{.ecore}.
  819. %\todo{$^{[\text{à voir}]}$}.
  820. Dans sa forme actuelle, {\tomemf} est en mesure de traiter plusieurs paquetages
  821. {\ecore} (\emph{EPackages}) en entrée, et de générer un fichier d'ancrages pour
  822. chacun d'entre eux. Si des éléments du métamodèle sont utilisés alors qu'ils
  823. appartiennent à un autre \emph{EPackage} du métamodèle (ou d'un autre
  824. métamodèle chargé en mémoire), alors notre générateur génère les
  825. \emph{mappings} en cascade, tout en évitant la génération multiple d'un même
  826. paquetage. De la même manière, cet outil ne génère les ancrages formels que
  827. pour les types qui n'en ont pas déjà. Durant l'opération, nous maintenons donc
  828. un ensemble d'ancrages générés et à générer pour les types rencontrés.
  829. Pour chaque \emph{EPackage} spécifié par l'utilisateur, {\tomemf} récupère les
  830. \emph{EClassifiers} (surclasse commune de \emph{EClass} et \emph{EDataType}
  831. permettant de spécifier les types d'opérations, de \emph{structural features}
  832. et de paramètres) et génère les ancrages algébriques associés.
  833. %\emph{EClassifier} (surclasse commune de \emph{EClass} et
  834. %\emph{EDataType} permettant de spécifier les types d'opérations, de
  835. %\emph{structural features} et de paramètres) d'un métamodèle {\ecore}, un
  836. %ancrage algébrique est généré.
  837. Si le métamodèle spécifie qu'un élément
  838. \emph{EClass} possède la propriété \emph{abstract}, l'opérateur (\lex{\%op})
  839. n'est naturellement pas généré. Lorsque la multiplicité d'un attribut est
  840. strictement supérieure à 1 (\emph{structural feature} \texttt{many}), le champ
  841. de l'opérateur est un type liste. Un ancrage supplémentaire est alors généré,
  842. accompagné de l'opérateur variadique correspondant. Les associations et
  843. compositions sont donc représentées de cette manière. Il est à noter que {\tom}
  844. disposant d'un moteur d'inférence de type équipé du
  845. sous-typage~\cite{tavares09}, nous avons intégré cette fonctionnalité dans
  846. {\tomemf}. Lorsque l'option adéquate (\texttt{-nt}) est activée, les ancrages
  847. générés prennent en compte le sous-typage proposé par {\ecore}. Si un type n'a
  848. pas de surtype explicitement donné, le surtype généré dans l'ancrage est
  849. \emph{EObject} (le type \emph{Object} de {\ecore}) afin de correspondre aux
  850. conventions de {\emf}. Cette fonctionnalité de génération des sous-types est
  851. toutefois limitée au sous-typage simple : en effet {\ecore} supporte l'héritage
  852. multiple, mais pas {\java} (au niveau des classes). Nous verrons dans la
  853. section suivante que la fonctionnalité de sous-typage de {\tom} est utilisée en
  854. interne par le mécanisme de résolution (génération et remplacement des éléments
  855. \emph{resolve}).
  856. S'agissant des types issus des métamodèles {\ecore} ou {\uml} (ainsi que les
  857. types dits \emph{builtin}), ceux-ci sont traités à part (et non en cascade
  858. lorsqu'ils apparaissent) étant donné qu'il s'agit de métamodèles très utilisés
  859. et que leurs types sont souvent inclus dans les transformations. De ce fait,
  860. nous diffusons les ancrages pour ces métamodèles en tant que bibliothèques dans
  861. le projet {\tom}. L'outil {\tomemf} lui-même est écrit en {\tomjava} et utilise
  862. ces ancrages {\ecore}. La première utilisation de notre générateur a donc été
  863. pour terminer son \emph{bootstrap}, ce qui nous a permis de remplacer les
  864. ancrages écrits manuellement par des ancrages générés, comme l'illustre la
  865. figure~\ref{fig:bootstrapTomEMF}. Dans cette figure, les flèches en trait plein
  866. sont à comprendre comme des flux d'entrée et sortie, tandis que les flèches en
  867. pointillés signifient \emph{intégration à l'outil}.
  868. \begin{figure}[h]
  869. \begin{center}
  870. \input{figures/bootstrapTomEMF}
  871. \end{center}
  872. \caption{\emph{Bootstrap} de {\tomemf} : remplacement des ancrages algébriques \texttt{Ecore.tom} écrits manuellement par les ancrages générés.}
  873. \label{fig:bootstrapTomEMF}
  874. \end{figure}
  875. {\tomemf} gère aussi le préfixage des noms de types et d'opérateurs générés. En
  876. effet, il n'est pas rare de nommer de la même manière des éléments de
  877. métamodèles différents, mais qui n'appartiennent pas aux mêmes paquetages.
  878. Cependant, {\tom} n'ayant pas de système d'espaces de noms (\emph{namespaces})
  879. pour ses types et opérateurs, nous offrons à l'utilisateur la possibilité de
  880. préfixer les ancrages générés.
  881. %\ttodo{Quoi d'autre à dire sur la partie technique de {\tomemf} ?
  882. %EcoreContainmentIntrospector}
  883. Enfin, pour rendre complètement opérationnel le pont entre les deux espaces
  884. technologiques, {\tomemf} comprend un outil additionnel :
  885. \texttt{EcoreContainmentIntrospector}. Il s'agit d'une bibliothèque permettant
  886. le parcours de modèles par des stratégies. Elle repose sur le fait que le
  887. modèle possède une structure arborescente par la relation de composition et
  888. définit le parcours de modèles suivant ces relations. Cette bibliothèque
  889. s'utilise en conjonction des stratégies (l'utilisateur passe cet
  890. \emph{introspecteur} dédié à {\ecore} en paramètre de la stratégie).
  891. Techniquement, cette bibliothèque spécialisée fournit des services nécessaires
  892. à {\tom} pour compter, récupérer et modifier les enfants d'un nœud d'un terme
  893. représentant un modèle.
  894. \subsection{Mise en œuvre de l'extension}
  895. \label{subsec:meoExt}
  896. %\todo{à traiter : comment est faite l'implémentation ? Quelle(s) phase(s)
  897. %concernée(s) ? comment c'est compilé ? etc.}
  898. Dans cette partie, nous décrivons la mise en œuvre de l'extension du langage au
  899. sein du compilateur {\tom}. %Il s'agissait d'intégrer les constructions
  900. %\lex{\%transformation}, \lex{\%resolve} et \lex{\%tracelink} au langage
  901. %\ttodo{ajout du transformer, modif du parser+backend forcément, modif de
  902. %l'expander pour ajouter des bouts de code aux stratégies si besoin (pour
  903. %resolve), adt}
  904. Lors de l'implémentation de constructions d'un langage, plusieurs modifications
  905. de la chaîne de compilation sont nécessaires, de l'analyseur syntaxique au
  906. générateur de code. Dans notre cas, s'agissant de nouvelles constructions avec
  907. de nouveaux lexèmes, il fallait étendre le \emph{parser} (début de chaîne) pour
  908. pouvoir les reconnaître. Ensuite, ces constructions entraînant la génération de
  909. code qui n'était pas encore traité par le compilateur, le \emph{backend} (fin
  910. de chaîne) a aussi été étendu. Cependant, ces deux tâches ne sont pas le cœur
  911. de la mise en œuvre de l'extension du langage dédiée aux transformations de
  912. modèles. En effet, l'essentiel de l'implémentation réside dans l'ajout d'une
  913. nouvelle phase ---~le \emph{transformer}~--- dont la charge est de transformer
  914. les nœuds de l'arbre spécialisé dans la transformation de modèles en des
  915. stratégies. À cela s'ajoute la génération automatique d'ancrages ainsi que
  916. celle de la trace dont les instructions sont ajoutées à l'arbre.
  917. %\todo{[Pas grand chose à dire côté parsing, c'est très classique, rien de bien
  918. %compliqué, l'intelligence n'est pas là]\\}
  919. \paragraph{Parser.} L'aspect inhabituel de l'analyseur syntaxique de {\tom}
  920. réside dans le fait qu'il n'analyse pas tout le code, mais uniquement les îlots
  921. formels. Le code hôte est quant à lui vu comme une chaîne de caractères qui est
  922. parcourue jusqu'à l'îlot suivant. Ce type d'analyse où la grammaire du langage
  923. n'est pas totalement définie est appelé \emph{fuzzy parsing} : seule la
  924. grammaire de {\tom} l'est, totalement (on parle de grammaire îlot ou
  925. \emph{island grammar}). L'analyseur syntaxique de {\tom} repose sur le très
  926. populaire générateur de \emph{parser} {\antlr}~\footnote{\emph{ANother Tool for
  927. Language Recognition} : \url{http://www.antlr.org}}, ainsi que sur
  928. {\gomantlradapter}, un outil du projet permettant de lier les arbres générés
  929. par {\antlr} aux structures {\gom}. Lorsque le \emph{parser} principal détecte
  930. une construction donnée, il donne la main à un \emph{parser} dédié ({\tom} ou
  931. {\gom}). Il s'agissait donc d'étendre ces analyseurs pour mettre en œuvre les
  932. nouvelles constructions, en ajoutant de nouvelles règles adéquates dans la
  933. grammaire. En parallèle, la signature de {\tom} a été étendue afin de prendre
  934. en compte ces nouvelles constructions.
  935. \paragraph{Transformer.} Le cœur de la mise en œuvre de l'extension de {\tom}
  936. dédiée aux transformations de modèles se situe au niveau du \emph{plugin}
  937. \emph{transformer}, juste après l'analyseur syntaxique, et avant la phase de
  938. typage. Ce choix de nous insérer tôt dans la chaîne de compilation est tout à
  939. fait logique : la seule contrainte forte que nous avions était d'apparaître
  940. avant l'\emph{expander} ---~\emph{plugin} dédié aux stratégies~--- et nous
  941. souhaitions aussi bénéficier au maximum des éléments de contrôle déjà
  942. implémentés dans le compilateur {\tom} (\emph{syntax checker}, \emph{typer},
  943. \emph{type checker}).
  944. Cette phase prend en entrée l'arbre issu de l'analyseur syntaxique et produit
  945. un arbre syntaxique ne contenant plus aucun sous-arbre de type
  946. \emph{Transformation} obtenu après \emph{parsing} de la construction
  947. \lex{\%transformation}. Elle est implémentée de manière classique ---~du point
  948. de vue d'un développeur {\tom}~---, à savoir qu'une stratégie {\tom} est
  949. appliquée sur l'arbre en entrée.
  950. Les nœuds de type \emph{Resolve} et \emph{Tracelink} obtenus à partir du
  951. \emph{parsing} des constructions \lex{\%resolve} et \lex{\%tracelink} sont
  952. forcément des sous-arbres des arbres dont la racine est un nœud
  953. \emph{Transformation} étant donné que ces constructions sont uniquement
  954. utilisables dans le cadre des transformations de modèles. En ne manipulant que
  955. ces derniers, nous sommes donc en mesure de collecter et traiter tous les nœuds
  956. \emph{Resolve} et \emph{Tracelink}.
  957. %\todo{
  958. %\begin{itemize}
  959. %\item run : process transfonode -> abstractdecl
  960. %\item gen resolve element nodes à partir des instructions Resolve
  961. %\item concElementaryTransfo (genElementaryStrategy + elemenStratSymbol
  962. %\item gen stratégie resolve
  963. %\item on empaquette tout dans une séquence
  964. %\end{itemize}
  965. %}
  966. Dans le sous-arbre représentant une transformation, nous filtrons les nœuds de
  967. type \emph{Resolve} correspondant aux utilisations de la construction
  968. \lex{\%resolve}. Si un tel motif est filtré, le mécanisme d'enrichissement du
  969. métamodèle cible présenté dans le chapitre~\ref{ch:approach} est déclenché. Il
  970. est alors nécessaire de créer d'une part les structures de données concrètes
  971. représentant les éléments \emph{resolve}, et d'autre part des ancrages
  972. algébriques correspondants. Pour illustrer concrètement ce mécanisme, reprenons
  973. l'instruction \verb+%resolve(l:AText,target_left:Circle);+ de l'exemple
  974. précédent transformant du texte en figure géométrique. Elle entraîne la
  975. génération de la structure {\java} par le \emph{backend}, donnée dans le
  976. listing~\ref{code:resolveClassA2Shape} (par souci de lisibilité, les noms ont
  977. été simplifiés et les attributs sont publics).
  978. \begin{figure}[h]
  979. \begin{center}
  980. \input{code/resolveClassA2Shape}
  981. \end{center}
  982. %\caption{Exemple de classe {\java} générée implémentant les éléments \emph{resolve}.}
  983. %\label{code:resolveClassA2Shape}
  984. \end{figure}
  985. La classe générée ---~ici \texttt{ResolveATextCircle}~--- étend naturellement
  986. la classe de l'élément cible ---~\texttt{Circle} dans notre cas~--- que
  987. l'élément \emph{resolve} est censé représenter. Cette classe est associée à un
  988. ancrage et la relation d'héritage de {\java} est exprimée par un sous-type dans
  989. le \emph{mapping} décrit dans le listing~\ref{code:resolveMappingA2Shape}.
  990. Étant donné que ce mécanisme a lieu durant le processus de compilation
  991. {\textsf{Tom}\texttt{->}\java}, cet ancrage n'apparaît pas en tant que tel, mais
  992. est directement généré en mémoire pour être traduit en {\java} par la suite.
  993. Le listing~\ref{code:resolveMappingA2Shape} est néanmoins une traduction fidèle
  994. du \emph{mapping} qui serait écrit en {\tom}.
  995. \begin{figure}[h]
  996. \begin{center}
  997. \input{code/resolveMappingA2Shape}
  998. \end{center}
  999. %\caption{Exemple d'ancrage algébrique pour un élément \emph{resolve}.}
  1000. %\label{code:resolveMappingA2Shape}
  1001. \end{figure}
  1002. C'est aussi dans le \emph{transformer} que nous filtrons tous les symboles de
  1003. type \emph{Tracelink}. Pour chaque instruction de traçage, le
  1004. \emph{transformer} crée (ou récupère si elle existe déjà) ce que nous appelons
  1005. une \texttt{ReferenceClass}. Il s'agit d'une structure de données permettant de
  1006. référencer les éléments cibles tracés.
  1007. En termes d'implémentation {\java}, nous fournissons une interface
  1008. \texttt{ReferenceClass} extrêmement simple
  1009. (listing~\ref{code:referenceClassInterface}) que les structures de données
  1010. générées implémentent.
  1011. \begin{figure}[h]
  1012. \begin{center}
  1013. \input{code/referenceClassInterface}
  1014. %\caption{Interface devant être implémentée par les structures de type \texttt{ReferenceClass}.}
  1015. %\label{code:referenceClassInterface}
  1016. \end{center}
  1017. \end{figure}
  1018. Ces classes sont essentiellement constituées d'attributs (les références vers
  1019. les éléments cibles), de leurs méthodes d'accès (\texttt{get} et \texttt{set})
  1020. ainsi que d'une méthode permettant d'associer un nom à un élément. Le
  1021. listing~\ref{code:exreferenceClass} montre une classe qui serait générée
  1022. dans le cas de notre exemple de transformation de texte en formes géométriques.
  1023. \begin{figure}[h]
  1024. \begin{center}
  1025. \input{code/exreferenceClass}
  1026. %\caption{Exemple de classes générées implémentant l'interface \texttt{ReferenceClass} dans le cas de la transformation \emph{Text2Shape}.}
  1027. %\label{code:exreferenceClass}
  1028. \end{center}
  1029. \end{figure}
  1030. Une structure de type \texttt{ReferenceClass} est elle-même liée à l'élément
  1031. source filtré par la règle qui lui a donné naissance. Techniquement, cela
  1032. consiste à maintenir une table de hachage dont les clefs sont des sources de
  1033. type \texttt{EObject} et dont les valeurs sont ces structures de données. Cette
  1034. table de hachage fait partie intégrante du modèle de lien de la transformation,
  1035. implémenté par la classe \texttt{LinkClass} (fournie en tant que bibliothèque
  1036. avec son ancrage associé).
  1037. Toute \emph{définition} d'un sous-arbre \emph{Transformation} est quant à elle
  1038. transformée en une stratégie comprenant les règles de la \emph{définition},
  1039. accompagnée de son symbole. Une stratégie plus complexe est ensuite composée à
  1040. partir de ces stratégies. Finalement, tout nœud de type \emph{Transformation}
  1041. est remplacé par sa stratégie nouvellement créée ainsi que par une éventuelle
  1042. stratégie de résolution.
  1043. %déclaration de ReferenceClass, générée par la suite une fois que toutes les
  1044. %tracelink instructins sont données
  1045. %HashMap, stockage, LinkClass : table:ConcurrentHashMap EObject-> ReferenceClass
  1046. %\ttodo{\emph{backend} : il y a plus de choses à dire que pour le \emph{parsing}
  1047. %(génération du métamodèle de lien/trace, resolve, adaptation de la génération
  1048. %des stratégies pour le cas où on ajoute du code}
  1049. \paragraph{Backend.} En fin de chaîne de compilation, au niveau du générateur
  1050. de code (\emph{backend}), le travail a consisté à ajouter des fonctions de
  1051. génération de la phase de résolution ainsi que celles pour le métamodèle de
  1052. lien qui n'existaient pas auparavant. Ces dernières produisent du code
  1053. similaire à celui que nous avons montré précédemment dans les
  1054. listings~\ref{code:referenceClassInterface} et~\ref{code:exreferenceClass},
  1055. dans la partie décrivant la mécanique du greffon \emph{transformer}.
  1056. %du métamodèle de lien ainsi que celles pour la phase de résolution.
  1057. %La génération du métamodèle
  1058. %
  1059. %Un autre aspect important de l'extension du \emph{backend} est l'ajout des
  1060. %fonctions de génération du modèle de trace qui n'existaient pas auparavant.
  1061. %Elles produisent du code similaire à celui que nous avons montré précédemment
  1062. %dans les listings~\ref{code:referenceClassInterface}
  1063. %et~\ref{code:exreferenceClass}, dans la partie décrivant la mécanique du
  1064. %greffon \emph{transformer}.
  1065. %\todo{parler de l'évolution de l'encodage résolution (ici ?):
  1066. %\begin{itemize}
  1067. % \item[v1] : stratégie + procédure de résolution iresolveInverseLinks avec
  1068. % services EMF ;
  1069. % \item[v2] : stratégie + procédure de résolution resodveInverseLinks en
  1070. % enlevant les services EMF ;
  1071. % \item[v3] : procédure resolve() à la place de la stratégie + procédure
  1072. % customResolveInverseLinks.
  1073. %\end{itemize}}
  1074. La mise en œuvre de la génération de la phase de résolution a fait l'objet de
  1075. nombreuses évolutions au cours de ce travail. Nous décrirons son état stable
  1076. actuel (inclus dans la dernière version stable publiée : {\tom}-2.10) ainsi que
  1077. celui de la prochaine version stable.
  1078. La phase de résolution étant encodée sous la forme d'une stratégie de
  1079. réécriture, sa génération est en partie identique à la génération de stratégies
  1080. classiques. Cependant, elle se distingue d'elles par le fait qu'il faille aussi
  1081. écrire une procédure supplémentaire permettant d'effectuer la \emph{résolution
  1082. de liens inverses}. Cette procédure consiste à notifier tous les objets du
  1083. modèle ayant un pointeur vers l'objet qui vient d'être modifié pour que ce
  1084. pointeur pointe vers le nouvel objet et non plus vers l'élément \emph{resolve}.
  1085. La figure~\ref{fig:resolutionInverse} illustre ce mécanisme. La
  1086. figure~\ref{fig:resolutionInverse-a} est l'état du modèle en fin de première
  1087. phase. Il est constitué d'éléments cibles ainsi que d'éléments \emph{resolve}
  1088. (en pointillés). Les éléments à résoudre sont détectés et l'élément cible
  1089. effectif est identifié (figure~\ref{fig:resolutionInverse-b}). Tous les
  1090. éléments faisant référence à cet élément \emph{resolve} doivent aussi être mis
  1091. à jour. Dans l'exemple, le connecteur entre le pentagone bleu et le carré vert
  1092. référence le carré vert temporaire. Son extrémité (un pointeur vers l'élément
  1093. \emph{resolve}) est mise à jour pour référencer l'élément cible final
  1094. (figure~\ref{fig:resolutionInverse-c}). Une fois la \emph{résolution de liens
  1095. inverses} effectuée, le modèle ne comprend plus d'élément \emph{resolve}
  1096. (\ref{fig:resolutionInverse-d}).
  1097. %En effet, il faut notifier tous les objets du modèle ayant
  1098. %un pointeur vers l'objet qui vient d'être modifié pour que ce pointeur pointe
  1099. %vers le nouvel objet et non plus vers l'élément \emph{resolve}.
  1100. \begin{figure}[h]
  1101. % \centering
  1102. % \begin{tabular}{cccc}
  1103. \begin{subfigure}{0.21\textwidth}
  1104. %\centering
  1105. \input{figures/resolutionInverse-a}
  1106. \subcaption{}
  1107. \label{fig:resolutionInverse-a}
  1108. \end{subfigure}
  1109. % &
  1110. \quad
  1111. \begin{subfigure}{0.21\textwidth}
  1112. %\centering
  1113. \input{figures/resolutionInverse-b}
  1114. \subcaption{}
  1115. \label{fig:resolutionInverse-b}
  1116. \end{subfigure}
  1117. % &
  1118. \quad
  1119. \begin{subfigure}{0.21\textwidth}
  1120. %\centering
  1121. \input{figures/resolutionInverse-c}
  1122. \subcaption{}
  1123. \label{fig:resolutionInverse-c}
  1124. \end{subfigure}
  1125. % &
  1126. \quad
  1127. \begin{subfigure}{0.21\textwidth}
  1128. %\centering
  1129. \input{figures/resolutionInverse-d}
  1130. \subcaption{}
  1131. \label{fig:resolutionInverse-d}
  1132. \end{subfigure}
  1133. % \\
  1134. % \end{tabular}
  1135. \caption{Processus de résolution de liens inverses.}%FIXME\ttodo{alignement ???}
  1136. \label{fig:resolutionInverse}
  1137. \end{figure}
  1138. Dans le contexte de {\emf}, ce traitement peut être fait en utilisant les
  1139. services fournis. Dans la stratégie de résolution, nous effectuons donc une
  1140. résolution de liens inverses pour chaque élément \emph{resolve} trouvé et
  1141. remplacé. La procédure de résolution de liens inverses peut être automatisée ;
  1142. mais dépendant des types des éléments du modèle, elle ne peut être générique et
  1143. doit donc être générée pour chaque transformation. Pour rendre possible la
  1144. génération de ce code additionnel dans les stratégies, il a été nécessaire de
  1145. modifier la signature des stratégies afin de pouvoir embarquer du code
  1146. supplémentaire, ainsi que l'\emph{expander}. Le \emph{backend} des stratégies a
  1147. ensuite été adapté afin de prendre en compte cette nouveauté.
  1148. Signalons que la phase de résolution n'apparaît pas dans l'extrait de
  1149. code présenté plus tôt dans le chapitre. Il ne s'agit pas d'une simplification
  1150. du code pour les besoins de notre propos, mais bien du fonctionnement normal de
  1151. nos outils. En effet, la phase de résolution est entièrement générée, en
  1152. fonction de l'utilisation des constructions \lex{\%resolve} au sein de la
  1153. transformation. Ainsi, une transformation ne nécessitant pas d'élément
  1154. \emph{resolve} (donc sans utilisation du lexème \lex{\%resolve}) n'a pas de
  1155. phase de résolution.
  1156. À l'inverse, l'utilisation de la construction provoque la génération du bloc de
  1157. résolution dédié au type traité. Dans la version actuellement publiée de
  1158. l'outil ({\tom-2.10}), cette phase est encodée par une unique stratégie que
  1159. l'utilisateur n'écrit qu'indirectement par l'usage judicieux des constructions
  1160. de résolution. L'application de la stratégie de résolution est néanmoins à la
  1161. charge de l'utilisateur au sein de son programme. Il doit appeler la stratégie
  1162. en l'appliquant sur le modèle intermédiaire créé lors de la première phase.
  1163. Par la suite, nous avons expérimenté notre langage et avons constaté que
  1164. l'utilisation intensive des services {\emf} avait des conséquences importantes
  1165. sur les performances de la transformation, tant du point de vue de la mémoire
  1166. consommée que du temps. Nous avons donc fait évoluer la phase de résolution en
  1167. nous passant des services {\emf} pour la résolution de liens. Dans un premier
  1168. temps, plutôt que d'utiliser les méthodes {\emf}, nous avons écrit notre propre
  1169. méthode de résolution en évitant de parcourir tous les objets du modèle comme
  1170. le fait {\emf}. Dans un second temps, nous avons écrit une phase de résolution
  1171. sans stratégie afin de ne plus du tout parcourir le modèle intermédiaire. Pour
  1172. réaliser cette optimisation, nous conservons tout au long de la transformation
  1173. un ensemble de références inverses pour chaque élément \emph{resolve} créé (les
  1174. seuls éléments du modèle intermédiaire concernés par la résolution de liens
  1175. inverses). Nous détaillerons l'aspect performances de nos outils dans le
  1176. chapitre~\ref{ch:evaluation}.
  1177. Nous avons aussi expérimenté une version modulaire de la phase de résolution.
  1178. Plutôt que de générer une stratégie monolithique effectuant toute la
  1179. résolution, nous avons écrit une solution alternative générant plusieurs
  1180. stratégies de résolution partielle, chacune de ces stratégies n'effectuant la
  1181. réconciliation que sur un type de terme donné. Dans notre exemple, cette
  1182. alternative générerait deux stratégies distinctes, ainsi qu'une stratégie
  1183. combinant les deux. L'inconvénient de cette solution est qu'elle est plus
  1184. complexe à prendre en main pour l'utilisateur. Cependant, elle a l'avantage
  1185. d'offrir une plus grande modularité en décomposant la seconde phase. Ainsi, le
  1186. code généré pour une \emph{définition} peut être réutilisé dans une autre
  1187. transformation, et l'utilisateur averti prendra soin d'accompagner la
  1188. définition de la (ou des) stratégie(s) de résolution correspondante(s).
  1189. Pour des raisons d'utilisabilité de nos outils, nous avons fait le choix de
  1190. diffuser la version du générateur de phase de résolution monolithique dans la
  1191. version stable de {\tom}.
  1192. %\section{\todo{ici ? Travaux connexes}}
  1193. %: approche classique en MDE, outils, différences
  1194. \section{Synthèse}
  1195. \label{ch:outils:synth}
  1196. %\ttodo{
  1197. % \begin{itemize}
  1198. % \item Extension du langage + critères
  1199. % \begin{itemize}
  1200. % \item transfo
  1201. % \item resolution
  1202. % \item traçabilité
  1203. % \end{itemize}
  1204. % \item Implémentation
  1205. % \begin{itemize}
  1206. % \item archi, fonctionnalité, stats, tour des phases
  1207. % \item générateur d'ancrages algébriques
  1208. % \item mise en œuvre de l'extension : parser / transformer / backend
  1209. % \item exemple d'utilisation (ligne de commande, etc.)
  1210. % \end{itemize}
  1211. % \item
  1212. % \end{itemize}
  1213. %}
  1214. Dans ce chapitre, nous avons d'abord montré une utilisation concrète de nos
  1215. outils appliquée sur un exemple simple. Nous avons présenté l'extension du
  1216. langage {\tom} permettant de mettre en œuvre notre approche de transformation.
  1217. Les trois aspects principaux de cette extension sont : l'expression de la
  1218. transformation elle-même, le mécanisme de résolution et d'extension du
  1219. métamodèle cible par des éléments temporaires, ainsi que la traçabilité. Ces
  1220. éléments sont respectivement mis en œuvre par les constructions
  1221. \lex{\%transformation}, \lex{\%resolve} et \lex{\%tracelink}.
  1222. Nous avons par ailleurs présenté nos travaux d'implémentation ainsi que leur
  1223. intégration au sein du projet {\tom}. Nous avons notamment décrit le générateur
  1224. d'ancrages algébriques {\tomemf} permettant d'opérer le changement d'espace
  1225. technologique $mod\grave eles\rightarrow termes$. Nous avons de plus expliqué
  1226. comment nous analysions et transformions les sous-arbres issus des nouvelles
  1227. constructions du langage {\tom} dans la phase \emph{transformer}, et quel était
  1228. le code généré par le \emph{backend}.
  1229. Nous avons expérimenté nos outils et les premiers retours nous donnent des
  1230. pistes de travail intéressantes sur l'usage des technologies externes sur
  1231. lesquelles le prototype repose, sur le concept de modularité d'une
  1232. transformation (et donc aussi de la résolution), mais aussi sur la conception
  1233. du langage lui-même (séparation explicite des traçabilités). Nous reparlerons
  1234. de ces expériences et des perspectives offertes dans la suite de ce document.
  1235. Tout au long de ce chapitre, nous nous sommes appuyés sur l'exemple simple
  1236. d'une transformation de texte en formes géométriques colorées pour expliquer
  1237. les mécanismes en jeu. Nous nous proposons d'étudier une transformation
  1238. complète dans le chapitre suivant.%~\ref{ch:usecase}.
  1239. % vim:spell spelllang=fr