Vous êtes sur la page 1sur 167

Théorie des langages et

compilation
Génie Informatique – S2
Prof. M. Oulhadj
2023/2024
Plan

• Introduction
• Expression régulière et automates finis
• Grammaires hors-contexte et automates à pile
• Analyse lexicale
• Analyse syntaxique
• Analyse sémantique
• Génération du code
Introduction
• Théorie de langage
• Etudier les caractéristiques des langages de programmation.
1- Connaître les propriétés des langages (Alphabet, Mot, Type).
Parties du module

2- Dénoter les langages par des expressions


3- Construire et étudier le système générateur d’un langage (Grammaire)
4- Construire et étudier le système reconnaisseur d’un langage (Automate).

• compilateur
• Construire un compilateur qui permet de traduire un programme
source en un programme objet:
• 1-Phases d’analyse: Dégage les constituants d’un programme source
(Lexical, syntaxique, sémantique).
• 2-Phases de synthèse: Construit le programme cible (Génération et
optimisation du code intermédiaire, génération du code final).
Introduction
❖ Théorie de langage

Définition
La théorie de langage est une matière qui permet de comprendre
le fonctionnement des langages par un modèle mathématique qui doit
être capable de:

1- Décrire un langage;
2- Reconnaître les mots qui appartiennent à un langage donné.
Introduction
❖ Théorie de langage

o Symbole: Un symbole est une entité abstraite.


Exemples: Lettres, Chiffres, Symboles graphiques.
o Alphabet: Un alphabet (ou vocabulaire) noté Ω est un ensemble de
symboles.
Exemples: Ω = {0 ,1}, Ω = {a, b,…..z}, Ω = {0; 1; 2; 3; 4; 5; 6; 7; 8; 9; .}.
o Mot: Un mot (ou bien lexème) défini sur un alphabet Ω est une suite finie de
symboles de Ω.
Exemples: -Le mot 1011 est défini sur l’alphabet {0, 1} ;
-Le mot 1.23 est défini sur l’alphabet {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, .}.
Remarque: Le mot vide est une suite vide de symboles et noté ε.
Introduction
❖ Théorie de langage

o Longueur d’un mot: La longueur d’un mot m est le nombre de symboles qui le
composent. Elle est notée par |m|.
Exemples: |ababb|=5 , | ε|=0

o Nombre d’occurrence: la cardinalité d’un mot m par rapport à un symbole a∈Ω


est Le nombre d’occurrence de la lettre a dans m. Elle est notée par |m|a.
Exemples: |ababb|a=2

Propriété: 𝒎 = σ𝒙∊Ω 𝒎 𝒙
Introduction
❖ Théorie de langage

Soient m, m’ et m’’ trois mots sur l ’alphabet Ω.


o Concaténation:
• La concatenation de m et m’ est obtenue en écrivant m suivi de m’, elle est notée par
mm’ ou m.m’.
• Exemple: aba.ba est le mot ababa sur Ω = {a, b}.
• mn (n∈ΙN) est la concaténation de n mots identiques.
• Exemple: (ab)3 = ababab.
• La concaténation est associativité: m(m’m’’) = (mm’)m’’
• La concaténation n'est pas commutative: mm’ ≠ m’m
• |mm’|= |m|+ |m’| , |mn|=n |m| , avec n∈ΙN
• εm = mε = m, avec ε est le mot vide .
Introduction
❖ Théorie de langage
Soient m, m’ et m’’ trois mots tels que: m=m’m’’. On dit que:

o Préfixe: m’ est un mot préfixe de m.


o Suffixe: m’’ est un mot suffixe de m.
• Exemple: aabbba=(aab)(bba). Donc aab et bba sont, respectivement, le préfixe et le suffixe de aabbba

o Miroir: Le miroir du mot m (notée par miroir(m) ou mR), est le mot formé par la suite des symboles
composant m mais pris dans l'ordre inverse.
• Propriétés: (mR )R = m , (mm’)R = m’R mR
• Exemple: (1010)R=0101. miroir(ε)= ε

o Facteur: u un mot facteur de m c-à-d il existe deux mots v et w tels que : m = vuw.

o Conjugués: Deux mots m et m’ sont dits conjugués s’il existe deux mots u et v tels que : m = uv et
m’=vu.
Introduction
❖ Théorie de langage
Langage formel
• Un langage L sur Ω est une partie de Ω* , et Ω* est l'ensemble de mots sur un
alphabet Ω tel que: L   * où L  Ρ(*)
• Exemple: Soit Ω = {a , b} un alphabet.
• Φ est le langage vide, il ne contient aucun mot.
• {ε} est un langage.
• {a , ba , aab} est un langage.
• {w ∈ Ω* / w=an tel que n>0} = {a, aa, aaa, aaaa,….} est un langage.
• Remarque:
• Un langage sur un alphabet Ω peut être fini ou infini.
• Φ est un langage définie sur n’import quel alphabet.
Introduction
❖Théorie de langage
Opération sur les langages
• Soient L et L’ deux langages définis sur un alphabet Ω.
➢L∪L’ (ou L+L’ ) est un langage sur un Ω obtenu par la réunion de L et L’,
tel que: L∪L’= {m / m ∈ L ou m ∈ L’}.
Exemple: L={ab,cd,ef} et L′={cd,gh,ij} ➔ L∪L′={ab,cd,ef,gh,ij}

➢ L∩L’ est un langage sur un Ω obtenu par l’intersection de L et L’,


tel que: L∩L’= {m / m ∈L et m ∈L’}.
Exemple: L={ab,cd,ef} et L′={cd,gh,ij} ➔ L∩L′={cd}.
Introduction
❖Théorie de langage
Opération sur les langages (suite)
➢Le complément du langage L , noté par L,est obtenu par: L = {m / m L}.
Exemple, L={ab,cd,ef} est un langage sur l'alphabet {a,b,c,d,e,f}, alors le
complément de L, serait l'ensemble de tous les mots qui peuvent être formés à
partir de cet alphabet, mais qui ne sont pas : ab, cd ou ef.

➢LL’ est un langage sur un Ω obtenu par la concaténation de L et L’,


tel que: L.L’ = {m / ∃u ∈ L, ∃v ∈ L’ : m = uv}.
Exemple: L={ab,cd} et L′={12,13} ➔ L.L′={ab12,ab13,cd12,cd13}.
Introduction
❖Théorie de langage
Opération sur les langages (suite)
➢La puissance d’un langage L, noté Ln, est obtenu par:

𝜀 𝑠𝑖 𝑛 = 0
𝐿𝑛 = ቐ𝐿 𝑠𝑖 𝑛 = 1
𝐿. 𝐿𝑛−1 = 𝐿𝑛−1 . 𝐿 𝑠𝑖 𝑛 > 1
Introduction
❖Théorie de langage
Opération sur les langages (suite)

➢La fermeture positive de Kleene de L est notée par: 𝑳+ = ራ 𝑳𝒊 = 𝑳𝟏 ∪ 𝑳𝟐 ∪ 𝑳𝟑 ∪ ⋯
𝒊=𝟏

➢La fermeture itérative de Kleene de L est notée par: 𝑳∗ = ራ 𝑳𝒊 = 𝑳𝟎 ∪ 𝑳𝟏 ∪ 𝑳𝟐 ∪ ⋯


𝒊=𝟎

➢Le langage miroir de L est donnée par: l'ensemble de tous les mots obtenus en inversant
l'ordre des lettres de chaque mot de L
𝑳𝑹 ={m/ ∃𝒖 ∈ 𝑳: 𝒎 = 𝒖𝑹 }
Remarque:
L*=L++ {ε} L+ = LL*=L*L (L*)*= L*
Introduction
❖Théorie de langage
Opération sur les langages (suite)
➢Exemple:
Soit Ω ={0,1}, L1= {00, 11, 01} et L2= {01, 10}.
• L1+ L2= {00, 11, 01, 10}
• L1∩ L2= {01}
• L1. L2={0001, 0010, 1101, 1110, 0101, 0110} ≠ L2. L1={0100,0111,0101,1000,1011,1001}
• L2* = {ε} + {L2} + {L2 L2}+ {L2 L2 L2}+…
Introduction
❖Théorie de langage
Opération sur les langages (suite)
➢Exercice 1:
soit l’alphabet Ω = {a, b}
1. Ecrire les mots uv, (uv)2 et u3V pour les mots u = aa, v =bab
2. Ecrire tous les mots de longueur 2 définis sur Ω. Pour les mots u = aa, v =bab
3. Préciser les ensemble suivant:
➢E1 = {u.v / u ∈ Ω+, v ∈ Ω+ }
➢E2 = {u.v / u ∈ Ω+, v ∈ Ω* }
➢E3 = {u.v / u ∈ Ω*, v ∈ Ω* }
Introduction
❖Théorie de langage
Opération sur les langages (suite)
➢Solution Exercice 1:
soit l’alphabet Ω = {a, b}, Etant données les mots u = aa, v =bab
1. uv = aabab; (uv)2 = (uv)(uv) = aababaabab; u3v = uuuv = aaaaaabab.
2. les mots de longueur 2 : {aa, bb, ab, ba}
3.
E1= {u.v / u ∈ Ω+, v ∈ Ω+ } est l'ensemble de toutes les concaténations
possibles de deux mots non vides sur l'alphabet Ω. . Les mots u et v peuvent
contenir un ou plusieurs symboles de l'alphabet Ω. E1 ={m /m ∈ Ω*/|m|≥2}
Introduction
❖Théorie de langage
Opération sur les langages (suite)
➢Exercice 1:
soit l’alphabet Ω = {a, b}
E2 = {u.v / u ∈ Ω+, v ∈ Ω* } est l'ensemble de toutes les combinaisons
possibles où le premier élément est un mot non vide et le deuxième élément
peut être n'importe quel mot (y compris le mot vide) sur l'alphabet Ω. E2 ={m
/m ∈ Ω*/|m|≥1} = Ω+

• E3 est l'ensemble de toutes les combinaisons possibles où les deux éléments peuvent
être n'importe quel mot (y compris le mot vide) sur l'alphabet Ω. E3 = Ω*.
Introduction
❖Théorie de langage

• Grammaire: Définition
Une grammaire est une notation utilisée pour la description de la
syntaxe d’un langage, c.à.d. la façon avec laquelle les mots de langage
seront organisées et utilisées.
Introduction
❖Théorie de langage

• Grammaire formelle: On appelle grammaire le quadruplet


G(VT,VN,R,S) telle que:
• VT: Ensemble fini de symboles (ou des mots) dits terminaux, on l’appelle
également vocabulaire terminal.
• VN: Ensemble fini de symboles (ou des mots) non terminaux qui représente les
noms attribués aux productions constituant la grammaire du langage.
• R: Ensemble de règles de productions de la forme g → d:
où g ∈ (VT∪VN)+-VT+ et d ∈ (VT∪VN)*
• S: Symbole (ou Mot) non-terminal particulier appelé axiome (mot de départ de
la grammaire).
Introduction
❖Théorie de langage
Grammaire formelle
• Exemple: Soit la grammaire G(VT,VN,R,S) telle que:
G = ({a, b}, {S, T}, {S → aS|aT, T → bT|b}, S).
• VT: Ensemble fini de symbole terminaux = {a, b}.
• VN: Ensemble fini de symbol non terminaux = {S, T}.
• R: Ensemble de règles de productions : R= {S → aS|aT, T → bT|b}
{S, T} ∈ (VT∪VN)+-VT+ et {a,b} ∈ (VT∪VN)*
• S: l’axiome (mot de départ de la grammaire) = S.
• Par convention, on utilisera les lettres majuscules pour les non-
terminaux, et les lettres minuscules pour représenter les terminaux.
Introduction
❖Théorie de langage
• Grammaire formelle: Propriétés sur les règles de production

• Dans la règle A → a: A est appelé partie gauche de la règle. Et a est appelé partie droite de la
règle.
• Lorsque plusieurs règles partagent la même partie gauche: A → a1, A → a2,…, A → an
On les notées : A → a1 | a2 | a3 | … | an
• On appelle dérivation sur G, toute suite finie X1 , X2 , ….. Xk telle que k≥1 et X1→ X2 →
…..→ Xk. ➔On dit que Xk est dérivé à partir de X1 ou X1 se dérive en Xk

• X Y : si X se dérive en Y par l’application de 0, une ou plusieurs règles de production.


• X n Y : si X se dérive en Y par application au moins une règle.
• X Y : si X se dérive en Y par application de n règles.
• X Y : si X se dérive en Y par application d’une seule règle.
Introduction
❖Théorie de langage
• Grammaire formelle: Arbre syntaxique
Soit une grammaire G=(VT,VN,R,S), les arbres de syntaxe de G sont des
arbres où les nœuds internes sont étiquetés par des symboles de VN, et les feuilles
étiquetés par des symboles de VT .
Exemple:
Soit la grammaire G = ({a, b}, {S, T}, {S → aS|aT, T → bT|b}, S).
Elle génère le mot aab selon la chaîne de dérivation:
S → aS → aaT → aab.
Ce qui donne donc l’arbre syntaxique suivant :

Remarque: Si l’arbre syntaxique a comme racine S, alors il est dit arbre de dérivation du
mot u tel que u est le mot obtenu en prenant les feuilles de l’arbre dans le sens
gauche→droite et bas→haut.
Introduction
❖Théorie de langage
• Grammaire: Classification de Chomsky
• Chomsky a propose une classification des grammaires selon le type
des règles de production:
• Grammaire générale (Type 0)
• Grammaire contextuelle (Type 1)
• Grammaire hors-contexte( algébrique) (Type 2)
• Grammaire régulière ( à droite ou à gauche) (Type 3)
Introduction
❖Théorie de langage
• Grammaire: Classification de Chomsky
• Grammaire générale (Type 0): dite aussi grammaire sans restriction,
si toutes ses règles sont de la forme :
X→Y où X ∈(VT∪VN)+-VT+ et Y∈(VT∪VN)*. (aucune restriction)

• Exemple :
G = {{a,b,c}, {S}, {S → aS|Sb|c, aSb → bS|a|b}, S}}
Introduction
❖Théorie de langage
• Grammaire: Classification de Chomsky
• Grammaire contextuelle (Type 1): si toutes ses règles sont de la
forme :
X→Y où X∈(VT∪VN)+-VT+ et Y∈(VT∪VN)* et |X|≤|Y|

• Exemple :
G = {{a,b,c}, {S,R}, {S → ε|aS|Rb, Ra → abR|aS}, S}}
Introduction
❖Théorie de langage
• Grammaire: Classification de Chomsky
• Grammaire hors-contexte (Type 2): si toutes ses règles sont de la
forme :
X→Y où X∈ VN Et Y∈(VT∪VN)*
• Exemple :
G = {{a,b}, {S}, {S → ε|aSb|}, S}}
Mots: ε, ab, aabb, aaabbb, …, anbn
Introduction
❖Théorie de langage
• Grammaire: Classification de Chomsky
• Grammaire régulière ( à droite ou à gauche) (Type 3): si toutes ses règles sont de la
forme :
➢ Une grammaire régulière à gauche:
X→Yc où X→ c avec X∈ VN Et Y∈ VN∪{ε} Et c ∈ VT*
➢ Une grammaire régulière à droite:
X→cY où X→ c avec X∈ VN Et Y∈ VN∪{ε} Et c ∈ VT*
Exemple:
𝐺1 = { 𝑎, 𝑏 , 𝑆, 𝐴 , 𝑆→𝑆𝑏|𝐴𝑏, 𝐴→𝐴𝑎|𝑎 , 𝑆} grammaire régulière à gauche.
𝐺2 = { 𝑎, 𝑏 , 𝑆, 𝐴 , 𝑆→𝑎𝑆|𝑎𝐴, 𝐴→𝑏𝐴|𝑏 , 𝑆} grammaire régulière à droite.
𝐺3 = { 𝑎, 𝑏 , 𝑆, 𝐴 , 𝑆→𝑎𝑆|𝑎𝐴, 𝐴→𝐴𝑏|𝑏 , 𝑆} grammaire n’est pas régulière; puisque n’est
régulière à gauche ni régulière à droite.
Introduction
❖Théorie de langage
• Grammaire: Classification de Chomsky

• Il y a une relation d’inclusion strict entre les 4 types des grammaires c’est-à-
dire: une grammaire de type i est aussi de type inferieur à i (1≤ i ≤ 3).
Type 3 ⊂ Type 2 ⊂ Type 1 ⊂ Type 0
• Le type retenu pour une grammaire est le type maximum de la grammaire
qui vérifie ses règles.
Introduction
❖Théorie de langage
• Grammaire: Langage engendrée
Soit G=(VT,VN,R,S) une grammaire . Le langage défini par la grammaire G appelé L(G)
est l'ensemble des mots dérivés du symbole de départ :
L(G) = { m ∈ VT* / S * m}
• Un langage de type i est un langage engendré par une grammaire de type i tel que:
• Langage de type 3 est un langage régulier ou rationnel (type 3 ).
• Langage de type 2 est un langage algébrique (type 2 ).
• Langage de type 1 est un langage contextuel (type 1 ).
• Langage de type 0 est un langage récursivement énumérable (type 0 ).
Remarque :
Une grammaire définit un seul langage. Par contre, un même langage peut être
engendré par plusieurs grammaires différentes.
Introduction
❖Théorie de langage
Exercice 1:
1. Trouvez les langages correspondants aux définitions suivantes:
• Tous les mots sur {a, b, c} qui commencent par un a et finissent par un b.
• Tous les mots sur {a, b} qui contiennent plus de a que de b.
2. Définissez la fermeture de Kleene (L∗) pour chacun des langages suivants:
1. L = {ε},
2. L = {a, aa}.
3. Précisez le type de chacune des grammaires suivantes :
1. G = ({a, b}, {S, T}, {S → aabS|aT, T → bS|ε} , S);
2. G = ({a, b, c}, {S, T,U}, {S → bSTa|aTb, T → abS|cU,U → S|ε}, S) ;
3. G = ({0, 1, 2}, {S,C, Z, T}, {S → TZ, T → 0T1C|ε,C1 → 1C,CZ → Z2, 1Z → 1}, S).
Introduction
❖Théorie de langage
Correction Exercice 1:
1. Les langages correspondants aux définitions suivantes :
• Tous les mots sur {a,b,c} qui commencent par a et finissent par b:
L = {m/ m= a{a,b,c}*b}
• Tous les mots sur {a,b} qui contiennent plus de a que de b:
L = {m / |m|a > |m|b}

2. Définissez la fermeture de Kleene (L*) :


• L = { ε }, donc L*={ ε }
• L = {a,aa}
L² = {aa, aaa, aaaa}, donc L𝑘 = {a𝑖 / i= k … 2k}
D’ou : L* = ∪i≥0 L𝑖 = ∪i≥0{a𝑗 /j=i … 2i, i≥0}
Introduction
❖Théorie de langage

Correction Exercice 1 (suite):


1. Préciser le type de chacune des grammaires suivantes :
• G = ({a, b}, {S, T}, {S → aabS|aT, T → bS|ε}, S). G est de type 3 :
régulière à droite.
• G = ({a, b, c}, {S, T, U}, {S → bSTa|aTb, T → abS|cU,U → S|ε}, S). G
est de type2 : hors-contexte.
• G = ({0, 1, 2}, {S, C, Z, T}, {S → TZ, T → 0T1C|ε, C1 → 1C,CZ → Z2,
1Z → 1}, S). G est de type 0 : Générale.
Introduction
❖Théorie de langage
Exercice 2:
• On considère la grammaire G = (VT,VN,R,S) :
• VT, = {b, c}.
• VN = {S}.
• R = {S → bS | cc}
1- Quel est le type de G.
2- Déterminer L(G)
Exercice 3:
• Construire une grammaire pour le langage L = {abn a/ n ∊ N }
Introduction
❖Théorie de langage
Correction Ex2 :
• On considère la grammaire G = (VT,VN,R,S) : VT, = {b, c}. VN = {S}. R = {S → bS |
cc}
1. G est une grammaire régulière a droite. Car on les règles de production
S→bS et S→cc vérifier les règles de production de grammaire de type 3.

2. L(G) = {bncc / n ∊ N}
Introduction
❖Théorie de langage

Correction Ex3:
• Construire une grammaire pour le langage L = {abn a/ n ∊ N }
On considère la grammaire G = (VT,VN,R,S) où :
• VT, = {b, c}.
• VN = {S, T}.
• R = {S → aTa, T → bT | ε }
Introduction
❖Compilateur

• Au début de l’informatique on programme directement les ordinateurs en langage


machine
o Tache assez dur.
o Solution : utiliser les possibilités de l’informatique pour faciliter le travail de
programmation.
o Contrainte :
Un ordinateur représente toutes les informations (données et programmes) par des
suites de 0, 1.
o Le programmeur utilise des langages proches du langage humain
o Solution : un traducteur  compilateur / interpréteur.
Introduction
❖Compilateur
✓Un compilateur est un programme qui lit un programme écrit dans un premier langage
(langage source) et le traduit en un programme équivalent écrit dans un autre langage
(langage cible).

✓Le programme cible est un programme exécutable, en langage machine, l’utilisateur


peut ensuite le faire exécuter afin de traiter des données et de produire des résultats.

• Exemple:
• Langage source : langage de haut niveau (C, C++, Java, Pascal, Fortran...)
• Langage cible : langage de bas niveau (assembleur, langage machine)
Introduction
❖Principe de compilateur

• Un compilateur est décomposé en


deux phases principales :

• Phases d’analyse : Permet d'identifier les composants d'un programme source dans une
représentation intermédiaire.
• Phases de synthèse : Permettent de construire le programme cible à partir de cette
représentation intermédiaire.
• Remarque : au cours de processus de traduction un rôle important du compilateur est de
signaler à l’utilisateur la présence des erreurs dans le programme source.
Introduction
❖Phases d’un compilateur
• Un compilateur typique se décompose en 6 phases élémentaires : 3 phases d’analyse et 3
phases de synthèse. Deux autres taches interagissent avec les six phases : La gestion
d’une table des symboles et la détection des erreurs.
Programme source Analyseur lexical

Analyseur syntaxique

Table des Analyseur sémantique Gestion des


symboles erreurs
Générateur de code intermédiaire

Optimiseur de code

Générateur de code final Programme Cible


Introduction
❖Phases d’un compilateur
Analyse lexicale
• L’analyse lexicale ou scanning, elle décompose le texte du programme en lexèmes
(tokens) les lexèmes sont classes comme suite : Identificateurs

o Les identificateurs : les mots déclares par l’utilisateur. y := a * b + 30


o Les constantes numérique (nombre): 11,10,30….
o L’affectation: = Affectation opérateurs nombre
o Les operateurs: +, *, / , ==, …
o Les mots clés : se sont les mots particuliers au langage (while, for, if, else,…).
o Les séparateurs : ce sont les caractères de ponctuation telle que le point-virgule, …

➢ Outils théoriques: Expression régulière, Automate fini.


Introduction
❖Phases d’un compilateur
Analyse Syntaxique
• Analyse syntaxique ou Parsing, Permet de Vérifier si la syntaxe de la chaîne codée est
conforme avec celle du langage à compiler.
• Permet de vérifier les entités en entrée apparaissent conformément ou non aux règles
définissent la grammaire de langage.
• Le résultat est souvent présenté sous la forme d’un arbre syntaxique.
:=
• Exemple : soit l’instruction : y := a * b + 30
id1 +

*
➢Outils théoriques: Grammaire 30
id2 id3
Introduction
❖Phases d’un compilateur
Analyseur sémantique:
• Utilise la structure hiérarchique déterminée par la phase d’analyse
syntaxique pour contrôler la cohérence sémantique du programme
source:
• Cette analyse effectuera quelques modifications de l’arbre syntaxique: :=
• Vérifie la cohérence des types des variables et des expressions
• Vérifie la visibilité des variables c-à-d vérifier qu’ils sont id1 +
déclarées et visibles aux endroits où ils sont utilisé. entier vers réel
*
• Par exemple on pourrait rajouter un nœud ‘’entier vers réel’’ qui
indique qu’une conversion doit être faite. id2 id3 30
Introduction
❖Phases d’un compilateur
Générateur de code intermédiaire:
• Permet de construire une représentation intermédiaire des programmes sources à
partir de l’arbre de analyses syntaxiques et sémantiques, indépendante de tous les
langages de programmations.
:=
• Exemple: Pour y:=a*b+30 on trouve:
id1 +
t1←EvR(30)
entier vers réel
t2←id2*id3 *
t3←t2+t1 id2 id3 30
id1←t3
Introduction
❖Phases d’un compilateur
Optimiseur de code
Permet d’améliorer le code intermédiaire par la réduction du nombre de variables et
d’instructions, de façon que le code machine résultant s’exécutant plus rapidement.
• Exemple: Pour y:=a*b+30 on trouve:
• Le compilateur peut déduire lui même que la conversion de l’entier 30 en réel peut être effectuée une fois
pour toute au moment de la compilation de sorte que l’on peut éliminer l’opération entier vers réel .
• t3 n’est utilisée qu’une seule fois pour transmettre sa valeur à id1, on peut donc en toute sécurité substituer
id1 à tmp3.
t1←EvR(30)
Optimisation de code
t2←id2*id3 t1← id2*id3
t3←t2+t1 id1←t1 + 30.0
id1←t3
Introduction
❖Phases d’un compilateur
Générateur de code final
• Cette phase produit le code objet (cible) équivalent au programme de départ à partir de
code intermédiaire (optimisé).
• Exemple: Pour id1:=id2*id3+30
• Généralement le code cible consiste en langage d’assemblage.
• On sélectionne les emplacements mémoire pour chacune des variables utilisées dans le programme,
ensuite les instructions intermédiaires sont traduites en une suite d’instructions machines qui effectuent
la même tâche.

Mov id2, R2 Mov id2, R2 // Déplacer la valeur de id2 dans le registre R2


Mul id3; Mul id3; // Multiplier la valeur de id3 avec R2 et sera stockée dans le registre R2
Mov 30,R! Mov 30, R1 // Déplacer la valeur 30 à R1
Add R2, R1 Add R2, R1 // addition de R1 et R2, Le résultat sera stocké dans le registre R1.
Mov R1, id1 Mov R1, id1 //Déplacer la valeur de R1 dans id1
Introduction
❖Phases d’un compilateur
Gestion de la table des symboles

• Permet de stocker toutes les informations nécessaires sur les lexèmes (mots) du
programmes source.
• Une table des symboles est une structure de données contenant un enregistrement pour
chaque identificateur, muni de champs pour ses attributs (emplacement mémoire, son type,
sa
protée..) Tables des symbols

indice nom adresse …..


• Exemple : soit l’instruction : y := a * b + 30
id1 y …
Id2 A …
id3 B ….
Introduction
❖Phases d’un compilateur
Gestion des erreurs
• Après avoir détecter une erreur, une phase doit la signaler et la traiter de telle façon que le
compilateur puisse continuer son traitement et que d’autre erreurs puissent être détectées.
• Chaque phase de compilation détecte son propre type d’erreur :
• L’analyse lexicale détecte peu d’erreurs essentiellement les fautes de frappe, il s’agit de
caractères interdits ou ayant une forme illégale pour le langage (3x, β, ф, ...).
• L’analyse syntaxique détecte les erreurs de construction du programme par exemple :
• en C :fi(x==4) (fi est considéré comme identificateur par l’analyseur lexical, mais l’analyseur
syntaxique dit que cette instruction est illégale.
• L’analyse sémantique détecte des erreurs de type, une trop longue les variables non
déclarées, etc.
• L’optimiseur du code peut informer une instruction du programme ne peut jamais être
accessible et par conséquent jamais exécutée.
• Le générateur du code objet peut indiquer une valeur créée par le compilateur est trop grande
pour être mémorisée.
Introduction
Phases d’un compilateur
y := a*b+30 Analyseur lexical Analyseur syntaxique Analyseur sémantique

id1:=id2*id3+nombre

Tables des
symboles
id1 y
id2 a
id3 b
Mov id2, R2
Mul id3; Générateur de code
Mov 30, R1 Générateur de code Optimiseur de code intermédiaire
Add R2, R1
Mov R1, id1 t1←ER(30)
t1←id2*id3
t2←id2*id3
id1←t1+30.0 t3←t2+t1
id1←t3
Introduction
❖Phases d’un compilateur

• Exemple: position = initial + rate * 60


position = initial + rate * 60

Analyseur lexical

id1 = id2 + id3 * 60

Analyseur syntaxique

:=
id1 +
id2
*

id3 60
Analyseur sémantique

:=
id1 +
id2
*
Entier vers
reel
id3
60

Générateur de code intermédiaire

temp1 = EVR(60)
temp2 = id3 * temp1
temp3 = id2 + temp2
id1 = temp3
Optimiseur de code

temp1 := id3 * 60.0


id1 := id2 + temp1

Générateur de code

MOV id3, R2
MUL #60.0, R2
MOV id2, R1
ADD R2, R1
MOV R1, id1
Plan

• Introduction
• Expression régulière et automates finis
• Grammaires hors-contexte et automates à pile
• Analyse lexicale
• Analyse syntaxique
• Analyse sémantique
• Génération du code
Expression régulière et automates finis
❖Expression régulière
Soit Ω un alphabet quelconque ne contenant pas les symboles {∗,+,|,.,(,)}.
• Une expression régulière (ou rationnelles) est un mot défini sur l’alphabet Ω ∪ {∗,+, |, ., (, )}
permettant de représenter un langage régulier de la façon suivante :

• L’expression régulière ε dénote le langage vide (L = {ε}) ;


• L’expression régulière a (a ∈ Ω) dénote le langage L = {a} ;
• Si r est une expression régulière qui dénote L alors (r)∗ (resp. (r)+) est l’expression régulière qui dénote
L∗ (resp. L+) ;
• Si r est une expression régulière dénotant L et s une expression régulière dénotant L′ alors:
• (r)|(s) est une expression régulière dénotant le langage L∪L′.
• (r).(s) (ou simplement (r)(s)) dénote le langage L.L′.
Expression régulière et automates finis
❖Expression régulière
Exemples: considérons l’alphabet Ω={0,1}.

1. L’expression 0* décrit tous les mots composés uniquement du symbole 0


ainsi que le mot vide ε. (0000, 000,…..).
2. L’expression 110*1 décrit tous les mots contenant deux fois le symbole 1
suivis d’un nombre quelconque de symboles 0 ou vide et suivis du
symbole 1. (1100001, 110000001,……).
3. L’expression 0*110*1 est la concaténation des deux expressions 1 et 2.
(00001100001, 00011001,……).
4. L’expression 0*|110*1 décrit l’expression des mots générées soit par
l’expressions 1 ou par 2 (00000, 1100001, ……).
Expression régulière et automates finis
❖Propriétés algébriques sur les expressions régulières:

• Soit r,s et t des expressions régulières.


• r|s = s|r : l'opérateur| (ou) est commutatif.
• r|(s|t) = (r|s)|t : l'opérateur | est associatif.
• (rs)t = r(st) : la concaténation est associative.
• r(s|t)=rs|rt :la concaténation est distributive par rapport au |
• εr = rε = r : ε est l'élément neutre de la concaténation.
• r* =(r| ε)* : ε est inclus dans une fermeture.

• Remarque: la chaîne vide ε = s°


Expression régulière et automates finis
❖Notations:
• * est un opérateur unaire poste-fixe qui veut dire zéro, un ou plusieurs fois. r* = r+| ε
• + est un opérateur unaire poste-fixe qui veut dire un ou plusieurs fois. r+ = r r* = r*r
• ? est un opérateur unaire poste-fixe qui veut dire zéro ou une fois: r? = r | ε
• [a-z] désigne un élément (une lettre) de cette classe: [a-z] = a|b|c...|z

• Priorité des opérateurs: * , +, concaténation , |


• Exemple:
• a|b*c est interprétée comme (a)|((b)*(c))
• aa*|b+ est interprétée comme (a(a)*)|(b)+
Expression régulière et automates finis
❖Langages réguliers

• Définition
Un langage régulier est un ensemble de chaînes de caractères qui peut être décrit par une
expression régulière ou reconnu par un automate fini (Voir la partie suivante).

Exemples:
• a∗ : dénote le langage régulier an (n ≥ 0) ;
• (a|b)∗ : dénote les mots dans lesquels le symbole a ou b se répètent un nombre quelconque
de fois. Elle dénote donc le langage de tous les mots sur {a, b} ;
• (a|b)∗ab(a|b)∗ : dénote tous les mots sur {a, b} contenant le facteur ab.
Expression régulière et automates finis
❖Langages réguliers
• Propriétés
Soient L et L’ deux langages réguliers désignés respectivement par les expressions
régulières r et s, nous avons :

• 1- L+L’ , L∩L’, L, 𝐿𝑅 , L.L’, L∗ (resp. L+) sont des langages réguliers.


• 2- L’union finie de langages réguliers représente un langage régulier. Ainsi, on peut dire que tout
langage fini représente un langage régulier.
• 3- L’union infinie de langages réguliers peut ou non être un langage régulier.
Expression régulière et automates finis
❖Langages réguliers

Exercice 1

Démontrez, à l’aide de la définition inductive des langages réguliers, que les deux langages
suivants sont réguliers (l’alphabet considéré est Ω= {0; 1}):

1. L’ensemble des mots composés d’un nombre arbitraire de 1, suivis de 01, suivis d’un
nombre arbitraire de 0.
2. L’ensemble des nombres binaires impairs.
Expression régulière et automates finis
❖Langages réguliers

Correction
1. Démontrons que l’ensemble des mots composés d’un nombre arbitraire de 1, suivis de 01, suivis d’un
nombre arbitraire de 0 est un langage régulier.

• On a : L= {1n010m / n,m≥0}
• 1 est une expression régulière donc 1* est aussi une expression régulière
• 01 est une expression régulière
• 0 est une expression régulière donc 0* est aussi une expression régulière
• D’où 1*010* est une expression régulière ce qui implique que L est un langage régulier
Expression régulière et automates finis
❖Langages réguliers

Correction
2. Démontrons que L’ensemble des nombres binaires impairs est un langage régulier.

• On a : L’={(0|1)n1 /n≥0}
• 0* est une expression régulière
• 1* est une expression régulière
• (0|1)*1 est une expression régulière car l’union est une expression régulière,
• Donc L’ est un langage régulier.
Expression régulière et automates finis
❖ Automates finis
Définition
• Un automate fini (AF) est un diagramme de transition qui peut reconnaitre avec précision
ce que les expressions régulières peuvent dénoter.
• Un automate fini est défini par un quintuplet A=(Q, V, δ, q0, F) où:
• Q est un ensemble d’états.
• V est un ensemble de symboles d'entrée (alphabet).
• δ est une fonction de transition qui prend comme argument un état et un symbole d'entrée et
qui retourne un état: δ: Q×V→Q
• q0 est l’état initial de l’automate tel que q0∈Q
• F est un ensemble d’états finals ou états d'acceptation tel que F ⊂ Q
Expression régulière et automates finis
❖ Automates finis
Représentation d’un AF par un graphe de transition
• Un AF est représenté par un graphe (ou diagramme) orienté étiqueté, appelé
graphe de transition tel que :
• L’état initial est désigné par une flèche entrante au sommet correspondant.
• Pour chaque état q, q∈Q, il existe un nœud étiqueté q.
• Pour chaque état q et chaque symbole a de V tel que δ(q; a) = p, il existe un arc du nœud q
vers le nœud p étiqueté a.
• Les nœuds correspondant aux états de satisfaction (états appartenant à F) sont représentés par
un cercle double.

Exemple: Soit le langage L = {akbr/ k≥0 et r >0}.

q0 q1
Expression régulière et automates finis
❖ Automates finis
Représentation d’un AF par une table de transition
La table de transition est un tableau qui permet de représenter la fonction de transition δ(q; a) = p
entre les deux états q et p par le symbole a.
Exemple: Soit l’AF de l’exemple précédent, la table de transition correspondante est:

a b
→ : désigne l’état initial
→ q0 q0 q1
q0 q1
* : désigne l’état final
* q1 - q1
Expression régulière et automates finis
❖ Automates finis
Langage accepté par un automate
• Définition
Soit l’automate d’état finis A=(Q, V, δ, q0, F) , on dit que:
• Tout mot fini W = x0x1x2… xn de V est accepte par un automate A si et seulement si il
existe une séquence q0.q1.q2 ….qn.qn+1 de Q telle que :
- Pour tout 0 ≤ i ≤ n : (qi, xi, qi+1) ∈ δ
- qn+1 appartient à l’ensemble F.
- Le langage accepte par un automate d’état fini est un langage régulier.
Expression régulière et automates finis
❖ Automates finis
Langage accepté par un automate
Exemple:
Le langage accepté par cet automate est:
L = {akbr/ k≥0 et r >0}. q0 q1

• bbab Non
• aaab Oui
• aba Non
• aaa
Expression régulière et automates finis
❖ Automates finis
Automate Fini non déterministe (AFN)
• Un AFN est un AF caractérisé par:
• Plusieurs transitions correspondantes au même symbole sortant d’un même état.
a q2
q a
q1

• Des transitions sur le symbole ε (mot vide): Changer d’état sans avancé dans le mot d’entrée.
ε
q > q1

Exemple d’un AFN


q0 q1 q2
Expression régulière et automates finis
❖ Automates finis
Automate Fini déterministe (AFD)

• Un AFD est un cas particulier des AFN tel que:


• Aucun état n’a de ε transition.
• Pour chaque état q et chaque symbole a, il existe une seule transition possible.

Exemple d’un AFD:

q0 q1
Expression régulière et automates finis
❖ Automates finis
Automate Fini déterministe (AFD)

Exercice : Soit A = {a,b,c}. Pour chacun des langages suivants, donner un automate fini déterministe
(AFD) le reconnaissant :
• l’ensemble des mots dont la longueur est un multiple de 3 ;
• l’ensemble des mots se terminant par b ;
• l’ensemble des mots ne se terminant pas par b ;
• l’ensemble des mots contenant exactement un b ;
• l’ensemble des mots ne contenant aucun b ;
• l’ensemble des mots comportant au moins 3 lettres et dont la troisième lettre à partir de la fin est un a
ou un c ;
Expression régulière et automates finis
❖ Automates finis
Automate Fini déterministe complet (AFDC)

Un automate fini déterministe complet (AFDC) est un automate


déterministe pour lequel chaque état q et chaque symbole a, il existe un et
un seul arc d’étiquette a partant de q.

q0 q1 q0 q1

a
AFD non complet car
pas de a-transition AFD complet
sortant de q1
Expression régulière et automates finis
❖ Automates finis
Transformation de l’AFD en AFDC
Tout AFD peut être transformé en un AFDC reconnaissant le même langage par l’algorithme suivant:
1. Rajouter à l’AFD un nouvel état P non final (« P est appelé état poubelle ou état erreur »)
2. Rajouter les transitions d’étiquettes manquantes en les dirigeant toutes vers cet état poubelle P ; ne pas oublier
les transitions de P vers lui-même .

a,b,c

AFD non complet AFD complet


Expression régulière et automates finis
❖ Automates finis
Transformation de l’AFD en AFDC

• Exemple: rendre cet automates Complet


q0 a q1
b a

q2
Expression régulière et automates finis
❖ Automates finis
Transformation de l’AFD en AFDC

a,b
• Exemple
q0 a q1 b
q3
b a
a,b
q2
Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFND en AFD

✓ Théorème de Rabin et Scott


Tout langage accepté par un AFN est également accepté par un
AFD.
✓ Proposition
Tout AFN (avec ou sans ε-transition) peut être transformé en un
AFD.
Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFN sans ε-transition en AFD
1. A partir de l’état initial E(0)={q0} (c’est l’état initial du nouvel automate);
2. Construire E(1) l’ensemble des états obtenus à partir de E(0) par la transition x:
𝐸 (1) = ራ δ(q’,x)
𝑞′∊𝐸 (0)
3. Recommencer l’étape 2 pour toutes les transitions possibles et pour chaque nouvel ensemble E(k)
𝐸 (𝑘) = ራ δ(q’,x)
𝑞′∊𝐸 (𝑘−1)
4. Tous les ensembles contenant au moins un état final du premier automate deviennent finaux;
5. Renuméroter les états en tant qu’états simples.
Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFN sans ε-transition en AFD
Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFN sans ε-transition en AFD

• Exercice Transformer en AFD l’automates suivant :


Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFN avec ε-transition en AFD
Soit A=(Q, V, δ, q0, F) un AFN et s ∊ V, q ∊ Q et T ⊂ Q on note par:
• ε-fermeture(q): L’ensemble des états de l’AFN accessible depuis q par des ε-transition (q appartient
aussi à cet ensemble).
• ε-transition: la transition sur le symbole ε.

• ε-fermeture(T) = q T ε-fermeture(q)

• Transition(T,s) = q Transition(q,s) =  δ(q,s)


T qT
Exemple
ε
a b c
q0 q1 q2 q3

ε
ε-fermeture(q0)={q2, q1, q0}
Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFN avec ε-transition en AFD
1. A partir de l’ε-fermeture de l’état initial (représente le nouvel état initial)
2. Rajouter dans la table de transition toutes les ε-fermetures des nouveaux états produits avec leurs
transitions;
3. Recommencer l’étape 2 jusqu’à ce qu’il n’y ait plus de nouvel état;
4. Tous les ε-fermetures contenant au moins un état final du premier automate deviennent finaux;
5. Renuméroter les états en tant qu’états simples.

2 3
1
Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFN avec ε-transition en AFD

• Exercice Transformer en AFD l’automates suivant :


Expression régulière et automates finis
❖ Automates finis
Transformation d’un AFN avec ε-transition en AFD
AFN
État a b c
A={0, 1, 3} B={1,2} ---- C={4}
B={1,2} D={2} E={1,3} ----
C={4} ---- ---- ----
D={2} ---- E={1,3} ----
E={1,3} D={2} ---- C={4}

AFD État a b c
A B -- C
B D E --
C -- -- --
D -- E --
E D -- C
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

1. Eliminer les états qui n’ont pas un chemin à


Réduire le nombre Par partir de l’état initial (inaccessible)
Minimiser un AFD d’états 2. Fusionner les états reconnaissant le même
langage.
Pour

➢ Réduire le temps de reconnaissance


➢ Réduire l’espace mémoire utilisé pour sauvegarder l’AFD
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD
1. Nettoyer l’automate en éliminant les états inaccessibles en utilisant l’algorithme de marquage:
Définition: Un état est dit inaccessible s’il n’existe aucun chemin
permettant de l’atteindre à partir de l’état initial.
a
7
Exemple: a
1 2 c,d b
e
• Les états 7 et 3 sont inaccessibles, Donc nous les supprimons. 5 6
c,d
4 b
b
3
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

1. Nettoyer l’automate en éliminant les états inaccessibles en utilisant l’algorithme de marquage:

1. Pour des automates de taille importante, nous utilisons l’algorithme de marquage


pour supprimer les états inaccessibles.
2. Le principe de cet algorithme est de commencer le marquage des états depuis l’ état
initial et marquer les états atteints de bout en bout jusqu’à des états non marques.
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

1. Nettoyer l’automate en éliminant les états inaccessibles en utilisant l’algorithme de marquage:

a a États a b
a b ⇾ *1 ∎ 2 5
1 2 3
a b *2∎ 2 4
b 3∎ 3 2
b b
6 4∎ 5 3
b
a 5∎ 4 6
5 a 4
6∎ 6 1
a
7 5 7
7 b
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

1. Nettoyer l’automate en éliminant les états inaccessibles en utilisant l’algorithme de marquage:


a a a a

a b a b
1 2 3 1 2 3
a b a b
b b b
6 b b 6 b
b b
a a
5 a 4 5 a 4
a
7 b
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD
2. Regrouper les états appartenant à la même classe d’équivalence
Définition: Deux états qi et qj sont dits β-équivalents s’ils permettent d’atteindre les
états finaux en utilisant les mêmes mots. On écrit alors : qiβqj.
Remarques:
1. La relation R (R= β-équivalence) est une relation d’équivalence car elle est:
• Réflexive (pRp), p∈Q
• Symétrique (pRq qRp), p,q ∈Q
• Transitive (pRq et qRq’ pRq’). p,q,q’ ∈Q
2. Le nombre de classes d’équivalence de la relation β-équivalence est égal au nombre des états de l’automate
minimal car les états de chaque classe d’équivalence reconnaissent le même langage (ils seront fusionnés).
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD
2. Regrouper les états appartenant à la même classe d’équivalence
a. Faire deux classes: A contenant les états finaux et B contenant les états non finaux;
b. S’il existe un symbole x et deux états qi et qj d’une même classe tel que δ(qi, x) et δ(qj, x)
n’appartiennent pas à la même classe, alors créer une nouvelle classe et séparer qi et qj. On
laisse dans la même classe tous les états qui donnent un état d’arrivée dans la même classe.
c. Recommencer l’étape 2 jusqu’à ce qu’il n’y ait plus de classes à séparer;
Exemple: soit AFN suivant (initial = 0, finaux = {2,3})
Etat a b Etat a b
0 1 0 0 1 0
1 1 2 1 1 2
2 3 2 2 3 2
3 3 2
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

2. Regrouper les états appartenant à la même classe d’équivalence


États a b
⇾ *1 2 5
Exemple:
*2 2 4
Soit AEF suivant (initial = 1, finaux = {1,2})
3 3 2
1. Nous avons éliminé les états inaccessibles (l’ état 7)
4 5 3
2. Nous ne trouvons pas des états ayant la même fonction donc pour 5 4 6
réduire les états if faut construire des classes d’ équivalence en suivant
l’algorithme de réduction des états. 6 6 1
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD
États a b
2. Regrouper les états appartenant à la même classe d’équivalence ⇾ *1 2 5
*2 2 4
Exemple: 3 3 2
Etape1: Créer deux classes d’ états 4 5 3
1. A= {1,2} (les états finaux) 5 4 6
2. B={3,4,5,6} (Les états non finaux) 6 6 1
Etape 2: Vérifier la cohérence des classes
• On dit qu'une classe A est cohérente par rapport à un symbole a si touts les transitions de A avec le
symbole a mènent a la même class.
• Si une classe n’est pas cohérente il faut la découper au moins en deux partie jusqu'à trouver des classes
cohérentes.
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

2. Regrouper les états appartenant à la même classe d’équivalence


Exemple:
1er Itération : A= {1,2}, B ={3,4,5,6}
États a b
États a b 3 3∊B 2∊A
⇾ *1 2 5 États a b 4 5 ∊B 3∊B
*2 2 4 ⇾ *1 2∊A 5∊B 5 4∊B 6∊B
3 3 2 *2 2∊A 4∊B 6 6∊B 1∊A
4 5 3 A est cohérente B n’est pas cohérente. Il
5 4 6 faut donc l’éclater en deux
6 6 1
classes B={3,6}, A={4,5}
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

2. Regrouper les états appartenant à la même classe d’équivalence


Exemple:
2ème Iteration : A= {1,2}, B ={3,6}, C={4,5}

États a b États a b États a b


⇾ *1 2∊A 5∊C 3 3∊B 2∊A 4 5 ∊C 3∊B
*2 2∊A 4∊C 6 6∊B 1∊A 5 4∊C 6∊B
A est cohérente B est cohérente C est cohérente

➔ Donc AFD contiendra trois états, A, B et C.


Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD
2. Regrouper les états appartenant à la même classe d’équivalence
Exemple:
États a b AFD minimal
⇾ *1 2∊A 5∊C États a b
*2 2∊A 4∊C ⇾*A A C
B B A
États a b
C C B
3 3∊B 2∊A
6 6∊B 1∊A • L’état initiale : la classe qui contient l’ancien
États a b état initial ➔ A.
4 5 ∊C 3∊B • Etats finaux : sot les classes qui contiennent
5 4∊C 6∊B des états finaux ➔ {A}.
Expression régulière et automates finis
❖ Automates finis
Minimisation d’un AFD

2. Regrouper les états appartenant à la même classe d’équivalence

Exemple:
Expression régulière et automates finis
❖ Automates finis

Opérations sur les automates


Complément d’un automate:
Soit A=(Q,V,δ,q0,F) un AFDC reconnaissant le langage L. L’automate reconnaissant le langage
inverse (c’est-à-dire L ou V∗−L) est défini par le quintuplet AC=(Q,V,δ,q0,Q-F) (en d’autres termes, les
états finaux deviennent non finaux et vice-versa).
Exemple:
Expression régulière et automates finis
❖ Automates finis
Opérations sur les automates
Miroir d’un automate:
Soit A=(Q, V, δ, q0, F) un automate reconnaissant le langage L(A). L’automate qui reconnaît le
langage (L(A))R est reconnu par l’automate AR=(Q, V, δR, F, {q0}) tel que : δR(q’,a)=q si δ (q,a)=q’

Remarques
1. Pour définir l’automate AR, il suffit d’inverser les sens des arcs de l’automate et le statut
initial/final des états initiaux et finaux.
2. L’automate AR peut contenir plusieurs états initiaux (ce qui signifie qu’il est le plus souvent non
déterministe).
Expression régulière et automates finis
❖ Automates finis
Opérations sur les automates
Produit de deux automates:
Soit A=(Q,V,δ,q0,F) et A’=(Q’,V’,δ’,q’0,F’) deux automates à états finis. On appelle produit des
deux automates A et A′ l’automate A"=(Q",V",δ",q"0,F") défini comme suit :
Q′′ = Q × Q′; V′′ = V ∪ V′; q′′0 = (q0, q′0); F′′ = F × F′; δ"((q,q’),a)=(δ(q,a),δ’(q’,a))
Remarques:
1. Si m est un mot reconnu par A′′ alors il l’est par A et A’.
2. Si L(A) est le langage reconnu par A et L(A′) est le langage reconnu par le langage A′ alors l’automate
A′′ reconnaît l’intersection des deux langages : L(A)∩L(A′).
Expression régulière et automates finis
❖ Automates finis
Opérations sur les automates
Produit de deux automates: Exemple

Produit de
Automate (1): reconnaît les mots 1 et 2
sur {a, b, c} contenant deux a

Automate (2): reconnaît les mots sur Automate (3): représente le


{a, b, c} contenant deux b produit des deux automates (1) et
(2)
Expression régulière et automates finis
❖ Automates finis
Passage de l’AF (D ou N) vers l’ER
Principes:
• Chaque mot accepté correspond à un chemin de l’état initial vers l’état final.
• L’expression régulière obtenue est l’union de tout les chemins possible.
Exemple:
a a a a,b
Chemin 1: a*
Chemin 2: a*ba* b b b
1 2 3 4
Chemin 3: a*ba*ba*b(a|b)

ER: a*|aba*|a*ba*ba*b(a|b)*
Expression régulière et automates finis
❖ Automates finis
Passage de l’AF (D ou N) vers l’ER
• L'algorithme des équations linéaires en utilisant le lemme d'Arden.
Soit A=(Q,V,δ,q0,F) un automate à états fini quelconque.
On note par Li le langage reconnu par l’automate si son état initial était qi. Par conséquent, trouver le
langage reconnu par l’automate revient à trouver L0 étant donné que la reconnaissance commence à partir
de q0.
L’automate permet d’établir un système d’équations aux langages de la manière suivante:
• Si δ(qi,a)=qj alors on écrit: Li= aLj
• Si qi∈F, alors on écrit: Li=ε.
• Si Li= α et Li=β alors on écrit Li= α| β
Il suffit ensuite de résoudre le système en précédant à des substitutions et en utilisant la règle
suivante: La solution de l’équation L= αL|β est le langage L=α*β.
Expression régulière et automates finis
❖ Automates finis
Passage de l’AF (D ou N) vers l’ER
• L'algorithme des équations linéaires en utilisant le lemme d'Arden.
Exemple: trouvons le langage accepte par cet automate.
Le système d’équations est le suivant:
1) L0= aL0 | bL1 | ε
2) L1= bL0 | aL2
3) L2= aL1 | bL2

On applique le lemme d’Arden:


La solution de l’équation L= αL|β est le langage L=α*β.
Expression régulière et automates finis
❖ Automates finis
Passage de l’AF (D ou N) vers l’ER
• L'algorithme des équations linéaires en utilisant le lemme d'Arden.
Exemple:
L0= aL0 | bL1 | ε L0= aL0 | bL1 | ε L0= aL0 | b(ab∗a)∗bL0| ε
ቐ L1= bL0 | aL2 ቐ L1= bL0 | ab∗aL1 ቐ L1= (ab∗a)∗bL0 L0= (a | b(ab*a)*b)L0| ε
L2= aL1 | bL2 L2= b∗aL1 L2= b∗aL1

On applique le lemme d’Arden a L0: Donc


L0 = (a | b(ab*a)*b)*ε = (a | b(ab*a)*b)*
Donc: ER: (a | b(ab*a)*b)*
Expression régulière et automates finis
❖ Automates finis
Passage de l’ER vers l’AF (D ou N)
La stratégie la plus utilisée consiste à construire tout d’abord l’AFN
correspondant ensuite on la convertit en un AFD ou on utilise la méthode de Glushkov .

Exemple: aa(a|b)* a a (a | b)*


0 1 2 3 4
a b
⇾0 1 - a q3
q0 a a q2
q1
1 2 - b
a
b
*2 3 4
q4
*3 3 4
*4 3 4
Expression régulière et automates finis
❖ Automates finis
Passage de l’AF (D ou N) vers la GR
Soit A=(Q,V,δ,q0,F) un AF, la grammaire qui génère le langage reconnu par A
est G=(VT,VN,R,S) :
• VT = V ;
• Associer à chaque état de Q un non terminal;
• L’axiome S est le non-terminal associé à l’état initial;
• Soit B le non terminal associé à qi et C le non-terminal associé à qj, si δ(qi,a)=qj alors
la grammaire possède la règle de production: B → aC ;
• Si qi est final et B est le non-terminal associé à qi alors la grammaire possède la règle
de production : B → ε.
Expression régulière et automates finis
❖ Automates finis
Passage de l’AF (D ou N) vers la GR
Exemple: a b
• VT = V = {a,b}; b
A B
• VN = {A, B} avec A est l’axiome.
• δ(A,a)=A, on déduit que A→aA, δ(A,b)=B, on déduit que A→bB, A un état final A→ε
➔donc: A→ aA | bB | ε
• δ(B,b)=B, on déduit que B→bB, B un état final B→ε ➔ donc: B→ bB | ε.

✓Donc la grammaire qui génère le même langage que l’automate est définie par G=(VT,VN,R,S)
telle que: VT=V={a,b}, VN={A, B}, A est l’axiome et R={A→ aA | bB | ε, B→ bB | ε}.
Expression régulière et automates finis
❖ Automates finis
Passage de la GR vers l’AF (D ou N)
GR Normalisée:
soit G=(VT,VN,R,S) une grammaire régulière à droite, elle est dite normalisée si toutes les règles de
production sont de l’une des formes suivantes :
• A → a, A∈ VN, a∈ VT ; A → aB, (A, B)∈ VN, a∈ VT ; A → ε, A ∈ VN
Normalisation d’une GR à droite:
1. Pour chaque règle de la forme A → wB (A, B ∈ VN et w ∈ VT* tel que |w|>1, créer un nouveau non-
terminal B′ et éclater la règle en deux : A → aB′ et B′ → uB tel que w = au et a∈VT ;
2. Pour chaque règle de la forme A → w (A ∈ VN et w ∈ VT*) tel que |w| > 1, créer un nouveau non-
terminal B′ et éclater la règle en deux : A→ aB′ et B′→u tel que w=au et a∈VT;
3. Recommencer 1 et 2 jusqu’à ce qu’il n’y ait plus de nouveaux non terminaux ;
4. Pour chaque règle A → B (A, B ∈ VN ) tel que B → β1| β2|...| βn
• Rajouter une règle A → β1| β2|...| βn
• Supprimer la règle A → B
5. Refaire l’étape 4 jusqu’à ce qu’il n’y ait plus de règles de la forme A → B.
Expression régulière et automates finis
❖ Automates finis
Passage de la GR vers l’AF (D ou N)
Soit G=(VT,VN,R,S) une grammaire régulière à droite normalisée, le passage de G vers l’AF
A=(Q,V,δ,q0,F) est trouvé par l’algorithme suivant:
1. V =VT
2. Associer un état à chaque non terminal de VN;
3. L’état initial est associé à l’axiome ;
4. Pour chaque règle de production de la forme A →ε, l’état qA est final ;
5. Pour chaque règle de production de la forme A→x (x∈VT), alors créer un nouvel état final qf
et une transition partant de qA vers qf avec l’entrée x
6. Pour chaque règle A→xB alors créer une transition partant de qA vers l’état qB en utilisant
l’entrée x ;
Remarques:
1. Si les règles de production A→B ne sont pas supprimées dans l’algorithme de normalisation,
il faut ajouter l’étape suivante:
Pour chaque règle A→B alors créer une ε-transition partant de qA vers l’état qB ;
Expression régulière et automates finis
❖ Automates finis
Passage de la GR vers l’AF (D ou N)
Exemple: G={{a,b},{A, B}, {A→ bB | a | ε, B→ bB | ε}, A}.
• Normalisation de G
• A→ a ➔ créer un nouvel état final qf et une transition partant de qA vers qf avec l’entrée a
• V = VT = {a,b};
• q0 A , q1 B donc Q={q0, q1, qf}. b
• F={q0, q1,qf} b q1
q0
• {δ(q0,b)= q1 , δ(q0,a)= qf ; δ(q1,b)= q1}
a

qf
Expression régulière et automates finis
❖ Automates finis

Exercice
Soit la grammaire régulière :

G = ({a, b}, {S, T}, {S→aaS|bbS|bT|aT|ε, T→bT|aT|aaS|bbS}, S).

Trouvez l’automate reconnaissant le langage généré par cette


grammaire puis en déduire son expression régulière.
Plan

• Introduction
• Expression régulière et automates finis
• Grammaires hors-contexte et automates à pile
• Analyse lexicale
• Analyse syntaxique
• Analyse sémantique
• Génération du code
Grammaires hors-contexte et automates à pile
❖ Grammaires hors-contexte

Rappel
Soit G=(VT,VN,R,S) une grammaire quelconque. G est dite hors-contexte ou de type 2 si
toutes les règles de production sont de la forme:
X→Y tel que X∈ VN et Y∈(VT∪VN)*

Remarques
• Le langage généré par une GHC est appelé un langage hors-contexte (ou algébrique).
• La plus part des langages de programmation sont des langages hors-contextes
Exemple :
G = {{a,b}, {S}, {S → ε|aSb}, S}}
Grammaires hors-contexte et automates à pile
❖ Grammaires hors-contexte
Ambiguïté
Une grammaire HC est dite ambiguë si elle peut générer au moins un mot par plusieurs
manière.
En d’autres termes, si on peut trouver un mot généré par la grammaire et possédant au moins
deux arbres de dérivation, alors on dit que la grammaire est ambiguë.

Exemple : Soit la grammaire G = ({0, 1,+, ∗,( ,)}, {E}, {E → E+E|E∗E|(E)|0|1}, E). Cette
grammaire est ambiguë car le mot 1+1*0 possède deux arbres de dérivation.
Grammaires hors-contexte et automates à pile
❖Grammaires hors-contextes propres (GHCP)

Définition
Une grammaire hors-contexte G=(VT,VN,R,S) est dite propre si elle vérifie:
• S→ε,
• A → w avec w ∈ VT+ ,
• A → w avec w∈((VN\{S})UVT)+
• Tous les non terminaux sont utiles, c’est-à-dire qu’ils vérifient :
• ∀ A∈ VN \{S}: A est atteignable depuis S:   ,   (VT  VN \ {S})* : S A
• ∀ A∈ VN : A est productif : ∃w ∈ VT+: A w
Propriété
Il est toujours possible de trouver une grammaire propre pour toute grammaire
hors-contexte.
Grammaires hors-contexte et automates à pile
❖Formes Normales de Chomsky (FNC) d’une GHC

Définition
Soit G=(VT,VN,R,S) une grammaire hors-contexte. On dit que G est sous forme
normale de Chomsky si les règles de G sont toutes de l’une des formes suivantes :
• A → BC, A ∈ VN , B,C ∈ VN\{S}
• A → a, A ∈ VN , a ∈ VT
• S→ε
Propriété
Il est toujours possible de transformer n’importe quelle grammaire hors-contexte
pour qu’elle soit sous la forme normale de Chomsky.
Remarque
Si la grammaire est propre, alors la procédure de transformation sera très facile.
Grammaires hors-contexte et automates à pile
❖Formes Normales de Chomsky (FNC) d’une GHC
Transformation d’une GHCP vers sa FNC
on suppose que la grammaire HC a été rendue propre. Donc toutes les règles sont sous l’une des
formes suivantes :
S→ε, A → w avec w ∈ VT+ , A → w avec w∈((VN\{S})UVT)+
1.La deuxième forme peut être facilement transformée en A → BC. En effet, si w = au, u ∈ VT+ , alors il
suffit de remplacer la règle par les trois règles A → A1A2, A1 → a et A2 → u. Ensuite, il faudra
transformer la dernière règle de manière récursive tant que |u| > 1.
2. Il reste alors à transformer la troisième forme.
Supposons que : w = w1A1w2A2...wnAnwn+1 avec wi ∈ VT* et Ai∈(VN\{S})
• Si w1≠ ε, alors il suffit de transformer cette règle en : A → B1B2 , B1→w1, B2 → A1w2A2...wnAnwn+1
• Sinon, elle sera transformée en : A → A1B , B → w2A2...wnAnwn+1
• Cette transformation est appliquée de manière récursive jusqu’à ce que toutes les règles soient des
règles normalisées.
Grammaires hors-contexte et automates à pile
❖Formes Normales de Chomsky (FNC) d’une GHC
Transformation d’une GHC vers sa FNC
1.Rajouter une nouvelle règle S′ → S tel que S′ est le nouvel axiome ;
2.Éliminer les règles A → ε:
• Pour toute règle B → αAβ de R
• Rajouter la règle B → αβ
• Enlever les règles A → ε
3.Eliminer les règles A→B:
• Pour chaque règle B → u1|...|un , rajouter la règle A → u1|...|un
• Enlever toutes les règles A → B
4.Supprimer tous les non-terminaux non-atteignables:
5.Supprimer tous les non-terminaux non-productifs.
6.Appliquer les règles de transformation d’une GHCP vers sa FNC.
Grammaires hors-contexte et automates à pile
❖Formes Normales de Chomsky (FNC) d’une GHC

Exercice
Transformer G, à sa forme normale de Chomsky.

G=({S’,S},{a,b},{S’→aSbS|aSb|abS|bSaS|bSa|baS|ab|ba|ε,
S→aSbS|aSb|abS|bSaS|bSa|baS|ab|ba}, S’)
Grammaires hors-contexte et automates à pile
❖Formes Normales de Chomsky (FNC) d’une GHC

Exercice
G=({S’,S},{a,b},{S’→aSbS|aSb|abS|bSaS|bSa|baS|ab|ba|ε, S→aSbS|aSb|abS|bSaS|bSa|baS|ab|ba}, S’)

- Les règles S’→ab|ba et S→ab|ba seront remplacées par S’→AB|BA et S→AB|BA avec A→a et B→b
- Les règles S’→bSa|baS et S→bSa|baS seront remplacées par : S’→BA’|BA’’ et S→BA’|BA’’ avec A’→SA
et A’’→AS
- Les règles S’→ aSb|abS et S→ aSb|abS seront remplacées par : S’→AB’|AB’’ et S→ AB’|AB’’ avec
B’→SB et B’’→BS
- Les règles S’→aSbS|bSaS et S→aSbS|bSaS seront remplacées par : S’→A’’B’’|B’’A’’ et S→A’’B’’|B’’A’’
•Donc la FNC de G est :
• S’→AB|BA|BA’|BA’’|AB’|AB’’|A’’B’’|B’’A’’|ε S→AB|BA|BA’|BA’’|AB’|AB’’|A’’B’’|B’’A’’
• A→a A’→SA A’’→AS
• B→b B’→SB B’’→BS
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Définition
- Le langage L= {anbn/n∈IN} est non régulier donc n’est pas reconnu par un automate fini.
G = {{a,b}, {S}, {S → ε|aSb}, S}}
- Il existe une grammaire HC qui permet de générer L, donc L est reconnu par un automate de type 2 ou
automate à pile.
- Alors dans ce cas, on peut dire que la pile est une mémoire qui est ajoutée à l’automate pour compter
le nombre de a du début du mot puis de décompter exactement le même nombre de b.

Un automate à pile possède les différents


éléments d’un reconnaisseur (bande et tête
de lecture, unité de contrôle), sa
particularité est son mode de stockage:
une pile dans laquelle sont stockés des
. symboles d’un alphabet particulier appelé
alphabet de pile.
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)

Définition
Un automate à pile est défini par A=(Q,π,V,δ,Z0,q0,F) où:
- Q: l’ensemble d’états.
- V: l’ensemble d’alphabet
- q0: l’état initiale
- F : l’ensemble d’états finaux.
- π est l’ensemble des symboles utilisés pour écrire dans la pile (l’alphabet de la
pile).
- Z0∈ π : est le symbole initial de la pile.
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Définition
Un automate à pile est défini par A=(Q,π,V,δ,Z0,q0,F) où:
- δ est la fonction de transition: prend comme argument le triple (q, a, U) où:
• q est un état de Q.
• a est le symbole d’ entrée de V ou le mot vide ε.
• U est le sommet de la pile
- La fonction δ retourne une paire (p, α) où :
• α indique le nouveau contenu de la pile.
• P est le nouvel état.

- L’exécution d’une transition δ(q, a, U)= (p, α) modifie le contenu de la pile selon
le mot α comme suit :
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Si α = v1 ……vn alors δ(q, a, U)= (p, V1 ……Vn)

✓ Si l’état q, si le symbole lu est ‘a’ et si le sommet de la pile est ‘U’


✓ Alors le sommet de pile est dépilé ensuite on empile v1 ……vn et on passe a l’état p.
➔ le sommet de pile contiendra Vn

Dépiler le Empiler le
sommet de pile mot v1 ……vn
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Si α = U alors δ(q, a, U)= (p, U)

✓ Si l’état q, si le symbole lu est ‘a’ et si le sommet de la pile est ‘U’


✓ Alors passe a l’état p et ne rien faire avec la pile .
✓ ➔ Si α = U alors la pile est inchangée, le sommet de la pile reste U.

Dépiler le Empiler le
sommet de pile mot U La pile est inchangée
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Si α = ε alors δ(q, a, U)= (p, ε)

✓ Si l’état q, si le symbole lu est ‘a’ et si le sommet de la pile est ‘U’


✓ Alors le sommet de pile est dépilé et on passe a l’état p.
✓ ➔ Si α = ε on dépilé le Sommet de la pile.

Le sommet de la pile
Dépiler le
sommet de pile
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Mode de reconnaissance
Il existe 2 modes de reconnaissance pour les automates à pile:
1- Reconnaissance par état final: Un mot m est accepté par un AP si après avoir lu
tout le mot m, l’automate se trouve dans un état final quelque soit le contenu de la
pile.
2- Reconnaissance sur pile vide: Un mot m est accepté par un AP si après avoir lu
tout le mot m, la pile est vide quelque soit l’état de l’automate.

Remarques:
• Ces deux modes sont équivalents, donc, dans ce qui suit, on accepte un mot si le ruban
vide (après avoir lu tout le mot), on est sur l‘état final et la pile vide
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Mode de reconnaissance
Remarques:
Ces deux modes sont équivalents, donc, dans ce qui suit, on accepte un mot si le
ruban vide (après avoir lu tout le mot), on est sur l’état final et la pile vide
• Un mot m est rejeté par un AP si:
- Aucune transition n’est possible (l’automate n’a pas pu lire tout le mot)
- L’automate se trouve dans un état non final.
- La pile est non vide.
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Exemple
L’automate reconnaissant les mots anbn (avec n ≥ 0) est le suivant :
A=({q0,q1,q2,q3}, {Z0}, {a,b},δ,q0,{q3}) telle que δ est définie par:
1. δ(q0, a, Z0) = (q1, Z0a) || Lire et empiler le 1er ‘a’ .
2. δ(q1, a, a) = (q1, aa) || Lire et empiler les ‘a’ suivants.
3. δ(q1, b, a) = (q2, ε) || dépiler le ‘a’ et Lire ‘b’.
4. δ(q2, b, a) = (q2, ε) || dépiler le ‘a’ et Lire ‘b’.
5. δ(q2, ε, Z0) = (q3, Z0) ||le nombre de ‘a’ est égal au ‘b’ on change l’ état.
6. δ(q0, ε, Z0) = (q3, Z0)
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)
Exemple : L’automate reconnaissant les mots anbn (avec n ≥ 0) est le suivant :
a, a→aa b, a→ε

q0
a, z0→z0a q1 b, a→ε q2 ε, z0→ z0 q3
ε, z0 → z0

Traitement des mots: aabb, aab, abb et ε


1- Le mot aabb: Le mot est reconnu.
2- Le mot aab: Le mot n’est pas reconnu car il n’y a plus de transitions possibles alors que l’état de
l’automate n’est pas final
3- Le mot abb: Le mot n’est pas reconnu car on n’arrive pas à lire tout le mot ;
4- Le mot ε: (q0, ε, z0) →(q3, ε, z0). Le mot est reconnu.
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)

• Grammaire hors-contexte vers un automate à pile

• Pour tout langage généré par une grammaire hors-contexte, il existe un automate
à pile qui le reconnaît.
• Réciproquement, pour tout langage reconnu par un automate à pile, il existe une
grammaire hors-contexte qui le génère.
Grammaires hors-contexte et automates à pile
❖ Automate à pile (AP)

Exercice :
Construire l’automate à pile du langage suivant L={mcmR tel que m∈ {a,b}*}.
Plan

• Introduction
• Expression régulière et automates finis
• Grammaires hors-contexte et automates à pile
• Analyse lexicale
• Analyse syntaxique
• Analyse sémantique
• Génération du code
Analyse lexicale

Définition
À partir du programme source, qui se présente comme un flot de caractères, l'analyse
lexicale permet de reconnaitre des unités lexicales, qui sont les mots que l'analyseur
syntaxique va ensuite les utiliser.

Remarques:
1-Les unités lexicales seront stockées au fur et à mesure dans la table de symboles.
2-L’opération du lecture du texte source doit s’accompagner avec des tâches supplémentaires:
Eliminer les blancs, les commentaires, fin de lignes, gérer les numéros des lignes pour
l’utiliser dans le cas d’une erreur rencontrée, …..
3-L’analyseur lexical doit signaler chaque présence d’erreur dans le texte d’entrée.
➔ associer à chaque erreur détecter le numéro de sa ligne.
Analyse lexicale
• Lexème, unité lexicale

Lexème (ou Token): est une chaîne de caractères qui constitue une seule entité tirée à
partir du texte source. Par exemple dans l’instruction suivante:
Exemple: aire:=base * hauteur / 2, l’analyseur lexical reconnaît les lexèmes suivants

Unité lexicale: est un type de lexème qui est un symbole terminal qui rentre dans la
construction du langage source. Pour l’exemple précédent, on trouve:
Lexèmes Unité lexicale
aire , base , hauteur identificateur
:= op-affectation
*,/ op-arithmétique
Analyse lexicale
❖Modèle

Modèle:
• Est une règle associée à une unité lexicale qui décrit l’ensemble des chaines
(Lexème) du programme qui peuvent appartenir à cette unité lexicale.
• Nous utilisons les expressions régulières ou les automates finis pour représenter
les modèles des unités lexicales.

Exemple: lettre | _ | chiffre

- Modèle identificateur:
0 1
Lettre

- ER: lettre(lettre|chiffre)* = [a-zA-Z][a-zA-Z0-9]*


Analyse lexicale
❖Modèle

Définitions régulières: Une définition régulière est une suite de définitions


de la forme:

• d1 r1 Chaque di est un nom distinct


• d2 r2 et chaque ri est une expression
• ………… régulière.
• dn rn
Analyse lexicale
❖Définitions régulières

Exemples:
1- Définition régulière d'un identificateur:
lettre A|B|…Z|a|b|…|z|_
chiffre 0|1|2|…………|9
id lettre(lettre|chiffre)*
2- Définition régulière des entiers signés et non signés:
chiffre 0|1|2|…………|9
entier [+|-]? (chiffre)+
Analyse lexicale
❖Définitions d’attribut
Définition
Un attribut est toute information supplémentaire inutile pour l’analyseur
syntaxique mais utile pour les autres phases de la compilation.

Exemple:

• Lors d’analyse sémantique on aura besoin du type de la variable.


• Lors de la génération de code on aura besoin de l’adresse de la variable

➔ l’adresse et le type des variables sont des attributs.


Analyse lexicale
❖ Construction de l’analyseur lexical (FLEX)

• Un programme écrit en langage LEX construit d'une manière automatique


un analyseur lexical.

1. Il prend en entrée un ensemble d'expressions régulières et de définitions régulières et


produit en sortie un code cible en langage C.

• Ce code en langage C doit être compilé par le compilateur du langage C pour produire
un exécutable qui est un analyseur lexical correspondant au langage défini par les
expressions régulières d'entrée.

• Plusieurs langages dérivés de LEX existent;


Flex produit du C++
Jlex produit du Java
Analyse lexicale
❖ Construction de l’analyseur lexical (FLEX)
Structure d'un programme FLEX:

Un programme source en langage Lex est constitué de 3 sections délimitées par %%:

//1ère partie: déclarations


%{
déclarations pour le compilateur C
%}
définitions régulières
%%
// 2ème partie: règles de traduction
expressions régulières + actions à réaliser
%%
// 3ème partie fonctions en C
Fonctions annexes en langage C
Analyse lexicale
❖ Construction de l’analyseur lexical (FLEX)
Structure d'un programme FLEX:

La 1ère partie est constituée de:


- déclarations en langage C des bibliothèques, variables, structures, unions...
- déclarations de définitions régulières utilisables par les règles de traduction
Exemple: 1ère partie:
//déclarations en C
%{
#include<stdio.h>
%}
lettre [a-zA-Z]
chiffre [0-9]
id {lettre}({lettre}|{chiffre})*
%%
Analyse lexicale
❖ Construction de l’analyseur lexical (FLEX)
Structure d'un programme FLEX:
La 2ème partie a la forme:
m1 {action1} avec mi une expression régulière ou une
m2 {action2} définition régulière de la 1ère partie
... .... Et
mi {actioni} actioni est l'action à réaliser par l'analyseur
... .... lexical si un lexème est accepté par mi.
mn {actionn}

Exemple: 2ème partie: //yytext est un pointeur sur la chaîne analysée.


{id} {printf("\n Identificateur: %s\n",yytext);}
"==" {printf("\n Operateur relationnel: EGA\n");}
"(" {printf("\n PO\n");}
")" {printf("\n PF\n");}
%%
Analyse lexicale
❖ Construction de l’analyseur lexical (FLEX)
Structure d'un programme FLEX:
La 3ème partie est une suite de fonctions en C qui aident à l'analyse dans l'analyse par
les règles de traduction de la 2ème partie.
Cette partie peut contenir une fonction main du langage C.
Exemple:3ème partie:
int main(){
FILE *fichier;
printf("Nom du fichier à analyser");
scanf("%s", &fichier);
yyin = fopen(fichier, "r"); //yyin le flux d'entrée sur le fichier.
yylex(); //yylex() est la fonction principale du programme écrit en LEX
return 0; }
Analyse lexicale
❖ Construction de l’analyseur lexical (FLEX)
Symbole Signification
X Le caractère 'x’ R{2,} Deux R ou plus
[a-z] N'importe quel caractère entre a et z R{2} Exactement deux R
[xyz] Soit x, soit y, soit z "[xyz\"foo" La chaine '[xyz"foo'
. N'importe quel caractère sauf \n RS R suivi de S
[^bz] Tous les caractères, SAUF b et z
R|S R ou S
[^a-z] Tous les caractères, SAUF ceux
R/S R, seulement s'il est suivi par S
compris entre a et z
R* Zero R ou plus, ou R est n'importe
quelle expression reguliere ^R R, mais seulement en debut de ligne
R+ Un R ou plus R$ R, mais seulement en fin de ligne
R? Zero ou un R (c'est-a-dire un R <<EOF>> Fin de fichier
optionnel)
R{2,5} Entre deux et cinq R
Analyse lexicale
❖ Construction de l’analyseur lexical (FLEX)

Exemple
blancs [\t\n ]+
lettre [A-Za-z]
chiffre [0-9] /* base 10 */
mot-cle-if if
identificateur {lettre}(_|{lettre}|{chiffre})*
entier {chiffre}+
exposant [eE][+-]?{entier}
Analyse lexicale
❖ Construction de l’analyseur lexical (automate)

1. Implémenter tous les modèles (automates) représentant les unités lexicales du langage traité.
Exemples: Identificateurs, Mots clés, Nombres, Opérations relationnelles, Opérations logiques,
opérations arithmétiques, …….
2. Traiter le programme source caractère par caractère pour:
• Extraire les lexèmes reconnus par leur automates et les enregistrer dans une table des
symboles avec d’autre attributs.
• Gérer les erreurs pour les lexèmes non reconnus.
Exemples: Lexèmes Unités lexicales Attributs
x:=y+30 x,y identificateur Adresse de x et y: Pour le GC
Type de x et y: Pour l’AS
:= op-affectation
. + op-arithmétique
30 nombre Type: Pour l’AS
Analyse lexicale
❖ Construction de l’analyseur lexical (automate)
1. Implémenter tous les modèles:
Pour chaque automate représentant une unité lexicale du langage source,
implémenter en java (ou un autre langage) une fonction booléenne portant le
même nom que l’unité lexicale traitée.

Exemple: Automate d’un identificateur


int identificateur(){
Remplir sa table de transition Tran[ ][ ] à partir de l’automate correspondant.
Remplir sa table F[ ] des états finaux.
if (AFD (Tran, F)) // Fonction d’automate fini déterministe
{
nom:= lexeme;
unlex:= "iden";
return 1
}
else return 0; }
Analyse lexicale
❖ Construction de l’analyseur lexical (automate)
II- Traitement du programme source : Algorithme
Répéter
Copier une partie du programme source dans le tampon.
Répéter
Positionner les pointeurs ptrdeb et ptrfin sur le 1er caractère du prochain lexème.
getlex

Déplacer ptrfin sur le tampon jusqu’à trouver un modèle ou une erreur.


Enregistrer chaque lexème reconnu dans la table des symbole
Enregistrer les erreurs rencontrées.
Jusqu’à la fin du tampon
Jusqu’à la fin du programme source.
Afficher toutes les erreurs enregistrées.

Remarque:
Toutes les instructions du bloc (Répéter….jusqu’à la fin du tampon) peuvent être implémentées dans une
seule fonction getlex().
Analyse lexicale
❖Gestionnaire de la table de symbole (GTS)
C’est une structure de données contenant des informations sur chaque lexème utilisé dans le code
source en cours d’analyse. La table de symboles est considérée comme un intermédiaire entre toutes les
phases d’un compilateur pour échanger les informations sur les lexèmes enregistrés.
Structure de la TS:
typedef struct ptrTS { char nom[20]; // Attribut: Lexème
char unilex[20]; // Attribut: Unité lexicale
int * adr //Attribut: Adresse mémoire sur la valeur du lexème
int taille //Attribut: Taille de la valeur du lexème
……………
type attribut // TS peut contenir d’autres attributs (par exemple: type de lexème, ..)
ptrTS *suc //pointeur sur un autre symbole
} STTS
Remarque:
A chaque fois que l’analyseur lexical rencontre une unité lexicale pour la première fois, le GTS doit
enregistrer les informations (attributs) actuellement disponibles (nom , unilex). Les autres informations
seront enregistrées lors du traitement des autres phases d’analyse.
Analyse lexicale
❖Erreurs lexicales

Un analyseur lexical doit détecter la présence d’une erreur et la signaler,


un bon analyseur lexical ne doit pas s’arrêter devant la 1ère occurrence
d’une erreur rencontrée.

Exemples:
- Un caractère n’appartient pas à l’alphabet.
- Un commentaire non fermé.
- Un mot clé non terminé
Plan

• Introduction
• Expression régulière et automates finis
• Grammaires hors-contexte et automates à pile
• Analyse lexicale
• Analyse syntaxique
• Analyse sémantique
• Génération du code
Analyse syntaxique
❖ Définition
L'analyse syntaxique (ASy) est un processus qui permet de vérifier si les éléments proviennent
de l’analyseur lexical (par getlex()) forment une chaine d’unité lexical acceptée par la grammaire du
langage .
unité lexicale
Analyseur Analyseur Arbre Syntaxique Analyseur
Lexical Syntaxique Semantique
Lire prochaine unité lexicale
Message d’erreur pour aider à
corriger le fichier source

Table des symboles Non + Message d’erreur


pour aider à corriger le
fichier source

Donc l’objectif de l’ASy est de:


1. Vérifier que le texte d’entrée est conforme à la grammaire.
2. Construire une représentation intermédiaire (arbre syntaxique) pour les autres modules du compilateur.
3. Indiquer les erreurs de syntaxe et éventuellement de poursuivre l’analyse après une erreur (reprise sur
erreur).
Analyse syntaxique
❖ Méthode de construction de l’ASy
Il existe fondamentalement deux méthodes pour construire l’ASy:

1. Analyse descendante (top-down): construction de l'arbre syntaxique en partant de la


racine vers les feuilles

2. Analyse ascendante (bottom-up): construction de l'arbre syntaxique en partant des


feuilles vers la racine
Analyse syntaxique
❖ Méthode de construction de l’Asy
1. Analyse descendante (top-down):
Construction d’un arbre d’analyse à partir de l’axiome vers les feuilles (chaine
d’entrée) par des dérivation à gauche: On part de l’axiome, puis on essaye les
dérivations (à gauche) successives de chaque non-terminal jusqu’à arriver aux symboles
terminaux de la phrase à analyser (retrouver la chaine d’entrée ou échec).
Exemple:
Grammaire Chaine Reconnaissance
S →ABC ch= abcd S →ABC →abBC→abbcC→abbcd Echec
A → ab|a S →ABC →abBC→abacC→abacd Echec
B → bc|ac S →ABC →aBC→abcC→abcd Succès
C→d

• Cette analyse peut impliquer des retours arrière


• On essaie la seconde alternative de A et on obtient l’arbre suivant.
Analyse syntaxique
❖ Méthode de construction de l’Asy
1. Analyse descendante (top-down):

Exemple: l'arbre syntaxique


de la chaîne id + id * id
Grammaire:{
E → TE’
E' → +TE’|ε
T → FT’
T' → *FT’|ε
F → (E) | id
}
Analyse syntaxique
❖ Construction d’analyseur syntaxique descendant

Il existe deux algorithmes pour construire l’ASyD :

1. Analyse par descente récursive

2. Analyse prédictive
Analyse syntaxique
❖ Construction d’analyseur syntaxique descendant

1. Analyse par descente récursive: est une méthode d’ASyD dans laquelle on
exécute un ensemble de procédure (ou fonction) récursive pour traiter l’entrée en
question. Cette analyse peut impliquer des retours arrière.
Exemple : Soit la grammaire définit par S → cAd , A → ab|a et soit la chaîne W = cad.
1. Un pointeur d’entrée repère c, le premier symbole de W. on utilise alors la
première règle de production de S, pour aboutir à l’arbre suivant :S ➔ cAd.
2. on avance le pointeur d’entrée sur a, seconde symbole de W. on utilise alors la
première règle de production de A, pour aboutir à l’arbre suivant :S ➔ cAd ➔
cabd.
3. comme b != d on signale un échec et on retourne à A pour voir s’il existe une autre
alternative non encore essayer.
4. En retournant à A on doit remettre le pointeur d’entrée en position 2. On essaie la
seconde alternative de A et on obtient l’arbre suivant : S ➔ cAd ➔ cad.
Analyse syntaxique
❖ Méthode de construction de l’Asy
Analyse par descente récursive:

S →ABC A → ab|a B → bc|ac C→d


int S( ) int A( ) int B( ) int C( )
{ if A( ) { getlex( ); { getlex( ); { getlex( );
{ if B( ) if(!strcmp (unilex, ‘a’) if(!strcmp (unilex, ‘b’) if(!strcmp (unilex, ‘d’)
{ if C( ) return 1; { getlex( ); { getlex( ); return 1;
else return 0; if(!strcmp (unilex, ‘b’); if(!strcmp (unilex, ‘c’); return 0;
} return 1; return 1; }
else return 0; else return 0; else return 0;
} } }
else return 0; if(!strcmp (unilex, ‘a’) if(!strcmp (unilex, ‘a’)
} return 1; { getlex( );
else return 0; if(!strcmp (unilex, ‘c’);
} return 1;
else return 0;
}
return 0;
}
Analyse syntaxique
❖ Méthode de construction de l’Asy
Analyse par descente récursive:

Problème:
L’analyse par descente récursive nécessite un rebroussement (retour en arrière.
Comme par exemple: A→ab|a) ce qui n’est pas toujours facile à implanter.
Solution:
Analyseur prédictif sans rebroussement
Analyse syntaxique
❖ Méthode de construction de l’Asy
❖Analyse prédictive

• L’analyseur prédictif est un analyseur par descente récursive ou non sans


rebroussement (déterministe) qui permet de déterminer laquelle des alternatives à
prendre à partir des productions de la forme: A → β1|β2| ……|βn .

• Pour pouvoir construire un analyseur prédictif sans rebroussement, la grammaire


doit être déterministe ou LL(1) (LL: lecture du texte de gauche à droite selon des
dérivations gauches)
Analyse syntaxique
❖ l’ASyD prédictive:
❖ Notion : Table d'analyse LL, First et Follow

• La table d'analyse LL permet d'indiquer quelle règle de la grammaire à appliquer.


Lecture des lettres de la gauche (Left : le premier L de LL) vers la droite.
Dérivation des non-terminaux les plus à gauche (Left : deuxième L de LL).

• Pour construire la table d'analyse LL , on a besoin de calculer deux types


d'ensembles de terminaux:
➢ PREMIER « First() ».
➢ SUIVANT « Follow() ».
Analyse syntaxique
❖ l’ASyD prédictive:
❖ Notion : Table d'analyse LL, First et Follow
Définition: PREMIER « First() »:
Premier de α désigne l'ensemble des terminaux qui commencent les chaînes qui se dérivent de α
• Si X est un terminal alors First(X)={X}
• Si X est un non-terminal et que X → Y1Y2....Yk est une production
• pour k>=1, alors ajouter a à First(X) si pour certain i, a Є First(Yi), et ε est dans First(Y1),...,
First(Yi-1); c-à-d que: Y1Y2....Yi-1 =*> ε.
• Si ε Є First(Yj) pour j=1,2,…,k, alors ajouter ε à First(X). la règle s'applique ainsi de suite sur tout
les éléments de la production.
• Si α=*> ε alors ε est aussi dans l'ensemble premier(α) ➔ ε Є First(α).
Exemple S →ABC ; A → ab|a ; B → bc|ac ; C → d.
First(S)={a} ; First(A)={a} ; First(B)={a,b} ; First(C)= {d}.
Analyse syntaxique
❖ l’ASyD prédictive:
❖ Notion : Table d'analyse LL, First et Follow
Exemple:

- Soit la grammaire :
• S → Ba
• B → cP| bP| P| ε
• P → dS
• First(S):
• On a S → Ba → εa = a donc a Є first(S)
• On a S → Ba →cPa donc c Є First(s)
• On a S → Ba → bPa donc b Є first(S)
• On a S → Ba → Pa → dSa donc d Є First(S)

First(S)= {a,c,b,d}
Analyse syntaxique
❖ l’ASyD prédictive:
❖ Notion : Table d'analyse LL, First et Follow
Définition: SUIVANT « Follow() »:
Pour chaque symbole non-terminal A, suivant(A) définit l'ensemble des terminaux à qui peuvent
apparaître immédiatement à droite de A dans toute chaînes de symboles constituant les règles de production.

• Si A est l'axiome de la grammaire alors ajouter $ à suivant de A. ➔ $ Є Follow(A).


• Si la règle X → AaB et a est un terminal alors ajouter a à suivant(A). ➔ a Є Follow(A).
• Si la règle X → αA, alors ajouter l'ensemble suivant(X) à suivant(A). ➔ Follow(X) Є Follow(A).
• Si la règle A → αBβ, le contenu de First(β) à l'exception de ε est ajouté à suivant(B). ➔ First(β) Є
Follow(B)
• Si la règle A → αBβ tel que First(β) contient ε, les éléments de Follow(A) sont ajoutés à Follow(B).
• Exemple S →ABC ; A → ab|a ; B → bc|ac ; C → d.
Follow(A)={a,b} ; Follow(B)={d}.
Analyse syntaxique
❖ l’ASyD prédictive:
❖ Notion : Table d'analyse LL, First et Follow
❖SUIVANT « Follow() »:
• Exemple
S → Ba | Sc ; B → P | ε ; P → dS
• Follow(S) = {c, Follow(P)} = {c, Follow(B)} = {c, a}= {$, a, c}

• Exemple
S → Ba | Sc ; B → cP | bPb |P| ε ; P → dS
• Follow(S) = {c, Follow(P)} = {c, b, Follow(B)} = {c, b, a}= {$, a, b, c}
Analyse syntaxique
❖ l’ASyD prédictive:
❖ Notion : Table d'analyse LL, First et Follow

Exemple :
S→aSb|cd|SAe; A→aAdB|ε; B→bb

First Follow
S a c $b ae
A a ε e d
B b e d
Analyse syntaxique
❖ l’ASyD prédictive:
❖ Notion : Table d'analyse LL, First et Follow

Exercice:
Soit la grammaire G=(VT, VN, R,E) telle que: VT=(+,*,(,),nbr), VN=(E,T,F,E’,T’) et R :
• E→TE’
• E’→+TE’ | ε
• T→FT’
• T’→*FT’ |ε
• F→(E) | nbr
1- Calculer les deux ensembles First et Follow pour les éléments de VN .

Vous aimerez peut-être aussi