Compilation Introduction Introduction Compiler : Traduire un programme écrit en « langage évolué » (C, C++, Java…) vers un langage de plus bas niveau (Java bytecode, assembleur, binaire) Pourquoi étudier les compilateurs ● Bien comprendre les messages d'erreur fournis par les compilateurs : % gcc toto.c toto.c:1: erreur d'analyse syntaxique before ',' token toto.c:2: Dans la fonction "main" : toto.c:2: error: 'a' undeclared (first use in this function) /tmp/ccImHOOb.o(.text+0x27): In function 'main' : undefined reference to 'get' toto.c: Dans la fonction "main" : toto.c:5: attention : suggest explicit braces to avoid ambiguous 'else' Pourquoi étudier les compilateurs ● Savoir écrire un parser facilement : – avant : deux milles lignes ● ● ● ● remplies *ptr++, strcmp, strcat, strcpy segmentation fault une fois sur deux aucune gestion d'erreurs code non réutilisable – après : quelques lignes claires ou utilisation d'un générateur de parsers et code modulaire – théorie des grammaires algébriques et leurs applications Pourquoi étudier les compilateurs ● Savoir quelles optimisations sont inutiles : a=b/2 int f(int x) { int a,b,c; a=x; b=a+2; c=2*b; return c; } a=b>>1 int f(int x) { return 2*(x+2); } Pourquoi étudier les compilateurs ● Savoir quelles optimisations sont utiles for(i=0;i<strlen(s);i++) { … } int len=strlen(s); for(i=0;i<len;i++) { … } Ce qui n'est pas de la compilation ● ● ● La phase de pré-traitement ou preprocessing (cpp : gestion des directives #define, #if…) ; l'édition des liens (ld), et la collecte des différentes parties du programme (ar, libtool, ld‑linux.so…) ; l'interprétation (ocamlrun, java (pas javac), python, ruby, perl). Les « phases » de la compilation Table des symboles Programme source Arbre de syntaxe abstraite Indép enda nt de l 'arch itectu re cib le Langage intermédiaire Programme objet Les « phases » de la compilation ● Parsing – analyse lexicale – analyse syntaxique – passe sémantique Table des symboles ● Génération de code intermédiaire ● Génération de code – choix d'instructions – durée de vie des variables – choix des registres Parsing du fichier source analyse lexicale analyse syntaxique passe sémantique Opération du parsing ● Le but du parsing est de transformer le programme source (suite de caractères) en une structure de données plus facile à utiliser : l'arbre de syntaxe abstraite (abstract syntax tree) Opération de parsing fonction f paramètres : entier x corps de la fonction int f(int x) { int y=x/2; if (y==0) return 1; else return 12/y; } variable entière : y if test initialisation / == y x 2 vrai return 1 faux return / 12 y 2 Les phases du parsing ● analyse lexicale – ● analyse syntaxique – ● découper le texte d'entrée en lexèmes vérifier que le programme est syntaxiquement correct et construire l'arbre de syntaxe concrète passe sémantique – vérifier le respect des règles du langages (typage, arité des fonctions…)