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