Compilation des Algorithmes en MIPS
Compilation des Algorithmes en MIPS
Télécom SudParis
CSC4536
Pascal Hennequin
12/10/2022 1 / 127
Sommaire (1/2)
Introduction
0) Prolégomènes 4
Analyse Lexicale et Syntaxique
1) Analyse Lexicale 18
2) Automate Fini 31
3) Grammaire Algébrique 48
4) Analyse Syntaxique 63
12/10/2022 2 / 127
Sommaire (2/2)
Compilation
6) Arbre de Syntaxe Abstraite 81
7) Analyse Sémantique 95
8) Représentation Intermédiaire 109
9) Génération de code 120
12/10/2022 3 / 127
Chapitre 0
0) Prolégomènes
Compilation 5
Interprétation 6
Méli-mélo 7
Traduction 8
Phases de Compilation 9
Objectif du cours 14
Bibliographie 16
12/10/2022 4 / 127
Compilation
De l’algorithme à la porte logique
COMPILATEUR
12/10/2022 5 / 127
Interprétation
Autre possibilité
INTERPRÉTEUR
12/10/2022 6 / 127
Méli-mélo
On peut mélanger
Entrée : un algorithme implanté sous forme d’ un programme dans
un langage de programmation «évolué »
COMPILATEUR
Exemple : Java
12/10/2022 7 / 127
Traduction
De façon plus large
TRADUCTEUR
12/10/2022 8 / 127
Phases de Compilation (1/4)
I) Analyse Lexicale
Reconnaître les mots du langage en entrée
12/10/2022 9 / 127
Phases de Compilation (2/4)
III) Analyse Sémantique
Établir la signification du fichier en entrée
Construire les éléments de contexte :
●
liaison entre les définitions et les utilisations des variables ou fonctions
●
vérification des contraintes de typage, gestion du transtypage
●
analyse des chemins d’exécutions, i.e code mort, return absent
●
...
πR2=alpha+1
?
ou transtypage avant affectation
double alpha Addition flottante Transtypage (double) 1 , ...
Concaténation Transtypage [Link]() ,
String alpha chaines Méthode [Link](), ...
12/10/2022 10 / 127
Phases de Compilation (3/4)
IV) Code Intermédiaire
Traduction de l’entrée dans un langage intermédiaire qui se veut :
●
Indépendant du langage en entrée et plus simple
●
Indépendant du langage en sortie ou du traitement à suivre
Interface entre partie avant et partie arrière du compilateur
12/10/2022 11 / 127
Phases de Compilation (3 bonus/4)
12/10/2022 12 / 127
Phases de Compilation (4/4)
V) Génération de code
Optimisation du code intermédiaire
Génération du code cible
Optimisation du code cible
Production de l’exécutable et édition de liens
V bis) Interprétation
Exécution directe du code intermédiaire
12/10/2022 13 / 127
Objectif du Cours (1/2)
Écrire un compilateur pour un sous-ensemble du langage Java
vers le langage assembleur MIPS
– Comprendre par la pratique les enjeux et les techniques des
différentes phases de la compilation
Trois objectifs sous-jacents
– Analyse lexicale et syntaxique : maitriser les concepts théoriques et
leurs mises en œuvre dans les outils « compiler’s compiler »
– Architecture des processeurs : instructions, registres, structures
algorithmiques, appel de fonction, gestion mémoire ...
– Algorithmique et programmation :
●
Dans l’écriture du compilateur (algorithmique d’arbre,...)
●
Dans la compréhension de la chaîne de compilation et de la façon dont
les paradigmes usuels de programmation sont implantés pour l’exécution
12/10/2022 14 / 127
Objectif du Cours (2/2)
Ne fait pas partie du cours
– Analyse sémantique dynamique et analyse de flux
– Aspects théoriques de l’analyse sémantique
– Optimisation du code généré et transformation d’arbre
– Optimisation du code du compilateur
– Compilation séparée et édition de lien
12/10/2022 15 / 127
Bibliographie (1/2)
Mots clés
Compilation, théorie des langages, expressions régulières, automates
finis, grammaires algébriques (context-free), compilateur de compilateur
(compiler’s compiler), analyse syntaxique ascendante (LR)
Bibles
●
Gödel, Escher, Bach: an Eternal Golden Braid, aka "GEB", Douglas
Hofstadter, 1979, Basic Books
●
Compilers: Principles, Techniques, and Tools, aka «dragon book», A.
Aho, M. Lam, R. Sethi, J Ullman. 2nd ed., 2006, Pearson Education, Inc.
●
Modern Compiler Design in Java, 2nd edition - A.W. Appel -
Cambridge, 2002
●
Compilateurs, D. Grune, H.E. Bal, C.J.H. Jacobs, K.G. Langendoen,
Dunod 2002.
12/10/2022 16 / 127
Bibliographie (2/2)
Références
●
Introduction to Automata Theory, Langages and Computation, John
E. Hopcroft, Rajeev Motwani, Jeffrey D. Ullman. 3ieme ed.2013,
Pearson Education.
●
Langages Formels, Calculabilité et Complexité, Olivier Carton, 1er ed.
2012. Vuibert
●
[Link]
●
Learning Perl, [Link], T. Christiansen, 1997, O’Reilly.
●
Mastering Regular Expressions, Jeffrey Friedl, 3ieme ed.. 2006,
O’Reilly.
12/10/2022 17 / 127
Chapitre 1
1) Analyse Lexicale
De la théorie 19
Et en pratique 21
Lexicale versus Syntaxique 22
Analyse Lexicale 24
Spécification du vocabulaire 27
Expression Régulière 28
12/10/2022 18 / 127
De la théorie (1/2)
Théorie des Langages, Théorie de la Calculabilité
Que peut on calculer automatiquement ?
Que peut on calculer efficacement ?
Systèmes et grammaires formels
Hiérarchie de CHOMSKY-SCHÜTZENBERGER
12/10/2022 19 / 127
De la théorie (2/2)
Machine de Turing et Calculabilité
BANDE : infinie 0 1 1 0 1 0 1 1 1 0 0 0 1 1 1 1 ...
TÊTE : Lecture / Écriture 0 ou 1
Déplacement Droite ou Gauche
CONTRÔLE : un état (« variable entière »),
des instructions (« table d’automate ») :
[état courant, symbole lu, nouvel état, action=0/1/D/G]
12/10/2022 20 / 127
Et en Pratique
Langage de type 3 = Expressions Régulières
– Reconnues par automates à états finis
– ∃ outils pour reconnaître les expressions régulières en temps O(n)
●
Générateurs d’analyseur lexical : lex, flex, JFlex …
●
Aussi : commande grep, langage Perl, éditeurs de texte, …, ...
12/10/2022 21 / 127
Lexicale versus Syntaxique (1/2)
Séparation usuelle dans les langages naturels
– Les mots et leur catégorie (nom, verbe, adjectif,..) définis par un
dictionnaire
– Les phrases définies par des règles de construction (grammaire)
12/10/2022 22 / 127
Lexicale versus Syntaxique (2/2)
Exemple : langage naturel élémentaire
– Lexique POINT = .
ARTICLE = un | le
VERBE = mange | tue
NOM_C = lapin | chasseur | gnou
NOM_P = Bart | Jeannot | Obi-Wan
– Syntaxe
<Phrase> := <SujetVerbeCompl> POINT ;
<SujetVerbeCompl>:= <GroupeNom> VERBE <GroupeNom> ;
<GoupeNom> := NOM_P | ARTICLE NOM_C ;
– Des phrases valides :
●
Obi-Wan mange un gnou.
●
le lapin tue un chasseur.
12/10/2022 23 / 127
Analyse lexicale (1/3)
Reconnaître
– Les mots du langage, ou unités lexicales ou lexème
– Leur catégorie lexicale ou token
12/10/2022 24 / 127
Analyse lexicale (2/3)
Qui est catégorie lexicale ?
– Ensemble de lexèmes non différentiés dans les règles de grammaire
– Dépend de l’écriture de la grammaire
●
OpBin={+ , - , * , / } ou OpPlus, OpMoins, OpMult, OpDiv ?
Token
– Entier identifiant la catégorie lexicale reconnue (type énuméré)
– De façon optionnelle :
●
Valeur du lexème dans la catégorie pour les traitements après l’analyse
syntaxique
●
Position du lexème dans le fichier source
●
...
12/10/2022 25 / 127
Analyse lexicale (3/3)
Analyseur Lexical (lexer, tokenizer)
– Entrée : Texte ASCII, ou Unicode, ou éventuellement binaire
Exemple
– Entrée : Alpha += 32 * bêta + 2 /* comment*/
– Sortie : 132414 2
Exemple
a* a (b | c)* a* sur ∑ = { a, b, c}
Mots commençant par au moins un a, suivi de b ou c en nombre
quelconque, et éventuellement terminé par des a
a, aa, ab, ac, aaa, aab, aac, aba, abb, abc,, abba, ...
12/10/2022 28 / 127
Expression Régulière (2/3)
Classes de caractères : Reconnaît 1 symbole parmi un ensemble
. Un caractère quelconque sauf fin de ligne
[xyzT] Un caractère de l’énumération == x|y|z|T
[ … A-F … ] Idem avec intervalle
[^…] Un caractère hors de l’énumération
Répétitions
r? r répétée 0 ou 1 fois == r | ε
r+ r répétée n>0 fois == r r*
r {k} r répétée k fois
r {k,l} r répétée entre k et l fois
Délimiteurs de contexte
^r r en début de ligne
r$ r en fin de ligne
12/10/2022 29 / 127
Expression Régulière (3/3)
Exemples
12/10/2022 30 / 127
Chapitre 2
2) Automate Fini
Abrégé de la théorie des langages 32
Automate Fini 34
Reconnaissance par un automate 37
Reconnaissance par des outils 38
Déterministe versus Indéterministe 39
Langage Rationnel et Automate Fini 40
Petit commentaire 42
Illustrations 43
12/10/2022 31 / 127
Abrégé de la théorie des langages (1/2)
Définitions
Alphabet ∑ : ensemble fini de lettres
Mot w sur ∑ : suite finie de lettres de ∑
∑* : ensemble de tous les mots = monoïde libre
Langage L : ensemble de mots inclus dans ∑*
Mot vide ε, Langage vide ∅ ≠ {ε}
Opérations
Alternative (union) , Concaténation (produit),
Fermeture de Kleene (étoile) : L*= {ε} ∪ L ∪ LL ∪ LLL
Aussi Intersection, Complémentaire, Quotient, …
Questions
w ∈ L ? , L = ∅ ?, L fini ?, L1=L2 ?, ...
décidable, calculable, facilement calculable ?
12/10/2022 32 / 127
Abrégé de la théorie des langages (2/2)
Langage Rationnel Algébrique Algébrique Contextuel Récursif Récursivement
déterministe énumérable
Machine Automate Automate à pile Automate borné Turing qui Machine de
fini s’arrête Turing
Spécification Expression Grammaire context-free Grammaire Grammaire générale ou
régulière context-sensitive phrase-structure
Exemples a n bn Palindrome Papou diag(CSL) diag(TM)
abcd
n n p p
anbncp ∪ abc,abcd
n n n n p n p
Ackermann pas diag(TM)
ap et p Dyck ([]()) a p bn c n a et p premier
p
paire ap et p carré
Déterministe == OUI NON, mais Décidable ; Problème ouvert OUI OUI
Non Déterministe Ambiguïté Indécidable.
w∈L O(n) O(n) O(n3) PSPACE EXPSPACE Indécidable
L rationnel OUI Décidable Indécidable Indécidable Indécidable Indécidable
L= ∅ Décidable PTIME PTIME Indécidable Indécidable Indécidable
L = ∑* Décidable Décidable Indécidable Indécidable Indécidable Indécidable
L1 = L2, L1 ⊂ L2 Décidable Décidable Indécidable Indécidable Indécidable Indécidable
Union,concat,étoile Fermé Non clos Fermé Fermé Fermé Fermé
Intersection Fermé Non clos Non clos Fermé Fermé Fermé
Complémentaire Fermé Fermé Non clos Fermé Fermé Non clos
12/10/2022 33 / 127
Automate fini (1/3)
Principe int état =0 ;
tant que pas_fini {
lire un caractère c
selon état et c
changer état
}
Automate Fini (Finite State Automaton)
12/10/2022 34 / 127
Automate fini (2/3)
Exemple c∉N N = [0-9]
0 c∉ A
A = [a-zA-Z] 0
c∈N c∈A
AN= A ∪ N
n=val(c) s=c
2 1 2 1
c∉N n=10*n+val(c) s=sc
c∉AN
c∈N c∈AN
a) reconnaître un entier b) reconnaître un identificateur
i=j=0 c∉AN
c∈ A 0 c∈N
si = c i++ j++ nj = val(c)
eof
c∉AN c∉N
s i = si c 1 3 2 nj = 10*nj + val(c)
eof eof
c∈AN c∈N
c) Reconnaître tous les identificateurs et tous les entiers
12/10/2022 35 / 127
Automate fini (3/3)
Représentations d’un automate
– Diagramme d’état
0 initial événement
États Transitions action
n final
– Table états/transitions
12/10/2022 36 / 127
Reconnaissance par un automate
Langage reconnu par un automate
Les mots dont la séquence de caractères mène l’automate de l’état
initial q0 à un état terminal q∈QT
Exemple
Sur l’alphabet ∑ ={a, b}, reconnaître une chaîne
●
contenant une seule chaîne d’au moins deux b consécutifs
●
éventuellement précédée d’un ou plusieurs a
●
et obligatoirement suivie d’au moins un a
a b
b b a a
0 1 2 3
a b a, eof eof
a eof eof b
0 b 1 b 2 a 3 5
4
Erreur Fin ok
12/10/2022 37 / 127
Reconnaissance par des outils
Reconnaissance multiple de chaînes valides dans un texte
– Glouton versus Récalcitrant
– retourner la forme la plus étendue (glouton, greedy) ou la plus courte
(récalcitrant, reluctant, lazy)
– [0-9]+ sur « 1234 » ?
– < .* > sur « <b>bold</b> » ?
– Avec ou sans recouvrement ( aussi : avec ou sans trou)
– a*bb+a+ sur « abbaabba » ?
●
« abbaa » et « aabba » ou sans recouvrement : « abbaa » et « bba »
– Plusieurs automates simultanément
– [0-9]+ et [a-zA-z]+ en même temps
Théorème
Pour tout automate fini non déterministe (NFA), il existe un automate
fini déterministe (DFA) reconnaissant le même langage
12/10/2022 39 / 127
Langage Rationnel et Automate Fini (1/2)
Théorème de Kleene (1956)
Expressions Régulières <==> Automates Finis
Corolaire pratique
Outils de reconnaissance par expressions régulières = 1 + 2 + 3 + 3bis
Théorèmes faciles
1. Le complémentaire d’un langage rationnel est rationnel
2. L’intersection de 2 langages rationnels est rationnel
Preuve ?
12/10/2022 41 / 127
Petit commentaire
Supprimer les commentaires /* … */
out(c)
– Expression régulière 0 c≠'/'
●
"/*" .* "*/" !!!
out('/')
"/*" tout_sauf("*/") "*/" ??? c='/'
●
out(c)
c≠'*' 1
– Plus facile : Automate
c='*'
12/10/2022 42 / 127
Illustrations (1/5)
LuBuChu
une rivière, une barque, un fermier,
un loup, un bouc, un chou
. .B . .|LBC
LB|C. .BC|L C|LB. .C|LB
.C .C .L .C .
.B . . .B
.LBC| LC|B. .LC|B B|LC. .B|LC |LBC.
. .L .L
.L .C
BC|L. . .LB|C L|BC. . .L|BC
LBC|. .B
12/10/2022 43 / 127
Illustrations (2/5)
L’ arbre de vie.
10 Sephiroth et 22 sentiers
Azriel de gérone XIIIe siècle
12/10/2022 44 / 127
Illustrations (3/5)
Langage fini A
E
Structure de données L S
E
pour dictionnaire 0 D U
N E
U
1 2 3
Ascenseur 0 1 2 3
0 1 2
0 a 1
a
Parité 0 1 b b
a a
2 3
12/10/2022 45 / 127
Illustrations (4/5)
Numération et Modulo e1
e0 e0
1 0 0 1
0 1 e2
0 1 2 e0= 0|3|6|9
e2 e2
1 0 e1 e1 e1= 1|4|7
Bin-Mod3 Dec-Mod3 e2= 2|5|8
2
e0
Déterminisme
a b c c
0 ε 1 ε 2 b
a c
Non déterministe avec ε 1 b 2 c 3
a b c a b c
0 a,b 1 b,c 2 0
a,b,c Déterministe
Non déterministe sans ε
12/10/2022 46 / 127
Illustrations (5/5)
Négation de « .*aba.* »
Exercice TP ABBA-3 : preuve du corrigé
a,b a,b
Non déterministe 0 a 1 b 2 a 3
b a a,b
Déterministe b
complet 0 a 0,1 0,2 a 0,3
b
Négation :
états finaux = 0, {0,1}, {0,2}
Re (0->0) = b*(aa*bbb*)* = b*(a+bb+)*
Re (0->{0,1}) = Re (0->0)aa*
Re (0->{0,2}) = Re (0->0)aa*b
Re (0->final) = b*(a+bb+)* (ε | aa* | aa*b)
=> Not ( .*aba.*) == b*(a+bb+)*(a*|a+b)
aussi = b*(a+bb+)*a*b?
12/10/2022 47 / 127
Chapitre 3
3) Grammaire Algébrique
Grammaire 49
Arbre de Syntaxe 52
Où est l’étoile ? 53
Exemple 55
Grammaire régulière 56
Grammaire ambiguë 59
Spécification avec BNF 61
12/10/2022 48 / 127
Grammaire (1/3)
(rappel) Exemple de langage naturel élémentaire
– Lexique POINT = .
ARTICLE = un | le
VERBE = mange | tue
NOM_C = lapin | chasseur | gnou
NOM_P = Bart | Jeannot | Obi-Wan
– Syntaxe
<Phrase> := <SujetVerbeCompl> POINT ;
<SujetVerbeCompl>:= <GroupeNom> VERBE <GroupeNom> ;
<GoupeNom> := NOM_P | ARTICLE NOM_C ;
– Des phrases valides :
●
Obi-Wan mange un gnou.
●
le lapin tue un chasseur.
12/10/2022 49 / 127
Grammaire (2/3)
Grammaire algébrique (context free)
G = ( VT , VN , S , P ) avec
VT , ensemble des symboles terminaux ou constantes ou tokens
VN , ensemble des symboles non-terminaux ou variables
VT et VN sont finis et disjoints
S ∈ VN , symbole de départ ou axiome.
P ⊂ VN× (VT ∪ VN)*, ensemble des règles de production :
v := s1 s2 …sn ;
– Le membre gauche v est un symbole non-terminal, le membre droit
est une concaténation de symboles si terminaux ou non-terminaux
– Les productions peuvent être regroupées en utilisant l’alternative :
v := s1 s2 …sn ; v := s1 s2 …sn
v := s'1 s'2 …s'p ; | s'1 s'2 …s'p ;
12/10/2022 50 / 127
Grammaire (3/3)
Utilisations
– En production
●
en partant de l’axiome, substitutions d’un membre gauche d’une
production par un membre droit.
●
on génère l’ensemble des phrases valides pour la grammaire
●
Ex :
<Phrase> => <SujetVerbeComp> POINT
=> <GroupeNom> VERBE <GroupeNom> POINT
=> NOM_P VERBE ARTICLE NOM_C POINT
=> Bart tue un lapin .
– En reconnaissance, parsing
●
Réductions d’une phrase en remplaçant des membres droits par les
membre gauches
●
La phrase est valide si les réductions terminent sur l’axiome
12/10/2022 51 / 127
Arbre Syntaxique
Décrit la reconnaissance d’une phrase donnée conformément à
une grammaire
Arbre étiqueté :
– Feuilles = tokens = mots de VT
– Nœud = membre gauche de production = symbole de VN
– Fils = membres droits de la production
– Racine = axiome
<Phrase>
< SujetVerbeCompl >
<GroupeNom> <GroupeNom>
12/10/2022 52 / 127
Où est l’étoile ?
Problème !
– Les grammaires algébriques contiennent la concaténation et
l’alternative mais pas la fermeture de Kleene
– Selon Chomsky, les langages rationnels sont algébriques
– Comment réaliser l’étoile avec une grammaire algébrique ?
Exercice
– Soit L un langage décrit par le symbole L, comment définir le langage
L* avec une grammaire algébrique ?
●
N.B. : si L est rationnel, L* est rationnel et doit donc être algébrique
12/10/2022 53 / 127
Où est l’étoile ? (soluces)
Solution(s)
« La récursivité contient l’étoile »
N.B. : dans les outils, le mot vide ε pourra s’écrire /* mot vide */
12/10/2022 54 / 127
Exemple
Ébauche d’un langage informatique
– Vocabulaire terminal TYPE = int | char | float
IDENT = [a-zA-Z] [a-zA-Z0-9]*
INT = -? [0-9]+
FLOAT = -? [0-9]+ ( \. [0-9] *) ?
– Règles de productions Program := Definitions Functions ;
Definitions := TypeVar
| Definitions TypeVar ;
TypeVar := TYPE VarList ';' ;
VarList := Var
| VarList ',' Var ;
– Exemple de production Var := ScalarVar | ArrayVar ;
ScalarVar := IDENT
int i, j, i42=-1 ; | IDENT '=' Number ;
int a[-42], b[3][1][4] ; ArrayVar := IDENT '[' INT ']'
float pi=3 ; | ArrayVar '[' INT ']' ;
int yy=0.3 ; Number := INT | FLOAT ;
12/10/2022 55 / 127
Grammaire Régulière (1/2)
Une grammaire algébrique peut décrire un langage rationnel
– Indécidable dans le cas général (non-déterministe)
– Mais certaines productions simples génèrent des langages rationnels
3) VN={S}, VT={a,b}
S := a b
Linéaire ? Régulier ? | aSb ;
Expression régulière pour S ?
12/10/2022 57 / 127
Grammaire Régulière (2/2 soluce)
Solutions
1) A = b* a S := b A | a S ;
A := b A | a ;
S = a* b A = a* b+ a
L(S) = {ba, aba, aaba, abba, aaaba ...}
Exemple : Instruction IF
(R0) Inst := Inst_if | ... ;
(R1) Inst_if := "if" "(" Condition ")" Inst
(R2) | "if" "(" Condition ")" Inst "else" Inst ;
R1
R0
R2
Entrée : if ( cond1 ) if ( cond2 ) inst1 else inst2
R1
R0
R2
12/10/2022 59 / 127
Grammaire Ambiguë (2/2)
Grammaire d’opérateur (pas de mot vide, pas de non-terminaux voisins)
Généralement ambiguë Expr := Expr '+' Expr
2+3+4 = (2+3)+4 ou 2+(3+4) ? | Expr '-' Expr
| Expr '*' Exp
a=1; a + ++a + ++a = ? | '-' Expr
2-3-4 = (2-3)-4 ou 2-(3-4) ? | '(' Expr ')'
2+3*4 = (2+3)*4 ou 2+(3*4) ? | INT
| SYMBOL ;
4) Analyse Syntaxique
Analyse syntaxique : trois stratégies 64
Analyse descendante 65
Analyse ascendante « Shift/Reduce » 68
Automate LR 73
12/10/2022 63 / 127
Analyse syntaxique : trois stratégies
Résolution générale
– Applicable aux langages algébriques non déterministes
– Complexité O(n3) ; Algorithmes : Earley, CYK,Valiant, …
Analyse descendante ou « LL »
– Applicable à « beaucoup » de langages algébriques déterministes
– Algorithme plus intuitif, mais contraignant sur l’écriture de la
grammaire
– Complexité linéaire O(n) ; Outils : « à la main », javacc, ANTLR, …
12/10/2022 64 / 127
Analyse descendante (1/3)
Principe
– Construction de l’arbre de syntaxe de haut en bas
– Utilisation de la grammaire en production
– Arbre de décision ET/OU
●
Nœud OU : pour remplacer un symbole non-terminal, on a le choix entre
les différentes productions (ou alternatives) avec ce symbole en membre
gauche
●
Nœud ET : pour une production, il faut reconnaître la séquence des
symboles en membre droit
(v1) v := s1 s2 …sn ;
(v2) v := s'1 s'2 …s'p ;
– Exploration de l’arbre
V
●
En profondeur avec retour arrière /---\
●
En « parallèle » ... / OU \
V1 V2
●
Rendre prédictible les choix OU ? / | \ / | \
s1 .. sn s'1 .. s'p
12/10/2022 65 / 127
Analyse descendante (2/3)
Exemple langage naturel élémentaire
<Phrase>
<SujetVerbeCompl>
<GroupeNom> <GroupeNom>
12/10/2022 69 / 127
Analyse ascendante « Shift/Reduce » (3/4)
Entrée = « alpha + bêta + 666 »
Expr := Expr '+' Expr
Opération Pile | INT
décalage SYMBOL | SYMBOL ;
réduction Expr
décalage Expr '+'
décalage Expr '+' SYMBOL
Ambiguïté
réduction Expr '+' Expr
Conflit shift/reduce
réduction Expr décalage Expr '+' Expr '+'
décalage Expr '+' décalage Expr '+' Expr '+' INT
décalage Expr '+' INT réduction Expr '+' Expr '+' Expr
réduction Expr '+' Expr réduction Expr '+' Expr
réduction Expr réduction Expr
succès succès
(alpha+bêta)+666 alpha+(bêta+666)
12/10/2022 70 / 127
Analyse ascendante « Shift/Reduce » (4/4)
Input = « 42 666 »
12/10/2022 71 / 127
Analyse ascendante « Shift/Reduce » (4/4 soluce)
Input = « 42 666 »
12/10/2022 72 / 127
Automate LR (1/3)
Analyse LR : Automate à pile pour décider des shift/reduce
États de l’automate
– états viables du sommet de pile ( séquence de n symboles)
– viable = le sommet de pile pourra être réduit à terme
– sommet de pile = préfixe de membre droit de production
Pile
– A chaque Push, l’état de l’automate est empilé avec le symbole
Transitions
– Shift : transition « simple » avec Push d’un token
– Reduce : transition avec remplacement (Pop* + Push) et retour à
l’état stocké dans la pile (dernier Pop)
– En général, les transitions reduce ne sont pas représentées
12/10/2022 73 / 127
Automate LR (2/3)
Exemple LALR(1) avec « cup -dump »
12/10/2022 74 / 127
Automate LR (3/3)
(using CUP eclipse plugin)
R1 R2
EOF TOK
lalr_state [1]:
[list ::= list (*) TOK , {EOF TOK }]
[$START ::= list (*) EOF , {EOF }]
list
lalr_state [0]:
[list ::= (*) list TOK , {EOF TOK }]
R0
[$START ::= (*) list EOF , {EOF }]
[list ::= (*) , {EOF TOK }]
12/10/2022 75 / 127
Chapitre 5
12/10/2022 76 / 127
Utilisation JFlex et CUP
[Link]
[Link] [Link]
[Link] [Link]
Spécification JFlex Spécification CUP
Options,main() main()
Règles lexicales Règles syntaxiques
Analyseur Analyseur
Lexical Syntaxique
java Yylex <data java -cp java_cup.[Link] CupParse <data
12/10/2022 77 / 127
Format des spécifications
Jflex Cup
package [Link] package [Link]
import [Link] import [Link].*
%% parser code {: /* … */ :}
%include [Link] action code {: int i ; :};
%include [Link] init with {: i=0; :}
%{ terminal int TOK ;
%} terminal TIK, TAK ;
%init{ nonterminal int sym, var;
%init} precedence left TIK;
%eof{ precedence right TAK ;
%eof} start with sym,;
ANY = [^] sym ::= sym:s TOK:n {: RESULT=s+n; :}
BLANC = [ \t] | var:v {: RESULT=v; :}
%% ;
[a-zA-Z] [a-zA-Z0-9]* { ECHO("ID"); } var ::= /* vide */ {: RESULT=0; :}
[ \t] | {NL} { ECHO(); } | TIK {: RESULT=42 ; i++; :}
{ANY} { WARN("Invalid char"); } ;
12/10/2022 78 / 127
Automate LALR et Conflit (1/2)
« cup -dump » : ===== Viable Prefix Recognizer ===
–--lalr_state [0]:
===== Terminals ===== [list ::= (*) TOK , {EOF TOK }]
terminal TOK; [0]EOF [1]error [2]TOK [$START ::= (*) list EOF , {EOF }]
nonterminal list; ===== Non terminals == [list ::= (*) list TOK , {EOF TOK }]
[0]list [list ::= (*) , {EOF TOK }]
list ::= /* vide */
===== Productions === transition on TOK to state [2]
| TOK [0] list ::=
| list TOK transition on list to state [1]
[1] $START ::= list EOF ---lalr_state [1]:
; [2] list ::= TOK [$START ::= list (*) EOF , {EOF }]
[3] list ::= list TOK [list ::= list (*) TOK , {EOF TOK }]
transition on TOK to state [4]
transition on EOF to state [3]
---lalr_state [2]:
Warning : *** Shift/Reduce conflict [list ::= TOK (*) , {EOF TOK }]
found in state #0 ---lalr_state [3]:
between list ::= (*) [$START ::= list EOF (*) , {EOF }]
and list ::= (*) TOK ---lalr_state [4]:
under symbol TOK [list ::= list TOK (*) , {EOF TOK }]
12/10/2022 79 / 127
Automate LALR et Conflit (2/2)
(using CUP eclipse plugin)
R1 R3
EOF TOK
R2
lalr_state [1]:
lalr_state [2]: [$START ::= list (*) EOF , {EOF }]
[list ::= TOK (*) , {EOF [list ::= list (*) TOK , {EOF TOK }]
TOK }]]
list
Conflit TOK
shift/reduce lalr_state [0]:
[list ::= (*) TOK , {EOF TOK }]
R0 [$START ::= (*) list EOF , {EOF }]
[list ::= (*) list TOK , {EOF TOK }]
[list ::= (*) , {EOF TOK }]
12/10/2022 80 / 127
Chapitre 6
12/10/2022 81 / 127
Arbre Syntaxique
L’Arbre Syntaxique est :
– La preuve de la validité syntaxique de l’entrée
– Le support d’une part importante de la sémantique de l’entrée
– La structure de données transmise dans les deux phases suivantes de
la compilation : analyse sémantique et génération de code
intermédiaire
Rappel :
– Nœud=règle de production
<Phrase>
– feuille=token
< SujetVerbeCompl >
<GroupeNom> <GtoupeNom>
12/10/2022 82 / 127
...
12/10/2022 83 / 127
CST vs AST (1/2)
Concrete Syntax Tree (CST) :
– Forme adaptée pour la validation syntaxique
– Pas de valeurs sémantiques pour les tokens
– Les nœuds respectent strictement les règles de grammaire
– Construction automatique avec les outils d’analyse syntaxique
12/10/2022 84 / 127
CST vs AST (2/2)
Exemples : « F(a, b+3, 1) »
CST AST
Call Call("F")
12/10/2022 85 / 127
Arbre et Analyse LR
Analyse LR
– Construction ascendante de l’arbre
– Action sémantique = nouvel arbre à partir des fils déjà existants
12/10/2022 86 / 127
Arbre et Typage Objet
Utilisation d’un langage objet :
– Typage des nœuds
●
new ArbreRegleN (x1,…) vs new Arbre(« RegleN »,x1,...).
– Héritage et productions alternatives dans la grammaire
●
ArbreV = classe abstraite pour ArbreRegleV1, ArbreRegleV2,...
– Surdéfinition (overriding) et liaison dynamique
●
ArbreV T = new ArbreRegleVi() ;
[Link]() ; /* méthode xxx de la classe concrète de T (ArbreRegleVi) */
Réalisation d’une fonction sur l’arbre
– Méthodes d’objets dans les nœuds et parcours récursifs
– Variante : patron de conception « Visiteur » (Visitor Pattern)
But : obtenir le même résultat mais avec le code des méthodes d’objets
de chaque nœud regroupé dans une seule classe.
12/10/2022 87 / 127
Visiteur (1/2)
Ajouter une fonction à une hiérarchie de classes (classes visitées)
– Non pas en utilisant le schéma naturel OO des méthodes d’instance
dans chaque classe (héritage, surdéfinition)
– Mais en utilisant une classe externe (classe visiteuse).
Utilité
– Regrouper l’algorithme de la fonction dans une même classe
– Ne pas modifier les classes visitées pour chaque nouvelle fonction
12/10/2022 88 / 127
Visiteur(2/2)
« Accept et Visit sont dans un bateau »
12/10/2022 89 / 127
Classes du cours (1/4)
AstNode : Classe abstraite ancêtre des « visitées »
/** Patron Visiteur */
public abstract void accept(AstVisitor v);
12/10/2022 91 / 127
Classes du cours (3/4)
AstVisitor : Interface des classes « Visiteuses »
– Méthodes abstraites visit() pour chaque classe visitable de l’AST
interface AstVisitor {
12/10/2022 92 / 127
Classes du cours (4/4)
AstVisitorDefault : Visiteur générique de l’AST
– Classe mère pour des Visiteurs qui font des calculs par parcours en
profondeur de l’arbre.
– Les méthodes visit() sont alors à surdéfinir (override). Ou pas !
12/10/2022 93 / 127
(Bonus) Retour au source
Propager les informations de positions dans le fichier source
– JFlex vers CUP : transparent avec [Link]
●
ComplexSymbolFactory et TOKEN()
– CUP vers AST :
●
Option « -locations » de CUP requise (Makefile ou [Link])
●
Méthode addPosition() de AstNode :
v ::= s1: aa … sn:zz
{: RESULT= new Arbre ( aa, …,zz) ;
[Link](aaxleft, zzxright) ; :}
;
●
Exemple : [Link]() -> RopBin[16/10/293-16/21/304](+)
12/10/2022 94 / 127
Chapitre 7
7) Analyse Sémantique
Où en est-on ? 96
Analyse sémantique 99
Attributs sémantiques 101
Analyse statique ou dynamique 102
Des fonctions sémantiques 103
Table des symboles 106
Contrôle de type 107
12/10/2022 95 / 127
Où en est-on ? (1/3)
Retour : Phases de Compilation
Texte Tokens AST Sémantique
Lexicale Syntaxe
12/10/2022 96 / 127
Où en est-on ? (2/3)
Compilation Classique versus Moderne
– « Dragon Book » Aho, Ullman 1977
– « Modern Compiler » Appel 2000 , ...
12/10/2022 97 / 127
Où en est-on ? (3/3)
Compilation Multi-passe ou Mono-passe ?
– Exécution en séquence vs chainage (pipeline) des phases
– Mono-passe : contraignant sur l’algorithmique du compilateur, mais
économe sur les performances en temps, en espace, en entrée-sortie
– Multi-passe : plus souple dans la programmation et l’indépendance
des phases de compilation
Historiquement : Mono-passe était un enjeu vital
– Contrainte sur le langage : Tout ce qui est nécessaire pour analyser
une portion de programme doit exister « avant » dans le source.
– Algorithmique lourde pour tout résoudre en une fois
12/10/2022 98 / 127
Analyse sémantique (1/2)
Objectifs :
– Valider les règles du langage non gérables au niveau syntaxique
12/10/2022 99 / 127
Analyse sémantique (2/2)
De la théorie :
– « Haute » : Lambda-calcul, Théorèmes du point fixe, Preuve de
programmes
– « Basse » : Grammaires Attribuées, Traduction dirigée par la syntaxe
Mais en pratique ?
– Trop théorique, et peu de résultats pour de « vrais » programmes
– Trop orientée sur la contrainte « compilation mono-passe »
Dynamique
– On ajoute à l’AST, les chemins d’exécutions du programme pour
calculer des attributs qui vont hériter de nœuds traversés « avant » ou
« après » à l’exécution.
– Algorithmique :
●
« Couture d’arbre »
●
Interprétation symbolique
●
Équations de flots de données
●
Analyse de vivacité
8) Représentation Intermédiaire
Objectif 110
Principe 111
Code à trois adresses 113
Représentation pour Minijava 114
Traduction AST vers IR 116
Objectif programmation
– Étape intermédiaire pour la phase « Génération »
– Génération = traduction de l’AST vers code machine
●
Linéarisation du code
●
Génération de l’assembleur
●
Allocation mémoire
●
Optimisations : allocations des registres, évaluation des expressions, ...
Instruction
[ OP , X , Y, Z]
– Une opération et zéro à trois « adresses »
– « adresses » ou variables intermédiaires « Z = X OP Y »
●
Variables du programme source (ou nom de fonction, ou … )
●
Variables temporaires pour évaluation des expressions
●
Labels pour des sauts
●
Valeurs constantes
Exemple : [ * , 2, x, t1 ] t1 = 2 * x
A = 2*x +1 [ + , t1, 1, t2 ] t2 = t1+1
[ = , t2, , A ] A = t2
/* ExprOpBin */ traduction(exp1)
exp1 + exp2 traduction(exp2)
setVar node, newTemp()
… QAssign +, getVar(exp1), getVar(exp2), getVar(node)
/* ExprCall */ traduction(exp)
[Link](arg1,arg2,..) traduction(arg1)
/* … args suivants */
QParam getVar(exp) // this
QParam getVar(arg1)
/* … args suivants */
QCall newLabel(«xxx»), newConst(nb_args)
/* StmtAssign */ traduction(exp)
X = exp setVar(node, lookup(« X »))
QCopy getvar(exp), getvar(node)
QLabel L1 L1 = newLabel()
/* StmtWhile */ traduction(exp) L2 = newLabel()
while (exp) inst QJumpCond L2, getVar(exp)
traduction(inst)
… QJump L1
QLabel L2
12/10/2022 119 / 127
Chapitre 9
9) Génération de code
Différentes fonctions 121
Mémoire et Variables 124
Cadre d’appel 125
Convention d’appel 126
Fin de Compilation ! 127
overflow -128
traduction(exp2) /* ershow(exp2)>ershow(exp1) */
/* ExprOpBin */ traduction(exp1)
exp1 OP exp2 ?? QAssign OP, getVar(exp1), getVar(exp2), getVar(n)
traduction(exp1)
« Qassign »
« QJumpCond L0» En java :
traduction(exp2) (f==null) || (f.x==0)
« Qassign » (f!=null) && (f.x==0)
QLabel L0
$sp (0)
$sp = stack pointer $fp
$fp = frame pointer $a0,… $a3
Appelant
$t0,… $t9, $v0, $v1 si besoin.
ArgN
Arguments 0 à 3 $fp ..
$a0,... $a3 Arg4
$sp (1)
$ra
Appelé
Frame $s0,… $s7 si besoin
Valeur de retour
size Variables locales
$v0
(et temporaires)
$sp (2)