Introduction Lex permet de créer automatiquement le code source d’un analyseur

Introduction Lex permet de créer automatiquement le code source d’un analyseur lexical à partir d’un fichier construit par l’utilisateur. Le code source (en c) obtenu peut être complété par celui d’un analyseur syntaxique construit grâce à YACC. L’utilitaire Lex lit le fichier lex et construit le fichier lex.yy.c (nom imposé par Lex) qui contient le code source de l’analyseur. I- Présentation de Lex Lex est un langage de spécification d’analyseurs lexicaux.Un programme en lex définit un ensemble de schema qui sont applicables à un flux textuel. Il prend en entrée la définition des unités lexicales (expression régulière) ; produit le code source C d’un AFD minimal permettant de reconnaître les mots du langage spécifié par l’expression régulière. L’automate construit , défini la fonction yylex(void) qui constitue l’analyseur lexical. Une modification du langage entraine une regénération du code de l’analyseur. I-1. Structure d’un fichier Lex Les fichiers Lex ont pour extension « .l ». Leur structure est la suivante : %{ Partie 1 : Déclarations pour le compilateur C %} Partie 2 : Définitions régulières %% Partie 3 : Règles traduction %% Partie 4 : Fonctions C supplémentaires Explication de la structure du fichier Lex ➔La partie 1 se compose de déclarations C qui seront simplement recopiées au debut du fichier produit. Cette partie et les symboles%{ et%} qui l’encadrent peuvent être omis. ➔La partie 4 se compose des fonctions C qui seront simplement recopies à la fin du fichier produit. ➔Partie 2 : Les définitions régulières Les définitions régulières sont de la forne identificateur expressionRégulière. Exemple: lettre [a-zA-Z] ; chiffre [0-9] Les identificateur définis peuvent être utiliser dans les règles et dans les définitions suivantes. Exemple : lettre [a-zA-Z] ; chiffre [0-9] ; alphanum {lettre}|{chiffre} ➔Partie 3 : Les règles de traduction Les règles sont sous la forme expressionRégulière {action} où expression régulière est ecrit au debut de ligne et action est un morceau de code c qui sera recopiée tel quel au bon endroit dans la fonction yylex. La fonction yylex () renvoie 1 chaque fois qu’une expression que vous avez spécifiée se trouve dans la chaine entrée et 0 lorsque la fin du fichier est rencontrée. Chaque appel à yylex() analyse un jeton (en supposant un retour) ; lorsque yylex() est appellée à nouveau, elle reprend où elle s’est arrêtée. Remarque : La compilation du fichier lex avec l'option -t lui fait écrire sa sortie sur stdout plutôt que sur lex.yy.c, afin qu'il puisse être redirigé. I-2- Jargon de Lex I-3- Avantages et inconvénients de LEX Avantages ➔Gain de temps à la conception de l’analyseur lexical ➔Souplesse et optimisation automatique des flux dans l’analyseur ➔Avantages du C (La rapidité d’exécution) Inconvénients ➔Code source volumineux ➔Méta-langage difficile à maitriser et parfois peu cohérent II- Cas pratiques Cas 1 : Donner sous lex le code permettant de reconnaitre ➢Un opérateur ➢Une suite de F ➢Deux ab ou plus ➢Des mots de longueurs 3 %{ #include<stdio.h> %} %% [-+*/] {printf("OPERATOR \n");} [F|f]+ {printf("F/f Suite \n");} ("ab"|"AB"){2,} {printf("At least 2 ab/AB \n");} .{3} {printf("The word of three length\n");} .* {printf("ERREUR \n");} %% int yywrap(){ return 1 ; } int main (void){ yylex(); } cas 2: Donner sous lex le code permettant de reconnaitre ➢Un nombre entier et un nombre réel ➢un identificateur qui commence obligatoirement par une lettre majuscule suivi d’au moins un caractère alphanumérique. %{ #include<stdio.h> %} chiffre [0-9] lettre [a-zA-Z] alpha ({chiffre}|{lettre})+ %% [-|+]?{chiffre}+ {printf("INTEGER \n");} [-|+]?{chiffre}+"."{chiffre}+ {printf("REAL \n");} [A-Z]{alpha} {printf("IDENTIFICATEUR \n");} .* {printf("ERREUR \n");} %% int yywrap(){ return 1; } int main (void){ yylex(); } Cas 3 : Donner sous Lex la spécification permettant de supprimer les espaces multiples entre les mots dans une phrase, de compte le nombre de «a » dans cette phrase. %{ #include<stdio.h> int nbreA = 0 ; %} %% " "{2,}|"\t"+ {printf(" ");} "a"|"A" {nbreA++;} %% int yywrap(){ return 1; } int main (void){ yylex(); } Cas 4 : Donner sous Lex la spécification permettant de transfomer toutes les majuscules dans une phrase en minuscule. %{ #include <stdio.h> #include <stdlib.h> #include<ctype.h> %} %% [A-Z] { printf(tolower(yytext) ;} %% int yywrap() { return 1; } int main() { printf("Enter a text: \n"); yylex(); } Cas 5 : Ajout d’un numéro à chaque ligne d’un fichier %{ int yylineno; %} %% ^(.*)\n printf("%4d\t%s",++yylineno,yytext); %% int yywrap() { return 1; } int main(int argc,char* argv[]) { yylineno = 0; yyin = fopen(argv[1],"r"); yylex(); fclose(yyin); } $ lex nom_fichier.l PROCEDURE DE COMPILATION ET EXECUTION DE L’ANLYSEUR Pour executer un fichier a l’aide de lex, l’on doit suivre un ensemble d’etapes qui sont : ➢ Compilation de notre programme lex contenu das le fichier nom_fichier.l à l’aide de la commande qui genère toujours le fichier lex.yy.c qui est l’equivqlence en C de notre automate. ➢ Compilation du programme C obtenu à l’aide de gcc par exemple. ➢ Execution de l’executable genere par le compilateur EXEMPLE DE COMPILATION ET EXECUTION D’UN PROGRAMME LEX CONTENU DANS UN FICHIER NOMME lineNo.l SOUS WINDOWS uploads/S4/ expose-lex-corriger-et-readapter-fusionne.pdf

  • 28
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager
  • Détails
  • Publié le Sep 04, 2022
  • Catégorie Law / Droit
  • Langue French
  • Taille du fichier 0.2415MB