COMPIL
COMPIL
COMPIL
Chapitre 0 : Introduction
1\ Définition :
L’analyse lexicale consiste à partir d’un programme qui est une
suite de caractères et de :
- Spécifier les différentes entités lexicales
- Eliminer les blancs ainsi que les commentaires s’ils existent
- Coder les différentes entités lexicales
- Construire la table des symboles
2\ Entités lexicales :
il existe 4 types d’entité lexicale :
- les identificateurs : x / y …
- les mots clés : if then else for BEGIN END …
- les constantes : 5 / -2 / 4.13 …
- les séparateurs : ; / : / { / } …
Début
Lecture de la donnée ;
tc ← 1er caractère de la chaîne à analyser ;
Ec ← état initial de l’automate ;
Tant que (Ec ≠ ∅) et (⎤ fin de chaîne) faire
Ec ← T(Ec, tc) ; /* T = la table de transition */
tc ← ts ;
Fait ;
Si (Ec = ∅) alors
‘chaîne incorrecte lexicalement’ ;
Sinon
Si (Ec n’est pas final) alors
‘chaîne incorrecte lexicalement’ ;
Sinon
‘chaîne correcte’ ;
coder l’entité ;
insérer dans la table des symboles ;
Fsi ;
Fsi ;
Fin.
L’ANALYSE SYNTAXIQUE
1\ Définition :
L’analyse syntaxique a pour rôle la vérification de la forme et de
la succession des entités lexicales, cette vérification est faite à
l’aide de la grammaire spécifique au langage, appelée
grammaire syntaxique.
Exemple :
S → Abc / Baa / AB
A → aSc / ε / aScA’ / A’ (car εA’ = A’)
A’ → aB / b / aBA’ / bA’
B → bB / ε
Remarque : la récursivité droite ne pose pas de problème,
donc les règles de types : A → αA sont correctes, on ne
s’intéresse qu’à la récursivité gauche
Exemple :
S → Ac / b
A → dd / a / ddA’ / aA’
A’ → cd / cdA’
B → Ac / d
Exemple :
Soit la règle : A → aX / aY / aZ / α / β , après factorisation :
A → aE/ α / β
E→X/Y/Z
4\ L’ensemble des débuts et suivants :
1) A → αβB
- deb(A) = {α}
2) A → B
- deb(A) = deb(B) = {β}
3) A → Bα
B → βcC
- deb(A) = deb(B) = {β}
4) A → Bα
B→β|ε
- deb(A) = deb(B) + deb(A si B = ε) = {β, α}
- deb(B) = {β, ε}
1) Si A → Bα alors α ⊆ suiv(B)
7\ L’analyse descendante :
Pour vérifier si un mot respecte la syntaxe fournit par la
grammaire on lui applique une analyse descendante, cette
méthode étant un peu compliqué à expliquer sur un PDF, je
vous redirige vers ces 2 vidéos qui l’explique très bien :
Explication de l'analyse & Exemple d'application de l'analyse
8\ Méthodes ascendantes :
C’est l’inverse de la dérivation, elle consiste à remplacer un
membre droit de production par son membre gauche, et
continuer ainsi jusqu’à arriver à l’axiome, c’est le principe de
réduction, on va voir ces 3 méthodes : L’analyse LR, l’analyse
SLR et l’analyse LALR
1) Analyse LR :
C’est une méthode d'analyse efficace et déterministe qui
consiste en des décalages et réductions, elle utilise une pile et
une table d’analyse LR, pour construire la table d’analyse LR
on utilise la méthode des items
2) Analyse SLR :
1- Construction de l’ensemble des items LR(0)
2- Construction de la table d’analyse SLR(1)
3- Si la table est monodéfinie alors la grammaire est SLR(1)
9\ Notion d’ambiguïté :
Une grammaire ambigüe veut dire qu’elle accepte plusieurs
arbres syntaxiques, pour monter qu'une grammaire est
ambiguë il suffit de prendre une chaine et de construire 2
arbres syntaxiques différents
Z E#
EE+A|E–A|A
AAxB|A/B|B
B (E) | nb
LES FORMES INTERMÉDIAIRES
1\ Définition :
On appelle forme intermédiaire, une forme dont l’ensemble des
instructions est composé d’un opérateur et de 2 opérandes
Un opérande peut être une constante, une variable, un nom de
procédure, un opérateur peut être arithmétique ou logique
2\ Forme postfixée :
Exemple :
Soit l’expression : a - c + d * e
Exemple : x := x+y*z x x y z * + :=
Exemple :
Soit la déclaration d’un tableau : Array A [a+b : c*d , 5*x : z-y]
Exemple :
Soit la condition : IF a≠b THEN b := b*a ELSE c := a*c
3\ Forme préfixée :
Notation : opérateur opérande1 opérande2
fp(t1 opérateur t2) = opérateur fp(t1) fp(t2)
fp(opérateur t) = opérateur fp(t)
4\ Quadruplés :
Notation : (opérateur, opérande1, opérande2, Temporaire)
Exemple :
Soit l’opération : a * b / c + d en d’autres termes ((a*b) / c) + d
1- (*, a, b, T1)
2- (/, T1, c, T2)
3- (+, T2, d, T3)
Quadruplé de l’affectation :
Var := <expression> ( :=, T, ,Var)
1- (BE, else(5), a, b)
2- (*, b, a, T1)
3- ( :=, T1, , b)
4- (BR, Fin(7), , )
5- (*, a, c, T2)
6- ( :=, T2, , c)
7-
Quadruplé d’une déclaration de tableau :
Pour construire ce quadruplé il faut d’abord calculer les
quadruplés de la borne inférieure (T1.1) et supérieure (T1.2) de
la première dimension ensuite on créer le quadruplet avec
l’opérateur BOUNDS : (BOUNDS, T1.1, T1.2, ) et on fait cela
pour chaque dimension i du tableau : (BOUNDS, Ti.1, Ti.2, )
jusqu’à la dernière dimension : (BOUNDS, Tn.1, Tn.2, ), enfin
en ajoute le dernier quadruplet : (ADEC, nomTableau, , )
Exemple :
Soit la déclaration de tableau suivante : Array A [1:i+j-k , 2:c-d]
1- (+, i, j, T1)
2- (-, T1, k, T2)
3- (BOUNDS, 1, T2, )
4- (-, c, d, T3)
5- (BOUNDS, 2, T3, )
6- (ADEC, A, , )
Exemple :
Soit l’affectation suivante : x := T[x+y, a*b] * 6
1- (+, x, y, T1)
2- (*, a, b, T2)
3- (*, T[T1,T2], 6, T3)
4- ( :=, T3, ,x)
5\ Arbre abstrait :
C’est une représentation sous forme d’arborescence des
relations entre les opérandes et les opérateurs
Exemple : i * i + i Affectation :
1\ Définition :
L’analyse sémantique permet de donner un sens à ce qui été
reconnu dans l’analyse syntaxique, cette phase vérifie :
• Si un IDF a été bien déclaré
• La concordance des types dans une expression
• L’utilisation correcte d’une étiquette
• et bien d’autres choses …
Routine <A> :
Debut
QUAD(Qc) := (BZ, , <exp-bool>.temp, ) ;
Sauv-BZ := Qc ;
Qc := Qc + 1;
Fin.
Routine <B> :
Debut
QUAD(Qc) := (BR, adresse de la fin , , ) ;
Sauv-BR := Qc ;
Qc := Qc + 1 ;
QUAD(Sauv-BZ, 2) := Qc ;
Fin.
Routine <C> :
Debut
QUAD(Sauv-BR, 2) := Qc ;
Fin.
Instruction While :
WHILE <condition> DO <Inst>
Routine <A> :
Debut
Sauv-deb := Qc ;
Fin.
Routine <B> :
Debut
QUAD(Qc) := (BZ, , <condition>.temp, ) ;
Sauv-BZ := Qc ;
Qc := Qc + 1 ;
Fin.
Routine <C> :
Debut
QUAD(Qc) := (BR, Sauv-deb, , ) ;
Qc := Qc + 1 ;
QUAD(Sauv-BZ, 2) := Qc ;
Fin.
Expressions arithmétiques :
Grammaire transformée :
<Inst-IF> <debut-inst-if> <Inst2> R3
<debut-inst-if> <debut-if> <Inst1> ELSE R2
<debut-if> IF <exp-bool> THEN R1
Soit la grammaire G :
EE+T/T
TT*F/F
F id / (E)
Et la chaine : a + b * c
Routine R1
Debut
Lookup(id,P) ;
Si (P = 0) Alors
‘Erreur : idf non déclaré’ ;
Sinon
empiler(pile-opérande, F, P.nom, P.type) ;
Fsi ;
Fin.
Routine R2
Debut
opérande := dépiler(pile-opérande) ;
empiler(pile-opérande, F, opérande.nom, opérande.type) ;
Fin.
Routine R3
Debut
opérande := dépiler(pile-opérande) ;
empiler(pile-opérande, T, opérande.nom, opérande.type) ;
Fin.
Routine R4
Debut
opérande2 := dépiler(pile-opérande) ;
opérande1 := dépiler(pile-opérande) ;
Si (opérande1.type et opérande2.type sont incompatibles) Alors
‘Erreur : incompatibilités des types’ ;
Sinon
CréerTemp(R) ;
QUAD(Qc) := (*, opérande1.nom, opérande.nom, R);
Qc := Qc + 1 ;
CalculType(opérande1.type, opérande2.type, R-Type) ;
empiler(pile-opérande, T, R, R-Type) ;
Fsi ;
Fin.
Routine R5
Debut
opérande := dépiler(pile-opérande) ;
empiler(pile-opérande, E, opérande.nom, opérande.type) ;
Fin.
Routine R6
Debut
opérande2 := dépiler(pile-opérande) ;
opérande1 := dépiler(pile-opérande) ;
Si (opérande1.type et opérande2.type sont incompatibles) Alors
‘Erreur : incompatibilités des types’ ;
Sinon
CréerTemp(R) ;
QUAD(Qc) := (+, opérande1.nom, opérande.nom, R) ;
Qc := Qc + 1;
CalculType (opérande1.type, opérande2.type, R-Type) ;
empiler(pile-opérande, E, R, R-Type) ;
Fsi ;
Fin.
Exemple :
• À la rencontre d’un Goto vers une même étiquette (etiq) : on
génère un BR vers le début du dernier Goto rencontré
Schéma de traduction :
Découpage de la grammaire :
Routine R1
Debut
Lookup(tc,P) ;
Si (P = 0) Alors
Insert(tc, P) ;
P.déclare := 1 ;
P.util := 0 ;
P.type := Label ;
P.adresse := 0 ;
Sinon ‘Erreur : double déclaration’ ;
Fsi ;
Fin.
Routine R2
Debut
Lookup(tc,P) ;
Si (P = 0) Alors
‘Erreur : étiquette non déclarée’ ;
Sinon
Si (P.util = 1) Alors // étiquette déjà utilisée
QUAD(Qc) := (BR, P.adresse, , )
Sinon // étiquette non utilisée
QUAD(Qc) := (BR, P.adresse, , ) ;
P.adresse := Qc ;
Fsi ;
Qc := Qc+1 ;
Fsi ;
Fin.
Routine R3
Debut
Lookup(tc,P) ;
Si (P = 0) Alors
‘Erreur : étiquette non déclarée’ ;
Insert( etiq, p) ,
p.type = label, ....
Sinon
Si (P.util = 1) Alors
‘Erreur : double utilisation’ ;
Sinon
a := P.adresse ;
P.util := 1 ;
Tant que (a ≠ 0) Faire
B := QUAD(a, 2) ;
QUAD(a, 2) := Qc ;
A := b ;
Fait ;
Fsi ;
Fsi ;
Fin.