PRM, prmc
Un langage de programmation et un compilateur
Jean Privat
LIRMM
161 rue Ada
34392 Montpellier Cedex 5 - France
esum´e Ce papier pr´esente un langage de programmation
(PRM) et son compilateur (prmc) en prenant comme points
de vues l’interaction entre humains et ordinateurs, et la
qualit´e des logiciels.
Mots-cl´es PRM, langage de programmation, objets,
compilation s´epar´ee.
I. Introduction
0110010 ?Bonjour !
Fig. 1. Probl`eme de communication ?
La boutade de la figure 1 caricature le probl`eme
fondamental sous-jacent `a de nombreuses recherches en
informatique : comment faire pour que l’humain et
l’ordinateur puissent interagir ?
Le travail que j’ai men´e pendant ma th`ese concerne
deux facettes de ce probl`eme de communication dans le
cadre du d´eveloppement de logiciels. Plus pr´ecis´ement, mon
travail se situe de part (cˆot´e humain) et d’autre (cˆot´e
machine) des langages de programmation1. Cˆot´e humain,
j’ai travaill´e sur les traits des langages et propos´e le
raffinement de classes, une extension du mod`ele `a objets.
ot´e machine, j’ai travaill´e sur la compilation des langages
et propos´e un sch´ema de compilation s´epar´e qui permette
d’obtenir l’efficacit´e des compilateurs globaux tout en
conservant les avantages de la compilation s´epar´ee. Afin,
de mettre en oeuvre les r´esultats de ma recherche, j’ai
d’une part sp´ecifi´e PRM, un langage de programmation
qui int`egre le raffinement et d’autre part impl´ement´e prmc,
un compilateur PRM efficace et s´epar´e.
II. Quelques notions de base
Afin de comprendre le paragraphe pr´ec´edent et plus
particuli`erement les mots en italique, nous allons tenter
de pr´esenter quelques notions de base. Dans un premier
temps nous parlerons de langages de programmation, puis
de la qualit´e des logiciels. Nous pr´esenterons ensuite les
langages `a objets, une famille de langages qui permet
d’avoir une meilleure qualit´e des logiciels. Nous terminerons
en pr´esentant le m´ecanisme de la compilation.
1Plus pr´ecis´ement encore, des langages de programmation orient´es
objets, statiquement typ´es et en eritage multiple.
A. Langages de programmation
Les langages de programmation (ou langages informatiques)
sont des langages artificiels permettant d’´ecrire des
programmes informatiques. Le code source (ou simplement
code) d´esigne le (( texte )) d’un programme (( r´edig´e )) dans
un langage de programmation.
Un langage de programmation est constitu´e d’une
syntaxe (le vocabulaire et la grammaire) et d’une
s´emantique (les abstractions exprimables et leur signification).
Toutefois, il est n´ecessaire de comprendre qu’un langage de
programmation ne sert pas `a discuter avec un ordinateur
mais plutˆot `a lui donner des ordres2.
Ordinateur« Lecture »Programmeur « Écriture »
Idée Code source Exécution
Fig. 2. Programmeur, langage et ordinateur
Si l’on reprend la m´etaphore de la figure 1, on peut
dire que les d´eveloppeurs de logiciels informatiques (ou
programmeurs3) communiquent avec les ordinateur en
utilisant des langages de programmation (figure 2). Cette
communication pr´esente deux aspects :
´
Ecriture. Un programmeur humain doit pouvoir exprimer
ses (( ordres )). Le langage doit donc ˆetre intelligible
par le programmeur. En g´en´eral, plus le langage est
naturellement intelligible, plus celui-ci est ´eloign´e des
instructions primitives des machines physiques.
Lecture. L’ordinateur doit pouvoir (( comprendre )) le code
source. Contrairement aux humains, les machines n’ont pas
la capacit´e d’(( interpr´eter )), elle ne peuvent que lire le code
source (( `a la lettre )). Il est donc n´ecessaire que le langage
ne soit pas ambigu.
Il existe de nombreux langages de programmations
diff´erents. Ils se distinguent les uns des autres par leur
syntaxe bien sˆur, mais ´egalement par leurs domaines
d’utilisation ou les concepts qu’ils manipulent. La figure 3
montre deux programmes calculant la factorielle. Le
premier est ´ecrit en Basic et le second en C4.
2Les langages de programmation partagent de nombreuses
caract´eristiques avec les langages militaires.
3´
Evitez le terme (( programmateur )) qui ne concerne g´en´eralement
que les lave-linges et l’arrosage automatique.
4Le Basic est un langage de programmation d´evelopp´e en 1964
INPUT "Nombre: ", N
R = 1
FOR A = 1 TO N
R = R * A
NEXT A
PRINT N; "! = "; R
#include <stdio.h>
int main(void)
{
int a, n, r=1;
printf("Nombre: ");
scanf("%d", &n);
for(a=1; a<=n; a++)
r *= a;
printf("%d! = %d\n", n, r);
return 0;
}
Fig. 3. Exemples : le calcul de la factorielle
On peut remarquer que la structure du programme ´ecrit
en C ressemble plus ou moins `a celle du programme ´ecrit
en Basic. C’est d’une part parce que les deux programmes
impl´ementent le mˆeme algorithme (ils calculent la
factorielle de la mˆeme mani`ere), et d’autre part parce que le
Basic et le C appartiennent `a une mˆeme famille de langages,
celle des langages imp´eratifs.
B. Qualit´e des logiciels
Le g´enie logiciel est la branche de l’informatique qui
s’ineresse `a la mani`ere dont le code source d’un logiciel
est sp´ecifi´e puis produit. En particulier, cette science de
l’ing´enieur a identifi´e plusieurs facteurs qui composent la
qualit´e globale des logiciels produits. Parmi ces facteurs
on trouve par exemple : la conformit´e (le logiciel fait-
il ce qu’il doit faire ?), la fiabilit´e (se comporte-t-il
correctement dans tous les cas ?), l’efficacit´e (utilise-
t-il au mieux les ressources de la machine ? (temps,
m´emoire...)), la maintenabilit´e (est-il facile de maintenir
le logiciel dans un ´etat correct ? (correction de bugs,
mises-`a-jour mineures...)), la souplesse (est-il facile de faire
´evoluer le logiciel, de l’adapter de diff´erente mani`eres ?), la
r´eutilisabilit´e (est-il possible de r´eutiliser un morceau du
logiciel dans un autre logiciel ?), etc.
Il est important de remarquer que certains facteurs de
qualit´e concernent plus ou moins directement le code source
des logiciels (la r´eutilisabilit´e par exemple). Les langages de
programmation ont donc pleinement leur rˆole `a jouer dans
l’am´elioration de la qualit´e des logiciels.
C. Langages orient´ees objet
Cr´e´es il y a plus de de vingt ans, les langages `a objets
(ou langages orienes objet) sont devenus la norme dans
les processus de d´eveloppement de logiciels. La raison d’un
tel succ`es est sans doute li´ee `a quatre caract´eristiques qui
augmentent l’expressivit´e du langage (i.e. les abstractions
exprimables par le programmeur sont plus nombreuses) :
le concept d’objet permet au programmeur de d´esigner
et de manipuler de fa¸con naturelle des abstractions
(des objets) d’entit´es du monde r´eel. Ainsi, une
voiture, un utilisateur, un achat sur internet ou une
vid´eo en train d’ˆetre visionn´ee peuvent ˆetre consid´er´es
comme des objets ;
par John George Kemeny et Thomas Eugene Kurtz `a l’universit´e de
Dartmouth afin de rendre l’utilisation de l’informatique accessible aux
´etudiants. Le langage C fut d´evelopp´e en 1972 dans les laboratoires
Bell en mˆeme temps que le syst`eme d’exploitation Unix par Dennis
Ritchie et Ken Thompson.
le concept de classe permet au programmeur de d´efinir
des cat´egories d’objets (c’est-`a-dire des objets de
mˆeme nature). Par exemple, l’objet (( la 206 de Roger
)) appartient `a la classe des (( Voitures )) (on dit qu’un
objet est instance d’une classe) ;
le m´ecanisme d’eritage permet au programmeur de
d´efinir (c’est-`a-dire d’exprimer) de nouvelles classes
par rapport `a des classes d´ej`a d´efinies. Par exemple, le
programmeur disposant d’une classe (( Voiture )) peut
d´efinir une sous-classe (( Ambulance )) comme ´etant une
(( Voiture )) blanche qui fait (( pin-pon )), le tout sans
avoir `a exprimer que les ambulances ont un moteur et
quatre roues (puisque ces informations sont h´erit´ees
de la classe (( Voiture ))) ;
– la m´etaphore de l’envoi de messages (appel´ee aussi
liaison tardive) permet d’exprimer de fa¸con g´en´erale
des manipulations sur les objets sans se soucier de la
classe dont ils sont instances. Ainsi, le programmeur
qui consid`ere une voiture quelconque, peut exprimer
le fait de d´emonter une roue ou de couper le moteur,
ceci ind´ependemment de la classe dont est instance
la voiture en question (celle-ci pouvant ˆetre une
ambulance, un 4x4, un corbillard, etc.).
D. Compilation
Une fois le code source d’un programme ´ecrit par un
d´eveloppeur humain, la question qui se pose concerne
l’utilisation de ce programme sur un ordinateur. Pour
utiliser un programme, la fa¸con la plus r´epandue (et la
plus efficace) consiste `a compiler les fichiers informatiques
contenant le code source d’un programme. L’utilisateur
final n’a plus alors qu’a ex´ecuter le r´esultat de la
compilation.
D.1 Principe de la compilation
FOR A = 1 TO 9
B = B + A
NEXT A
01100100100
11101110110111
10110010110001
10000011010110
Programmeur
Compilation
Code source Exécutable Ordinateur
Fig. 4. Principe de la compilation
La compilation (figure 4) consiste `a traduire un
programme du langage de programmation utilis´e vers
le langage machine, c’est-`a-dire le seul langage que
l’ordinateur est capable d’ex´ecuter directement. On appelle
ex´ecutable le fichier produit par la compilation, celui-ci est
constitu´e d’une suite instructions primitives repr´esent´es de
fa¸con binaire.
Une fois produit, l’ex´ecutable n’est plus li´e au code
source. Il peut ˆetre distribu´e : les utilisateurs finaux n’ont
plus qu’a double-cliquer sur l’ex´ecutable qui leur a ´et´e
vendu.
Un programme particulier, appel´e compilateur, est
charg´e d’effectuer la compilation.5. Celui-ci fonctionne en
5Question : qui a compil´e le compilateur ? R´eponse : un autre
compilateur. Question : qui a alors compil´e cet autre compilateur ?
prenant en donn´ee le code source d’un programme et en
produisant en sortie un ex´ecutable.
Remarque : en g´en´eral, un compilateur ne fonctionne que
pour un seul langage et pour une seule plate-forme. Ainsi,
un compilateur C ne saura pas compiler un programme
´ecrit en Basic. De la mˆeme mani`ere, l’ex´ecutable produit
par un compilateur pour microprocesseurs Intel 8086 ne
pourra pas ˆetre ex´ecut´e par une machine Apple munie d’un
microprocesseur Motorola.
D.2 Compilation efficace
Parmi les facteurs de qualit´e des logiciels, nous avons
la performance. Or, pour un code source donn´e, plusieurs
traductions vers le langage machine sont possibles,
certaines ´etant plus performantes que d’autres. Un
compilateur est d’autant plus efficace qu’il produit du code
machine performant.
Toutefois, plus le langage de programmation est
´eloign´e du langage machine, plus les techniques de
compilation permettant de produire du code efficace
deviennent difficile `a trouver. Ainsi, il est malheureusement
fr´equent que les cr´eateurs de langages de programmation
prennent en compte les contraintes de compilation pour
sp´ecifier leur langage ce qui entraˆıne in´evitablement
un appauvrissement du langage (moins d’expressivit´e)
voire une complexification (cr´eation de nombreux cas
particuliers).
D.3 Compilation s´epar´ee et globale
code
binaire
code
binaire
code
source
code
source
programme
source du
code
binaire
exécutable
compilation
de liens
édition
compilation
Fig. 5. La compilation s´epar´ee
La compilation est un processus complexe et, pour de
nombreuses raisons pratiques, un programme n’est jamais
compil´e d’un coup. On pr´ef`ere compiler un programme par
petits bouts puis produire un ex´ecutable en liant ensemble
les petits bouts compil´es : on appelle ¸ca la compilation
s´epar´ee (voir figure 5). Les avantages d’une telle fa¸con de
faire sont nombreux : si l’on modifie un programme, seul le
bout de code modifi´e a besoin d’ˆetre recompil´e ; une seule
compilation d’un bout de code est n´ecessaire mˆeme si celui-
ci est partag´e par plusieurs programmes (cela arrive tr`es
fr´equemment) ; un bout de code compil´e s´epar´ement peut
ˆetre vendu tel quel `a d’autres programmeurs (le vendeur
qui le souhaite peut ainsi garder le code source secret).
S’il existe une (( compilation s´epar´ee )), c’est qu’il existe
une (( compilation globale )). Celle-ci consiste `a compiler
d’un coup un programme en entier. L’avantage de la
compilation globale consiste `a profiter de la connaissance
de la totalit´e du code source pour faire des analyses plus
profondes et ainsi tenter de produire du code machine plus
efficace. Malheureusement, la compilation globale n’offre
pas la souplesse de la compilation s´epar´ee, `a tel point que
dans l’industrie, l’utilisation de compilateurs globaux est
marginale.
III. PRM, le langage
PRM, pour (( Programmation, raffinement et modules )),
est le langage de programmation que nous avons d´evelopp´e.
C’est un langage de programmation oriene objet et
statiquement typ´e. Il se place donc dans la mˆeme famille
que C++, Java, C# ou Eiffel6(les autres langages que nous
citons ne faisant pas partie de cette famille). Toutefois,
contrairement `a ces quatre langages, PRM se distingue
de deux mani`eres : sa simplicit´e, puisque les concepts
manipul´es par le langage, ainsi que la syntaxe qui en
d´ecoule, ont ´et´e sp´ecifi´es de fa¸con `a ˆetre le plus clair possible
(en particulier parce que nous n’avons pas pris en compte
dans la sp´ecification du langage les ´eventuels probl`emes de
compilation), et son expressivit´e, puisque celui-ci contient
entre autre des traits de langages avanc´es qui n’existent que
dans quelques langages voire sont compl`etement in´edits !
La syntaxe du langage est fortement inspir´ee de celle
des langages `a typage dynamique et des langages de script
(en particulier Ruby7). Ces langages sont g´en´eralement
r´eput´es pour leur facilit´e d’apprentissage et d’utilisation.
Toutefois, PRM revendique Pascal comme l’un de ses
lointains ancˆetres8. Au final PRM est sans doute un tr`es
bon langage pour d´ebuter la programmation, d’ailleurs
malgr´e sa jeunesse il est d´ej`a utilis´e en tant que langage
d’apprentissage `a l’IUT de B´eziers.
Bien que les concepts de base du langage soient (`a
dessein) peu nombreux, celui-ci en int`egre certains qui sont
plus ou moins rares :
h´eritage multiple (existe en Eiffel et en C++) :
les classes peuvent h´eriter de plusieurs classes. Cela
permet par exemple d’exprimer que les poulets sont `a
la fois des oiseaux et des animaux de basse-cour.
les types primitifs sont des classes (existe en Eiffel et
Ruby) : les autres langages traitent de fa¸con diff´erente
les types primitifs (comme les entiers) des classes ce
qui am`ene parfois `a des complications inutiles pour le
programmeur.
g´en´ericit´e born´ee (existe en Eiffel et dans la derni`ere
version de Java, existe aussi de fa¸con non born´ee en
C++) : c’est un concept qui permet d’augmenter le
niveau d’abstraction du code source.
red´efinition covariante (existe en Eiffel mais pas
exactement pour les mˆemes raisons) : cela permet par
exemple d’exprimer des choses comme (( les animaux
mangent de la nourriture et les vaches mangent de
l’herbe ))9.
– it´erateurs automatiques (existe en Ruby et dans la
derni`ere version de Java) : cela permet de manipuler
6Bjarne Stroustrup a d´evelopp´e C++ au cours des ann´ees 1980 en
tant qu’extension du langage C. Java est un langage con¸cu en 1995
chez Sun Microsystems par James Gosling et Patrick Naughton. C#,
cr´e par la soci´et´e Microsoft, est un langage proche de Java. Eiffel,
evelopp´e par Bertrand Meyer `a partir de 1985, est un langage qui se
concentre sur la qualit´e logicielle.
7Yukihiro Matsumoto a commenc´e l’´ecriture de Ruby en 1993 avec
un objectif de coh´erence et d’intelligibilit´e.
8Pascal est un langage cr´ee par Niklaus Wirth en 1970 `a l’universit´e
de Zurich. Il a ´et´e con¸cu pour servir `a l’enseignement de la
programmation de mani`ere rigoureuse mais simple.
9Toute la subtilit´e d’une telle banalit´e consiste `a remarquer qu’il
existe malgr´e tout un sophisme : les animaux mangent de la
nourriture, or les vaches sont des animaux, donc les vaches mangent de
la nourriture, or les saucisses sont de la nourriture, donc on pourrait
nourrir les vaches avec des saucisses.
simplement les collections d’´el´ements, quelque soit le
type de la collection ou des ´el´ements. On peut alors
exprimer simplement des choses comme (( pour chaque
lapin du clapier, donner une carotte )) ou (( pour chaque
client abonn´e, envoyer une facture )).
Les deux principaux concepts in´edits sont l’h´eritage
multiple s´emantique id´eal et le raffinement de classes.
Les diff´erentes sp´ecifications de l’h´eritage multiple dans
les langages existants posent tellement de probl`emes
(peu intelligibles, voire parfois franchement ambigu¨es) que
certaines documentations vont jusqu’`a conseiller de ne pas
faire d’h´eritage multiple. Notre sp´ecification de l’h´eritage
multiple se base exclusivement sur une approche naturelle
de la sp´ecialisation (c’est-`a-dire sans prise en comptes
des probl´ematiques de compilation). Au final, l’h´eritage
multiple de PRM est plus simple (`a comprendre et `a
utiliser) et g`ere plus naturellement les divers conflits
d’h´eritage.
Le raffinement de classes [1] permet une meilleure
souplesse des logiciels. L’id´ee de base consiste `a pouvoir
faire ´evoluer (raffiner) une classe d’un programme sans
avoir `a modifier le morceau de code source dans lequel est
d´efinie la classe. Ne pas avoir `a toucher un morceau de code
source existant est un r´eel avantage dans certains cas :
le morceau de code source est partag´e par plusieurs
programmes donc la modification de ce morceau de
code aurait un impact sur tous les programmes (ce
qui n’est pas forc´ement souhait´e) ;
le morceau de code source est inaccessible (on nous a
vendu, sans les sources, un bout de code d´ej`a compil´e) ;
on veut deux versions du programme, une sans
l’´evolution, une avec l’´evolution. Il est donc n´ecessaire
de pouvoir conserver le morceau de code non modifi´e.
D’autres approches ont ´et´e propos´ees pour r´epondre
aux mˆemes besoins (parmi lesquelles la programmation
orienee aspect). Toutefois, notre proposition a l’avantage
de s’inegrer parfaitement `a notre sp´ecification de l’h´eritage
multiple et permet de conserver le langage simple et
intelligible.
IV. prmc, le compilateur
prmc, pour (( PRM Compiler )), est le compilateur que
nous sommes en train de d´evelopper pour le langage PRM.
Notre objectif est ici de mettre en œuvre les techniques de
compilation que nous avons d´evelopp´ees (qui sont toutefois
applicables `a tout langage `a objets et statiquement typ´e).
A. Principe de compilation
Comme nous l’avons dit pr´ec´edemment, plus un langage
est intelligible, plus celui-ci est ´eloign´e du fonctionnement
de la machine, et plus celui-ci est difficile `a compiler
efficacement. Comment les langages et compilateurs font-
ils pour r´esoudre ce probl`eme ? Trois voies existent : le
langage peut faire des concessions `a l’intelligibilit´e (c’est
le choix de C++ par exemple, choix que nous r´eprouvons
car nous pensons qu’un langage n’a pas `a ˆetre corrompu
par des consid´erations bassement mat´erielles) ; le langage
peut faire des concessions `a la performance (c’est le choix
des langages de script comme Ruby, choix honorable s’il en
est) ; le langage peut faire des concessions `a la souplesse
de la compilation. Cette troisi`eme voie consiste `a ajouter
des contraintes au processus de compilation comme par
exemple utiliser un compilateur global (c’est le choix de
SmartEiffel, un compilateur pour Eiffel).
Nous proposons une quatri`eme voie : utiliser un sch´ema
de compilation s´epar´ee mais qui int`egre des techniques
globales jusque l`a r´eserv´es au compilateurs globaux. L’id´ee
de base consiste `a repousser jusqu’au dernier moment
l’application de ces techniques, ce dernier moment ´etant `a
l’´edition de liens (le moment o`u les bouts de code compil´es
sont li´es ensemble, voir figure 5). Toutefois, il nous a fallu
r´esoudre un probl`eme de taille : lors de l’´edition de liens,
le code source du programme a d´ej`a ´et´e compil´e et il n’est
plus possible de revenir sur la traduction puisque le code
source n’est plus disponible `a ce moment l`a. La solution `a
ce probl`eme est d´etaill´ee dans [2].
B. Performances
Le compilateur prmc tient ses promesses d’efficacit´e
comme le prouvent les diff´erents tests que nous avons
effectu´es.
1
2
3
4
5
6
7
8
9
10
11
0 5 10 15 20 25 30 35
Temps (s)
Nombre de réponses potentielles par envoi de message
g++
smarteiffel
prmc
Fig. 6. Performances de trois compilateurs
En particulier, la figure 6 compare l’impl´ementation de
l’envoi de message vis-`a-vis de trois compilateurs : g++ (un
compilateur s´epar´e pour C++), SmartEiffel (le compilateur
global Eiffel) et prmc. En abscisse nous faisons varier la
complexit´e des envois de messages (le nombre de classes
diff´erentes des receveurs potentielles) et en ordonn´ee nous
notons le temps mesur´e. R´esultat, on remarque que prmc
est aussi efficace que le compilateur global (et mˆeme plus
efficace dans les envois de messages les plus complexes !)
V. Perspectives
Bien qu’utilisable, le langage PRM et son compilateur
prmc sont actuellement en d´eveloppement. Nous esp´erons
obtenir une premi`ere version stable et utilisable par tout
un chacun cet ´et´e.
Pour en savoir plus (ou pourquoi pas participer `a
l’´elaboration), vous pouvez consulter le site web :
http://www.lirmm.fr/privat/prm
R´
ef´
erences
[1] J. Privat et R. Ducournau. Raffinement de classes dans les
langages `a objets statiquement typ´es. M. Huchard, S. Ducasse,
et O. Nierstrasz, editors, Actes LMO’05 in L’Objet vol. 11, pages
17–32. Herm`es, 2005.
[2] J. Privat et R. Ducournau. Link-time static analysis for efficient
separate compilation of object-oriented languages. M. Ernst et
T. Jensen, editors, Program Analysis for Software Tools and
Engineering, pages 29–36, 2005.
1 / 4 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !