• Aucun résultat trouvé

Le développement d'un langage dédié n'est pas une tâche facile. Il se décompose principalement en deux phases : la conception et l'implémentation du DSL. La concep-tion du langage permet de délimiter le domaine d'applicaconcep-tion, notamment en dénissant précisément les objectifs et la portée du langage. Un domaine trop restreint réduit le domaine d'utilisation du langage et rend le langage inutilisable car trop spécique, alors qu'un domaine trop grand accroît la complexité du langage, de son analyse et de la vérication de propriétés. Une fois le domaine bien délimité, il s'agit de s'occuper de l'implémentation du langage.

3.3.1 Conception

Lors de la conception d'un langage dédié, de nombreux aspects doivent être pris en compte. En eet, il convient de concevoir un langage simple, tant dans sa sémantique (un nombre minimal de concepts et d'abstractions) que dans sa syntaxe, mais susamment expressif pour pouvoir résoudre tous les problèmes du domaine ciblé. Le langage doit, en

outre, être lisible, facilement compréhensible, mais aussi able (vis-à-vis des propriétés du domaine à respecter).

Un concept clé est au c÷ur de la conception d'un langage dédié, le domaine. An de pouvoir répondre à toutes les attentes d'un DSL, il est indispensable de bien dénir le domaine d'application dans son intégralité. C'est le rôle de l'analyse de domaine.

Cependant, elle ne permet pas à elle seule de bien caractériser le domaine, notamment parce qu'elle ne prend pas en compte les diérences entre les entités (systèmes) qui constituent ce domaine. Pour cela, il convient d'eectuer une analyse de famille de programmes, qui vise à identier les points communs et les variations des programmes du domaine. An d'aider le concepteur du langage dans sa tâche, il est possible de se reposer sur des méthodologies existantes.

Analyse de domaine. Avant de rééchir à la syntaxe d'un langage dédié à un do-maine ou encore à ses propriétés, il est indispensable de s'intéresser au problème de l'identication du domaine. Si cette observation semble une évidence, savoir reconnaître le domaine et déterminer sa portée n'est pas aussi facile qu'il y paraît. C'est pour cela que l'analyse de domaine est une composante primordiale de la conception d'un DSL.

Le principe consiste à étudier et dénir le domaine d'application de manière précise et modéliser ce domaine à partir de sources d'information très hétérogènes. Ces sources incluent, par exemple, les systèmes existants, les experts du domaine, les manuels, les prototypes, les standards ou encore les clients potentiels. Il s'agit de collecter les infor-mations pertinentes du domaine et les intégrer avec cohérence au sein d'un modèle du domaine. Le concept d'analyse de domaine a été déni pour la première fois par Neigh-bors en 1980 [Nei80], mais a été revisité de nombreuses fois, que ce soit par McCain [McC85], Arango [Ara89], ou encore Prieto-Diaz [PD90]. Pour caractériser de manière précise le domaine d'application et sa portée, l'analyse doit permettre de dénir le contenu et les limites du domaine, que ce soit sous la forme d'exemples de systèmes possibles mais aussi de contre-exemples. Il est également indispensable d'identier les intervenants du domaine, ainsi que leurs besoins et leurs buts. Ils font partie inté-grante de la dénition du domaine [CE00]. Néanmoins, une analyse de domaine est bien souvent insusante pour spécier l'ensemble du domaine. En eet, elle ne s'intéresse qu'aux points communs qui existent à l'intérieur du domaine, mais pas aux diérences, aux variations.

Analyse de famille de programmes. Parnas dénit une famille de programmes comme suit [Par76] :

"Nous considérons qu'un ensemble de programmes constitue une famille, lorsqu'il est utile d'étudier les programmes de cet ensemble, en étudiant d'abord ses propriétés communes puis en déterminant les particularités de chaque membre de la famille.".

Une famille de programmes représente donc un domaine, comme déni par Neighbors.

Cependant, contrairement à un domaine quelconque, une famille de programmes est

un ensemble restreint où il est possible d'étudier les variations de l'ensemble, c'est-à-dire les particularités de chaque membre. Un point important de l'analyse de famille de programmes consiste à séparer les points communs des points de variations. Le but est d'identier un maximum de points communs an de les réutiliser de façon systé-matique. Un point commun dénit une caractéristique intrinsèque à tous les membres d'une famille de programmes. Une variation précise, quant à elle, les diérences entre les membres. Parnas propose une méthodologie pour développer une famille de pro-grammes, permettant de réutiliser les points communs de ses membres. Un travail plus récent, l'approche FAST, est également proposé par Weiss [Wei96] et vise à identier et dénir une famille de programmes. Pour cela, il développe une analyse, appelée analyse de points communs, qui permet de découvrir la terminologie du domaine, les points communs et les variations de la famille de programmes. Ces méthodologies ne sont pas les seules pour faciliter la conception de langages dédiés. Nous donnons plus loin un éventail des approches existantes.

Méthodologie. La plupart du temps, l'analyse de domaine est réalisée de manière informelle, mais dans certains cas, des méthodologies peuvent être utilisées et faciliter le travail de conception. Parmi ces méthodologies, nous pouvons citer DARE (Domain Analysis and Reuse Environment) [FPDF98], DSSA (Domain-Specic Software Archi-tectures) [Tra95], FAST (Family-Oriented Abstractions, Specication, and Translation) [WL99], FODA (Feature-Oriented Domain Analysis) [KCH+90], ODE (Ontology-based Domain Analysis) [FGD02], ou encore ODM (Organization Domain Modeling) [Sim95].

Le but de ces méthodologies est de fournir un support an de déterminer le bon niveau d'abstraction du langage, une terminologie spécique au domaine adéquate, ou encore la dénition et la description des concepts du domaine. Mernik et al. [MHS05] donnent une description plus détaillée de ces approches. Ils proposent également une étude sys-tématique des facteurs à prendre en compte dans les phases de décision, d'analyse, de conception et d'implémentation d'un DSL en se basant sur l'identication de modèles existants, ainsi que sur l'étude de Spinellis [Spi01]. D'autres méthodologies de dévelop-pement de DSL peuvent encore être citées comme Sprint [CM98]. Sprint est un processus complet de développement logiciel, qui démarre par l'identication des besoins du DSL jusqu'à son implémentation. Il utilise la sémantique dénotationnelle [Sch86] an de for-maliser les composants de base du DSL. La structure de la dénition sémantique permet d'étager les décisions de conception et d'intégrer les problèmes d'implémentation.

La gure 3.1 résume le processus de développement d'un langage dédié à un domaine d'application. Avant de s'intéresser à la conception du langage, il est indispensable de dénir de manière précise le domaine. Cette phase de conception consiste à délimiter avec précision le domaine, en spéciant les objectifs et la portée du langage, mais aussi en caractérisant les propriétés communes et variables de tous les systèmes du domaine.

Des analyses, de domaine et de famille de programmes, permettent d'aboutir à de telles conclusions. Elles permettent également d'identier et formuler des propriétés et des concepts du domaine. Il devient alors possible de dénir la syntaxe et la sémantique du langage. Les contraintes concernant le langage, comme des besoins en analyse, sont

Analyse de Domaine et de Famille Littérature

Implémentations existantes Informations des experts

Concepts Points communs Variations Propriétés

Syntaxe Sémantique Définition

du Langage

Implémentation du Langage Intervenants

du domaine

Fig. 3.1 Processus de développement d'un langage dédié

directement intégrées dans le processus de conception. Cela permet, par exemple, de rendre décidable certaines propriétés critiques du domaine au niveau du DSL. Il s'agit ensuite de s'intéresser à l'implémentation du langage.

3.3.2 Implémentation

La dernière phase du processus de développement d'un langage dédié correspond à son implémentation. Il existe diérentes techniques de mise en ÷uvre, qui ne présentent pas le même coût ni les mêmes avantages. Ce point entraîne donc un choix de concep-tion, qui est souvent guidé par les contraintes du domaine (besoin de performance par exemple). An d'éclairer la tâche des concepteurs, Mernik et al. [MHS05] proposent une comparaison plus aboutie de ces approches que celles présentées dans ce document.

Interprétation et compilation. L'interprétation et la compilation de DSL (e.g., Mawl [ABBC99] ou Atmol [Eng01]) sont les approches les plus répandues. L'interpré-tation est plus appropriée pour les langages présentant un caractère dynamique du fait d'un contrôle plus important sur l'environnement d'exécution. La compilation, quant à elle, présente l'avantage de pouvoir réaliser une analyse statique complète du programme et donc d'assurer des propriétés du domaine avant l'exécution. Elle permet également la réutilisation des outils de compilation standards [ASU86, Ben86], ou des outils dédiés à l'implémentation de DSL comme Draco [Nei84], ou ASF+SDF [vDHK96]. La construc-tion d'un compilateur ou d'un interprète permet de complètement adapter l'implémen-tation au domaine. De plus, aucune concession n'est nécessaire au niveau de la nol'implémen-tation ou encore des opérations. Néanmoins, le problème reste le coût de la construction du compilateur ou de l'interprète et le manque de réutilisation pour d'autres implémenta-tions de DSL.

Langages enchâssés et librairies spéciques. La manière la plus simple de conce-voir un langage dédié est de le baser sur un langage existant. Ainsi, son implémentation en devient plus simple et les utilisateurs sont déjà familiers avec la syntaxe ou le para-digme du langage. Le concept de langage enchâssé a été introduit par Hudak [Hud96].

Un des avantages d'une telle approche réside dans le fait que le nouveau langage pos-sède toute la puissance et l'expressivité du langage hôte, tout en ajoutant des primitives

dédiées au domaine qui sont plus proches des experts du domaine. La réutilisation de l'infrastructure existante du langage hôte est aussi un autre avantage (environnements de développement et de débogage, éditeurs). Une possibilité de mise en ÷uvre consiste à partiellement utiliser un langage hôte existant (e.g., Hancock avec C [CFPR00]). Une autre possibilité est d'étendre un langage existant avec de nouvelles fonctionnalités et de nouveaux concepts, spéciques au domaine (e.g., Swul avec Java [BV04], ou en-core Verischemelog avec Scheme [JB00]). Les principales limitations de cette technique se situent au niveau de l'expressivité des mécanismes, qui est restreinte aux possibili-tés du langage hôte, mais également au niveau de l'environnement d'exécution hérité du langage hôte, qui n'est pas optimisé pour le langage enchâssé. Haskell est souvent cité comme le langage le plus approprié à ce type d'implémentation de langages dédiés [PHH99], avec des réalisations dans le domaine de la musique [HMGW96], ou encore la robotique [PHH99].

Pré-processing et expansion de macro. Dans cette approche, les constructions du DSL sont traduites par un pré-processing dans les expressions d'un langage de base.

Son principal avantage est sa simplicité. Néanmoins, l'analyse statique est limitée à celle réalisée par le processeur du langage de base. Les traitements ne se font pas au niveau du domaine. Par exemple, la couverture d'erreurs se situe, elle aussi, au niveau du langage de base, ce qui complexie la gestion des erreurs pour l'utilisateur. Les implémentations sont multiples [Spi01]. Parmi celles-ci, nous pouvons citer entre autres : l'expansion de macros (e.g., Latex), la méta-programmation par patrons ou templates (e.g., Blitz++

[Vel98]), ou encore la traduction successive appelée pipeline (e.g., CHEM [BJK87]).

Extension de compilateur et d'interprète. Cette approche est similaire à l'ap-proche précédente, à l'exception que le pré-processing est ici intégré au compilateur ou à l'interprète. Il est alors possible de réaliser des optimisations et des vérications plus abouties. Le compilateur ou l'interprète est étendu avec des règles d'optimisation, ou une génération de code, spéciques au domaine. L'interprète TCL [Ous97], ou encore le compilateur DiSTiL [SB97] sont deux implémentations de cette approche. Si les in-terprètes sont plus faciles à étendre, il est complexe d'appliquer cette technique aux compilateurs, sauf si la possibilité d'extension a été prévue dès leur conception.

Approche COTS. L'approche basée sur les composants sur étagère (Commercial O-The-Shelves ou COTS) permet de réutiliser des outils ou des notations existantes et de les appliquer à un domaine en particulier. La meilleure illustration de cette approche reste les langages dédiés sur XML [GK02] (e.g., ACML [KG03]), où de nombreux outils peuvent être réutilisés (analyseurs SAX, outils de transformation XSLT).

L'utilisation d'un langage dédié en lieu et place d'un langage généraliste est bénéque en de nombreux aspects. Toutefois, sa conception n'en demeure pas moins complexe et nécessite une étude et une analyse minutieuses du domaine. En eet, des aspects à la fois fonctionnels, comme le niveau d'abstraction du langage et le degré d'analysabilité,

mais aussi non-fonctionnels, comme la lisibilité ou la facilité d'écriture, doivent être pris en compte. Pour cela, il est indispensable de bien dénir et délimiter le domaine d'appli-cation. L'analyse de domaine et l'analyse de famille de programmes visent à atteindre cet objectif et permettent d'aboutir à la dénition du langage dédié. Il devient alors possible d'implémenter le DSL, facilité par l'utilisation de méthodologies existantes, ou par des approches hybrides (e.g., GAL [TMC97] ou encore PLAN-P [TMC98]), qui combinent les avantages des diérentes stratégies.