Vous êtes sur la page 1sur 44

Analyseurs syntaxiques

Leur fonctionnement par l'exemple

Sbastien Jean Robert

Doeraene

Anne scolaire 2005-2006

Remerciements
Ce travail n'aurait jamais pu voir le jour sans l'aide de certaines personnes. Elles m'ont soit
aid et soutenu, soit relu, soit t une source d'informations importante.
Tout d'abord, je remercie monsieur Paul Goethals, qui a accept d'tre mon promoteur
pour ce travail. Ses conseils m'ont t trs utiles pour cerner le sujet tudier, ainsi que pour le
rendre accessible des non-dingues-de-programmation...
Ensuite, je voudrais remercier messieurs Dick Grune, Henri E. Bal, Ceriel J.H. Jacobs et
Koen G. Langendoen, pour leur livre Compilateurs [GBJL02]. Cet ouvrage a t ma rfrence
en matire de compilation tout au long de la prparation et de la rdaction de ce document.
Troisimement, je remercie monsieur Laurent Dardenne, membre de l'quipe de rdaction
de www.developpez.com, pour ses relectures attentives et ses conseils toujours aussi constructifs.
Enn, encore un grand merci messieurs Nguib Serhani et Pierre Caboche, galement
rdacteurs sur www.developpez.com, qui ont relu mon travail et en ont corrig les fautes d'orthographe et de formulation.

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Table des matires


Table des matires

I Introduction la compilation

I.1

Qu'est-ce qu'un compilateur ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

I.2

Langages source, cible et d'implmentation . . . . . . . . . . . . . . . . . . . . .

I.3

Les direntes parties d'un compilateur . . . . . . . . . . . . . . . . . . . . . . .

I.3.1

Partie avant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

I.3.2

Partie arrire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

I.3.3

Quels modules peuvent signaler des erreurs ? . . . . . . . . . . . . . . . .

Architectures des compilateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . .

I.4.1

Largeur d'un compilateur . . . . . . . . . . . . . . . . . . . . . . . . . . .

I.4.2

Quel module commande ? . . . . . . . . . . . . . . . . . . . . . . . . . . .

10

Grammaires et leurs notations . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10

I.5.1

Symboles grammaticaux . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10

I.5.2

Productions et choix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11

I.5.3

Proprits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

12

I.5.4

propos des diagrammes de Conway . . . . . . . . . . . . . . . . . . . .

13

I.4

I.5

II Introduction l'analyse syntaxique

14

II.1 Dterminisme de l'analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15

II.2 Descendant ou ascendant ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15

III Analyse descendante

17

III.1 Principe gnral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

III.2 L'algorithme dtaill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18

III.2.1 Analyse par descente rcursive . . . . . . . . . . . . . . . . . . . . . . . .

19

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

III.2.2 Analyse LL(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21

III.3 Pour aller plus loin... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

IV Analyse ascendante

31

IV.1 Principe gnral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31

IV.2 Vous cherchez plus d'informations ? . . . . . . . . . . . . . . . . . . . . . . . . . .

32

V Projet exemple

33

VI Conclusion

36

A Analyseur lexical utilis

37

B Rfrentiel des chiers sources

39

Glossaire

40

Bibliographie

41

Table des gures

42

Index

43

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Chapitre I
Introduction la compilation
Qu'est-ce que la compilation ? Voil une question que la plupart des personnes poseront en
entendant parler de cette notion. Non, ce n'est pas le fait de compiler plusieurs chansons sur un
CD ; du moins, ce n'est pas cette compilation-l que nous tudierons ici.
Qui sont ces personnes ? Ce sont celles qui n'ont jamais programm. En eet, la compilation
est un des fondements de la programmation.
De mme les dveloppeurs, pour la plupart d'entre eux, ne se sont jamais rellement pos la
question de savoir ce qu'taient les compilateurs, au sens technique du terme.
Nous allons donc voir, au travers de ce document, ce que sont rellement les compilateurs,
et comment ils fonctionnent. Nous nous attarderons plus particulirement sur une tape de leur
fonctionnement qui fait peur beaucoup de dbutants en la matire.

I.1 Qu'est-ce qu'un compilateur ?


Un compilateur est tout d'abord un programme. C'est un programme qui satisfait les quelques
proprits suivantes.
Premirement, un compilateur reoit un code source en entre, et produit du code objet ou code
excutable en sortie. Il indique galement les erreurs ventuelles survenues lors de la compilation.
La compilation en elle-mme est la transformation, ou conversion du code source en code
objet. Cela a une inuence beaucoup plus large que la programmation. Le principe initial de
la compilation n'est pas de produire un programme excutable partir de son source, c'est de
transformer un chier crit dans un format en un autre chier utilisant un autre format mais
ayant une smantique identique.
Voici quelques oprations courantes qui, contre toute apparence, sont eectivement lies la
compilation :
 transformer un document XML en un document d'un autre type (ex. : (X)HTML) au
moyen d'une feuille de style XSL ;
 transformer la chane de caractres d'une expression mathmatique en son rsultat ;
 transformer un texte crit dans une langue en ce texte traduit dans une autre langue.

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Cependant, pour faciliter la comprhension de ce tutoriel, nous nous limiterons au sens le


plus commun, savoir la transformation du texte source d'un programme en code excutable.
Le code source est un chier texte. Il est habituellement cod avec la norme ANSI, bien que
les compilateurs rcents commencent supporter les autres normes.
Le code excutable est un chier binaire, respectant le format des chiers excutables pour
une architecture et un OS donns. Pour un environnement Windows, il s'agit du format PE.
Pour de plus amples informations sur ce format, consultez le tutoriel d'Olivier Lance [LAN05].
Pour certains types de langages, que l'on appelle les langages semi-compils, le chier en
sortie n'est pas du code objet. Il s'agit alors de pseudo-code. C'est une version analyse mais
non fonctionnelle du code source. Cela a l'avantage de pouvoir tre excut sur plusieurs platesformes, tout en tant plus rapide qu'un langage interprt. C'est le cas, pour exemple, du langage
Java. Dans ce cas, le pseudo-code ainsi gnr sera lu et excut par une machine virtuelle .
En ce qui concerne les erreurs, il en existe traditionnellement de quatre types :

Les conseils : Ils donnent une information au programmeur pour probablement amliorer l'ef-

cacit de son programme, mais n'arrtent pas le processus de compilation ;


Les avertissements : Ils avertissent le programmeur d'une erreur probable lors de l'excution,
mais n'arrtent pas le processus de compilation ;
Les erreurs : Elles indiquent au programmeur une faute dans le code source, faute qui doit tre
corrige avant de pouvoir produire un code objet correct (mais la compilation continue) ;
Les erreurs fatales : Elles stoppent immdiatement la compilation, et empchent le compilateur de produire le code objet.

I.2 Langages source, cible et d'implmentation


Lors de l'tude d'un compilateur, on parle rgulirement de langage source, de langage cible,
et de langage d'implmentation.
Le langage source est le langage dans lequel est crit le code source. Il peut s'agir, comme
nous l'avons signal au dbut de ce document, aussi bien de XML ou d'une expression mathmatique que d'un langage de programmation. Dans nos exemples, nous parlerons essentiellement
du langage Pascal ; les mmes raisonnements peuvent tre appliqus n'importe quel type de
langage source.
Le langage cible est le langage dans lequel est crit le code objet (ou excutable). Nous nous
limiterons dans notre cas une reprsentation XML de la structure du code source.
Le langage d'implmentation est le langage de programmation avec lequel est cr le compilateur lui-mme. Ici, il s'agira de Delphi, version 2005, dition Architecte.

I.3 Les direntes parties d'un compilateur


Tout compilateur est compos de deux parties : la partie avant et la partie arrire.
La partie avant se charge en premier lieu d'analyser le texte source, suite linaire de caractres,
pour le transformer en une reprsentation en arbre. Ceci permet de clarier la structure du

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Fig.

1.1  Modules d'un compilateur

code, conformment aux spcications du langage source. Dans un second temps, elle rcrit le
comportement du programme dans un Langage Intermdiaire (abrg en LI), plus simple que le
langage source, et donc plus facile convertir ensuite en du code objet. Il en ressort du Code
Intermdiare, abrg en CI.
La partie arrire reoit le code intermdiaire gnr par la partie avant, et le dcline dans le
langage cible.
Chacune de ces deux parties est elle-mme compose de plusieurs modules. Nous allons voir
leurs rles respectifs dans les grandes lignes.
La gure 1.1 reprsente les connexions entre les dirents modules.
I.3.1

Partie avant

Comme nous l'avons vu plus haut, la partie avant reoit en entre la suite linaire des caractres du code source, et a pour responsabilit d'en extraire la structure, an de la rcrire dans
un langage plus simple, le langage intermdiaire.
Pour faire ceci, le code source passe au travers de cinq modules dirents.

I.3.1.1 Module de lecture du texte source


Ce module lit le chier source, au moyen des APIs du systme d'exploitation utilis pour la
compilation, et donne au module suivant la suite des caractres qui le composent.
En Delphi, on peut se servir simplement de la mthode LoadFromFile de la classe TStrings.

I.3.1.2 Module d'analyse lexicale


Ce deuxime module rassemble des suites de caractres, donnes par le module de lecture du
texte source, en une suite, tout autant linaire, de lexmes. Un lexme est une entit compose
de plusieurs caractres, qui a une signication dans le langage source. Il s'agit par exemple
d'identicateurs, d'oprateurs, ou de mots-clefs. Les lexmes peuvent tre spars par des espaces ;
et dans certains cas, ils doivent l'tre.
Observons l'instruction Pascal suivante :
if Entier > 0 then
ShowMessage ( ' Le nombre est positif ' );

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

On peut y trouver 10 lexmes, que l'on peut rpartir en cinq catgories :

Identicateurs : Entier et ShowMessage ;


Mots-clefs : if et then ;
Oprateurs : plus grand (>), parenthses () et point-virgule (;) ;
Nombres entiers : 0 ;
Chanes de caractres : 'Le nombre est positif'.
Il ne faut pas confondre les constantes de types nombre entier ou chane de caractres, comme

0 et 'Le nombre est positif', avec les variables comme Entier. Dans le cas des constantes,

c'est l'analyseur lexical de dterminer le type et la valeur, l'aide d'une classe de lexmes
dirente selon le type. Dans le cas des variables, c'est l'analyseur smantique de dcouvrir le
type, puisqu'elles sont toutes regroupes sous la classe de lexmes Identificateur.
Vous pourrez trouver une introduction l'analyse lexicale dans l'article sur les Lexers (autre
nom des analyseurs lexicaux) d'Olivier Lance [LAN04].
Bien que nous n'tudierons pas l'analyse lexicale, nous aurons besoin d'un analyseur, dans
la mesure o nous travaillerons sur des lexmes dans l'analyse syntaxique. Vous trouverez une
brve explication de l'analyseur lexical utilis dans l'annexe A.

I.3.1.3 Module d'analyse syntaxique


"Le module d'analyse syntaxique restructure le ot de lexmes, donns de faon linaire par
le module prcdent, en un arbre abstrait. Chaque feuille de l'arbre correspond un lexme..."
Le module d'analyse syntaxique restructure le ot de lexmes, donns de faon linaire par
le module prcdent, en un arbre abstrait. Chaque lexme est plac sur une feuille de l'arbre. Il
fournit cet arbre abstrait non dcor au module d'analyse smantique.

I.3.1.4 Module d'analyse smantique


L'analyse smantique collecte des informations dans l'arbre abstrait non dcor pour le dcorer
des rsultats obtenus. Elle forme ainsi l'arbre abstrait dcor, abrg en arbre abstrait.
Notre module d'analyse smantique ne fera rien en ralit. Puisque tout ce que nous voulons
dans cette tude de l'analyse syntaxique, c'est rcuprer l'arbre abstrait non dcor.

I.3.1.5 Module de gnration du code intermdiaire


Ce dernier module de la partie avant produit un code intermdiaire partir de l'arbre abstrait
dcor. C'est une criture de l'arbre abstrait que pourra comprendre la partie arrire.
Puisque nous ferons oce nous-mmes de partie arrire, an de vrier si l'analyseur syntaxique fait bien son travail, notre module de gnration du code intermdiaire nous fournira une
criture XML de l'arbre abstrait1 .
1 Note : dans un vrai compilateur, ce serait une bien mauvaise ide, tant donn que la reprsentation XML
devrait tre nouveau analyse !

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

I.3.2

Partie arrire

La partie arrire est responsable de la transformation du code intermdiaire, en principe


identique quelle que soit la plate-forme d'exploitation, en du code objet excutable par un systme
en particulier, par un systme en particulier tel que Windows ou Linux.
Les informations ci-aprs sont prsentes uniquement titre indicatif, puisque nous ne produirons pas du tout de partie arrire. Nous rcuprerons directement le code intermdiaire crit
en XML pour visualiser l'arbre abstrait.

I.3.2.1 Module d'optimisation du code intermdiaire


Ce module eectue quelques optimisations directement sur le code intermdiaire. Une optimisation couramment implmente ici est le pliage des constantes. C'est la compression d'une
expression, dont on connat la valeur de toutes les oprandes la compilation, en son rsultat.

I.3.2.2 Module de gnration de code


La gnration de code rcrit le code intermdiaire en une liste linaire d'instructions du
systme d'exploitation, de faon plus ou moins symbolique.

I.3.2.3 Module d'optimisation du code objet


Ce troisime module de la partie arrire optimise nouveau le code symbolique que lui
donne la gnration de code. Certaines de ces optimisations peuvent tre places dans le module
d'optimisation du CI, et vice versa. Cependant, certaines ont plus leur place dans l'un ou l'autre
module.

I.3.2.4 Module de gnration de langage machine


Le module de gnration de langage machine convertit la liste des instructions symboliques
en leur reprsention binaire supporte par le processeur de la machine cible. Il gnre aussi des
tables d'adresses, de constantes et de relocalisation.

I.3.2.5 Module de production du code excutable


Ce dernier module assemble les suites de bits des instructions et les direntes tables, ainsi que
d'ventuels prologues et pilogues, en un seul chier qui respecte le format des chiers excutables
du systme d'exploitation.
I.3.3

Quels modules peuvent signaler des erreurs ?

La question peut se poser : quels sont les modules susceptibles de signaler des erreurs ?

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Techniquement, n'importe quel module peut provoquer des erreurs  comme n'importe quel
programme  mais seuls les trois modules que l'on peut qualier d'analyse indiquent des erreurs
relatives la compilation :
 l'analyseur lexical signale des erreurs lexicales, c'est--dire des caractres non autoriss,
comme la prsence (hors-chane) d'un $ dans un code source Pascal ;
 l'analyseur syntaxique signale des erreurs syntaxiques, c'est--dire une malformation dans
la structure du code source, par exemple une instruction MaVariable := ; dans un code
source Pascal ;
 l'analyseur smantique signale des erreurs smantiques, comme des incompatibilits de
types de variables (aectation d'un integer un string en dans un code source Pascal,
par exemple).
Si un autre module gnre une erreur, il s'agit probablement d'un bogue du compilateur, ou
d'un quelconque problme systme comme des erreurs d'entre/sortie (accs aux chiers) ou un
dpassement de la mmoire disponible.

I.4 Architectures des compilateurs


Il existe des compilateurs avec direntes architectures. Malheureusement, il n'existe pas de
terminologie exacte dnie pour tel ou tel type d'architecture.
Cependant, les grandes dirences d'architectures peuvent se placer en deux grandes catgories : la largeur du compilateur, et le choix du module qui commande.
Nous allons voir ces deux choix.
I.4.1

Largeur d'un compilateur

Une des deux grandes questions est quelles sont les donnes  quelle est la granularit des
donnes pour tre exact  qui transitent entre les dirents modules.
Il y a deux choix raisonnables possibles : soit la plus petite quantit signicative de donnes
d'un module au suivant (par exemple, un lexme de l'analyse lexicale l'analyse syntaxique) ;
soit le programme dans son intgralit. En l'absence de terminologie pour ces deux types de
largeur, nous parlerons respectivement de compilateurs troits et larges.
Jusqu'en 1980, l'utilisation de compilateurs larges tait impensable, cause des besoins en
mmoire d'un tel type de compilateur. Seuls des compilateurs troits taient alors construits.
Ainsi, de nombreux outils ont t dvelopps pour faciliter ce type d'architecture. C'est pourquoi
les compilateurs troits sont encore fortement utiliss.
En revanche, les compilateurs larges sont plus intressants d'un point de vue pdagogique,
puisqu'ils sont en vrit construits de telle sorte que le texte du programme passe successivement
dans dirents modules, chacun lui appliquant certaines transformations. En outre, ils sont aussi
plus simples concevoir, puisqu'ils vitent de se poser des questions telles que le choix du module
qui commande, comme nous le verrons dans la section suivante.
Bien que ces deux architectures paraissent diamtralement opposes, il n'est pas impossible
de mlanger les deux types. Par exemple, un compilateur pourrait rassembler des modules conscutifs en un seul, qui aurait une entre et une sortie large, mais qui serait troit l'intrieur.

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

En pratique, avec l'augmentation permanente de la puissance et de la mmoire des machines,


les compilateurs larges se dveloppent. Ceci particulirement avec des paradigmes non impratifs,
comme les paradigmes fonctionnel et logique.
Cependant, nous utiliserons le modle troit dans nos deux exemples, car nous n'aurons
pas besoin des apports supplmentaires d'une architecture large, dans la mesure o nous nous
arrterons l'analyse syntaxique.
Pour terminer, sachez que, mme dans les compilateurs troits, le premier module  celui de
lecture du texte source  est gnralement large. En eet, cela permet d'obtenir des informations
intressantes pour la production de messages d'erreurs constructifs, tels que la position des
lexmes dans le texte source.
I.4.2

Quel module commande ?

La seconde grande question d'architecture pose le problme du choix du module qui doit
commander les autres.
Comme nous l'avons dit plus haut, cette question ne se pose pas dans le cas des compilateurs
larges. En eet, ceux-ci traitent l'information module par module.
En revanche, dans un compilateur troit, il est essentiel de savoir quel est le module qui tourne
en permanence et qui  appelle  les autres.
Cette question tant complexe, et ne faisant pas partie du sujet de cet article, je vous renvoie
au livre Compilateurs [GBJL02, section 1.4.2] pour plus d'informations ce propos.
Pour notre part, c'est le module d'analyse syntaxique qui commandera. C'est en eet celui
que nous tudions et il sera plus simple de l'tudier s'il possde en permanence le contrle.

I.5 Grammaires et leurs notations


Les grammaires sont un lment important dans la dnition d'un langage de programmation.
Non seulement, elle permettent de dnir de faon formelle la syntaxe valide d'un code source,
mais elles permettent aussi de faire gnrer automatiquement des analyseurs syntaxiques pour
celles-ci.
D'autre part, l'analyse syntaxique tant troitement lie (pour ne pas dire fusionne) aux
grammaires, l'utilisation en est largement faite dans ce tutoriel. Il est donc important d'en comprendre la signication et la notation.
Nous allons voir ici la notation BNF (Backus Normal Form, en franais forme normale
de Backus ; aussi appele Backus-Naur Form, ou forme de Backus-Naur), qui est la plus
rpandue pour les grammaires.
I.5.1

Symboles grammaticaux

L'lment de base de la grammaire est le symbole grammatical. Il en existe de deux types :


les terminaux et les non-terminaux.

10

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

D'un point de vue de la thorie des arbres, un terminal est une feuille, et un non-terminal est
un nud intrieur, y compris la racine de l'arbre d'analyse.
D'un point de vue de la structure d'un langage, un terminal est un lexme, et un non-terminal
est un groupe cohrent smantiquement de symboles grammaticaux.
Des exemples de terminaux que nous pouvons trouver dans le langage Pascal sont des identicateurs, des mots-clefs, des oprateurs, etc. Des non-terminaux seraient les instructions, les
blocs begin...end, les dclarations de classes.
Un non-terminal peut tre compos de lui-mme galement ! Et c'est en eet trs souvent le
cas.
Un terminal est habituellement not au moyen de la lettre t, avec ventuellement un indice
indiquant sa position dans l'entre, ainsi qu'au moyen des lettres x, y et z . Tandis qu'un nonterminal est not au moyen d'une lettre majuscule, essentiellement N , A, B , et C . Le terminal
symbolisant la n du chier source est reprsent par le symbole a.
Chaque grammaire dnit un symbole de dpart , qui est un non-terminal. Il correspond au
non-terminal qui se trouve au-dessus de tous les autres, et partir duquel on peut produire tout
le texte du programme, en entier. Ce symbole de dpart tant un non-terminal, il est not au
moyen d'une lettre majuscule ; en gnral, on utilise la lettre S , pour Start.
En Pascal, le symbole de dpart pourrait tre le non-terminal Unite suivant :
Unite

'unit' Identificateur ';' 'interface' PartieInterface


'implementation' PartieImplementation 'end' '.' a

Souvent, on a besoin de reprsenter une suite de symboles grammaticaux. On utilise pour


cela les lettres grecques minuscules, en particulier (alpha), (bta) et (gamma). Une chane
de symboles grammaticaux vide est note E (epsilon).
Voici un exemple de suite de symboles grammaticaux que l'on peut trouver dans un source
Pascal :
, UnNombre * ( 2 +

Comme vous pouvez le remarquer, une suite de symboles grammaticaux ne dbute et ne


s'arrte pas forcment un endroit logique du point de vue de la smantique. La chane vue plus
haut pourrait par exemple faire partie de l'instruction complte suivante :
UneFonction ( False , UnNombre * (2 + AutreNombre ));

I.5.2

Productions et choix

Une production est la recette de fabrication d'un non-terminal. Elle indique les dirents
symboles grammaticaux qui peuvent former un non-terminal. On note une production de cette
faon :
N

11

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Cela indique que le non-terminal N peut tre form de la suite de symboles grammaticaux

Dans les productions, on note les terminaux xes (comme les mots-clefs ou les oprateurs)
tels quels, entours de guillemets simples. Et on note les terminaux variables (comme les identicateurs et les nombres) par leur nom de classe.
Par exemple, une production possible en Pascal pour l'instruction d'aection serait :
Affectation

Identificateur ':=' Expression

Un non-terminal a souvent plusieurs faons d'tre implment. Chacune des faons d'implmenter un non-terminal N est appele un choix de N . Chaque choix est une suite de symboles
grammaticaux et est donc not au moyen d'une lettre grecque minuscule.
Pour crire l'ensemble des productions de N en une seule fois, on utilise la notation suivante :
N

|||...

O , , sont les dirents choix de N , spars d'un caractre pipe (|).


Voici par exemple un ensemble de productions de l'instruction if...then...else :
IfThenElse
Else

'if' ExpressionBool 'then' Instruction Else


'else' Instruction | E

Certains non-terminaux peuvent aussi avoir un choix vide. Dans ce cas, on n'oubliera pas
d'ajouter E comme dernier choix de N .
N

|...|E

Ainsi, en Pascal par exemple, tant donn qu'une instruction peut tre vide, on crira :
Instruction
I.5.3

Affectation | IfThenElse | ... | E

Proprits

Les grammaires sont dotes de proprits. Ces proprits sont trs importantes pour leur
tude. Vous verrez que ce tutoriel fait souvent appel aux proprits des grammaires.
Un non-terminal N est rcursif gauche si, partir du syntagme N (c'est--dire un sousarbre de drivation qui correspond au non-terminal N ), on peut produire un autre syntagme qui
commence par N . Voici une forme de rcursivit gauche (directe) :
N

N |

12

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Il existe aussi la rcursivit indirecte, lorsqu'un syntagme A produit un syntagme commenant


par B , qui produit lui-mme un syntagme commenant par A. On peut envisager une rcursivit
plus longue encore.
L'exemple type de rcursion directe est le non-terminal reprsentant une somme de nombres :
Somme

Somme '+' Nombre | Nombre

Toute grammaire qui contient au moins un non-terminal rcursif gauche est elle-mme dite
rcursive gauche. La rcursivit droite existe aussi mais a moins d'importance.
Un non-terminal N est nulliable si, partir du syntagme N , on peut produire un syntagme
vide (E ).
Le contenu de la partie interface d'une unit Pascal en est un bon exemple :
PartieInterface
ClauseUses
ClauseTypes
ClauseConsts
DefProcs

ClauseUses ClauseTypes ClauseConsts DefProcs


'uses' Identificateur Identificateurs ';' | E
'type' DefType DefTypes | E
'const' DefConst DefConsts | E
DefProc DefProcs | E

tant donn que chaque composante de PartieInterface peut tre une chane de symboles grammaticaux vides (E ), la PartieInterface peut elle-mme tre une chane de symboles
grammaticaux vides, et est donc nulliable.
Un non-terminal N est inutile s'il ne peut driver aucune chane de terminaux. Cela peut
arriver si, de quelque faon qu'on drive le syntagme N , on retombe invitablement sur un
syntagme contenant N (de faon directe ou indirecte). En voici un exemple :

Une grammaire est dite ambigu lorsque deux arbres de drivation dirents produisent la
mme suite de lexmes. Ce type de grammaires doit tre absolument cart, car il empche toute
russite de cration d'un analyseur syntaxique.
I.5.4

propos des diagrammes de

Conway

Habituellement, dans la documentation des langages, ce n'est pas la notation BNF qui est
utilise. Elle n'est pas assez lisible pour les humains que nous sommes.
On utilise dans ce type de documents les diagrammes de Conway, qui sont une reprsentation
graphique des grammaires, plutt que textuelle.
Une excellente source d'informations propos des diagrammes de Conway est un document
sur le lexique et la syntaxe de Michel Beaudoin-Lafon [BELA98, section 3].

13

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Chapitre II
Introduction l'analyse syntaxique
Nous en arrivons au sujet principal de ce tutoriel, savoir l'analyse syntaxique proprement
dite. Ainsi que nous l'avons vu, il s'agit d'un des modules de la partie avant du compilateur.
Son rle est de dterminer la structure en arbre, que cache la suite linaire de lexmes fournie
par l'analyseur lexical, et ceci en correspondance avec la grammaire du langage compiler.
J'ai choisi d'tudier ce module car j'estime que c'est celui qui me semble le plus dlicat
implmenter pour un nophyte de la compilation. Sans un minimum de connaissances thoriques,
le risque est d'tre rapidement bloqu par la manire d'arranger les lexmes en arbre.
Mais pourquoi un arbre ? Tout simplement parce que c'est de cette faon qu'est dcrite
un langage. Les terminaux des grammaires forment les feuilles de l'arbre, tandis que les nonterminaux en forment les nuds intrieurs, le nud racine tant le symbole de dpart de la
grammaire.
Il y a deux types de mthodes pour l'analyse syntaxique : l'analyse dterministe, de gauche
droite, et descendante et l'analyse dterministe, de gauche droite, et ascendante.
Le terme de gauche droite signie que l'analyseur avance squentiellement, dans l'ordre de
gauche droite du texte du programme, ou plus exactement des lexmes.
Le dterminisme signie qu'aucune recherche n'est ncessaire. Le traitement de chaque lexme
amne l'analyseur un pas plus loin vers la construction de l'arbre syntaxique.
Les termes descendant et ascendant seront expliqus plus loin.
L'arbre syntaxique qui rsulte du module d'analyse syntaxique reprsente la structure du
code source compiler, et satisfait les points suivant :
 Les nuds feuilles sont tiquets par des terminaux, et les nuds internes par des nonterminaux ;
 Le nud racine est tiquet par le symbole de dpart de la grammaire ;
 Les ls d'un nud interne tiquet N correspondent aux membres d'un des choix de N ,
dans le mme ordre que dans le choix ;
 Les terminaux tiquetant les nuds feuilles correspondent la suite de lexmes, dans le
mme ordre que dans l'entre.
Vous trouverez une reprsentation d'un arbre abstrait sur la gure 2.1.

14

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Fig.

2.1  Arbre abstrait ou arbre syntaxique

II.1 Dterminisme de l'analyse


Premirement, l'importance du dterminisme dans l'analyse syntaxique est marque par le
fait que le temps d'excution d'une analyse dterministe est une fonction linaire de la taille
du texte du programme. Des techniques non dterministes existent, mais ne sont pas (encore)
utilises, car elles sont trop lentes. Nous n'en parlerons donc pas.
Cependant, une analyse dterministe n'est pas capable de traiter toutes les grammaires. La
plupart des grammaires trouves dans des manuels de langages ne conduisent pas directement
une mthode dterministe. Heureusement, il existe des techniques qui permettent de rendre
adapte une mthode dterministe une grammaire qui ne l'est pas. Nous supposerons donc
ici que toutes les grammaires utilises peuvent tre analyses de faon dterministe. Pour plus
de renseignements sur les techniques de transformations, reportez-vous au livre Compilateurs
[GBJL02, sections 2.2.4.3 et 2.2.5.7].
L'autre avantage du dterminisme est qu'une grammaire qui peut tre analyse de faon
dterministe est non ambigu. C'est une proprit trs importante pour un langage de programmation. Si un langage ne l'tait pas, il pourrait exister des codes sources qui peuvent avoir deux
signications direntes. Permettre une analyse dterministe et tre non ambigu ne sont pas
tout fait les mmes notions. La premire implique la seconde mais la rciproque n'est pas vraie.
Toutefois, demander le dterminisme est en pratique le meilleur test de non ambigut que nous
possdons.

II.2 Descendant ou ascendant ?


L'on fait une distinction importante entre deux catgories d'analyseurs, selon l'ordre dans
lequel ils construisent l'arbre d'analyse.
Un analyseur descendant construit l'arbre d'analyse en prordre (ou prxe), alors qu'un
analyseur ascendant le fait en postordre (ou postxe, voire suxe). On trouvera sur le Web de
nombreuses dnitions de ces termes, par exemple, le tutoriel sur les arbres de Romuald Perrot
[PER06, chapitre VI].
La mthode en prordre commence par construire le nud racine, puis  rentre l'intrieur 
pour construire ses ls ; la mthode en postordre assemble les premiers lexmes rencontrs en

15

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

petites portions de l'arbre, puis remonte pour construire le reste partir des portions dj
construites.
Nous verrons le principe gnral de ces deux types d'analyseurs. En revanche, nous n'tudierons en dtail que l'analyse descendante dans le cadre de ce travail de n d'tudes, et laisserons
donc de ct les techniques de l'analyse ascendante. Ce choix a t fait essentiellement cause
des limitations imposes sur la longueur des travaux.
Ainsi, pour la mthode descendante, nous tudierons ensuite en dtail le fonctionnement de
son algorithme, au moyen d'un exemple de grammaire.

16

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Chapitre III
Analyse descendante
Nous commenons par l'analyse descendante, et ce pour la bonne et simple raison que c'est
la premire avoir t invente... En eet, c'est la seule des deux mthodes qu'il est possible
d'appliquer la main, en programmant son analyseur de la premire la dernire ligne de code.
Rappelons au passage que c'est la seule mthode que nous tudierons en dtail dans ce travail.

III.1 Principe gnral


Dans un analyseur descendant, on connat le nud courant et le premier lexme en entre
(voire plusieurs des premiers).
Au dpart le nud courant est le symbole de dpart de la grammaire, not S , et le lexme
en entre est le tout premier lexme du source, t1 .
Au moyen de ces deux informations, on dtermine le bon choix de S , mais on n'avance
pas dans l'entre. L'analyseur se retrouve alors avec le non-terminal N du dbut du choix
dtermin, et le lexme t1 en entre.
On rpte le processus jusqu' ce que le premier symbole grammatical du choix dtermin
soit un terminal. Ce terminal reconnat le lexme t1 en entre. Ce n'est pas un hasard : on a
dtermin les choix , 0 , etc. des non-terminaux S , N , etc. de sorte que cela arrive. Nous verrons
comment on peut le faire.
On peut donc avancer dans l'entre et on se retrouve avec la partie gauche de l'arbre construite
et en entre le deuxime lexme t2 .
En continuant le processus, la construction de l'arbre est poursuivie en slectionnant les bons
choix de sorte que les lexmes ti soient tous reconnus (sauf s'il y a erreur syntaxique bien sr).
Vous pouvez voir sur la gure 3.1 une situation dans laquelle l'analyseur a dj construit les
nuds des non-terminaux S , A et B , a avanc sur le lexme t1 , puis a construit le nud du
non-terminal N , et a nalement avanc sur les lexmes t2 et t3 . Il doit maintenant continuer le
remplissage du nud du non-terminal N , avec en entre le lexme t4 .
Dans la gure suivante, les carrs symbolisent les noeuds de l'arbre. Les noirs sont dj
construits, tandis que les blancs ne le sont pas encore , bien que leur existence soit connue.

17

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Fig.

3.1  Exemple de situation d'un analyseur descendant

Dans cette gure, les carrs symbolisent les nuds de l'arbre. Les noirs sont dj construits,
tandis que les blancs ne le sont pas encore, bien que leur existence soit connue. D'autre part, les
cercles symbolisent les lexmes, les noirs tant ceux sur lesquels l'analyseur a dj avanc, et les
blancs tant ceux qui restent dans l'entre.

III.2 L'algorithme dtaill


prsent que nous avons vu comment fonctionnait l'algorithme dans sa plus grande gnralit, nous allons pouvoir entrer en profondeur dans ses techniques les plus obscures...
Il existe deux grands types d'analyseurs descendants, les analyseurs non-prdictifs et les
analyseurs prdictifs dits LL(1) . LL signie que l'on travaille de gauche (Left ) droite, avec une
drivation gauche (Leftmost ). Le (1) indique que nous travaillons avec un lexme d'avance. C'est
une appellation un peu thorique et peu explicite... Retenez simplement LL(1).
Les analyseurs LL(1) sont encore diviss en deux sous-groupes : les analyseurs prdictifs par
descente rcursive et les analyseurs prdictifs non-rcursifs .
En revanche, les analyseurs non-prdictifs sont tous par descente rcursive .
Ces analyseurs  non-prdictifs et par descente rcursive  sont les analyseurs syntaxiques
que l'on peut crire la main. Nous commencerons par tudier ce type d'analyseur : il est simple
comprendre et mettre en uvre.
Ensuite, nous tudierons les analyseurs prdictifs par descente rcursive, qui sont toujours
crits la main, mais qui ncessitent d'avoir des informations qui doivent tre calcules par
programme.
Enn, nous nous approcherons un peu plus de la modernit avec les techniques avances
d'analyse syntaxique que sont celles des analyseurs prdictifs non-rcursifs engendrs de A Z
par des gnrateurs.
Comme nous l'avons signal plus haut, dans la petite introduction au principe de l'analyse
descendante, on connat le nud courant (et donc le non-terminal associ) et un lexme dans
l'entre. partir de ces deux informations, nous allons devoir dterminer quel choix de ce
nud tiquet du non-terminal N (par la suite, pour la simplicit, nous crirons le nud N ,
bien que ce soit un abus de langage) slectionner pour qu'une drivation du syntagme puisse

18

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Entree
Expression
Terme
ExpressionParenthesee
ResteExpression
Fig.

Expression a
Terme ResteExpression
Nombre | ExpressionParenthesee
'(' Expression ')'
'+' Expression | E

3.2  Exemple de grammaire pour l'analyse descendante

commencer par le terminal t en entre.


Les trois types d'analyse descendante que nous allons tudier dirent justement essentiellement par la faon de dterminer quel est le bon choix.
La descente rcursive est lgrement nave : elle teste chaque choix de N jusqu' ce que
l'un d'eux fonctionne. Les mthodes LL(1) sont plus intelligentes : elles prdisent le bon choix
directement. La mthode non-rcursive est encore plus ecace car elle utilise des tables et non
des tests.
III.2.1

Analyse par descente rcursive

Nous venons de dire que la descente rcursive tait nave. Alors... Soyons nafs pour dcouvrir
comment elle fonctionne.
La manire la plus simpliste de trouver quel est le bon choix du nud N slectionner, est
tout simplement de les tester l'un aprs l'autre, et de prendre le premier qui fonctionne.
Pour cela, l'analyseur est compos d'une fonction pour chaque non-terminal de la grammaire.
Pour rendre tout cela moins abstrait et ainsi amliorer la comprhension, nous allons utiliser une
grammaire exemple relativement simple, que vous pouvez voir sur la gure 3.21 .
Ainsi, notre analyseur possdera cinq fonctions essentielles, une pour chacun des cinq nonterminaux de cette grammaire. Une fonction supplmentaire est ajoute pour analyser un terminal (dont la classe est passe en paramtre). Chaque fonction renvoie une valeur boolenne
indiquant si on a pu driver le syntagme N jusqu' obtenir le lexme t en entre.
Pour arriver faire cela, elle teste si le premier choix du non-terminal N peut commencer
par t. Si le premier symbole grammatical de est un terminal, alors c'est trivial : le choix est
bon si ce terminal est t. Si c'est un non-terminal, alors est le bon choix si, en descendant 2 la
fonction correspondante ce non-terminal, on reoit une valeur de retour positive.
Si le choix n'tait pas le bon, alors on teste le deuxime choix , et ainsi de suite jusqu'
ce que tous les choix aient t puiss. Dans ce cas, la fonction renvoie False, pour indiquer la
fonction appelante que le choix du non-terminal N n'tait pas bon.
Si on a trouv un choix correct, alors on admet qu'il est compltement correct, et ce pour
assurer le dterminisme tant recherch. Cela signie qu'on exige que la suite de ce choix soit
prsente. Si ce n'est pas le cas, il y a erreur syntaxique.
Le chier source DescenteRecursive.pas (voir annexe B) montre le code d'un analyseur
pour la grammaire de la gure 3.2. Pour analyser une chane d'entre, il faut la passer en pa1 Cet exemple
2 D'o le nom

a t repris partir du livre Compilateurs [GBJL02, gure 2.57]


d'analyse par descente rcursive

19

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

t
t
t
t
t
t
t
t
t
t
t
t
t

=
=
=
=
=
=
=
=
=
=
=
=
=

AnalyseSyntaxique('(i + i) + i + (i)')
, Entree
, Expression
, Terme
, Lexeme(lexNombre) renvoie False
, Terme
, ExpressionParenthesee
, Lexeme('(') renvoie True
, ExpressionParenthesee
, Expression
, Terme
, Lexeme(lexNombre) renvoie
, Terme renvoie True

(
(
(
(
(
(
(
1
1
1
1
+
+

True

etc.

Fig.

3.3  Dbut du graphe de contrle du ux de l'analyse de (1 + 2) + 3 + (4) a

ramtre la fonction AnalyseSyntaxique, et on reoit en valeur de retour un objet de type


TNoeudEntree qui est la racine de l'arbre syntaxique analys. Le mme fonctionnement sera
utilis pour tous les types d'analyseurs syntaxiques que nous donnerons en exemple.
Nous allons maintenant examiner comment cet analyseur peut analyser une entre. Voici
l'exemple d'entre (valide) que nous allons utiliser :
(1 + 2) + 3 + (4) a

Je vous conseille fortement de suivre le droulement de l'explication avec le source de l'unit

DescenteRecursive.pas (voir annexe B) ct de vous, et ventuellement de vous reprsenter

un graphe de contrle du ux entre les direntes fonctions. Vous trouverez la partie explicite
de ce graphe la gure 3.3.
Un appel est donc fait de l'extrieur la fonction AnalyseSyntaxique, comme ceci :
ArbreSyntaxique := AnalyseSyntaxique ( ' (1 + 2) + 3 + (4) ' );

Le code de la routine AnalyseSyntaxique commence par faire dmarrer l'analyseur lexical


avec cette entre3 . Ensuite, il exige de reconnatre le non-terminal Entree, qui est le symbole de
dpart de la grammaire.
Le programme rentre dans la fonction Entree, qui elle-mme, appelle immdiatement la
fonction Expression, puis Terme, qui nalement appelle Lexeme.
Cette dernire ne reconnat pas le premier lexme ( comme tant un nombre. Elle renvoie
donc False Terme, qui teste alors ExpressionParenthesee.
Cette fois, la fonction Lexeme, appele par ExpressionParenthesee, reconnat correctement le lexme (. L'analyseur syntaxique construit alors le nud correspondant ce lexme puis
demande l'analyseur lexical de passer au lexme suivant.
De retour dans la fonction Terme, avec un code de retour positif, on entre dans le bloc

if...then.
3 Pour

rappel, des informations sur l'analyseur lexical utilis pourront tre trouves en annexe A.

20

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

On commence alors reconnatre un non-terminal Expression. la dirence que, cette


fois-ci, on l'exige, ce qui signie que si l'appel la fonction Expression renvoie False, c'est qu'il
y a erreur syntaxique.
De la mme manire que ExpressionParenthesee avait reconnu le lexme identicateur,
la fonction courante Expression reconnat un nouveau lexme nombre, au travers d'un nonterminal Terme.
L'analyse se poursuit ainsi jusqu' ce que le ux soit rendu la fonction Entree, avec pour
lexme t en entre le lexme a. Elle va alors reconnatre compltement le non-terminal Entree,
et comme c'est le symbole de dpart de la grammaire, l'analyse est termine.

III.2.1.1 Limitations de l'analyse par descente rcursive


Nous avons pu voir que la construction d'un analyseur par descente rcursive est relativement
simple. Mais tout n'est pas si rose.
En eet, il existe de nombreuses grammaires qui posent problme avec les analyseurs par
descente rcursive.
D'abord, vous aurez remarqu dans le graphe de contrle du ux de la gure 3.3 qu'il faut
plusieurs appels avant d'avancer sur un lexme. Cela reprsente une perte de temps qui peut tre
drangeante. De plus, les tests qui renvoient la valeur False sont en quelque sorte un retour en
arrire sur les lexmes, ce qui signie que l'analyse n'est pas rellement dterministe.
Ensuite, dans la majorit des cas de grammaires usuelles, il est impossible de crer un analyseur correct. Par exemple, toute grammaire rcursive gauche produit inluctablement un
bouclage sans n sur la procdure de traitement du non-terminal responsable.
Finalement, le traitement des erreurs est quasiment nul. Tout ce que nous sommes en mesure
de faire, c'est de signaler qu'on s'attendait voir un non-terminal particulier et qu'on a trouv
un lexme incorrect, avant de devoir purement et simplement abondonner la compilation. Ce
n'est rellement pas pratique pour l'utilisateur.
III.2.2

Analyse LL(1)

En examinant le comportement de l'analyseur par descente rcursive vu prcdemment, le


lecteur attentif aura remarqu que pour chaque fonction, le rsultat ne dpend que d'un seul
facteur : le lexme en entre.
En eet, pour une fonction donne et un lexme donn, c'est toujours la mme suite d'appels
rcursifs qui est excute. Par exemple, l'appel de la fonction Expression avec un lexme Nombre
en entre renverra toujours True, mais avec le lexme + elle renverra toujours False.
On peut exploiter cela par ce que l'on appelle le prcalcul . Il s'agit de dterminer avant la
compilation le rsultat de la fonction pour chaque paire non-terminal/lexme en entre. Plus
exactement, on le fait lors de la production du code du compilateur.
Une fois que l'on connat ces rsultats, on peut les exploiter dans les fonctions de nonterminaux, pour qu'elles ne doivent plus essayer chaque choix mais prdire immdiatement le
bon. Ce serait videmment un gain de temps considrable, et surtout cela rendrait rellement
dterministe notre analyseur.

21

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Le problme, c'est que pour obtenir ces rsultats, il faut eectuer des quantits astronomiques
de calculs. Bien entendu ce n'est pas le cas pour notre petite grammaire exemple, mais la quantit
de calculs eectuer est fonction exponentielle de la complexit de la grammaire !
Y a-t-il alors une solution ? Oui. Il s'agit de faire calculer ces rsultats par un autre programme,
que l'on appelle communment gnrateur de compilateur.
Voyons maintenant quelles sont exactement les informations dont nous avons besoin, avant
de nous demander comment les obtenir.

III.2.2.1 Informations requises pour une analyse LL(1)


Nous devons donc savoir comment dterminer quel choix devra tre choisi plutt qu'un autre,
sur seule base du premier terminal en entre.
Comment le savoir ? Tout simplement en connaissant l'ensemble des terminaux par lesquels
peut commencer un choix donn. En eet, en connaissant cela, il nous sut de choisir ce choix si le
lexme en entre appartient cet ensemble. Nous appellerons dsormais cet ensemble l'ensemble
des premiers d'un choix , et le noterons prem().
Cela parat susant... Mais ne l'est malheureusement pas.
En eet, que se passe-t-il si un choix est nulliable ? Il peut alors ne commencer par aucun
terminal. Comment pourrions-nous alors dterminer qu'il faut slectionner ce choix ?
On se base sur la considration suivante : il faut choisir un choix nulliable si le lexme en
entre est un lexme qui peut suivre directement ce choix, cela revient dire ceux qui peuvent
suivre directement le non-terminal concern. Cela ncessite de calculer une nouvelle information :
l'ensemble des lexmes qui peuvent suivre un non-terminal donn. Nous appellerons cet ensemble
l'ensemble des suivants d'un non-terminal N , et le noterons suiv(N ).
Restera savoir si oui ou non un choix donn est nulliable. Cette donne peut tre obtenue
facilement en tendant la notion d'ensemble des premiers, pour lui faire comprendre la chane de
symboles grammaticaux vide E si le choix correspondant est nulliable.
Nous allons maintenant voir comment on peut calculer le contenu de ces deux ensembles.

III.2.2.2 Ensemble des premiers

prem

Voyons tout d'abord comment calculer les prem().


Pour chaque choix, s'il commence par un terminal t, c'est facile : prem() est le singleton
{t}. Si c'est un non-terminal N , alors le choix peut commencer par n'importe quel terminal
par lequel N peut commencer. Cela ncessite donc d'obtenir un nouveau type d'information :
l'ensemble des premiers d'un non-terminal N , que l'on notera bien entendu prem(N ).
An de travailler de faon plus gnrique et plus abstraite  et donc plus simple , nous adopterons galement un ensemble des premiers pour les terminaux. Ainsi, il existera aussi l'ensemble
des premiers d'un terminal t  not prem(t) pour changer  qui sera quivalent au singleton {t}.
Ainsi, prem() est tout simplement gal l'ensemble des premiers de son premier symbole
grammatical.
Nous connaissons donc les ensembles des premiers des terminaux, et nous savons que pour

22

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

calculer ceux des choix, nous avons encore besoin de ceux des non-terminaux. Voyons donc
comment les calculer.
Pour un non-terminal N de la forme :

||

prem(N ) est naturellement l'union des ensembles des terminaux par lesquels peuvent commencer les choix , et de N . Nous avons donc besoin des prem des non-terminaux pour
calculer ceux des choix, mais aussi ceux des choix pour calculer les prem des non-terminaux.

Cela peut sembler tre un cercle vicieux. En fait, beaucoup d'algorithmes dans le domaine de la
compilation paraissent tre insolvables cause de cela. Pourtant, ils sont bel et bien ralisables.
On appelle ce type d'algorithme des algorithmes de fermeture transitive, ou plus simplement
algorithmes de fermeture .
Ce type d'algorithme possde trois parties : la dnition des donnes, l'initialisation, et les
rgles de dduction. La dnition des donnes peut tre assimile la dclaration var d'une
routine Pascal. Durant l'initialisation, on dnit les donnes de dpart. Et les rgles de dduction
sont les directives qui indiquent comment faire progresser l'ensemble des donnes vers la solution
nale.
Les algorithmes de fermetures ont besoin de donnes initiales, partir desquelles calculer
des informations supplmentaires. Mais que sont donc nos donnes initiales, dans ce cas ? Il
s'agit des ensembles des premiers des terminaux. Nous savons en eet que pour tout terminal t,
prem(t) = {t}.
Vous trouverez en gure 3.4 l'algorithme de fermeture qui calcule les ensembles prem d'une
grammaire. Appliqu sur la grammaire de la gure 3.2 (page 19), les ensembles prem calculs
seront tels que montrs sur la gure 3.5.
Vous aurez remarqu qu'une quatrime variante de l'ensemble des prem a t ajoute. Il
s'agit des prem des ns de choix. Nous aurons en eet besoin de ces informations pour le calcul
de l'ensemble des suivants.

III.2.2.3 Ensemble des suivants suiv


Le calcul de l'ensemble des suivants d'un non-terminal est plus simple. Par ailleurs, on ne doit
pas tendre la notion aux terminaux et choix/ns de choix dans ce cas. Entrons donc directement
dans le vif du sujet.
Pour calculer les suiv, nous aurons nouveau recours un algorithme de fermeture. Vous
trouverez cet algorithme sur la gure 3.6, et le rsultat de son application la grammaire de la
gure 3.2 (page 19) la gure 3.7.
Nous disposons maintenant de toutes les informations ncessaires la conception d'un analyseur LL(1). Toutefois, nous nous devons d'abord d'tudier certains cas qui rendent impossible
l'criture d'un tel analyseur. Ce sont ce qu'on appelle des conits LL(1).

23

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Dnition des donnes


1. Un ensemble de lexmes nomm prem(t) (resp. prem(N ), prem()) pour chaque
terminal (resp. non-terminal, choix) de la grammaire G ;
2. Un ensemble de lexmes nomm prem() pour chaque n de choix de G ; nous appelons n de choix une suite de symboles grammaticaux  longue de zro plusieurs
symboles  telle qu'il existe au moins un choix de la forme A dans la grammaire G.

Initialisation
1.
2.
3.
4.

t GT : prem(t) = {t} ;
N GN : prem(N ) = ;
choix ou n de choix non vide de G : prem() = ;
choix ou n de choix vide de G : prem() = {E}.

Rgles de dduction

1. Pour chaque production N dans G, prem(N ) doit contenir tous les lexmes de
prem() ;
2. Pour chaque choix ou n de choix de la forme N , prem() doit contenir tous les
lexmes de prem(N ), except E ;
3. Pour chaque choix ou n de choix de la forme N telle que prem(N ) contient E ,
prem() doit contenir tous les lexmes de prem( ).
Fig.

3.4  Algorithme de fermeture pour le calcul des

lement de grammaire

lexNombre
'+'
'('
')'
a
Entree
Expression
Terme
ExpressionParenthesee
ResteExpression
Fig.

prem

{
{
{
{
{
{
{
{
{
{

prem

lexNombre
'+' }
'(' }
')' }
a }
lexNombre
lexNombre
lexNombre
'(' }
'+' E }

d'une grammaire G

'(' }
'(' }
'(' }

3.5  Ensembles prem naux pour la grammaire de la gure 3.2

24

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Dnition des donnes


1. Un ensemble de lexmes nomm suiv(N ) pour chaque non-terminal de la grammaire
G;
2. Les ensembles prem de la grammaire G.

Initialisation

1. Calculer les ensembles des prem au moyen de l'algorithme de la gure 3.4 ;


2. N GN : suiv(N ) = .

Rgles de dduction

1. Pour chaque production M N , suiv(N ) doit contenir tous les lexmes de


prem( ), except E ;
2. Pour chaque production M N telle que E prem(), suiv(N ) doit contenir
tous les lexmes de suiv(M ).
Fig.

3.6  Algorithme de fermeture pour le calcul des

Non-terminal

Entree
Expression
Terme
ExpressionParenthesee
ResteExpression
Fig.

suiv

d'une grammaire G

suiv

{}
{ ')'
{ '+'
{ '+'
{ ')'

a }
')' a }
')' a }
a }

3.7  Ensembles suiv naux pour la grammaire de la gure 3.2

25

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

III.2.2.4 Conits LL(1)


Nous avons vu comment on pouvait dcider quel choix devait tre slectionn. Il faut prendre
celui qui contient dans son ensemble prem le lexme t en entre, ou E si le lexme t est dans
l'ensemble suiv du non-terminal en cours.
Mais que se passe-t-il si plusieurs choix remplissent les conditions ? Dans ce cas il y a conit
LL(1) .
Il y aura conit LL(1) si les choix et d'un non-terminal N sont tels que :
 prem() prem() 6= (conit prem-prem) ;
 E prem() et prem() suiv(N ) 6= (conit prem-suiv) ;
 E prem() et E prem() (conit suiv-suiv).
Une grammaire qui ne contient aucun de tels conits est une grammaire LL(1). On ne peut
crire d'analyseurs LL(1) que pour les grammaires qui sont LL(1).
L'ennui, c'est que la plupart des grammaires ne sont pas LL(1). Il convient, pour crer un
analyseur syntaxique LL(1), de supprimer ces conits en modiant la grammaire du langage.
Cela dpassant le cadre de ce travail, je vous renvoie une fois de plus au livre Compilateurs
[GBJL02, section 2.2.4.3].

III.2.2.5 Analyse prdictive par descente rcursive


Voil, nous disposons enn de toutes les informations ncessaires la construction d'un
analyseur LL(1). An de vous permettre d'avancer progressivement, et donc de vous faciliter la
comprhension, nous tudierons d'abord l'analyse prdictive par descente rcursive. Elle est aussi
proche de l'analyse non-prdictive tant par son fonctionnement que par son nom.
En fait, elle fonctionne exactement de la mme faon, si ce n'est qu'on n'eectue plus un test
de type if sur le rsultat des fonctions rcursives, mais bien une instruction de type case of
sur le lexme en entre.
Du point de vue de l'excution, c'est videmment beaucoup plus rapide. Et du point de vue
de la maintenance et de la comprhension du code, c'est galement beaucoup plus clair. On
aura donc toujours avantage utiliser une mthode LL(1) par rapport la mthode entirement
manuelle.
Vous trouverez le code d'un analyseur prdictif par descente rcursive pour la grammaire de
la gure 3.2 (page 19) dans le chier Predictif.pas.
Ainsi que vous pouvez le constater, la structure gnrale est totalement conserve : on utilise
toujours une routine par non-terminal et une gnrique pour les terminaux. La dirence, c'est
qu'elles ne renvoient plus un boolen tmoin de leur succs ou de leur chec. En eet, on sait, ds
lors qu'on entre dans une routine de non-terminal (ou mme d'un terminal) que ce non-terminal
est le bon  sauf s'il y a erreur syntaxique.
D'autre part, cela nous permet d'apporter une amlioration notoire. Puisque l'on sait qu'on
tudie le bon non-terminal, on peut dj construire le nud correspondant, et le transmettre aux
routines appeles rcursivement en tant que parent du nud qu'elles devront construire. Cela
permet non seulement de simplier la libration propre des objets en cas d'erreur syntaxique
(remarquez que les blocs try...except...end sont plus lgants) ; mais cela permet aussi de

26

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Entree
Expression
Terme
ExpressionParenth
ResteExpr
Fig.

lexNombre
Expression
Terme ResteExpr
Identificateur

'+'

'+' Expression

'('
Expression
Terme ResteExpr
ExpressionParenth
'(' Expression ')'

')'

3.8  Table de transition LL(1) pour la grammaire de la gure 3.2

possder directement des informations de contexte qui pourront tre utiles une analyse smantique combine l'analyse syntaxique. Un avantage indniable pour les compilateurs troits.
Finalement, on peut maintenant utiliser la valeur de retour des fonctions pour une information
bien plus intressante qu'un code de russite, savoir le nud construit. Cela permet de simplier
galement l'criture des blocs de choix.
Vous voyez donc que l'analyse prdictive par descente rcursive ne possde que des atouts par
rapport l'analyse non-prdictive. Aussi, je vous dconseille de jamais construire un analyseur
non-prdictif professionnel.

III.2.2.6 L'automate pile LL(1) : l'analyse prdictive non-rcursive


Courage... Il ne nous en reste plus qu'un ! L'analyseur prdictif non-rcursif.
Quelles dirences avec l'analyseur rcursif ? D'abord, c'est que ce petit dernier range tous les
rsultats calculs prcdemment dans une table constante, plutt que de les exploiter au travers
d'un case of. Cette table est deux dimensions : l'une indexe par des non-terminaux, l'autre
par des lexmes. L'autre dirence majeure rside dans le fait que nous n'avons plus une routine
par non-terminal, mais bien une seule routine concentrant tout l'algorithme en elle-mme.
An de mieux vous reprer, vous trouverez en gure 3.84 ce que l'on appelle la table de
transition de la grammaire de la gure 3.2 (page 19).
Cette table indique, pour chaque non-terminal actif et terminal en entre, le choix du nonterminal slectionner. Lorsqu'une case est vide, cela signie qu'il y a erreur syntaxique.
On peut se reprsenter les non-terminaux comme les tats d'un automate d'tats, et les
terminaux en entre comme les vnements extrieurs de cet automate. Par exemple, lorsqu'on
est dans l'tat Entree, et qu'un terminal '(' se prsente dans l'entre, on passe dans l'tat
Expression.
Cependant, ce n'est pas aussi vident qu'un automate d'tats ni. En eet, lorsqu'on se trouve
dans l'tat ResteExpression et qu'on reoit un lexme '+' en entre, on transite vers une suite
d'tats ! Mieux encore, si l'on reoit un lexme ')', on va une chane vide d'tats...
C'est pourquoi nous aurons besoin de ce que l'on appelle un automate pile . Un tel automate
est constitu d'une pile d'tats. Lors d'un cycle de l'automate, on dpile le sommet de la pile (qui
est un tat) et, selon son type et le contenu de la table de transition, on empile les composantes
du choix slectionn dans l'ordre inverse (pour les dpiler ensuite dans le bon ordre). Lorsqu'on
termine un choix, on eectue une sorte de mouvement-E pour remonter au non-terminal parent.
4 Les

noms longs des non-terminaux ont t tronqus pour faire tenir le tableau dans la largeur de la page.

27

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Tout cela doit vous sembler bien abstrait et peu comprhensible... Ne vous en faites pas, je suis
de votre avis. Aussi je vous propose de dcouvrir sans plus tarder le code de cet automate, que
nous allons expliquer ensuite. Vous pourrez trouver ce code dans le chier AutomateAPile.pas
(voir annexe B).
La routine matresse de ce source est bien entendu la routine AnalyseSyntaxique. Nous la
reproduisons sur la gure 3.9. Voyons son comportement pas pas.
Tout d'abord, l'instar de nos deux premiers analyseurs syntaxiques, celui-ci dmarre l'analyse lexicale (ligne 122).
Ensuite, on cre la pile prdictive (ligne 126). On transmet en paramtre du constructeur le
symbole de dpart de la grammaire : il sera empil originellement.
De la ligne 128 la ligne 156, on trouve la boucle principale de l'algorithme. Cette boucle
remplace en ralit les appels rcursifs des analyseurs prcdents. Elle ne s'arrte que sur erreur
syntaxique ou lorsque la pile prdictive est vide. Cette dernire situation signie que l'entre est
compltement analyse.
L'algorithme rptitif eectue la tche suivante : il dpile le sommet de la pile prdictive et,
selon son type, eectue une des trois actions suivantes.
Si le sommet de la pile est un code de retour au parent (ligne 133), alors on rednit le nud
courant comme tant le parent de l'ancien. Il s'agit du mouvement-E dont nous avions parl plus
haut. D'autres implmentations de ce mouvement peuvent tre faites. Par exemple, si l'on code
de manire ce qu'un nud de non-terminal puisse indiquer lorsque son choix est complet, on
peut se baser sur cette information pour remonter au parent.
Si le sommet de la pile est un terminal (ligne 137), il faut simplement reconnatre ce terminal
et l'ajouter aux ls du nud courant.
Si le sommet de la pile est un non-terminal (ligne 145), on eectue un mouvement de prdiction. Voici les direntes instructions qui sont eectues.
1. On commence par consulter la table de transition pour dterminer le choix slectionner,
en fonction du non-terminal rcupr en pile et du lexme en entre (ligne 146).
2. On cre ensuite le non-terminal indiqu en pile et on signale son choix (ligne 147). Remarquez au passage que nous utilisons dsormais un type gnrique pour les non-terminaux.
Il serait en eet impensable d'utiliser ici un case of pour dterminer son type. Si l'on
construit un analyseur troit, ce peut tre gnant. On recourra alors des tables de correspondance entre un non-terminal et sa classe et on utilisera un constructeur polymorphique.
3. La ligne 149 constitue une action un peu barbare : on assigne Result le premier nonterminal rencontr. Cela marche eectivement, mais c'est peu joli. Une programmation
propre requerrait ici un code plus lourd et donc plus lent. On prfre ainsi conserver cette
impuret informatique...
4. L'instruction suivante relie le nouveau nud au nud courant, qui est son parent (ligne
151).
5. Aprs cela, on dnit le nouveau nud comme le nud courant (ligne 153).
6. Finalement, on empile les dirents symboles du choix slectionn sur la pile (ligne 154).
Notez que les procdures EmpileChoixi empilent d'abord un code de retour au parent,
qui est la n du choix, puis tous les symboles dans l'ordre inverse sur la pile. Et ce pour
les dpiler plus tard dans le bon ordre.

28

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

120

125

130

135

140

145

150

155

160

165

function AnalyseSyntaxique ( Entree : string ) : TNoeudEntree ;


var Courant , Nouveau : TNoeudNonTerminal ;
NouveauLexeme : TNoeudLexeme ;
Symbole : Char ;
Choix : integer ;
begin
DemarrerAnalyseurLexical ( Entree );
Result := nil ;
try
Courant := nil ;
Pile := TPilePredictive . Create ( ntEntree );
try
while not Pile . Empty do
begin
Symbole := Pile . Pop ;
if Symbole = codeRetourneAuParent then
begin // le choix courant est termin
Courant := Courant . Parent ;
end else
if Symbole < ntEntree then
begin // la prdiction est un terminal -> reconnaissance
if CurLex . Classe <> Symbole then
ErreurSyntaxique ;
NouveauLexeme := TNoeudLexeme . Create ;
NouveauLexeme . Lexeme := CurLex ;
Courant . AjouteFils ( NouveauLexeme );
LexemeSuivant ;
end else
begin // la prdiction est un non - terminal -> prdiction
Choix := TableTransition [ Symbole , CurLex . Classe ];
Nouveau := TNoeudNonTerminal . Create (
Courant , Symbole , ChoixDuNonTerminal [ Symbole ]( Choix ));
if not Assigned ( Result ) then
Result := Nouveau ;
if Assigned ( Courant ) then
Courant . AjouteFils ( Nouveau );
Courant := Nouveau ;
EmpileChoix [ Choix ];
end ;
end ;
finally
Pile . Free ;
end ;
except
if Assigned ( Result ) then
Result . Free ;
raise ;
end ;
end ;
Fig.

3.9  Algorithme principal de l'analyseur prdictif non-rcursif

29

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Notez enn la clause except (ligne 160) qui doit librer les nuds construits en cas d'erreur.
La seule libration du nud Result sut librer tous les nuds construits. En eet, dans cet
algorithme, le nud Result est le premier construit et ds qu'un nouveau nud est cr, il est
directement reli son parent et son parent lui. Ainsi, comme chaque parent dtruit les enfants
qui lui sont relis sa libration, une seule libration entrane toutes les autres. Rien de plus
simple...

III.3 Pour aller plus loin...


Ici s'achve notre tour d'horizon des analyseurs syntaxiques descendant. Bien entendu la
notion n'a pas t tudie jusqu'au bout. On peut encore et toujours approondir le sujet,
autant qu'on le dsire.
Les lecteurs dont la soif de connaissance n'aura pas t apaise pourront se rfrer au livre
Compilateurs [GBJL02], comme toujours.
Par exemple, ils y trouveront des informations complmentaires (mais non compltes, tant
donn que ce sujet est toujours l'tude) sur la gestion ecace des erreurs. Ils y apprendront
direntes techniques permettant de remettre sur ses rails un analyseur qui a draill suite une
erreur syntaxique.
D'autre part, ils trouveront galement dans cet ouvrage de rfrence une introduction
l'utilisation du programme LLgen, qui est le gnrateur d'analyseurs syntaxiques le plus connu.
Ce logiciel reoit une dnition formelle d'une grammaire et engendre compltement le texte d'un
programme en C, qui, compil, donnera un analyseur syntaxique complet pour cette grammaire.

30

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Chapitre IV
Analyse ascendante
Ainsi que nous l'avons indiqu plusieurs fois, nous n'tudierons pas en dtail l'analyse ascendante. Nous nous contenterons d'en donner le principe gnral. Ceci pour rester dans les limites
acceptables d'un travail de rhtorique.

IV.1 Principe gnral


Dans un analyseur ascendant, le paradigme est tout autre. On construit les sous-arbres syntaxiques qui englobent les premiers lexmes de l'entre.
Au dpart, on ne connat aucun nud construire. On ne connat que le premier lexme t1
en entre.
On le reconnat comme tant un nud feuille (puisque c'est un terminal) et on construit celuici. On avance ensuite sur le lexme t2 , dont on construit aussi le nud feuille correspondant.
partir de l, si les nuds n1 et n2 correspondant aux lexmes t1 et t2 sont les nuds ls
d'un non-terminal N , alors le nud correspondant n3 est cr puis reli ses ls n1 et n2 . Par
la suite, ce nud n3 pourra lui-mme tre ls d'un autre non-terminal.
Si ce n'est pas la cas, on continue d'avancer sur les lexmes ti jusqu' ce que les n derniers
lexmes soient les composantes d'un choix d'un non-terminal N , auquel cas on procde la
cration du nud correspondant que l'on relie ses ls.
On continue ainsi jusqu' ce que toutes les composantes d'un choix du symbole de dpart S
de la grammaire soient cres. On construit alors le nud racine r correspondant au symbole de
dpart S , et on le relie ses ls. L'analyse est alors termine et l'arbre est construit.
La gure 4.1 montre une situation dans laquelle un analyseur ascendant a avanc sur les
lexmes t1 t4 de l'entre, tout en construisant leurs nuds correspondants n1 n4 , puis, ayant
reconnu les nuds t2 , t3 et t4 comme les trois composantes d'un non-terminal N , a construit le
nud n5 correspondant et l'a reli ses trois ls, et nalement a avanc sur le lexme t5 et a
construit son nud correspondant n6 .
Les carrs noirs reprsentent les nuds de l'arbre dj construits. Les cercles symbolisent les
lexmes, en noir ceux dj lus et reconnus et en blanc ceux qui restent dans l'entre.

31

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Fig.

4.1  Exemple de situation d'un analyseur ascendant

On remarque que, contrairement la gure 3.1 (page 18), on ne trouve pas ici de carr blanc,
reprsentant les nuds non construits mais dont on connat l'existence. En eet, dans l'analyse
ascendante, on ne connat l'existence d'un nud qu'au tout dernier moment, et on le construit
alors immdiatement.

IV.2 Vous cherchez plus d'informations ?


Si vous tes avide de plus de dtails sur la mthode ascendante, je ne puis que trop peu
vous conseiller de vous reporter au livre Compilateurs [GBJL02, section 2.2.5]. Sachez aussi que
ce document fera certainement plus tard l'objet d'une extension sur la page Web suivante :

http://sjrd.developpez.com/algorithmique/compilation/analyseurs-syntaxiques/

32

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Chapitre V
Projet exemple
Nous avons donc tudi les analyseurs syntaxiques sous beaucoup d'angles. Cependant, nous
n'avons encore tudi que des petites parties isoles de leur fonctionnement.
C'est pourquoi j'ai dvelopp un projet exemple. C'est un ensemble de packages et de programmes Delphi qui permet d'analyser un code source Extra Simple Pascal et d'en donner la
structure au format XML.
Le langage que j'ai appel Extra Simple Pascal est une simplication l'extrme du langage
Pascal. Les deux seuls types de variables autoriss sont integer et string. Les seules oprations
utilisables sont + - * / et le parenthsage. Enn, il n'existe que l'aectation, l'appel de routine
et l'impression l'cran comme instructions. Le chier Exemple de source.txt de l'archive
indique ci-aprs prsente un exemple de code source valide de ce langage.
Vous pourrez trouver sur la gure 5.1 la grammaire de ce mini-langage. Bien entendu, celle-ci
a t crite de faon tre LL(1).
Vous pourrez tlcharger les sources compltes via ce lien :

ftp://ftp-developpez.com/sjrd/tutoriels/compilation/analyseurs-syntaxiques/projet.zip

Si votre conguration informatique vous empche d'utiliser le FTP, utilisez le miroir HTTP
suivant :
http://sjrd.ftp-developpez.com/tutoriels/compilation/analyseurs-syntaxiques/projet.zip

Ces sources ont t dveloppes avec Delphi 2005 dition Architecte, en Delphi Win32. Normalement, elle devraient tre compilables directement avec n'importe quelle dition de Delphi
2005 et Delphi 2006, et devraient galement se compiler sans problmes avec les versions antrieures.
Les cinq projets inclus dans le groupe de projet de ce .zip sont les suivants :

AnalyseurCommon.bpl : contient la dnition des classes d'analyse et l'analyseur lexical ;


AnalyseurDescendant.bpl : contient une unit commune aux trois types d'analyse descen-

dante, ainsi qu'une unit pour chacun de ces trois analyseurs ;


ProjetTest.exe : permet de tester l'analyse lexicale et les trois types d'analyse descendante
implments dans les deux prcdents packages ;
Generateurs.bpl : fournit de nombreuses classes pour le chargement des grammaires, leur ges-

33

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Source
Routines
Routine
Procedure

Fonction

Parametres
SuiteParametres
DefVariable
TypeVariable
CorpsRoutine
DefVariables
SuiteDefVariables
Bloc
SuiteInstructions
Instruction
Print
IdentInstr
SuiteIdentInstr
Affectation
Augmentation
Diminution
Params
SuiteParams
Expression
SuiteExpression
Terme
SuiteTerme
Facteur

Fig.

Routines CorpsRoutine '.' a


Routine Routines | E
Procedure | Fonction
'procedure' Identificateur Parametres ';'
CorpsRoutine ';'
'function' Identificateur Parametres TypeVariable ';'
CorpsRoutine ';'
'(' DefVariable SuiteParametres ')' | E
';' DefVariable SuiteParametres | E
Identificateur TypeVariable
':' Identificateur
DefVariables Bloc
'var' DefVariable ';' SuiteDefVariables | E
DefVariable ';' SuiteDefVariables | E
'begin' Instruction SuiteInstructions 'end'
';' Instruction SuiteInstructions | E
Bloc | Print | IdentInstr | E
'print' Expression
Identificateur SuiteIdentInstr
Affectation | Augmentation | Diminution | Params
':=' Expression
'+=' Expression
'-=' Expression
'(' Expression SuiteParams ')' | E
',' Expression SuiteParams | E
Terme SuiteExpression
'+' Expression | '-' Expression | E
Facteur SuiteTerme
'*' Terme | '/' Terme | E
Identificateur Params | Nombre | Chaine
'(' Expression ')'

5.1  Grammaire du mini-langage Extra Simple Pascal

34

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

tion, et surtout les calculs des premet suiv, des tables de transition, etc. ;
Generateur.exe : fournit une interface avec l'utilisateur pour utiliser les classes du package
prcdent.
Trois grammaires sont fournies avec les sources (chiers .gra). L'une reprsente la grammaire
exemple de la gure 3.2 (page 19). L'autre reprsente la grammaire du langage Extra Simple
Pascal. La troisime est une grammaire qui provoque les trois types de conits LL(1) tudis en
section III.2.2.4.
Vous pouvez ouvrir ces chiers dans le bloc-notes de Windows pour lire leur contenu, mais
surtout les charger avec le programme Generateur.exe pour rcuprer plus d'informations sur
elles que vous ne pouvez l'imaginer...
Ceci dit, ce qui est le plus intressant par rapport ce que nous avons tudi tout au long
de ce document, ce sont bien les trois units responsables de l'analyse syntaxique selon les trois
mthodes vues, ainsi que l'unit qui dnit les classes d'analyse.
Je ne vous en dis pas plus ici et vous laisse le soin de dcouvrir ces sources, muni du bagage
de connaissances que vous avez rassembles lors de la lecture de ce travail.

35

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Chapitre VI
Conclusion
Nous voici donc arrivs au terme de ce travail sur les analyseurs syntaxiques.
Nous avons commenc par introduire la compilation au sens gnral, et le fonctionnement
global d'un compilateur. Nous avons galement vu la notation BNF pour les grammaires.
Ensuite, nous avons commenc nous concentrer sur un module des compilateurs : l'analyse
syntaxique. Ce module qui a la responsabilit d'organiser les lexmes du texte source en un arbre
abstrait.
Nous avons aprs cela tudi en dtails les direntes techniques d'analyse syntaxique descendante. Rappelons que nous n'avons pas couvert le sujet 100 % : nous nous sommes concentrs
sur l'essentiel et n'avons pas approch les techniques avances que sont celles de la rcupration
d'erreurs par exemple.
Nous avons galement vu le principe gnral de l'analyse ascendante, mais ne nous sommes
pas intresss son comportement exact. Encore une fois, ce choix a t impos par les limites de
longueur des travaux de rhtorique, qui ont dj t largement dpasses pour ce travail. Sachez
toutefois que ce travail sera plus que probablement tendu dans le futur, et disponible sur la
page Web suivante :
http://sjrd.developpez.com/algorithmique/compilation/analyseurs-syntaxiques/

Finalement, vous avez t invit examiner un projet d'analyse syntaxique fonctionnel, utilisant les trois techniques d'analyse descendante tudies.
Vous trouverez encore en annexe A des informations sur le fonctionnement de l'analyseur
lexical qu'ont utilis nos codes exemples.
L'annexe B rappelle les dirents chiers sources exemples que vous avez t invit consulter
lors de l'tude de ce travail.
Pour la dernire fois, je renvoie encore les lecteurs non rassasis au livre Compilateurs
[GBJL02], qui est sans aucun doute la rfrence en matire de compilation.
J'espre que ce document vous aura permis de comprendre les techniques essentielles de
l'analyse syntaxique, et que vous l'aurez apprci.

36

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Annexe A
Analyseur lexical utilis
L'analyseur lexical que nous avons utilis dans nos exemples fonctionne de faon trs simple,
vu de l'extrieur. Il n'est que virtuel, et n'est pas rellement implment. Il est juste l pour
pouvoir comprendre son intgration dans l'analyseur syntaxique.
Voici donc la partie interface de l'unit virtuelle AnalyseurLexical, laquelle nous faisons
rfrence dans les analyseurs syntaxiques exemples.
unit AnalyseurLexical ;
interface
5

10

type
TLexeme = record
Lig , Col : integer ;
Classe : Char ;
Repr : string ;
end ;
procedure DemarrerAnalyseurLexical ( Entree : string );
procedure LexemeSuivant ;

15

var
CurLex : TLexeme ;

Le type TLexeme dnit les informations que contient chaque lexme. Ses deux proprits
essentielles sont Classe et Repr, puisque ce sont les deux seules qui sont strictement ncessaires
du point de vue de l'analyse. On peut mme exagrer, en supprimant la proprit Repr, puisque,
pour l'analyse syntaxique, seule la proprit Classe importe. Les proprits Lig et Col sont
prsentes uniquement an de pouvoir fournir des messages d'erreurs plus sophistiqus.
La procdure DemarrerAnalyseurLexical doit tre appele en premier. Elle reoit l'entre
analyser et analyse le premier lexme. Elle stocke les informations sur ce lexme dans la variable
CurLex.
Ensuite, pour avancer sur un lexme et analyser le suivant, il sut d'appeler la procdure

37

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

LexemeSuivant. nouveau, les donnes sur le lexme analys sont stockes dans la variable
CurLex.
Il est inutile et hors-sujet d'expliquer ici l'implmentation de cet analyseur. Si vous dsirez
plus d'informations sur l'analyse lexicale, je vous renvoie au tutoriel d'Olivier Lance [LAN04]
ainsi qu'au livre Compilateurs [GBJL02, section 2.1]. Vous pouvez aussi vous intresser au code
de l'analyseur lexical du projet de test.

38

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Annexe B
Rfrentiel des chiers sources
Ce document est accompagn de quelques chiers sources, qui servent illustrer les explications donnes. Tous ces chiers sources peuvent tre trouvs dans le dossier FTP suivant :
ftp://ftp-developpez.com/sjrd/tutoriels/compilation/analyseurs-syntaxiques/

Si vous n'avez pas la possibilit d'utiliser le FTP sur votre ordinateur, utilisez le miroir HTTP
suivant :
http://sjrd.ftp-developpez.com/tutoriels/compilation/analyseurs-syntaxiques/

Vous pouvez tlcharger chacune de ces sources sparment, selon vos intrts, ou vous pouvez
tlcharger directement l'ensemble des sources proposes au moyen de ce chier .zip :
ftp://ftp-developpez.com/sjrd/tutoriels/compilation/analyseurs-syntaxiques/sources.zip (FTP)
http://sjrd.ftp-developpez.com/tutoriels/compilation/analyseurs-syntaxiques/sources.zip (HTTP)

DescenteRecursive.pas 19
Predictif.pas 26
AutomateAPile.pas 28

39

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Glossaire
fermeture (algorithme de) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23, 23

Famille d'algorithmes caractriss par le dpart d'une petite quantit de donnes et allant
en progressant, en agrandissant ces donnes partir des donnes dj calcules, et ce jusqu'
ce que plus aucune nouvelle donne ne soit trouve.
lexme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6, 11, 14
La plus petite entit signicative de caractres dans un langage source.
non-terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Utilis dans la terminologie des grammaires ; est un groupe cohrent smantiquement de
symboles grammaticaux.
premiers (ensemble des) prem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Ensemble des lexmes par lesquels peut commencer un non-terminal, un terminal, un choix
ou une n de choix donn. Si l'lment grammatical en question est nulliable, cet ensemble
contient E .
programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4, 9
Dans ce document, nous entendons par  programme  un code compil excutable, autrement dit un chier .exe. Je prcise cela car on peut prendre le terme dans le sens de code
source galement.
smantique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
La smantique d'un chier est sa signication, peu importe la faon dont elle est dcrite.
En programmation, la smantique d'un programme est son comportement  comportement crit au moyen d'un langage de programmation et traduit en code excutable par un
compilateur.
suivants (ensemble des) suiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Ensemble des lexmes qui peuvent suivre directement un non-terminal donn.
symbole grammatical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
lement de base de la dnition d'une grammaire ; ses deux types sont les terminaux et les
non-terminaux.
syntagme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 13, 18
Sous-arbre d'un arbre abstrait dont les feuilles peuvent tre des non-terminaux. L'action de
driver un syntagme signie remplacer l'un des non-terminaux qui composent ses feuilles
par un nouveau nud dont les ls reprsentent un choix de ce non-terminal. Une drivation
d'un syntagme est le rsultat de l'application rpte zro ou plusieurs fois de cette action.
terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11, 17
Utilis dans la terminologie des grammaires, signie un lexme.

40

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Bibliographie
[BELA98] Michel

Beaudouin-Lafon,

Lexique et syntaxe, site Web personnel, 1998

http: // www. lri. fr/ ~mbl/ ENS/ DEUG/ cours/ 3-lexique-syntaxe. html

[GBJL02]

Grune, Bal, Jacobs

et

Langendoen,

Compilateurs, Dunod, 2002

http: // www. eyrolles. com/ Informatique/ Livre/ 9782100058877/


[LAN04] Oliver Lance, Lexers 1/2 : Thorie, www. developpez. com , 2004
http: // olance. developpez. com/ articles/ delphi/ lexers-theorie/
[LAN05] Olivier Lance, Tutoriels sur le format PE, www. developpez. com , 2005
http: // olance. developpez. com/ articles/ windows/ pe-iczelion/
[PER06] Romuald Perrot, Introduction aux arbres, www. developpez. com , 2006
http: // rperrot. developpez. com/ articles/ algo/ structures/ arbres/

41

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Table des gures


1.1 Modules d'un compilateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.1 Arbre abstrait ou arbre syntaxique . . . . . . . . . . . . . . . . . . . . . . . . . .

15

3.1 Exemple de situation d'un analyseur descendant . . . . . . . . . . . . . . . . . .

18

3.2 Exemple de grammaire pour l'analyse descendante . . . . . . . . . . . . . . . . .

19

3.3 Dbut du graphe de contrle du ux de l'analyse de (1 + 2) + 3 + (4) a

. .

20

3.4 Algorithme de fermeture pour le calcul des prem d'une grammaire G . . . . . . .

24

3.5 Ensembles

naux pour la grammaire de la gure 3.2 . . . . . . . . . . . . .

24

3.6 Algorithme de fermeture pour le calcul des suiv d'une grammaire G . . . . . . .

25

3.7 Ensembles

naux pour la grammaire de la gure 3.2 . . . . . . . . . . . . .

25

3.8 Table de transition LL(1) pour la grammaire de la gure 3.2 . . . . . . . . . . . .

27

3.9 Algorithme principal de l'analyseur prdictif non-rcursif . . . . . . . . . . . . . .

29

4.1 Exemple de situation d'un analyseur ascendant . . . . . . . . . . . . . . . . . . .

32

5.1 Grammaire du mini-langage Extra Simple Pascal . . . . . . . . . . . . . . . . . .

34

prem

suiv

42

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.

Index
large (compilateur) . . . . . . . . . . . . . . . . . . . . . 9
A
ambigu (grammaire) . . . . . . . . . . . . . . . . . . . . . . 13 lexme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
arbre abstrait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 LI (Langage Intermdiaire) . . . . . . . . . . . . . . . . . . 6
automate
LL(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
pile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
non-rcursif . . . . . . . . . . . . . . . . . . . . . . . 18, 27
rcursif . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 26

BNF (notation) . . . . . . . . . . . . . . . . . . . . . . . . 10, 13

non-terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
nulliable (non-terminal) . . . . . . . . . . . . . . . . . . . 13

choix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
CI (Code Intermdiaire). . . . . . . . . . . . . . . . . . . . . 6
P
code intermdiaire . . . . . . . . . . . . . . . . . . . . . . . . . . 6 prcalcul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
conits
prem (ensemble des) . . . . . . . . . . . . . . . . . . . . . . . 22
LL(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 production . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Conway (diagramme de) . . . . . . . . . . . . . . . . . . 13
dpart (symbole de). . . . . . . . . . . . . . . . . . . . . . . .11 rcursivit
droite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
descente rcursive
gauche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
prdictif . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 26
descente rcursive
S
non-prdictif . . . . . . . . . . . . . . . . . . . . . . . . . . 18
suiv (ensemble des) . . . . . . . . . . . . . . . . . . . . . . . . 22

inutile (non-terminal) . . . . . . . . . . . . . . . . . . . . . . 13

terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
transition (table). . . . . . . . . . . . . . . . . . . . . . . . . . .27

langage intermdaire . . . . . . . . . . . . . . . . . . . . . . . . 6
V
largeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
troit (compilateur). . . . . . . . . . . . . . . . . . . . .9 virtuelle (machine) . . . . . . . . . . . . . . . . . . . . . . . . . . 5

43

Les sources prsentes dans ce document ainsi que les descriptions d'algorithmes sont
libres de droits, et vous pouvez les utiliser votre convenance. Par contre, la page
de prsentation constitue une uvre intellectuelle protge par les droits d'auteurs.
Copyright
2006 Sbastien Doeraene. Aucune reproduction, mme partielle, ne
peut tre faite de ce document et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi
jusqu' 3 ans de prison et jusqu' 300 000 e de dommages et intrts.