Uploaded by Niima bettaoui

Chapitre1 compilation

advertisement
COMPILATION
Mohamed BOUHDADI & Faissal OUARDI
Théorie
des langages et
COMPILATION
des langages de programmations impératifs
Syntaxe &
Sémantique de traduction
des langages de programmation impératifs
Introduction et vue
d’ensemble
Fonction et Spécification d’un compilateur
Erreurs
Programme dans
un langage source
Compilateur
Programme équivalent
dans un langage cible
( ou exécutable)
1- Vérifier si le programme source ∊ au langage source : ANALYSE - ANALYSEUR
2- Traduire un programme bien formé en son programme équivalent dans un langage
cible (exécutable) : SYNTHÈSE ou TRADUCTION ; SYNTHÉTISEUR - TRADUCTEUR
SPÉCIFICATION d’un COMPILATEUR :
1- Comment spécifier le langage source ? Théorie des langages (trois
type de langages)
2- Comment spécifier le langage cible ?
3- Comment vérifier l’appartenance d’une chaîne de caractères au
langage source ? Théorie des automates : (Trois sous-fonctions )
4- Comment traduire ou synthétiser une chaîne de caractères (un
programme) bien formée en son équivalent (unique) dans le langage
cible. (Trois sous fonctions )
SYNTAXE et SÉMANTIQUE
La syntaxe d’un langage de programmation détermine ce qui constitue un
programme valide du point de vue de la forme du texte.
Quelles séquences de caractères constituent des programmes ?
Théorie des langages et des automates : Classification de Chomsky
LA FORME DES CONCATÉNATIONS
La sémantique définit la signification d’un programme, c’est-`a-dire ce
qu’il calcule, comment il le calcule.
Dans le cas de la compilation il s’agit d’une sémantique de traduction :
translational semantics
Sémantiques formelles: théories de la programmation
La sémantique formelle est l’étude de la signification des programmes informatiques
vue en tant qu’objets mathématiques
Les objets mathématiques dépendent des propriétés à connaître du programme.
L’objectif d’une sémantique formelle est de prouver qu’un programme est correct
Sémantiques usuelles d’un langage de programmation
Sémantique opérationnelle : la signification d’un programme est la suite des états
de la machine qui exécute le programme.
Un programme est considéré comme la description d’un système de transition d’états.
Sémantique dénotationnelle :
Une fonction mathématique appelée dénotation est associée à chaque
programme, et représente en quelque sorte son effet, sa signification.
Cette fonction prend par exemple pour argument l’état de la mémoire avant
exécution, et a pour résultat l’état après exécution.
Ce type de sémantique joue un rôle très important en compilation
Sémantique axiomatique :
Le programme n’est plus qu’un transformateur de propriétés logiques sur l’état de la
mémoire.
si on a p vrai avant exécution, alors on a q vrai après. On ne s’intéresse plus à l’état
précis de la mémoire tant que l’on sait dire si la propriété tient.
Sémantique algébrique :
est une forme de sémantique axiomatique qui se base sur les lois algébriques pour la
description et le raisonnement liés au sens d’un programme de façon formelle
Tendance actuelle : Vers un cadre unique pour les différentes sémantiques :
UTP : Unifying Theories of Programming
Langages de Spécification formels
Un langage de spécification est un langage formel utilisé pour décrire un système
à un niveau beaucoup plus élevé qu'un langage de programmation, qui est utilisé
pour produire un code exécutable pour un système.
Domaines d’utilisations :
-
Ingénierie des protocoles de communications : Vérification et validation
-
Conception électronique
-
Les systèmes qualifiés de « critiques » :
Une panne peut avoir des conséquences dramatiques :
des morts ou des blessés graves, des dégâts matériels importants, ou des
conséquences graves pour l’environnement
●
les systèmes de transport : pilotage des avions, des trains, logiciels
embarqués embarqués automobiles
●
la production d'énergie : contrôle des centrales nucléaires;
●
la santé: chaînes de production de médicaments, appareil médicaux (à
rayonnement ou contrôle de dosages)
●
le système financier : paiement électronique ;
●
les applications militaires.
Exemples de langages de spécification formels :
Z, Object-Z, CSP (Calculus of Sequential Processes), T-CSP (Timed-CSP),
TCOZ ( T-CSP Object-Z)
Calculus of Communicating Systems ( CCS )
Language Of Temporal Ordering Specification ( LOTOS )
SDL (Specification and Description Language), Estelle, Esterel
B, Event-B
Paradigmes et Langages de programmation
Un langage de programmation est une notation conventionnelle destinée à
formuler des algorithmes et produire des programmes informatiques qui les
appliquent.
Un langage de programmation est composé d'un alphabet, d'un vocabulaire, de
règles de grammaire et de significations
Un paradigme de programmation est une façon d'approcher la programmation
informatique et de traiter les solutions aux problèmes et leur formulation dans un
langage de programmation approprié.
Un paradigme de programmation fournit (et détermine) la vue qu’a le développeur
de l’exécution de son programme
Programmation impérative
La programmation impérative est un paradigme de programmation qui décrit les
opérations en séquences d'instructions exécutées par l'ordinateur pour modifier
l'état du programme.
L'état du programme à un instant donné est défini par le contenu de la mémoire
centrale à cet instant.
La programmation impérative s'appuie sur le modèle des machines à états avec une
mémoire centrale et des instructions qui modifient son état grâce à des affectations
successives. ( Machine de Turing et Architecture de von Neumann),
Exemples : le langage machine, Fortran, Algol, Cobol, Basic, Pascal, C, ADA,
Smalltalk, C++, Objective C, Perl, Python, Php, Java, Javascript
Programmation fonctionnelle
La programmation fonctionnelle est un paradigme de type déclaratif qui
considère le calcul en tant qu'évaluation de fonctions mathématiques.
Le paradigme fonctionnel n'utilise pas de machines à états pour décrire un
programme, mais un emboîtement de fonctions qui agissent comme des « boîtes
noires » que l'on peut imbriquer les unes dans les autres.
Exemples : Lisp, ML, Haskell, OCaml,
Programmation logique
La programmation logique définit les applications à l'aide d'un ensemble de faits
élémentaires les concernant et de règles de logique leur associant des
conséquences plus ou moins directes.
Ces faits et ces règles sont exploités par un démonstrateur de théorème ou
moteur d'inférence, en réaction à une question ou requête.
Exemples : Prolog, Oz, Python : PyPy
Et bien d’autres paradigmes
Programmation concurrente,
Programmation par contraintes,
Programmation distribuée,
Programmation génétique,
métaprogrammation, etc
SYNTAXE : Théorie des langages et des automates
La hiérarchie ou classification de Noam Chomsky
TYPE 3 : Langages rationnels (réguliers)
TYPE 2 : Langages algébriques (indépendant du contexte)
Contexte-free
TYPE 1 : Langages contextuels (Contexte-sensitive)
TYPE 0 : Langages récursivement énumérables
TYPE 3 ⊊ TYPE 2 ⊊ TYPE 1 ⊊ TYPE 0
QUESTION : Les langages de programmation sont de quel type ?
REPONSE : Ils sont contextuels mais
ILs contiennent des sous langages qui sont indépendants du
contexte et des sous langages qui sont réguliers
Langages impératifs : Instructions
Une Instruction est soit :
1- une entrée ou une sortie (input/output)
2- une séquence d’instructions : instruction ; instruction
3- une instruction d’assignement ( l’affectation) :
Identificateur ← Expression
4 - une instruction d’alternative (choix conditionnel) :
si ( Expression ) alors Instruction sinon Instruction ;
5 - une instruction de répétition (bouclage ou itération) :
Tant que ( Expression ) faire Instruction ;
6- Appel de fonction ( déclaration et définition) :
Identificateur ( liste de paramètres effectifs) ;
La séquence, l’affectation, le choix et la répétition sont suffisantes
pour implémenter toutes les solutions informatiques possibles
Ces 4 instructions constituent un système Turing Complet
Information - donnée ( types )
Types de base ou types primitifs :
alphabet, entiers, réels, booléens
Constructeurs de types :
1- Structure
2- Tableaux
3- Adresses : de données et de fonctions
LANGAGE DES IDENTIFICATEURS
Alphabet : ensemble fini de symboles ou lettres ou caractères, ou TERMINAUX
exemples : ASCII, {0,1}, {a, b, c }, { bleu, rouge, vert } sont des alphabets.
La seule information dont on dispose est l’ordre de chaque terminal
Opérations sur un alphabet : la concaténation notée . , l’union notée + ou
* ( zéro ou pusieurs )
a.(a | b).(a+b)* , (a+b).(a+b)*.b sont des langages
répétition notée
*
(a | b)*,
| et la
LANGAGE DES IDENTIFICATEURS
Question : Comment peut on définir un exemple de langage pour les
identificateurs ?
Exemple : un identificateur est chaine de caractères qui commence par une lettre
suivie de zéro ou plusieurs lettres ou chiffres et terminée par le symbole $
On peut introduire de nouveaux symboles NON-TERMINAUX pour simplifier la
définition du langage des identificateurs ID :
lettre
⟶ {a,b, ..z, A, B, ..Z }
Chiffre ⟶ {0,1,..,9}
//
//
⟺
[a..z,A..Z]
⟺ [0..9]
ID
⟶ lettre.( lettre | chiffre).*$
//
* signifie zéro ou plusieurs
Notation : Une partie gauche suivie d’une flèche suivie d’une partie droite
NomDUnLangage ⟶ FormeDesMotsDeCeLangage
La partie gauche est un symbole non-terminal ( c’est à dire
∉ à l’alphabet )
La partie droite est une expression résultant de l’application des trois opérations sur
l’union l’ensemble des terminaux ( symboles ∈ à l’alphabet) et l’ensemble des
non-terminaux ( symboles ∉ à l’alphabet ).
Une substitution des nouveaux symboles par ce qu’ils désignent ( parties droites)
donne : ID
*
⟶ {a,b, ..,z, A, B, ..Z } . ( {a,b, ..z, A, B, ..Z } | {0,1,..,9} ) $
Les identificateurs (les mots du langage ID ) sont définis indépendamment les uns
des autres. Pas de relation entre eux.
Le langage ID est défini en utilisant uniquement les symboles de l’alphabet (les
terminaux).
Ce type de langage est dit langage régulier ou rationnel
Le langage qui permet de décrire les langages réguliers : les grammaires
régulières
Les entiers, les réels, les opérateurs arithmétiques, les opérateurs logiques,
les opérateurs relationnels sont des langages réguliers
Une question s'impose : Etant donnée une expression spécifiant un langage régulier,
et étant donné un mot, comment répondre à la question :
Ce mot appartient-il au non au langage spécifié par cette expression ?
Comment analyser un langage régulier ?
ID :
lettre.( lettre | chiffre)*.$
Départ
Acceptation
Un mot a un début et une fin : le premier caractère et le dernier caractère
Le premier pointeur Départ désigne la situation où on doit être avant la lecture du
premier caractère du mot.
Le pointeur Arrivée ou Acceptation désigne la situation finale, là on on doit etre
après la lecture du dernier caractère du mot
L’expression peut être spécifiée par un ensemble de situations dont deux types
sont particulières : situations de départ et situations d’arrivée.
Le diagramme de situations pour l’expression dénotant le langage ID :
lettre | chiffre
lettre
ID :
⟲
$
Situation de départ est marquée par une flèche entrante
Situation d’acceptation est marquée par une flèche sortante.
Il s’agit de gérer deux avancées ( deux mouvements) :
-
une avancée dans le mot en entrée : variable caractère
et une avancé dans dans le modèle des mots : variable situation
Initialization :
On pointe sur la situation de départ, et on pointe sur le premier caractère en entrée,
A chaque étape, l'action consiste à comparer le caractère courant avece l’étiquette
(chacune des étiquettes) de la flèche sortant de la situation courante.
Si ces deux symboles coïncident on avance dans l’entrée ( on lit le prochain
caractère) et on avance dans le modèle ( on change de situation).
Sinon le mot en entrée n’est pas un identificateur
Si après la lecture de tous les caractères formant le mot en entrée, on atteint une
situation d’acceptation, alors le mot appartient au langage dénoté par l’expression.
Sion il ne lui appartient pas.
Les mots a$, a1A$, Ba1?ad, 12a sont-ils des identificateurs ?
lettre | chiffre
lettre
ID :
q1
q0
⟲
$
q2
a$
q0,a,q1,$,q2
a$ ∊
a1A$
q0,a,q1,1,q1,A,q1,$,q2
a1A$ ∊
Ba1?ad
q0 ,B,q1,a,q1,1,q1, ?, ∅
ID
ID
Ba1?ad ∉ ID
Analyse linéaire : structure d’automates à états finis
lettre | chiffre
lettre
ID :
q1
q0
⟲
$
q2
a$
q0,a,q1,$,q2
a$ ∊
a1A$
q0,a,q1,1,q1,A,q1,$,q2
a1A$ ∊
Ba1?ad
q0 ,B,q1,a,q1,1,q1, ?, ∅
ID
ID
Ba1?ad ∉ ID
Analyse linéaire : structure d’automates à états finis
Le langage des expressions arithmétiques sur N:
E : ensemble des expressions arithmétiques
∀ nb ∊ N : nb ∊ E
∀ e1,e2 ∊ E : (e1 + e2 ) ∊ E et ( e1 * e2 ) ∊ E
NOTATION :
E ne peut être défini que de
façon récursive
E ⟶ nb | E⟶ E + E | E⟶ E * E
L’alphabet = {nb, +, *} , E : non terminal et désigne un langage,
Les parties droites désignent les concaténations de terminaux et non terminaux
définissant la forme des expressions. Elles sont dites parties droites des Productions E
Formalisme : < Terminaux, Non Terminaux, Non-Terminal Principal, Productions>
E
E:
0
2
1
E
E:
E
+
4
3
E
*
5
6
7
nb
E:
8
9
mot = nb + nb * nb ⋲ E ?
↑↑ ↑
?
E ⟹ E + E ⟹ nb + E ⟹ nb + E * E ⟹ nb + nb * E ⟹ nb + nb * nb
↑
↑
↑ ↑↑
↑
↑ ↑↑
↑
La séquence d’états :
0, 8, 9, 1, 2, 4, 8, 9, 5, 6, 8, 9, 7, 3
On a besoin de sauvegarder l’état à partir duquel on va continuer l’analyse :
Structure arborescente - Automate + Pile
Arbre syntaxique
E
E
Arbre abstrait
+
+
E
*
nb
nb
E
nb
*
E
nb
nb
nb
E ⟹ E * E ⟹ E + E * E ⟹ nb + E * E ⟹ nb + nb * E ⟹ nb + nb * nb
Arbre syntaxique
Arbre abstrait
E
*
E
*
E
+
nb
E
+
E
nb
nb
nb
nb
nb
Deux choix doivent être faits :
- Choix concernant le sens de lecture de la chaîne en entrée : de la
gauche vers la droite ou l'inverse : left to right
- Choix concernant l’utilisation des productions : de la gauche vers la
droite ( Dérivation ) ou de la droite vers la gauche ( Réduction)
. Approche descendante ( top-down ) :
L’arbre syntaxique est construit du haut vers le bas
. Approche ascendante (Bottom-Up)
L’arbre est construit du bas vers le haut
Analyse descendante et analyse ascendante
LL(1) : Left to Right Scanning of the Input
LeftMost Derivation
1 lookahead ( un seul de prévision)
LR(1) : Left to Right Scanning of the Input
Rightmost Derivation in Reverse
1 lookahead
Souvent, on utilise les deux approches
Le langage des expressions arithmétiques, des expressions logiques, des instructions,
des parenthèses équilibrées ne peuvent être définis que de façon récursive
Ils sont dits langages algébriques ou indépendants du contexte (contexte-free)
et sont décrits par des grammaires algébriques ou grammaires indépendantes
du contexte (contexte sensitive)
Formalisme de grammaires indépendantes du contexte ou algébriques :
< Terminaux : T, Non Terminaux : N, Non-Terminal Principal : S, Productions> : P
T : ensemble de symboles définissant l’alphabet
N : ensemble de symboles définissant des langagaes (sous-langages)
S : le symble de départ (ou axiome) :Start
P: ensemble de productions définissant les différents sous-langages
T∩N=∅
S∈N
P ⊆ { ( X , 𝞪 ) | X N , 𝞪 ∈ ( N ⋃ T )* }
La partie gauche d’une production doit etre un non-terminal et la partie droite
peut contenir à la fois des terminaux et des non-terminaux
Les différents langages X ∈ N sont définis indépendamment les uns des autres :
Pas de relation longue distance
Les suites de symboles sont des chaînes.
Une chaîne 𝝱 est directement dérivable d’une chaîne 𝝰 ce qui s’écrit 𝝰 ⟹ 𝝱 si et
seulement s’il existe les chaînes 𝞭₁, 𝞭₂ et 𝞬 et un non-terminal X ∈ N, tels que
𝝰 =𝞭₁ X 𝞭₂, 𝝱 =𝞭₁ X 𝞭₂, (X,𝞬 ) ∈ P
Si nous avons une chaîne et remplaçons un non-terminal X qu’elle contient par sa
partie droite 𝞬 dans une production, nous obtenons une chaîne directement dérivable
de X
Cette substitution est appelée étape de dérivation
Une chaîne 𝝱 est dérivable d’une chaîne 𝝰 ce qui s’écrit 𝝰 ⟹* 𝝱 si et seulement si
𝝰 = 𝝱, ou il existe une chaîne 𝞬 telle que 𝝰 ⟹* 𝞬 et 𝞬 ⟹ 𝝱
Une chaîne est dérivable d’une autre si nous pouvons atteindre la deuxième
chaîne depuis la première par zéro, un ou plusieurs pas de dérivation.
Le langage 𝖫 engendré par une grammaire G est défini par
L(G) = { 𝝰 | ( S ⟹* 𝝰 ) ∧ ( 𝝰 ∈ T*) }
Langages de programmation sont contextuels (contexte-sensitive)
Deux exemples de contraintes contextuelles :
1- Chaque identificateur doit être déclaré avant d’être utilisé.
{ 𝞪𝞪 | 𝞪 ∈ ∑* } , ∑ un alphabet n’est indépendant du contexte
2- Chaque appel de fonction doit être conforme à la déclaration en terme de
nombre et types de paramètres : { aⁿ bⁱ cⁿ dⁱ | n, i ≥ 1 }
X désigne un langage. X est un langage contextuel si X admet une
production dont la forme est :
𝝰X𝝱 ⟶𝝰𝜸 𝝱
𝝰, 𝝱 et 𝜸 sont des concaténations de terminaux et de non terminaux
Les mots de X ont la forme 𝜸 à condition que le contexte à droite et celui à
gauche de S sont respectivement 𝝰
et 𝝱.
Hiérarchie de Chomsky
TYPE 3 : Langages rationnels - Grammaires régulières - Automate fini
TYPE 2 : Langages algébriques - Grammaires algébriques - Automate à pile
TYPE 1 : Langages contextuels - Grammaires contextuels - Automate
linéairement borné ( Grammaires attribuées )
TYPE 0 : Langages récursivement énumérables - Machine de Turing
Principes de Conception d’un Compilateur (phase d’analyse)
La conception d’un compilateur se base sur la classification de Chomsky pour
la spécification des langages de programmation et pour automatiser la
construction de leurs analyseurs.
Le sous-langage régulier (LE LEXIQUE) : analyse lexicale (micro-syntaxe)
Le sous-langage indépendant du contexte ( LA SYNTAXE) : analyse syntaxique
(macro-syntaxe)
Le sous langage contextuel ( LE CONTEXTE ): analyse sémantique ou analyse
du contexte
Analyse lexicale (micro-syntaxe)
Les identificateurs, les entiers, les réels, les opérateurs arithmétiques, les
opérateurs logiques, les opérateurs relationnels ..
Analyse syntaxique (macro-syntaxe)
Les expressions arithmétiques, les expressions logiques, les instructions, les
types, les parenthèses équilibrées.
Analyse sémantique ou du contexte
- Analyse des identificateurs ( noms) - durée de vie - scope
- les types.
Grammaires attribuées : Compléter par l’information liée au contexte et contrôler les
contraintes contextuelles et ...
Erreurs
chaîne
de caractères
Analyseur
Lexical
Lexème :
une chaîne
de lexèmes
Représentation
Analyseur
Syntaxique
Arbre syntaxique ou abstrait
Classe lexicale
L’analyse lexicale transforme un flot de caractères en un flot de lexèmes
(mot , classe) ;
L’analyse syntaxique transforme un flot de classes de lexèmes en un arbre d’analyse,
ou, probablement en un arbre abstrait.
Un arbre abstrait est une version de l’arbre syntaxique dans laquelle on ne conserve que
les noeuds sémantiquement importants
Un analyseur lexical est reconnaisseur de modèles, qui découpe le flot d’entrée
en lexèmes reconnus par les modèles de lexèmes du langage source
La forme des lexèmes est décrite par des modèles dans un formalisme
spécial, appelés expressions régulières
Le travail de base d’un analyseur lexical est : étant donné un ensemble S de
descriptions de lexèmes et une position P dans le flot d’entrée, de déterminer quelle
expression régulière dans S reconnaît un segment de donnée commençant en P, et
quel est ce segment.
S’il y a plus d’un tel segment, l’analyseur lexical doit avoir une règle pour lever
l'ambiguïté ; le segment le plus long est celui qu’on veut.
Si le segment le plus long est reconnu par plus d’une expression régulière, on se
repose sur l’ordre textuel dans lequel les descriptions de lexèmes sont
données.
Spécifier les descriptions de lexèmes les plus spécifiques avant les moins spécifiques
Si toute suite de lettres sauf xyzzy est un identificateur ce qui suit suffira :
symbole_magique
identificateur
xyzzy
[a-z ]⁺
Un analyseur représente ses connaissances par un ensemble de situations. Une
situation est une expression régulière nommée avec un point quelque part.
.xyzzy x.yzzy xy.zzy xyz.zy xyzz.y xyzzy.
La partie avant le point correspond à la dernière partie de l’entrée déjà examinée
La partie après le point doit reconnaître la première partie du reste de l’entrée pour
que la situation réussisse.
Situation pointée
Cₙ
Cₙ₊₁
entrée
T
.
𝝰 𝝱
Déjà reconnu
par 𝝰
Pas encore reconnu
par 𝝱
L’examen d’un caractère a pour effet qu’une situation est transformée en zéro, une ou
plusieurs nouvelles situations. Cette transition est un avancement.
T
.
𝝰 c𝝱
c
⟹
c
T
.
𝝰c 𝝱
L’ensemble des situations sont des états, les transformations sont des transitions
d’états.
Une situation avec un point à la fin, appelée situation de réduction (utilisation
de productions de la droite vers la gauche), signale qu’on vient de trouver un
lexème possible, mais la fin de lexème le plus long est peut être plus loin.
ID
Entier
lettre.( lettre | chiffre)*
chiffre . chiffre*
lettre | chiffre
lettre
ID :
q0
⟲
q1
Reconnaît tous les identificateurs
chiffre
chiffre
Entier :
q2
⟲
q3
Reconnaît tous les entiers
Règle de la correspondance la plus longue :
- Changer la nature des situations finales ( les états d’acceptation ou
états finaux) : ne sont plus états d’acceptation
- Continuer à avancer tant qu’il s’agit de préfixes du même lexème
lettre | chiffre
⟲
lettre
ID :
q0
chiffre
Entier :
ni lettre, ni chiffre
q1
chiffre
q2
Exemple :
entrée : a1b3d?a12a.123a
⟲
q3
ACTION
q4
ACTION
autre que chiffre
q5
sortie : ?
Nous avons besoins de deux pointeurs pour délimiter la représentation de
chaque type de lexème son début et sa fin
a 1 b 3 d ? a 1 2 a !1 2 3 a
a
début
1
b
fin fin
3
fin
d
fin
?
fin
a
1
2
a
!
1
2
3
a
fin
On explore le modèle des identificateurs en premier puis si nécessaire celui des
entiers : deux variables pour parcourir les modèles : L’état initial courant et l’état
courant : Initial ← état ← q0
(état, a) ⟶ q1
(q1, ?) ⟶ q4
(q1, 1) ⟶ q1
(q1, b) ⟶ q1
(q1, 3) ⟶ q1
(q1, d ) ⟶ q1
∈ F = ensemble des états finaux
Reconnaître que le mot situé entre début et fin moins 1 est un
identificateur ; et traiter le reste de l’entrée : debut ← fin (refaire le même
traitement )
a
1
b
3
d
?
a
début
1
2
a
.
1
2
3
a
fin
Initial ← état ← q0
(état, ?) ⟶ ∅ : Ce modèle ID ne peut accepter de mot commençant par ce
caractère
{ ACTION : Acceptation }
⟲
lettre
ID :
q0
q1
ni lettre, ni chiffre
q4
autre que lettre
∅
{ ACTION : annuler les mouvements et explorer l’automate
suivant }
Annuler les mouvements dans la chaîne d’entrée et explorer le modèle suivant s’il
en reste
fin ← début
Initial ← état ← q2
(état, ?) ⟶ ∅
Aucun modèle ne peut reconnaître un mot commençant par le caractère ?
On ignore ce symbole : debut ← debut +1; fin ← début ;
a
1
b
3
d
Initial ← état ← q0
(état, a) ⟶ q1
(q1, .) ⟶ q4
?
a
1
début fin fin
(q1, 1) ⟶ q1
2
a
fin
fin
(q1, 2) ⟶ q1
!
1
2
3
fin
(q1, a) ⟶ q1
∈ F = ensemble des états finaux
a
a
1
b
3
d
?
a
1
début fin fin
2
a
fin
fin
!
1
2
3
a
fin
Initial ← état ← q0
(état, a) ⟶ q1
(q1, .) ⟶ q4
a
1
b
(q1, 1) ⟶ q1
(q1, 2) ⟶ q1
(q1, a) ⟶ q1
∈ F = ensemble des états finaux : a12a ∈ id
3
d
?
a
1
2
a
!
début
1
fin
2
3
a
a
1
b
3
d
?
a
1
2
a
!
1
2
début fin fin
3
a
fin
fin
état = q5 : 123 est un entier
a
1
b
3
d
?
a
1
2
a
!
1
2
3
début
a
fin
a
1
b
3
d
entrée : a1b3d?a12a.123a
sortie : ( a1b3d , ID )
( a12a , ID )
( 123, Entier )
( a, ID )
?
a
1
2
a
!
1
2
3
début
a
fin
L'analyseur lexical initialise une structure de donnée appelée Table de symboles
ou tables des noms.
Chaque entrée correspond à une déclaration d’un nom. Ce qui signifie qu’ à
chaque reconnaissance d’un mot on teste s’il existe dans “ la table ”. Si oui on fait
rien sinon on l’insère ainsi que sa classe.
Une table de symboles est un tableau extensible d'articles, indexé par des chaînes.
La chaîne est l’identificateur, et l’article correspondant contient toutes les informations
à son sujet
Représentation
Classe
a1b3d
ID
a12a
ID
123
Entier
a
ID
Table de Symboles
L’analyseur lexical est un programme qui gère quatres variables :
- deux pointeurs pour délimiter la représentation de chaque lexème en entrée : son
début et et sa fin ;
-
deux états pour parcourir les différents modèles de lexèmes état initial courant (
initial ): pour sauvegarder l’automate en cours d’exploration, et état courant pour
sauvegarder l’état où on est.
-
Pour chaque état on associe un fragment de code qui consiste en des
comparaisons du caractère en entrée courant avec les différents étiquettes des
différents transitions sortant de cet état, et on transfère le contrôle.
- Initialise la table des symboles
deux fonctions : rechercher et insérer
Erreurs
chaîne
de caractères
Analyseur
Lexical
Lexème :
une chaîne
de lexèmes
Analyseur
Syntaxique
Représentation
Arbre syntaxique ou abstrait
Classe
Table de symboles ou table des noms
E ⟹ E + E ⟹ nb + E ⟹ nb + E * E ⟹ nb + nb * E ⟹ nb + nb * nb
Arbre syntaxique
E
Arbre abstrait
E
+
E
+
*
nb
nb
E
nb
*
E
nb
nb
nb
Un analyseur construit l’arbre syntaxique correspondant à une suite donné de lexèmes
Construire l’arbre syntaxique signifie que l’on crée un arbre de noeuds et que ces
noeuds sont étiquetés par les symboles grammaticaux, de telle manière que :
- les noeuds feuilles sont étiquetés par des terminaux, et les noeuds internes par
des non-terminaux ;
-
le noeud racine est étiqueté par le symbole de départ de la grammaire ;
-
les fils d’un noeud interne X correspondent aux membres d’un des choix de X,
dans le même ordre que dans le choix ;
-
les terminaux étiquetant les noeuds feuilles correspondent à la suite de lexèmes,
dans le même ordre que dans l’entrée.
-
Un analyseur syntaxique est un analyseur lexical dans le sens ou ils font la
même chose, la différence réside dans les formes des mots qu’ils
reconnaissent
-
-
Pour l'analyseur lexical l’alphabet est l’ensemble des caractères ; et
pour l’analyseur syntaxique l’alphabet est l’ensemble des classes de
lexèmes.
L’analyseur syntaxique est le programme principal qui appelles (ou invoque)
l’analyseur lexicale pour lui retourner la prochaine unité lexicale : lexème_suivant ( )
Erreurs
lexème_suivant
chaîne
de caractères
Analyseur
Syntaxique
Analyseur
Lexical
Lexème
mot
classe
Table des symboles
Arbre syntaxique
ou abstrait
Erreurs
chaîne
de caractères
lexème
Analyseur
Lexical
Analyseur
Syntaxique
Lexème_suivant
Mot
Unité Lexicale
Table des symboles
Type
Arbre syntaxique
ou abstrait
Erreurs
lexeme_suivant
chaîne
de caractères
Analyseur
Lexical
Arbre abstrait
lexème
Mot
Analyseur
contextuel
Analyseur
Syntaxique
Unité Lexicale
Type
Arbre Abstrait
décoré
Table des symboles
Principes de Conception d’un Compilateur (phase de synthèse)
- Le code doit être indépendant de toute machine (Unité centrale)
et de tout système d’exploitation : code intermédiaire ( codes à
trois adresses, C--)
- Le code doit être optimisé :
Analyse de la complexité algorithmique
Gestion des variables Temporaires (évaluations des
expressions)
Optimisation des boucles imbriquées
Principes de Conception d’un Compilateur (phase de synthèse)
Arbre
Abstrait
Décoré
générateur
du code
intermédiaire
Optimisation
du code
Code
intermédiaire
Générateur
du code cible
Code optimisé
Code cible
Sommaire :
Chapitre 2 - Contexte et traduction des constituants de langages de
programmation impératifs
Chapitre 3 - Les langages réguliers
- Algorithmes ( de transformations) :
Expression régulière
⋳-NFA
DFA
⋳-NFA
- Automate Minimal
-
Lemme de l’étoile : caractérisation des langages réguliers
- Analyseurs lexicaux manuels et automatiques ( l'outil flex)
Chapitre 4- Langages algébriques (context free)
-
Grammaires algébriques - langages algébriques
-
Analyse par descente récursive : LL(1)
-
Analyse automatique et Interprétation (l’outil BISON)
Download