Cm02 Intro THL
Cm02 Intro THL
Alexis Nasr
Carlos Ramisch
Manon Scholivet
Compilation – L3 Informatique
Département Informatique et Interactions
Aix Marseille Université
1 / 76
Langages
Grammaires
Arbres de dérivation
Types de grammaires
Reconnaisseurs
Généralités
Automates finis
Automates à pile
Machines de Turing
2 / 76
Langages
Grammaires
Arbres de dérivation
Types de grammaires
Reconnaisseurs
Généralités
Automates finis
Automates à pile
Machines de Turing
3 / 76
Le paysage syntaxique
4 / 76
Exemples de langages
5 / 76
Opérations sur les langages
Union L1 ∪ L2 { x | x ∈ L1 ou x ∈ L2 }
Intersection L1 ∩ L2 { x | x ∈ L1 et x ∈ L2 }
Différence L1 − L2 { x | x ∈ L1 et x ∈
/ L2 }
Complément L̄ { x ∈ Σ∗ | x ∈
/ L}
Concaténation L1 L2 { xy | x ∈ L1 ety ∈ L2 }
n
z }| {
Auto concaténation L...L Ln
L∗ Lk
S
Fermeture de Kleene k ≥0
6 / 76
Comment décrire un langage ?
Énumération
L2 = {ε, ab, aabb, aaabbb, aaaabbbb, . . .}
Description littéraire
Ensemble des mots construits sur l’alphabet { a, b}, commençant par
des a et se terminant par des b et tel que le nombre de a et le nombre de
b soit égal
Grammaire de réécriture
G = h{S}, { a, b}, {S → aSb | ε}, Si
7 / 76
Langages
Grammaires
Arbres de dérivation
Types de grammaires
Reconnaisseurs
Généralités
Automates finis
Automates à pile
Machines de Turing
8 / 76
Grammaires de réécriture
9 / 76
Notation
α → β1 | β2 | . . . | βn
les n règles :
α → β1 , α → β2 , . . . , α → βn
10 / 76
Proto-mots d’une grammaire
S est un proto-mot de G
si αβγ est un proto-mot de G et β → δ ∈ P alors αδγ est un
proto-mot de G.
Un proto-mot de G ne contenant aucun symbole non-terminal est
appelé un mot engendré par G. Le langage engendré par G, noté
L( G ) est l’ensemble des mots engendrés par G.
11 / 76
Dérivation
αβγ ⇒ αδγ
k
On note α ⇒ β pour indiquer que β se dérive de α en k étapes.
+ ∗
On définit aussi les deux notations ⇒ et ⇒ de la façon suivante :
+ k
α ⇒ β ≡ α ⇒ β avec k > 0
∗ k
α ⇒ β ≡ α ⇒ β avec k ≥ 0
Attention
Les symboles ⇒ et → ne représentent pas la même chose.
12 / 76
Conventions
13 / 76
Langage engendré par une grammaire
14 / 76
L1 = {ε, a, aa, aaa, . . .}
15 / 76
L2 = {ε, ab, aabb, aaabbb, aaaabbbb, . . .}
16 / 76
L3 = { aa, bb, aaaa, abba, baab, bbbb, . . .}
17 / 76
L4 = {ε, abc, aabbcc, aaabbbccc, . . .}
S → aS1 c, S1 → b | SS2 ,
G = h{S, S1 , S2 }, { a, b, c}, , Si
cS2 → S2 c, bS2 → bb
aS1 c
H
HH
abc aSS2 c
aaS1 cS2 c
HH
H
aabcS2 c aaSS2 cS2 c
aabS2 cc
aabbcc
18 / 76
Sens de dérivation
E ⇒ T+E
⇒ T+T
⇒ F+T
⇒ F+F∗T
⇒ F+a∗T
⇒ F+a∗F
⇒ a+a∗F
⇒ a+a∗a
19 / 76
Sens de dérivation
E ⇒ T+E E ⇒ T+E
⇒ F+E ⇒ T+T
⇒ a+E ⇒ T+F∗T
⇒ a+T ⇒ T+F∗F
⇒ a+F∗T ⇒ T+F∗a
⇒ a+a∗T ⇒ T+a∗a
⇒ a+a∗F ⇒ F+a∗a
⇒ a+a∗a ⇒ a+a∗a
20 / 76
Arbre de dérivation
E
H
HH
H
T + E
F T
HH
a F * T
a F
21 / 76
Arbre de dérivation
22 / 76
Ambiguïté
a a a a
23 / 76
Symboles et règles de production utiles
24 / 76
Types de règles
Les grammaires peuvent être classées en fonction de la forme de leurs
règles de production. On définit cinq types de règles de production :
25 / 76
Type d’une grammaire
26 / 76
Hiérarchie de Chomsky
0 : sans restriction
1 : contextuelle
2 : hors-contexte
3 : régulière
27 / 76
Type d’un langage
Type Nom
3 régulier
2 hors contexte
1 dépendant du contexte
0 récursivement énumérable
28 / 76
Exemples de langages réguliers
L1 = {m ∈ { a, b}∗ }
29 / 76
Exemples de langages réguliers
L1 = {m ∈ { a, b}∗ }
G1 = h{S}, { a, b}, {S → aS | bS | ε}, Si
29 / 76
Exemples de langages réguliers
L1 = {m ∈ { a, b}∗ }
G1 = h{S}, { a, b}, {S → aS | bS | ε}, Si
29 / 76
Exemples de langages réguliers
L1 = {m ∈ { a, b}∗ }
G1 = h{S}, { a, b}, {S → aS | bS | ε}, Si
29 / 76
Exemples de langages réguliers
L1 = {m ∈ { a, b}∗ }
G1 = h{S}, { a, b}, {S → aS | bS | ε}, Si
29 / 76
Exemples de langages hors-contexte
L1 = { a n b n | n ≥ 0}
30 / 76
Exemples de langages hors-contexte
L1 = { a n b n | n ≥ 0}
G1 = h{S}, { a, b}, {S → aSb | ε}, Si
30 / 76
Exemples de langages hors-contexte
L1 = { a n b n | n ≥ 0}
G1 = h{S}, { a, b}, {S → aSb | ε}, Si
30 / 76
Exemples de langages contextuels
L1 = { a n b n c n | n ≥ 0}
31 / 76
Exemples de langages contextuels
L1 = { a n b n c n | n ≥ 0}
G1 = h{
S, B, B̄, C }, { a, b, c},
S → aSBC | ε, CB
→ B̄B,
B̄B → B̄C, B̄C → BC,
, Si
aB → ab, bB → bb,
bC → bc, cC → cc
L2 = {m]m | avec m ∈ { a, b}∗ }
...
31 / 76
Grammaire v/s Reconnaisseur
32 / 76
Langages
Grammaires
Arbres de dérivation
Types de grammaires
Reconnaisseurs
Généralités
Automates finis
Automates à pile
Machines de Turing
33 / 76
Représentation graphique d’un reconnaisseur
BANDE D’ENTREE
TETE DE LECTURE
UNITE DE CONTROLE
MEMOIRE
AUXILIAIRE
34 / 76
Éléments d’un reconnaisseur
Un reconnaisseur est composé de quatre parties :
1 une bande de lecture
elle est composée d’une succession de cases.
Chaque case pouvant contenir un seul symbole d’un alphabet
d’entrée.
C’est dans les cases de cette bande de lecture qu’est écrit le mot à
reconnaître.
2 une tête de lecture
Elle peut lire une case à un instant donné.
La case sur laquelle se trouve la tête de lecture à un moment donné
s’appelle la case courante.
La tête peut être déplacée par le reconnaisseur pour se positionner
sur la case immédiatement à gauche ou à droite de la case courante.
3 une mémoire
Elle peut prendre des formes différentes.
La mémoire permet de stocker des éléments d’un alphabet de
mémoire.
35 / 76
Éléments d’un reconnaisseur
36 / 76
Configuration et mouvement
37 / 76
Configurations
configuration initiale
L’unité de contrôle est dans un état initial
La tête est au début de la bande
La mémoire contient un élément initial.
configuration d’acceptation
L’unité de contrôle est dans un état d’acceptation
La tête de lecture est à la fin de la bande
La mémoire se trouve dans un état d’acceptation.
38 / 76
Déterminisme
39 / 76
Reconnaissance
40 / 76
Automates finis
a
1 3
a b c a
0 2
b
41 / 76
Définition
δ : Q × (Σ ∪ {ε}) → ℘( Q)
q0 ∈ Q est l’état initial,
F ⊆ Q est l’ensemble des états d’acceptation.
42 / 76
Exemple
h Q, Σ, δ, q0 , F i
Q = {0, 1, 2, 3}
a
1 3 Σ = { a, b, c}
δ(0, a) = {1}
δ(0, b) = {2}
a b c a
δ(1, a) = {3}
δ(1, b) = {0}
0 2 δ(2, c) = {3}
b δ(3, a) = {2}
q0 = 0
F = {1, 3}
43 / 76
Configurations et mouvement
A = h Q, Σ, δ, q0 , F i
Configuration : (q, m) ∈ Q × Σ∗ où :
q représente l’état courant de l’unité de contrôle
m est la partie du mot à reconnaître non encore lue. Le premier
symbole de m (le plus à gauche) est celui qui se trouve sous la tête
de lecture. Si m = ε alors tout le mot a été lu.
Configuration initiale : (q0 , m) où m est le mot à reconnaître
Configuration d’acceptation : (q, ε) avec q ∈ F
Mouvement : (q, aw) ` (q0 , w) si q0 ∈ δ(q, a).
44 / 76
Reconnaissance
a
1 3 (0, ababbc)
a b c a
0 2
b
45 / 76
Reconnaissance
a
1 3 (0, ababbc)
` (1, babbc)
a b c a
0 2
b
45 / 76
Reconnaissance
a
1 3 (0, ababbc)
` (1, babbc)
` (0, abbc)
a b c a
0 2
b
45 / 76
Reconnaissance
a
1 3 (0, ababbc)
` (1, babbc)
` (0, abbc)
a b c a
` (1, bbc)
0 2
b
45 / 76
Reconnaissance
a
1 3 (0, ababbc)
` (1, babbc)
` (0, abbc)
a b c a
` (1, bbc)
` (0, bc)
0 2
b
45 / 76
Reconnaissance
a
1 3 (0, ababbc)
` (1, babbc)
` (0, abbc)
a b c a
` (1, bbc)
` (0, bc)
0 2 ` (2, c)
b
45 / 76
Reconnaissance
a
1 3 (0, ababbc)
` (1, babbc)
` (0, abbc)
a b c a
` (1, bbc)
` (0, bc)
0 2 ` (2, c)
b ` (3, ε)
45 / 76
L1 = {m ∈ { a, b}∗ }
46 / 76
L1 = {m ∈ { a, b}∗ }
46 / 76
L2 = {m ∈ { a, b}∗ | |m| a mod 2 = 0}
47 / 76
L2 = {m ∈ { a, b}∗ | |m| a mod 2 = 0}
b b
a
0 1
a
G2 = h{S, T }, { a, b}, {S → aT | bS | ε, T → aS | bT }, Si
47 / 76
L3 = { xaaa | x ∈ { a, b}∗ }
48 / 76
L3 = { xaaa | x ∈ { a, b}∗ }
a
a a a
0 1 2 3
48 / 76
L3 = { xaaa | x ∈ { a, b}∗ }
a
a a a
0 1 2 3
48 / 76
L3 = { xaaa | x ∈ { a, b}∗ }
b a
a
a a
0 b 1 2 3
b
b
49 / 76
L3 = { xaaa | x ∈ { a, b}∗ }
(0, abaabaaa)
b a ` (1, baabaaa)
a ` (0, aabaaa)
a a
0 b 1 2 3 ` (1, abaaa)
` (2, baaa)
` (0, aaa)
b ` (1, aa)
b ` (2, a)
` (3, ε)
49 / 76
Déterminisme
50 / 76
Limite des automates finis
51 / 76
Automates à pile
52 / 76
Représentation graphique
a, B → c
1 2
53 / 76
Représentation graphique
a, B → c
1 2
cas particuliers
a, ε → A b, A → ε
b, A → ε ε, ⊥ → ⊥
1 2 3
54 / 76
Définition formelle
δ : Q × (Σ ∪ {ε}) × (Γ ∪ {ε}) → ℘( Q × Γ∗ )
q0 ∈ Q est l’état initial
F ⊆ Q est l’ensemble des états d’acceptation
55 / 76
Configurations et mouvement
A = h Q, Σ, Γ, δ, q0 , F i
Configuration : (q, m, α) ∈ Q × Σ∗ × Γ∗ où :
q représente l’état courant de l’unité de contrôle
m est la partie du mot à reconnaître non encore lue. Le premier
symbole de m (le plus à gauche) est celui qui se trouve sous la tête
de lecture. Si m = ε alors tout le mot a été lu.
α représente le contenu de la pile. Le symbole le plus à gauche est
le sommet de la pile. Si α = ε alors la pile est vide.
Configuration initiale : (q0 , m, ⊥) où m est le mot à reconnaître
Configuration d’acceptation : (q, ε, ⊥) avec q ∈ F
Mouvement : (q, aw, Zα) ` (q0 , w, γα) si (q0 , γ) ∈ δ(q, a, Z ).
56 / 76
Équivalence
h Q, Σ, Γ, δ, q0 , F i
Q = {0, 1, 2, 3}
3
Σ = { a, b}
Γ = { A, ⊥}
57 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
ε, ⊥ → ⊥
⊥ b, A → ε
1 2
a, ε → A b, A → ε
58 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
` (1, aabbb, A⊥)
ε, ⊥ → ⊥
A
⊥ b, A → ε
1 2
a, ε → A b, A → ε
58 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
` (1, aabbb, A⊥)
ε, ⊥ → ⊥ ` (1, abbb, AA⊥)
A
A
⊥ b, A → ε
1 2
a, ε → A b, A → ε
58 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
A ` (1, aabbb, A⊥)
ε, ⊥ → ⊥ ` (1, abbb, AA⊥)
A
` (1, bbb, AAA⊥)
A
⊥ b, A → ε
1 2
a, ε → A b, A → ε
58 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
` (1, aabbb, A⊥)
ε, ⊥ → ⊥ ` (1, abbb, AA⊥)
A
` (1, bbb, AAA⊥)
A ` (2, bb, AA⊥)
⊥ b, A → ε
1 2
a, ε → A b, A → ε
58 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
` (1, aabbb, A⊥)
ε, ⊥ → ⊥ ` (1, abbb, AA⊥)
` (1, bbb, AAA⊥)
A ` (2, bb, AA⊥)
⊥ b, A → ε ` (2, b, A⊥)
1 2
a, ε → A b, A → ε
58 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
` (1, aabbb, A⊥)
ε, ⊥ → ⊥ ` (1, abbb, AA⊥)
` (1, bbb, AAA⊥)
` (2, bb, AA⊥)
⊥ b, A → ε ` (2, b, A⊥)
1 2 ` (2, ε, ⊥)
a, ε → A b, A → ε
58 / 76
Reconnaissance
3
(1, aaabbb, ⊥)
` (1, aabbb, A⊥)
ε, ⊥ → ⊥ ` (1, abbb, AA⊥)
` (1, bbb, AAA⊥)
` (2, bb, AA⊥)
⊥ b, A → ε ` (2, b, A⊥)
1 2 ` (2, ε, ⊥)
` (3, ε, ⊥)
a, ε → A b, A → ε
58 / 76
L = {mm−1 | m ∈ { a, b}∗ }
59 / 76
L = {mm−1 | m ∈ { a, b}∗ }
b, ε → B b, B → ε
ε, ε → ε ε, ⊥ → ⊥
1 2 3
a, ε → A a, A → ε
59 / 76
L = {m ∈ { a, b}∗ , |m| a = |m|b }
60 / 76
L = {m ∈ { a, b}∗ , |m| a = |m|b }
b, B → BB
b, ⊥ → B⊥
b, A → ε
ε, ⊥ → ⊥
1 2
a, A → AA
a, ⊥ → A⊥
a, B → ε
60 / 76
L = { ai b j ck | i ≥ 0, i = j ou i = k}
61 / 76
L = { ai b j ck | i ≥ 0, i = j ou i = k}
ε, ⊥ → ⊥
2 3 c, ε → ε
ε
→ b, A → ε
ε ,ε
a, ε → A 1
ε,
ε→
ε
c, A → ε ε, ⊥ → ⊥
4 5 6
b, ε → ε c, A → ε
61 / 76
L = { ai b j ck | i ≥ 0, i = j ou i = k}
ε, ⊥ → ⊥
2 3 c, ε → ε
ε
→ b, A → ε
ε ,ε
a, ε → A 1
ε,
ε→
ε
c, A → ε ε, ⊥ → ⊥
4 5 6
b, ε → ε c, A → ε
61 / 76
Langages hors-contexte déterministes
non-déterministe
déterministe
62 / 76
Limites des automates à pile
63 / 76
Machines de Turing
64 / 76
Généralités
65 / 76
Caractéristiques
66 / 76
Représentation graphique
a → b, D
1 2
67 / 76
Représentation graphique
a → b, D
1 2
67 / 76
Définition
δ : Q × (Γ ∪ {ε}) → ℘( Q × Γ × { D, G })
q0 ∈ Q est l’état initial,
q A ∈ Q est l’état d’acceptation,
q R ∈ Q est l’état de rejet, avec q R 6= q A .
68 / 76
Configurations et mouvement
M = h Q, Σ, Γ, δ, q0 , q A i
Configuration : (u, q, av) ∈ Γ∗ × Q × Γ∗ où :
q représente l’état courant de l’unité de contrôle
u est la partie de la bande se trouvant à gauche de la tête.
v est la partie de la bande se trouvant à droite de la tête.
a est le symbole se trouvant sous la tête.
Configuration initiale : (ε, q0 , m) où m est le mot à reconnaître
Configuration d’acceptation : (u, q A , v)
Configuration de rejet : (u, q R , v)
Mouvement :
69 / 76
Exemple
70 / 76
Exemple — début d’exécution
... a b b # a b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
71 / 76
Exemple — début d’exécution
2a
... x b b # a b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
71 / 76
Exemple — début d’exécution
2a
... x b b # a b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
71 / 76
Exemple — début d’exécution
2a
... x b b # a b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
δ (2 a , #) = (#, 3a , D ) 3a cherche une lettre non-z
71 / 76
Exemple — début d’exécution
3a
... x b b # a b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
δ (2 a , #) = (#, 3a , D ) 3a cherche une lettre non-z
δ (3 a , a ) = (z, 4, G ) vérifie la lettre
71 / 76
Exemple — début d’exécution
... x b b # z b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
δ (2 a , #) = (#, 3a , D ) 3a cherche une lettre non-z
δ (3 a , a ) = (z, 4, G ) vérifie la lettre
δ(4, α) = (α, 4, G ) pour α 6= x revient vers x
71 / 76
Exemple — début d’exécution
... x b b # z b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
δ (2 a , #) = (#, 3a , D ) 3a cherche une lettre non-z
δ (3 a , a ) = (z, 4, G ) vérifie la lettre
δ(4, α) = (α, 4, G ) pour α 6= x revient vers x
71 / 76
Exemple — début d’exécution
... x b b # z b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
δ (2 a , #) = (#, 3a , D ) 3a cherche une lettre non-z
δ (3 a , a ) = (z, 4, G ) vérifie la lettre
δ(4, α) = (α, 4, G ) pour α 6= x revient vers x
71 / 76
Exemple — début d’exécution
... x b b # z b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
δ (2 a , #) = (#, 3a , D ) 3a cherche une lettre non-z
δ (3 a , a ) = (z, 4, G ) vérifie la lettre
δ(4, α) = (α, 4, G ) pour α 6= x revient vers x
δ(4, x ) = ( x, 1, D ) relance le processus
71 / 76
Exemple — début d’exécution
... x b b # z b b ...
δ(1, a) = ( x, 2a , D ) enregistre a
δ (2 a , α ) = (α, 2a , D ) pour α 6= # cherche #
δ (2 a , #) = (#, 3a , D ) 3a cherche une lettre non-z
δ (3 a , a ) = (z, 4, G ) vérifie la lettre
δ(4, α) = (α, 4, G ) pour α 6= x revient vers x
δ(4, x ) = ( x, 1, D ) relance le processus
δ(1, b) = ( x, 2b , D ) . . .
71 / 76
Exemple — machine
z → z, D 5
a, b
,# qA
α→D z → z, D
#→D
#→D b, #
2a 3a
D a→
x, z,
a→ G
x → x, D
1 4 qR
G
b→ z,
b→ β→G
x,
D
2b 3b a, #
#→D
α→D z→D
α = Γ \ {#}, β = Γ \ { x }.
72 / 76
Déterminisme
73 / 76
Langages récursivement énumérables
74 / 76
Rapports avec la compilation
75 / 76
Sources
Michael Sipser,
Introduction to the Theory of Computation.
PWS Publishing Company, 1997.
John Hopcroft, Rajeev Motwani, Jeffrey Ullman,
Introduction to Automata Theory, Languages and Computation.
2ème édition, Pearson Education International, 2001.
John Aho, Jeffrey Ullman, The Theory of Parsing, Translation and
Compiling, Vol I : Parsing.
Prentice-Hall, 1972
76 / 76