TP Compilation Dr. T. DIAB 1 Compilation d’un programme (texte, chaine de carac
TP Compilation Dr. T. DIAB 1 Compilation d’un programme (texte, chaine de caractères…) : 1. Analyse lexicale : Générer l’analyseur lexical en utilisant l’outil Flex : Flex : Fast LEXical analyzer - Générateur d'analyseurs lexicaux en C, - Version GNU de Lex. - Lex (LEXical analyser): - Utilitaire d’UNIX. - Années 1970, laboratoires Bell, Analyseur lexical Analyseur syntaxique Compilateur (C, C++ …) Analyseur sémantique Générateur du Code Code Assembleur Chaine de caractères (code source, texte …) Analyseur lexical (Reconnait les mots) 1- Eliminer les caractères superflus (espaces, commentaires) 2- Identifier les unités lexicales. … Chaine de caractères (code source, texte …) Unité_lexicale_2 Unité_lexicale_1 Analyseur lexical Desc_flex.l Analyseur_L.exe Description lexicale Analyseur lexical Desc_flex.l Analyseur_L.exe Description lexicale Compilateur Flex Compilateur C Programme en C lex.yy.c Flex (1) (2) (3) (4) Flex TP Compilation Dr. T. DIAB 2 Description lexicale en fichier Flex (.l) : %{ Partie 1 : Déclaration des variables, constantes, includes … (en C) %} Partie 2 : Définitions régulières %% Partie 3 : Règles de traduction (Colonne droite en C) %% Partie 4 : Bloc principal (fonction main) et fonctions auxiliaires (en C) Fichier_flex.l %{ #include <stdio.h> int i ; … %} nb [0-9]+ … %% [A-Z]+ {printf ("ID");} ("+"|"-"){nb} {printf ("nombre");} … … %% int yywrap() { return 1; } int main () { yylex (); return 0 ; } // Partie 3 : Règles de traduction (Colonne droite en C) // Partie 2 : Définitions régulières // Partie 1 : Déclaration des variables, constantes, includes … (en C) Fichier_flex.l // Partie 4 : Bloc principal (fonction main) et fonctions auxiliaires (en C) TP Compilation Dr. T. DIAB 3 Variables et fonctions prédéfinies : Variable/ fonction Signification char yytext [] Tableau de caractères qui contient la chaine de caractères entrée par l’utilisateur et acceptée par une expression régulière. Le contenu de ce tableau peut être récupéré devant chaque expression régulière → Ce tableau va contenir la chaine de caractère acceptée par cette expression régulière. int yyleng Variable contient la longueur de ce tableau (yytext). int yylex () Fonction qui lance l’analyseur lexical (et appelle la fonction yywrap () à la fin du fichier d’entrée). int yywrap () Fonction appelée à la fin du fichier d’entrée (le fichier qui contient la chaine de caractères (le programme qu’on veut analyser lexicalement). Dans le TP, nous n’avons pas utilisé ce fichier, nous avons utilisé l’entrée standard sdtin (taper les caractères avec le clavier)). yywrap () peut retourner deux valeurs : 1 : Si on veut utiliser l’entrée standard stdin (si on n’a pas de fichier d’entrée), ou si on veut analyser un seul ficher d’entrée, 0 : Si on veut analyser plusieurs fichiers d’entrée. int main () Fonction principale contient par défaut juste l’appel à yylex (). yyterminate () Fonction qui stoppe l’analyseur lexical. Remarques : - L’analyseur lexical obtenu lit le texte d’entrée caractère par caractère jusqu’à ce qu’il trouve la plus longue chaine de caractères du texte d’entrée qui corresponde à l’une des expressions régulières : • Si plusieurs règles sont possibles => la première règle de ces règles (de haut en bas) est exécutée. • Si aucune règle ne peut être sélectionnée => copier le caractère lu en entrée vers la sortie (l’écran). - Les expressions régulières doivent commencer en colonne 0. - Les actions sont des blocs d’instructions en C (si plusieurs instructions, elles doivent être entre {}) doivent commencer en colonne 1 et sur la même ligne que l’expression correspondante. Cas exceptionnels : Exemple Flex Chaine de caractères entrée Résultat Commentaires \< {printf (“Meta_c”);} \n {printf (“Entrer”);} \H {printf (“Maj”);} \5 {printf (“Chiffre”);} < (Cliquer sur Entrer) H 5 Meta_c Entrer Maj Chiffre Le caractère \ est utilisé pour : - Afficher les métacaractères littéralement, - Exécuter la signification de certains caractères (\n, \t…), - Peut être utilisé pour afficher des chiffres et majuscules. TP Compilation Dr. T. DIAB 4 ab\nc {printf (“id”);} ab(puis tapez Entrer) (puis tapez c)c id id est affichée après le deuxième Entrer "abc*+" {printf (“id”);} abc*+ id Entrer la chaine de caractères qu’elle est entre "" littéralement (sauf le caractère \) "abc*+\\" {printf (“id”);} abc*+\ id Pour afficher \, écrire \\ "abc*+\n" {printf (“id”);} "ab\tc*+" {printf (“id”);} Abc*+(puis taper Entrer) ab c*+(ab puis tabulation puis c*+) id id A l’intérieur des "", le caractère \ voit le caractère qui suit pour exécuter sa signification : \n => Entrer \t => tabulation "ab\Ac*+" {printf (“id”);} "ab\6c*+" {printf (“id”);} "ab\-c*+" {printf (“id”);} abAc*+ ab6c*+ ab-c*+ id id id A l’intérieur des "", si après le caractère \ un majuscule, chiffre, symbole (autre qu’un minuscule) => affiche ce caractère littéralement [dgh+*] {printf (“id”);} d (ou) g (ou) h (ou) + (ou) * id A l’intérieur des [], un seul caractère est concerné (sauf \ et -) [d\nf\t\Si\8] {printf (“id”);} d (ou) Entrer (ou) f (ou) tabulation (ou) S (ou) i (ou) 8 id A l’intérieur des [], le caractère \ voit le caractère qui suit pour exécuter sa signification [ah-n*+] {printf (“id”);} a (ou n’importe quel caractère entre h et n) (ou) * (ou) + id Si le caractère – est au milieu des caractères entre [] => il signifie l’ensemble des caractères entre le caractère à gauche et celui à droite [ah*+-] {printf (“id”);} [-ah*+] {printf (“id”);} a (ou) h (ou) * (ou) + (ou) – - (ou) a (ou) h (ou) * (ou) + id id Si le caractère – est au début ou à la fin => il signifie le – littéralement [ah|k] {printf (“id”);} a (ou) h (ou) | (ou) k id A l’intérieur des [], le caractère | (ou) devient un caractère normal %% ^ab {printf (“Id”);} . {printf (“Err”);} %% abab IdErrErr ^ signifie le début de la ligne (première ab) ^ab|xy {printf (“id”);} ab(au début) … (ou) xy(au début) … id … ^ab|xy égale à ^(ab|xy) a^b {printf (“id”);} (^ab) {printf (“id”);} a^b ^ab id id Si ^ n’est pas au début de l’expression => devient caractère normal %% ab$ {printf (“Id”);} . {printf (“Err”);} %% abab ErrErrId $ signifie la fin de la ligne (dernière ab) a$b {printf (“id”);} (ab$) a$b ab$ id id Si $ n’est pas à la fin de l’expression => devient caractère normal machine* {printf (“id”);} machin (ou) machineee … id *, + et ? concerne le dernier caractère à gauche (machin(e*)) TP Compilation Dr. T. DIAB 5 machine{3} {printf (“id”);} machineee id 3 occurrences du dernier caractère à gauche machin(e{3}) %% ab/j {printf (“Id1”);} j {printf (“Id2”);} %% abj Id1Id2 ab est suivie par j donc => exécuter l’action de ab puis l’action de j (ab/j) (Erreur) (Erreur) Ne pas mettre le caractère / entre () %{ %} ident ab/j %% (Erreur) (Erreur) Ne pas mettre le caractère / dans les définitions régulières %{ %} ident ^ab %% (Erreur) (Erreur) Ne pas mettre le caractère ^ dans les définitions régulières %{ %} ident ab$ %% (Erreur) (Erreur) Ne pas mettre le caractère $ dans les définitions régulières %% “prog“ {printf (“id”);} [a-z]+ {printf (“identificateur”);} %% prog programme id identificateur L’analyseur lexical choisit la première expression régulière la plus longue qui correspond la chaine de caractère entrée “prog“ contient prog et elle est en premier => id “prog“ ne contient pas programme mais [a-z]+ le contient => identificateur %% [a-z]+ {printf (“identificateur”);} “prog“ {printf (“id”);} %% prog programme identificateur identificateur [a-z]+ contient prog et programme et elle est en premier => identificateur [a-z]+ {printf (“%s”, yytext);} (ou) [a-z]+ {ECHO;} abc abc abc abc printf (“%s”, yytext); et ECHO; sont les mêmes uploads/Management/ tp-flex.pdf
Documents similaires
-
51
-
0
-
0
Licence et utilisation
Gratuit pour un usage personnel Attribution requise- Détails
- Publié le Oct 01, 2022
- Catégorie Management
- Langue French
- Taille du fichier 0.3795MB