Théorie des langages et compilation
Théorie des langages et compilation
Jean-Guy Mailly
jean-guy.mailly@parisdescartes.fr
1
Théorie des langages et compilation
2. Analyse lexicale
3. Analyse syntaxique
4. Analyse sémantique
5. Conclusion
2
Structure d’un compilateur
Un compilateur, c’est quoi ?
messages d’erreur
4
Les différentes étapes de la compilation
Programme source
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
5
Les différentes étapes de la compilation
Partie analyse : sépare les 6= constituants Programme source
du prog. source et produit une
représentation intermédiaire Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
5
Les différentes étapes de la compilation
Partie analyse : sépare les 6= constituants Programme source
du prog. source et produit une
représentation intermédiaire Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Partie synthèse : génère le prog. cible à
5
Analyse lexicale
Programme source
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
6
Analyse lexicale
identificateur
ab := y * x + 20
operateur
affectation nombre
7
Analyse syntaxique
Programme source
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
8
Analyse syntaxique
ab +
* 20
9
y x
Analyse sémantique
Programme source
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
10
Analyse sémantique
:=
ab +
y x 20
11
Partie synthèse
Programme source
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
12
Partie synthèse
13
Table des symboles
Programme source
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
14
Table des symboles
15
Détection des erreurs
Programme source
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Programme cible
16
Détection des erreurs
17
Analyse lexicale
Analyseur lexical et analyseur syntaxique
19
Analyse lexicale
20
Fragment d’automate lexical
q2
f
a-z
q0 0-9 q4 . q5 0-9 q6
=
0-9
q7 = q8
21
Analyse lexicale
22
Reconnaissance contextuelle
23
Problèmes de la reconnaissance contextuelle
24
Exemple de problème de la reconnaissance contextuelle
25
Générateurs d’analyseurs lexicaux
26
Construire un analyseur lexical avec lex
compilateur (f)lex
programme source (f)lex lex nom.l nom.yy.c
nom.l flex nom.l
compilateur C
gcc nom.yy.c -ll
nom.yy.c a.out
gcc nom.yy.c -lfl
27
Spécifications en lex
déclarations
%%
règles de traduction
%%
procédures auxiliaires
28
Déclarations
29
Règles de traduction
30
Analyseur lexical
31
Tableau des expressions régulières (1/2)
32
Tableau des expressions régulières (2/2)
33
Exemple – déclarations
%{
/* définitions des constantes littérales */
PPQ, PPE, EGA, DIF, PGQ, PGE, SI, ALORS, SINON, ID, NB, OPREL
%}
/* définitions régulières */
delim [ \n\t]
bl {delim}+
lettre [A-Za-z]
chiffre [0-9]
id {lettre}+ ({lettre}|{chiffre})∗
nombre {chiffre}+ (\.{chiffre}+ )? (E[+\-]? {chiffre}+ )?
%%
34
Exemple – règles de traduction
%%
35
Exemple – procédures auxiliaires
RangerId() {
/* Procédure pour ranger dans la table des symboles le lexème
dont le premier caractère est pointé par yytext et dont la
longueur est yyleng et retourner un pointeur sur son entrée */
}
RangerNb() {
/* procédure similaire pour ranger un lexème qui est un
nombre */
}
36
Analyse syntaxique
Qu’est ce que l’analyse syntaxique ?
38
Types d’analyseurs syntaxiques
39
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →
− acT bT
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →
− acTbT →
− accbT
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →
− acTbT →
− accbT →
− accbbS
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →
− acTbT →
− accbT →
− accbbS →
− accbbaSbT
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc
⇒ mène à un échec
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc ←
− acT bbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc ←
− acTbbadbc ←
− aSbbadbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc ←
− acTbbadbc ←
− aSbbadbc ←
− aSbbaSbc
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc ←
− acTbbadbc ←
− aSbbadbc ←
− aSbbaSbc ←
− aSbbaSbT
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc ←
− acTbbadbc ←
− aSbbadbc ←
− aSbbaSbc ←
− aSbbaSbT
←
− aSbbS
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc ←
− acTbbadbc ←
− aSbbadbc ←
− aSbbaSbc ←
− aSbbaSbT
←
− aSbbS ←
− aSbT
40
Exemple
Soit G = hV , Σ, P, Si avec
• Σ = {a, b, c, d}
• V \ Σ = {S, T }
• 6 règles de production :
• S → aSbT |cT |d
• T → aT |bS|c
• Soit w = accbbadbc
Analyse LL :
S →
− aSbT →− acTbT →
− accbT →
− accbbS →
− accbbaSbT
→
− accbbadbT →
− accbbadbc
Analyse LR :
accbbadbc ←
− acTbbadbc ←
− aSbbadbc ←
− aSbbaSbc ←
− aSbbaSbT
←
− aSbbS ←
− aSbT ←−S
40
Constructeur d’analyseur LR yacc/bison
41
Construire un analyseur syntaxique avec yacc
compilateur yacc/bison
spécification yacc/bison yacc nom.y
bison nom.y nom.tab.c
nom.y
compilateur C
42
Spécifications en yacc
déclarations
%%
règles de production et routines sémantiques
%%
routines C et bloc principal
43
Déclarations
44
Règles de production
45
Actions sémantiques
46
Routines annexes
• En langage C
• Un analyseur lexical nommé yylex() doit être fourni
• D’autres procédures comme les routines de récupération d’erreur
peuvent être ajoutées si nécessaire
• L’analyseur lexical yylex() produit des couples formés d’une unité
lexicale et de la valeur de l’attribut associé
• Si une unité lexicale est retournée, elle doit être déclarée dans la
première section de la spécification yacc
• La valeur de l’attribut associée à une unité lexicale est communiquée
à l’analyseur syntaxique par l’intermédiaire de la variable yylval
prédéfinie dans yacc
47
Exemple
48
Exemple – déclarations et règles de production
%{
#include <ctype.h>
%}
%token CHIFFRES
%%
%% 49
Exemple – Routines annexes
yylex()
{
int c ;
c = getchar() ;
if (isdigit(c))
{
yyval = c - ’0’ ;
return CHIFFRE ;
}
return c
}
50
Utilisation conjointe de lex et yacc
• lex a été conçu pour produire des analyseurs lexicaux qui peuvent
être utilisés avec des analyseurs syntaxiques faits avec yacc
• Pour utiliser lex, il faut remplacer la routine yylex() par la clause :
#include "lex.yy.c"
• Spécifier chaque action lex de façon à ce qu’elle retourne un
terminal connu de yacc
51
Utilisation conjointe de lex et yacc
52
Analyse sémantique
Analyse sémantique - pourquoi ?
54
Analyse sémantique - c’est quoi ?
55
Analyse sémantique - comment ?
56
Grammaire attribuée, informellement
57
Conclusion
Conclusion
Analyseur syntaxique
Analyseur sémantique
Table des
Erreurs
symboles
Générateur de code intermédiaire
Optimisateur de code
Générateur de code
Partie synthèse : génère le prog. cible à
59