Alain Girault
Le projet de compilation et génie logiciel se déroule de novembre à
février. Le but est de réaliser entièrement un compilateur d'un
sous-ensemble de Pascal
(appelé Mini-Pascal
)
vers de l'assembleur pour une machine abstraite style Motorola
68000
. Le langage de programmation est Ada95
. Le
projet consiste en une mise en oeuvre des techniques de base de
compilation (analyse lexicale et syntaxique, vérifications
contextuelles, et enfin génération de code), avec également les
aspects de génie logiciel (spécification, conception détaillée,
campagne de test, documentation, recette). Les étudiants travaillent
par groupes de trois (en trinômes).
Depuis les travaux de Aho, Sethi et Ullman [1], il est d'usage de décomposer un compilateur en trois partie, chacune réalisant une passe de compilation. Notre compilateur suit fidèlement ce découpage. Ces trois passes sont :
Passe 1 : analyse lexicale, analyse syntaxique et construction de l'arbre abstrait.
Passe 2 : vérifications contextuelles et décoration de l'arbre abstrait.
Passe 3 : génération de code.
En novembre, 3 séances de TD de 3 heures chacune servent à
présenter le travail à effectuer et faire des rappels sur les 3 passes
du compilateur. Ces rappels sont abordés sur un plan général sans se
soucier des contraintes de mise en oeuvre. Puis en janvier il y a un
stage d'une semaine à temps plein (15 heures de TD). Le but est de
reprendre en détails la première passe (analyse lexicale et
syntaxique, et construction de l'arbre abstrait) et d'en commencer la
mise en oeuvre. Les outils lex
et yacc
sont
utilisés pour cette première phase. Pendant tout le reste du projet,
les étudiants travaillent de façon autonome, avec deux séances de
soutien par semaine (2 fois 20 minutes par trinôme).
Le document qui suit est une synthèse des bilans des étudiants. Il est destiné aussi bien aux futurs enseignants qu'aux futurs étudiants.
Voici tout d'abord une synthèse rapide des commentaires faits par les étudiants à la fin du projet.
La passe 1 est très bien traitée en TD. Cela permet de faire
démarrer les étudiants sur de bonnes bases. La passe 2 bénéficie elle
aussi de documents de spécifications détaillés, en particulier
l'excellente grammaire attribuée. Donc sur les 2 premières passes,
tout le monde semble d'accord pour dire que les spécifications sont
bonnes. Par contre la passe 3 n'est que survolée alors qu'elle regorge
de subtilités. Du coup certains trinômes trouvent le document
gencode.doc
insuffisant. Inversement d'autres trinômes
trouvent que la passe 3 est encore trop spécifiée. Ils préféreraient
avoir beaucoup plus de liberté afin de donner libre cours à leurs
talents de programmeurs.
La passe 1 se révèle être une excellente mise en route pour les
étudiants. Certains utilisent même les programmes fournis pour se
familiariser avec Ada95
. Pour tous, les fichiers de
spécification de la passe 1 servent d'exemple pour pour les passes 2
et 3.
Le document principal de spécification de la passe 2 est la
grammaire attribuée. Pour chaque règle de grammaire de
Mini-Pascal
, un ensemble d'attributs sont hérités et
synthétisés par le non terminal en partie gauche, ainsi que par les
non-terminaux et terminaux en partie droite. De plus, des règles
contextuelles donnent des contraintes sur le contenu de certains
attributs. Deux problèmes se posent qui doivent être bien expliqués
aux étudiants. Premièrement certaines contraintes de vérifications
contextuelles sont implicites, et les étudiants ont du mal à les
voir. Deuxièmement, les attributs portent sur les règles de grammaire
du langage alors qu'en fait les vérifications contextuelles doivent
être effectuées sur l'arbre abstrait du programme. Donc il faudrait
réécrire la grammaire attribuée pour la grammaire d'arbre. En dépit de
mon insistance sur ce point, aucun trinôme n'a jugé utile de faire ce
travail, mais d'après leur bilan, tous s'en sont mordu les
doigts.
Peu d'étudiants réalisent l'importance des tests. Dans un projet logiciel, les tests représentent 40% de l'effort total. On a beau l'expliquer en cours et le répéter tout au long du projet, les trinômes persistent à les délaisser, pour se rendre compte à la fin qu'effectivement il y ont passé beaucoup de temps.
Une campagne de test comporte obligatoirement plusieurs étapes : définition des objectifs de test, écriture des jeux de tests, passage des tests, exploitation des résultats, et enfin conclusion. Or justement, le temps passé à préparer la campagne de test est du temps gagné.
Les tests unitaires d'un paquetage nécessitent bien souvent
d'écrire un programme tout spécialement pour tester le paquetage en
question. C'est une pratique systématique en entreprise pour tout
programme informatique. Le bénéfice est d'éliminer le plus possible de
bugs avant la phase d'intégration, au cours de laquelle plusieurs
paquetages sont liés, ce qui complique bien évidemment les tests. Or
les étudiants ne font presque jamais de tests unitaires, excepté ceux
qui sont fournis (test_lex
,
test1_tables
...). Là aussi les étudiants ne réalisent pas
que les tests unitaires représentent du temps gagné en fin de compte
sur les tests d'intégration.
Il est indispensable de faire de la programmation défensive. Dans de nombreuses entreprises c'est obligatoire. Il faut accepter un léger sur-coût de programmation, mais en échange on gagne énormément en temps passé aux tests. Là encore les étudiants mettent du temps à accepter le bien fondé de cette technique.
Enfin voici quelques extraits choisis parmi les bilans des étudiants. Ils sont à méditer :
« Nous avons du faire preuve de clarté, tant dans la rédaction des commentaires que dans le codage de nos paquetages, afin d'en permettre la lisibilité en cas de débuguage. »
« Force est de constater que nous aurions du passer plus de temps sur l'analyse proprement dire du travail à accomplir. Un exemple en est le codage des règles lors de la passe 2 : il nous est arrivé de suivre aveuglément la construction de l'arbre issu de la grammaire attribuée, au lieu de se concentrer sur l'arbre abstrait que nous avions généré. Tout le code alors déjà écrit a du donc être repris. »
« Rien ne sert de partir bille en tête sur le développement s'il faut revenir sur le code produit. »
« De bonnes spécifications, claires et détaillées, permettent de coder plus rapidement et plus efficacement. »
« Nous avons appris quelque chose d'aussi important que le génie logiciel : le travail de groupe. »
« Il a fallu composer avec la fatigue et avec l'aptitude plus ou moins développée de certains à se lever tôt. »
« Nous avons essayé d'accorder une part suffisamment importante de notre temps aux différentes phases d'analyse, mains il s'est avéré que nous aurions certainement du y passer un peu plus de temps afin que tout soit bien spécifié. »
« Il fallait coder de manière propre, indentée et surtout commentée pour que toute autre personne puisse relire le code sans avoir à en chercher pendant des heures sa signification. »
« La phase d'analyse est sans doute la plus importante, une mauvaise analyse pouvant mener un projet dans une impasse ; ceci est d'autant plus vrai que la taille du projet est grande. »
« Ce mois de janvier apparaissait pour certains comme un mauvais moment à passer ! Mais à notre grande surprise il n'en fut rien. Le fait de travailler sur un projet unique et de s'y consacrer entièrement, mais aussi d'être libre de travailler comme nous le voulions et quand nous le voulions fut très appréciable. »
« L'excellente initiative de mettre en commun une grande quantité de fichiers de tests a été, à notre grande surprise, tuée dans l'oeuf par les enseignants. »
« Nous avions une méconnaissance de ce que l'on nous demandait en terme de rapport (dossier de conception ...) et plus particulièrement en ce qui concerne le mode opératoire utilisé pour effectuer les tests du programmes. Nous avions tellement l'habitude de tester les paquetages en écrivant toujours sur le même fichier qu'il nous a fallu réécrire après coup les batteries de test pour la passe 2. »
« La vérité est que nous n'avons en génie logiciel que des bases très faibles fondées sur les quelques expériences de programmation de première et deuxième année. »
« La partie finale d'une semaine et demie nous a forcé à adopter des horaires dont nous pensons qu'ils ont pour principal effet de faire chuter de façon dramatique l'efficacité et d'inhiber en grande partie ce qui, pourtant, permet de travailler de la meilleure façon possible : le bon coeur à l'ouvrage »
« Nous avons trouvé particulièrement pénible l'imparable précision des spécifications, ne laissant à notre initiative qu'un territoire misérablement restreint. On peut estimer légitime sur un projet d'un mois de faire autre chose que de mettre en forme des spécifications imposées. »
« Ce projet constitue une application concrète de l'enseignement reçu à l'Ensimag depuis deux ans. »
« Travailler au sein d'une équipe pendant 1 mois s'est révélé très enrichissant ; même si nous avons manqué d'organisation au début, la cohésion au sein du trinôme est devenue de plus en plus forte. »
« Nous n'avons pas toujours utilisé des structures de programme très carrées, mais quelle ne fut pas notre joie lorsqu'on a réussi à compiler le démineur... »
« Nous nous sommes rendu compte, à nos dépends, à quel point le travail préalable sur papier était vital pour une gestion globale du projet. »
« Des spécifications claires permettent un codage plus rapide et plus efficace. »
« Ce travail un peu trop mâché aurait pu être plus formateur d'un point de vue algorithmique. »
« Ce projet, par ses différents aspects, nous a donné une vision plus claire du type de travail auquel nous serons confronté en entreprise, mais aussi de la manière dont il faut l'appréhender (s'imprégner des contraintes, prendre des décisions, travailler en équipe...). »
[1] A.V. Aho, R. Sethi et J.D. Ullman, « Compilateurs, principes, techniques et outils », InterEditions.