1 Introduction à LEX
Transcription
1 Introduction à LEX
Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Notes de cours GEI 443 : ORGANISATION DES LANGAGES ET COMPILATION Chapitre 3 Utilisation de l ’outil LEX Ahmed KHOUMSI GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 1 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Introduction à LEX Langage Lex : permet de définir des expressions régulières Il peut donc être utilisé pour définir des unités lexicales qui sont spécifiées par des expressions régulières Programme Lex : - constitué d ’un ensemble d ’expressions régulières écrites dans le langage Lex - son écriture correspond à l ’étape 1 (voir chap.2, page 33) - est mis dans un fichier avec l ’extension l exemple : scan.l Compilateur Lex : génère l ’analyseur lexical à partir du programme Lex - effectue les étapes 2 à 4 (voir chap.2, page 33) - exécuté à l ’aide de la commande lex exemple : lex scan.l La commande lex génère le code C du scanner qui est déposé dans un fichier lex.yy.c Le fichier lex.yy.c est soumis au compilateur C pour générer le code objet du scanner GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 2 1 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Écriture des expressions régulières expression c \c ``s ´´ . ^ $ [s] [^s] r* r+ r? r{m} r{m,n} r1r2 r1|r2 r1/r2 (r) <x>r exemple signification tout caractère c qui n ’est pas opérateur ou métacaractère caractère littéral c (lorsque c est un métacaractère) chaîne de caractères n ’importe quel caractère, sauf retour à la ligne l ’expression qui suit ce symbole débute une ligne l ’expression qui précède ce symbole termine une ligne n ’importe quel caractère de s n ’importe quel caractère qui n ’est pas dans s 0, 1 ou plusieurs occurrences de r 1 ou plusieurs occurrences de r 0 ou 1 occurrence de r m occurrences de r entre m et n occurrences de r r1 suivie de r2 r1 ou r2 r1 si elle est suivie de r2 r r si LEX se trouve dans l ’état x GEI 443 : Organisation des langages et compilation a \+ \. ``bonjour ´´ a.b ^abc abc$ [abc] [^xyz] b* a+ d? e{3} f{2,4} ab c|d ab/cd (a|b)?c <x>abc Hiver 2002 Ahmed KHOUMSI 3 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Quelques fonctions et variables de LEX L ’analyse lexicale est effectuée par une fonction yylex() qui est contenue dans le fichier lex.yy.c La fonction yylex() qui doit être appelée pour utiliser l ’analyseur lexical : - analyse séquentiellement un fichier d ’entrée - retourne 0 lorsqu ’elle rencontre une fin de fichier - effectue des opérations spécifiées par le programme Lex, lorsqu ’une unité lexicale est reconnue LEX fournit un ensemble de variables et de routines : - yytext = variable contenant la chaîne de caractères courante qui a été reconnue - yyleng = longueur de la chaîne yytext - yyless() = fonction admettant un entier comme argument yyless(k) : avec k >0 - supprime les (yyleng-k) derniers caractères de yytext, dont la longueur devient alors k - recule le pointeur de lecture sur le fichier d ’entrée de yyleng-k positions, les caractères supprimés de yytext seront donc considérés pour la reconnaissance des prochaines unités lexicales GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 4 2 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Quelques fonctions et variables de LEX (suite) - yymore() = fonction qui concatène la chaîne actuelle yytext avec celle qui a été reconnue avant - yywrap() = fonction appelée lorsque yylex() rencontre une fin de fichier - si yywrap() retourne true, alors yylex() retourne 0 pour indiquer une fin de fichier - si yywrap() retourne false, alors yylex() ignore la fin de fichier et continue son analyse Par défaut, yywrap() retourne 1, mais on peut la redéfinir. GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 5 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Quelques fonctions et variables de LEX (suite) L ’entrée standard est notée yyin La sortie standard est notée yyout Exemple : Si on veut que : - l ’entrée standard soit le fichier toto.e qui contiendra le texte à scanner - la sortie standard soit le fichier toto.s qui contiendra les sorties (messages …) générés par le scanner Alors : yyin = fopen(``toto.e``, ``r``); yyout = fopen(``toto.s``, ``w``); ... … ... fclose(yyin); fclose(yyout); GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 6 3 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Variable yylval de LEX On considère : - le scanner Lex et son utilisateur U (exemple : U = parser YACC) - l ’identificateur I de l ’unité lexicale courante reconnue par Lex A chaque fois que Lex reconnaît une unité lexicale I, alors Lex retourne I à U Certaines unités lexicales possèdent des attributs que U a besoin de connaître : exemples : (voir page 5 chapitre 2) I = id avec attribut = lexème I = nb avec attribut = valeur Une approche pour que U ait accès aux attributs de l ’ unité lexicale I reconnue : - Lex dépose les attributs dans une variable globale, juste avant de retourner I - U récupère les attributs en accédant à la variable Exemple : U=YACC - La variable est nommée yylval et elle est déclarée par YACC - Comme le scanner sera plus tard appelé par YACC, alors on utilisera yylval - Pour l ’instant, scanner appelé par un main() dans lequel il faudra déclarer yylval GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 7 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Exemple d ’utilisation de yylval de LEX (suite) Unités lexicales reconnues - nb (nombre) avec l ’attribut valeur - id (identificateur) avec l ’attribut lexème yylval peut être du type suivant : Union DescUnit /* descriptions des unités lexicales */ { int nombre; /* valeur */ char *chaine; /* pointeur sur lexème */ } Lorsque Lex reconnaît l ’unité lexicale nb alors : - il dépose la valeur du nombre : dans la variable yylval.nombre - il retourne nb Lorsque Lex reconnaît l ’unité lexicale id alors : - il dépose un pointeur sur le lexème : dans la variable yylval.chaine - il retourne id GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 8 4 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Structure d ’un programme LEX Un programme Lex est constitué de trois sections séparées par %% : Déclarations %% Règles de traduction %% Procédures auxiliaires optionnel La section Déclarations peut elle même se composer de : - un bloc littéral - des définitions - des conditions de départ GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 9 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Déclarations : bloc littéral - commence par %{ et se termine par %} %{ et %} doivent être placés en début de ligne - contient des déclarations et définitions en C - est copié tel quel dans le fichier lex.yy.c produit par la commande lex - les définitions et déclarations qu ’il contient sont globales au programme produit par lex Exemple : On considère l ’exemple (chap. 2, pages 14 et 15) avec les unités lexicales : PPQ, PPE, EGA, DIF, PGQ, PGE, AFF, si, alors, sinon, id, nb où seules id et nb ont des attributs GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 10 5 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Déclarations : exemple de bloc littéral (suite) Les unités lexicales peuvent être définies en utilisant la directive define Par exemple : #define PPQ 1 #define PPE 2 ... (Ces définitions seront supprimés lorsqu ’on utilisera YACC car celui-ci générera ces définitions) Le type contenant les attributs peut être défini comme suit : (voir page 8) Union DescUnit /* descriptions des unités lexicales */ { int nombre; /* valeur */ char *chaine; /* pointeur sur lexème */ } La variable yylval est déclarée de type DescUnit GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 11 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Déclarations : exemple de bloc littéral (suite) Si on utilise une table des symboles contenant unités lexicales et leurs attributs alors : - on définit le type d ’un élément de la table par : Struct symbole { IdUnit terminal; DescUnit attributs; /* utile seulement lorsque terminal = id ou nb */ } - on déclare la table des symboles comme étant un tableau d ’éléments de type symbole GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 12 6 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Déclarations : définitions Associations d ’identificateurs à des expressions régulières Exemple : separ [ \t\n] espace {separ}+ lettre [A-Za-z] chiffre [0-9] ident {lettre}({lettre}|{chiffre})* nbre {chiffre}+(\.{chiffre}+)?(E[+\-]?{chiffre}+)? Remarque : lorsqu ’on se réfère à une expression régulière en utilisant un identificateur, celui-ci est mis entre accolades. GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 13 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Déclarations : conditions de départ Les conditions de départ permettent de définir plusieurs états de Lex Exemple : %start etat1 etat2 …. Où etat1, état2 … sont les états possibles de Lex (on y reviendra ultérieurement) GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 14 7 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Règles de traductions Contient deux parties Partie gauche : - spécification des expressions régulières reconnues - pour une chaîne de lettres et de chiffres, les guillemets peuvent être omis - identificateurs d ’expressions mis entre accolades Partie droite : - actions exécutées lorsque unités lexicales reconnues - actions définies avec syntaxe C - si scanner appelé par parser YACC, alors : - les attributs de l ’unité lexicale reconnue doivent être déposés dans yylval - l ’unité lexicale reconnue doit être retournée GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 15 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Règles de traductions : exemple {espace} ``<=`` ``<>`` ``<`` ``=`` ``>=`` ``>`` ``:=`` if then else {ident} {nbre} { /* pas d ’action */ } {return(PPE);} {return(DIF);} {return(PPQ);} {return(EGA);} {return(PGE);} {return(PGQ);} {return(AFF);} {return(si);} {return(alors);} {return(sinon);} {yylval.chaine = yytext; /* pointeur sur lexème */ return(id); } {yylval.nombre = valeur(yytext,yyleng); /* valeur */ return(nb); } GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 16 8 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Section Procédures auxiliaires Section optionnelle qui permet de : - définir toutes les fonctions utilisées dans les actions associées aux expressions reconnues - définir (si nécessaire) le programme principal Exemple : on définit : int valeur(char *tab, int length) { int i, x=0; for (i=0; i < length; i++) x = x*10+tab[i]- `0`; return(x); } main() { yyin = fopen(``toto.e``, ``r``); yyout = fopen(``toto.s``), ``w``); while (a=yylex() != 0) { printf(`` Unité lexicale : %d\n``, a); printf(`` lexème : %s \n ``,yytext); } flcose(yyin); fclose(yyout); } GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 17 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Utilisation des conditions de départ : exemple On désire interpréter l ’expression régulière [a-zA-Z]+ (un mot d ’au moins une lettre) de deux manières, selon le contexte : Contexte 1. Si mot entre guillemet, alors il représente une constante alphanumérique (chaîne de caractères) Contexte 2. Si mot pas entre guillemet, alors il est un identificateur On définit deux états const_alpha et normal, respectivement pour les deux contextes. Ces états sont utilisés comme suit : - Initialement, état égal à 0 - Tout au début, état mis à normal par l ’instruction BEGIN normal - chaque fois qu ’on rencontre des guillemets, on commute d ’un état à l ’autre (entre normal et const_alpha) - lorsqu ’on reconnaît une expression régulière [a-zA-Z]+, alors : - si l ’état courant est normal : alors un identificateur est reconnu - si l ’état courant est const_alpha : alors une chaîne de caractères est reconnue GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 18 9 Chapitre 3 : Utilisation de l ’outil LEX Université de Sherbrooke Département de génie électrique et de génie informatique Utilisation des conditions de départ : exemple (suite) Le programme Lex peut alors être le suivant %start normal const_alpha %% <normal>[a-zA-Z]+ {printf(``identificateur : % s \n``,yytext);} <normal>\`` {BEGIN const_alpha;} <const_alpha>[a-zA-Z]+ {printf(``chaine : %s \n``,yytext);} <const_alpha>\`` {BEGIN normal;} <normal,const_alpha>. { /* aucune action */ } <normal,const_alpha>\n { /* aucune action */ } %% main() { yyin = fopen(``toto.e``, ``r``); yyout = fopen(``toto.s``, ``w``); BEGIN normal; yylex(); /* yylex appelé une seule fois car pas de return */ flcose(yyin); fclose(yyout); } GEI 443 : Organisation des langages et compilation Hiver 2002 Ahmed KHOUMSI 19 10