Analyse lexicale et unités lexicales
Analyse lexicale et unités lexicales
ISSAT Sousse
12/02/2023 Ben Njima 1
Cheyma
Introduction (1)
■
Rôle de l’analyseur lexicale (scanner) : lire les
caractères d’entrée (programme source) et produire
comme résultat une suite d’unités lexicales appelées
TOKENS que l’analyseur syntaxique va utiliser.
■
Les TOKENS sont constitués au fur et à mesure de la
lecture du texte source, on distingue deux types
d’unités lexicales.
■
Les unités propres au langage, les mots clés, les
séparateurs, les opérateurs, ...etc.
■
Les unités personnalisées qui sont crées par le
programmeur (les constantes, les identificateurs...).
12/02/2023 Ben Njima 2
Cheyma
Introduction (2)
■
Remarque : l’analyseur lexical de certains
compilateurs procèdent à l’élimination dans le
programme source des commentaires et des
espaces qu’apparaissent sous forme de caractères
blancs ou de tabulations ou bien les sauts de lignes.
12/02/2023 Ben Njima 3
Cheyma
Unités lexicales, lexèmes, modèles (1)
■
Token : unité lexicale, est une paire de nom et d’une valeur optionnelle.
Le nom du token est un symbole abstrait qui représente une unité lexicale,
(mot clé, suite de caractère dénotant un identifiant, ...).
■
Le modèle : est une description de la forme que peut prendre les lexèmes
d’une unité lexicale.
■
C’est une règle qui décrit l’ensemble des lexèmes pouvant représenter
une unité lexicale particulière dans le programme source.
■
Dans le cas des mots clés, le modèle est juste une séquence de
caractères qui forme le mot clé.
■
Pour les identificateurs et d’autres unités lexicales, le modèle est une
structure plus complexes.
■
Lexème : est une suite de caractères dans le programme sources qui
concorde avec le modèle.
■
Il est identifié par l’analyseur lexical comme instance d’un token.
■
Remarque : Ces notations sont employées dans l’écriture des
expressions régulières.
12/02/2023 Ben Njima 14
Cheyma
Spécification des unités lexicales (4)
■
Mots et langage :
■
Opérations sur les langages :
■
Exemple :
■
L = {a, ....,z,A,...,Z}, C={0,...,9}, on peut créer de nouveaux langages à
partir des langages L et C, en appliquant les opérateurs précédents.
■
L U C est l’ensemble des lettres et des chiffres.
■
LC est l’ensemble des mots formés d’une lettre suivie d’un chiffre.
■
L4 est l’ensemble des mots formés de 4 lettres.
■
L* est l’ensemble de tout les mots de lettres, y compris le mot vide, Ԑ.
■
L(LUC)* est l’ensemble des mots de lettres et de chiffres commençant
par une lettre.
■
C+ est l’ensemble des mots qui sont constitués d’au moins d’un chiffre.
12/02/2023 Ben Njima 15
Cheyma
Spécification des unités lexicales (5)
■
Expressions régulières :
■
On construit une expression régulière à partir d’expressions
régulières plus simples, en utilisant les règles de définition du
langage concerné.
■
Chaque expression régulière r dénote un langage L(r). Les règles de
définition spécifient comment L(r) est formé en combinant de
manière variée les langages dénotés par les sous-expressions de r.
■
Les expressions régulières sont construites récursivement à partir
d’expressions régulières plus simples, en utilisant des règles.
■ Chaque expression régulière r dénote un langage L(r), qui est aussi
définit récursivement à partir des langages dénotés par les sous-
expressions de r.
■ Les règles qui définissent les expressions régulières sur un alphabet
∑ et les langages dénotés par ces expressions.
12/02/2023 Ben Njima 16
Cheyma
Spécification des unités lexicales (6)
■
Expressions régulières :
■
Règles :
■
Ԑ est une expression régulière, et L(Ԑ) = {Ԑ}, le langage
dont le seule membre est le mot vide Ԑ.
■
Si a est un symbole de ∑, alors a est une expression
régulière, et L(a) = {a}, c-à-d le langage avec une seule
chaîne de caractère, de longueur 1.
o
ù ■
Chaque di est un nouveau symbole distinct qui n'appartient
pas à Σ
■
Chaque ri est une expression régulière sur les symboles : Σ
U {d1,d2,...,di-1}
12/02/2023 Ben Njima 23
Cheyma
Spécification des unités lexicales (13)
■
Expressions régulières :
■
Définitions régulières :
■
Exemple 1 : les identificateurs en C sont des mots formés de
lettres, chiffres, et underscore (_). Une définition régulière de
cet ensemble est la suivante :
lettre → A|B|...|Z|a|b|...|z| _
chiffre → 0|1|...|9
id → lettre(lettre|chiffre)*
■
Les caractères blancs (blank), tabulation (tab) et nouvelle
ligne (newline) sont des symboles abstraits utilisés pour
exprimer les caractères ASCII désignant la même chose.
■
L’unité lexicale ws est reconnue par l’analyseur lexical, mais
elle ne sera pas retournée à l’analyseur syntaxique, mais, on
reprend l’analyse qui suit l’espace blanc.
N’importe quel ws - -
if if -
then then -
else else -
N’importe quel id id Pointeur vers la table des symboles
N’importe quel number Pointeur vers la table des symboles
number
< relop LT
<= relop LE
= relop EQ
<> relop NE
> relop GT
12/02/2023
Prof. M. BENADDY Ben Njima
Compilation 34
>= relop Cheyma GE
Les automates à états finis (1)
■
Un reconnaisseur pour un langage est un programme qui prend en
entrée une chaîne x et répond oui si x est une phrase du langage et
non autrement.
■
On compile une expression régulière en un reconnaisseur en
construisant un diagramme de transition appelé automate fini.
■
Un automate fini est capable de reconnaître précisément les
ensembles réguliers.
■
Il existe types d'automates à états finis:
■
Les automates à états finis non déterministes (AFN) n'ont
aucune restrictions sur les étiquettes de leurs arcs. Un symbole
peut étiqueter plusieurs arcs partant d'un même état, et la chaîne
vide ε est une étiquette possible.
■
Les automates à états finis déterministes (AFD), pour lesquels,
ne peuvent pas partir plusieurs transitions du même état avec le
même caractère et n'accepte pas d'ε-transition.
12/02/2023 Ben Njima 35
Cheyma
Les automates à états finis (2)
■
Automates finis non déterministes (AFN) :
■
Un automate fini non déterministe noté AFN, noté par
l'expression aut = <Σ,E,D,F,T> avec :
■
Un ensemble Σ de symboles d'entrée, l'alphabet du
langage. On considère que la chaîne vide ε, n'est jamais un
membre de Σ.
■
L'ensemble fini E d'états.
■
Une fonction de transition qui donne pour chaque état et
pour chaque symbole de ΣU{ε}, l'ensemble des états
suivants T, sous ensemble de ExΣxE.
■
L'ensemble D sous-ensemble de E, des états de départ.
■
L'ensemble des états F, sous-ensemble de E, l'ensemble
des états d'acceptation ou états finaux ou états terminaux.
12/02/2023 Ben Njima 36
Cheyma
Les automates à états finis (3)
■
Automates finis non déterministes (AFN) :
■
Exemple :
■
Σ = {a,b,c} ; E={1, 2, 3, 4} ; D={1} ; F = {3,4} , T
={(1,a,2), (2,b,3),(1,c,4),(3,c,2)}
■
si tout état d'un ensemble donné Σ étiquette des
transitions d'un état i vers un état j on notera Σ={a, b, c}
■
Exemple : Σ = {x, y} ; E ={1, 2 ,3} ; D ={1} ; F ={3} ; T ={(1,
y, 1), (1, x, 2), (2, y, 2), (2, x, 3), (3, x, 3), (3, y, 3)}
■
Table de transition :
■
Une autre méthode de représentation d'un automate est la
table des transitions, pour décrire la fonction de transition
T on utilisera une table M indicée par E et Σ, tel que si e ϵ
E, a ϵ Σ, e' ϵ M(e,a) ssi (e, a, e') ϵ T
■
Exemple : table de transition correspondante à l'expression
régulière (a|b)*abb
État a b ε
0 {0,1} {0} -
1 - {2} -
2 - {3} -
3 - - -
12/02/2023 Ben Njima 41
Cheyma
Les automates à états finis (8)
■
Acceptation d'une chaîne par un automate :
■
Un AFN accepte une chaîne d'entrée x ssi il existe un chemin dans le
graphe de transition entre l'état de départ et un état d'acceptation
(final), tel que les étiquettes des arcs le long de ce chemin épellent
(enlever le poile) la chaîne x.
■
Exemples : La chaîne aabb est acceptée par l'automate de
l'exemple (slide 49) ,en se déplaçant via les états (0,0,1,2,3).
■
Soit l'automate suivant qui accepte les mots du langage engendrés par
l'expression régulière aa*|bb*
■
La chaîne aaa est acceptée en se déplaçant via les états (0,1,2,2,2).
les étiquettes de ces arcs sont εaaa = aaa.
■
Acceptation d'une chaîne par un automate :
■
Exemples (suite) : soit l'expression régulière a abb et la
+
■
Cet automate n'accepte pas la chaîne x.
■
Si on considère a*abb, l'automate correspondant est :
■
Cet automate accepte la chaîne x=abb en parcourant le
chamin 1,2,3,4.
12/02/2023 Ben Njima 43
Cheyma
Les automates à états finis (10)
■
Automates finis déterministes :
■
Un automate fini déterministe (AFD) est un cas particulier d'un automate fini non
déterministe (AFN) dans lequel :
■
Aucun état n'a une ε-transition (une transition sur l'entrée ε).
■
Pour chaque état e et chaque symbole a, il existe un et un seul arc étiqueté a
qui quitte e.
■
Un AFD a au plus une transition à partir de chaque état sur n'importe quel
symbole, en conséquence il est très facile de déterminer si un AFD accepte une
chaîne d'entrée, étant donné qu'il existe au plus un chemin depuis l'état de départ
étiqueté par cette chaîne.
■
Si on utilise une table de transition pour représenter un AFD, chaque entrée est un
état singleton.
■
Un AFN est une représentation abstraite d'un algorithme de reconnaissance des
chaînes d'un langage.
■
Un AFD est un algorithme concret de reconnaissance de chaînes.
■
N'importe quel AFN ou expression régulière peuvent être transformées en un AFD.
12/02/2023 Ben Njima 44
Cheyma
Les automates à états finis (11)
■
Simulation d'un AFD :
■
Soit x une chaîne d'entrée qui se termine par un caractère de fin
de fichier (fdf ou eof), soit e un état de départ et F l'ensemble des
0
états terminaux.
■
Soit la fonction transiter(e,c) qui donne l'état vers lequel il y a une
transition depuis l'état e sur le caractère d'entrée c, la fonction
carsuiv(x) retourne le prochain caractère de la chaîne d'entrée x.
La simulation d'un AFD est donnée par l'algorithme suivant :
e=e0
c=carsuiv(x)
tant que (c!=fdf){
e = transiter(e,c)
c = carsuiv(x)
}
si (e ϵ F) alors retrouner ''oui''
sinon retourner ''non''
12/02/2023 Ben Njima 45
Cheyma
Les automates à états finis (12)
■
Simulation d'un AFD :
■
Exercice d'application : dessiner l'AFD correspondant au
langage L((a|b)*abb), cette automate accepte-t-il la chaîne
x=ababb.
■
Solution : l'automate correspondant au langage L((a|b)*abb))
est :
■
Cet automate accepte la chaîne x en parcourant les états
0,1,2,1,2,3
■
Transformation d'une expression régulière en un AFN :
■
Il existe de nombreuses stratégies pour construire un
reconnaisseur à partir d'une expression régulière.
■
Un stratégie qui a été utilisée dans un grand nombre
d'analyseurs lexicaux, consiste à construire un AFN à
partir d'une expression régulière et ensuite convertir l'AFN
en AFD.
■
On suppose que les AFN des expressions régulières s
et t sont N(s) et N(t), l'AFN correspondant à
l'expression régulière r=s|t est le suivant :
Remarque : Les états de départ et
d'acceptation de N(s) et N(t) ne sont pas les
états de départ et d'acceptation de N(s|t). Ils
sont donc des états ordinaires de ce dernier.
12/02/2023 Ben Njima 50
Cheyma
Automates à états finis aux expressions régulières
■
l'état de départ de N(s) devient l'état de départ de l'AFN
composé et l'état d'acceptation de N(t) devient l'état
d'acceptation de N(r).
■
On peut aller de i à f directement en suivant un arc étiqueté ε
qui représente le fait que ε ϵ (L(s))* ou bien en traversant N(s)
une ou plusieurs fois. Pour l'expression régulière (s) l'AFN
correspondant est le même pour l'expression régulière s.
12/02/2023 Ben Njima 52
Cheyma
Automates à états finis aux expressions régulières
■ r2=b
■
Maintenant on peut combiner N(r1) et N(r2), pour
obtenir l'AFN N(r3) pour r3=r1|r2
■
r=r4r6 l'AFN correspondant à (a|b)*abb est :
■
Transformation d'un AFN en un AFD :
■ Soit les automates suivants :
■ Aut1
■
Aut2 :
■
Transformation d'un AFN en un AFD :
■
L'automate 1 a deux transitions de l'état 1 sur la chaîne
d'entrée a qui signifie qu'on peut aller vers l'état 1 ou 2.
■
De même l'automate 2 a deux transitions sur ε à partir de l'état
0.
■
Dans le cas où la fonction de transition est multivaluée, il est
difficile de simuler un AFN à l'aide d'un programme.
■
L'acceptation d'une chaîne d'entrée suppose qu'il puisse
exister un chemin étiqueté par cette chaîne qui mène depuis
l'état de départ jusqu'à un état d'acceptation.
■
Mais il existe dans un AFN plusieurs chemins qui épellent la
même chaîne d'entrée, on doit les prendre en considération
avant de décider d'accepter ou non la chaîne d'entrée.
12/02/2023 Ben Njima 57
Cheyma
Automates à états finis aux expressions régulières
■
Transformation d'un AFN en un AFD :
■
L'idée générale de la transformation d'un AFN en un AFD est
qu'un état de l'AFD correspond à un ensemble d'états de
l'AFN.
■
L'AFD utilise un état pour garder trace de tout les états
possibles que l'AFN peut atteindre après avoir lu chaque
symbole d'entrée.
■
Transformation d'un AFN en un AFD :
■
Algorithme :
■
Donnée : un AFN
■
Résultat : un AFD qui accepte le même langage de l'AFN.
■
Méthode : l'algorithme construit une table de transition
Dtrans pour l'AFD.
■
Chaque état de l'AFD est un ensemble d'états de l'AFN.
On construit Dtrans de telle manière que l'AFD simulera
tous les déplacements possibles que l'AFN peut effectuer
sur une chaîne d'entrée donnée.
■
Transformation d'un AFN en un AFD :
■
Algorithme :
■
Pour garder trace des ensemble des états de l'AFN on
utilisera les opérations suivantes :
■
Soit e et T tels que e représente un état de l'AFN et T
représente un ensemble d'états de l'AFN.
Opération Description
ε-fermeture(e) Ensemble des états de l'AFN accessibles depuis l'état e
Noté aussi ε-f(e) de l'AFN par des ε-transition uniquement.
ε-fermeture(T) Ensemble des états de l'AFN accessibles depuis un état
Noté aussi ε-f(T) e ϵ T par des ε-transition uniquement.
transiter(T,a) Ensemble des états de l'AFN vers lesquels il existe une
Noté aussi tran(T,a) transition sur a
12/02/2023 Ben Njima 60
Cheyma
Automates à états finis aux expressions régulières
■
Transformation d'un AFN en un AFD :
■
Exemple d'application : soit l'AFN suivant qui accepte le
langage (a|b)*abb
■
Transformation d'un AFN en un AFD :
■
Exemple d'application :
■
L'état de départ de l'AFD A=ε-f(0)={0,1,2,4,7}
■ L'alphabet Σ = {a, b}
■
B=ε-f(tran(A,a))=ε-f({3,8})={3,1,2,4,6,7,8} => Dtrans(A,a)=B.
■
C=ε-f(tran(A,b))=ε-f({5})={1,2,4,5,6,7} => Dtrans(A,b)=C.
■
ε-f(tran(B,a))=ε-f({3,8})={3,1,2,4,6,7,8} => Dtrans(B,a)=B.
■
ε-f(tran(B,b))=ε-f({5,9})={1,2,4,5,6,7,9} => Dtrans(B,b)=D.
■
ε-f(tran(C,a))=ε-f({3,8})={3,1,2,4,6,7,8} => Dtrans(C,a)=B.
■
ε-f(tran(C,b))=ε-f({5})={1,2,4,5,6,7} => Dtrans(C,b)=C.
■
ε-f(tran(D,a))=ε-f({3,8})={3,1,2,4,6,7,8} => Dtrans(D,a)=B.
■
ε-f(tran(D,b))=ε-f({5,10})={1,2,4,5,6,7,10} => Dtrans(D,b)=E.
■
ε-f(tran(E,a))=ε-f({3,8})={3,1,2,4,6,7,8} => Dtrans(E,a)=B.
■
ε-f(tran(E,b))=ε-f({5})={1,2,4,5,6,7} => Dtrans(E,b)=C.
12/02/2023 Ben Njima 62
Cheyma
Automates à états finis aux expressions régulières
■
Transformation d'un AFN en un AFD :
■
Exemple d'application :
■
L'état E est l'état de fin de l'AFD car E contient l'état 10 qui
est l'état d'acceptation de l'AFN.
■
Règle : un état de l'AFD est un état d'acceptation si c'est un
ensemble d'états de l'AFN qui contient au moins un état
d'acceptation de l'AFN.
■
L'AFD équivalent à l'AFN est :
■
Transformation d'un AFN en un AFD :
■ Exemple d'application :
■ Table de transition de l'AFD :
États de l'AFN États de a b
l'AFD
{0,1,2,4,7} A B C
{1,2,3,4,6,7,8} B B D
{1,2,4,5,6,7} C B C
{1,2,4,5,6,7,9} D B E
{1,2,3,5,6,7,10} E B C
■
Simulation d'un AFN :
■
Donnée : Étant donné une chaîne x se terminant par un
caractère de fdf (eof), un AFN N disposant d'un état de
départ 0 et d'un ensemble d'états d'acceptation F et une
fonction transiter.
■
Résultat : réponse oui si N accepte la chaîne et non
autrement.
■
Méthode : l'algorithme suivant appliqué à x permet de
renvoyer oui si l'AFN accepte x et non autrement.
■
Simulation d'un AFN :
E = ε-f({0})
c = carSuiv(x)
tant que (a!=fdf){
E = ε-f(transiter(E,c))
c = carSuiv(x)
}
si(E ∩ F!=Ø) alors retourner oui
sinon retourner non
■
L'algorithme réalise la construction des sous-ensembles à
l'exécution, il calcule une transition depuis l'ensemble
courant d'états E vers le prochain ensemble d'états.
Implicitement l'algorithme transforme l'AFN en AFD et
détermine si l'AFD accepte-t-il la chaîne d'entrée x.
12/02/2023 Ben Njima 66
Cheyma
Automates à états finis aux expressions régulières
■
Simulation d'un AFN :
■
Exemple : Soit l'AFN correspondant à (a|b)*abb et la chaîne
d'entrée x = aabb
E = ε-f({0})={0,1,2,4,7}
c = carSuiv(x)=a
E = ε-f(transiter(E,a))={3,1,2,4,6,7,8}
carSuiv(x)=a
E = ε-f(transiter(E,a))={3,1,2,4,6,7,8}
carSuiv(x)=b
E = ε-f(transiter(E,b))={1,2,4,5,6,7,9}
carSuiv(x)=b
E = ε-f(transiter(E,b))={1,2,4,5,6,7,10}
carSuiv(x)=fdf
E ∩ F =10 alors l'AFN accepte la chaîne x=aabb
■
Étant donné que deux AFD peuvent reconnaître les mots du même langage, le but
de la minimisation du nombre d'états d'un AFD consiste à produire un AFD avec le
minimum d'états possibles.
■
L'algorithme de minimisation consiste à partitionner les états de l'AFD en des
groupes d'états qui ne peuvent pas être distingués. Chaque groupe d’états qui ne
peuvent pas être distingués est alors fusionné en un état unique.
■
Initialement la partition consiste en deux groupes :
■
Les états d'acceptation et les états de non-acceptation.
■
L'étape fondamentale consiste à prendre un groupe d'état A={e , e , … , e } et un
1 2 k
symbole d'entrée 'a' et regarder si 'a' peut être utilisé pour distinguer des états du
groupe A.
■
On examine les transitions depuis chaque état e , e , … ,e sur l'entrée 'a', si ces
1 2 k
transitions conduisent à des états qui tombent au moins dans deux groupes
différents de la partition courante, alors, on doit diviser A en une collection de
groupes, de sorte que ei et eJ sont dans le même groupe ssi ils partent vers le
même groupe sur le symbole 'a'.
■
On répète le processus de division de groupe de la partition courante jusqu’à ce
que aucun groupe n'est besoin d'être divisé.
12/02/2023 Ben Njima 68
Cheyma
Minimisation du nombre des états d'un AFD
■
Algorithme de minimisation des états d'un AFD :
■
Donnée : un AFD D avec un ensemble d'états E, un
alphabet d'entrée Σ, un état de départ e0 et en ensemble
d'états d'acceptation F.
■
Résultats : un AFD D' qui reconnaît le même langage que
D et ayant le peu d'états possibles.
■
Algorithme de minimisation des états d'un AFD :
■
Méthode :
1)Construire une partition initiale П de l'ensemble des états avec deux groupes ; les états
d'acceptation F et les états de non-acceptation E-F.
2)Appliquer la procédure suivante à П pour construire une nouvelle partition Пnew
soit Пnew = П
pour chaque groupe G de П {
● Partitionner G en sous groupes de manière que deux états s et t de G soient dans le
même sous groupe ssi pour tout symbole d'entrée 'a', les états s et t ont des transitions
sur 'a' vers les états du même groupe de П.
● Remplacer G dans Пnew par les sous groupes formés.}
3) si Пnew = П alors Пf = П aller à 4 sinon répéter l'étape 2 avec П =Пnew
4)Choisir un état de chaque groupe de la partition П en tant que représentant de ce
f
groupe. Les représentants seront les états de l'AFD réduit D'.
● L'état de départ de D' est le représentant du groupe qui contient l'état de départ e0 de D.
● Les états de d'acceptation de D' sont les représentants contenant un état d'acceptation de
D.
5) Si D' contient un état mort, c-à-d un état e qui n'est pas un état d'acceptation et qui a
des transitions vers lui-même sur tout les symboles d'entrée, alors supprimer e de D'.
■
Exemple : soit l'AFD correspondant au langage L((a|b)*abb)
■
Exemple : soit l'AFD correspondant au langage L((a|b)*abb)
■
La partition initiale П est constituée de deux groupes, {E}{ABCD} le groupe des états
d'acceptation, et le groupe états de non-acceptation.
■
Pour construire la partition Пnew le groupe {E} est constitué d'un seul état donc, il ne peut pas
être découpé.
■ Le groupe {ABCD} sur le symbole a chacun des 4 états a une transition vers B, ce qui ne les
distingue pas.
■ Sur le symbole b A,B et C ont une transition vers les états du groupe {ABCD}, tandis que D a
une transition vers E qui est membre d'un autre groupe.
■
Dans la partition Пnew le groupe {ABCD} doit être découpé en 2 nouveaux sous groupes {ABC}
{D}. donc dans l'étape suivante la partition Пnew = {ABC}{D}{E}.
12/02/2023 Ben Njima 72
Cheyma
Minimisation du nombre des états d'un AFD
■
Exemple : soit l'AFD correspondant au langage L((a|b)*abb)
■
Retour à 2 avec la partition {ABC}{D}{E} les groupes {D}{E} sont singleton, donc
ils ne peuvent pas être découpés.
■ Sur le symbole a aucun découpage. Sur le symbole b, A et C ont une transition sur B
tandis que B a une transition vers D membre d'un autre groupe. D'où П new = {AC}{B}{D}
{E}.
■
Retour à 2 avec la nouvelle partition :
■ Sur le symbole a, A et C conduisent vers le même état B.
■ Sur le symbole b, A et C conduisent vers le même état C.
■ Par conséquent A et C constituent le même groupe d'où la partition finale П f ={AC}
{B}{D}{E}.
12/02/2023 Ben Njima 73
Cheyma
Minimisation du nombre des états d'un AFD
■
Exemple : soit l'AFD correspondant au langage L((a|b)*abb)
■
Si on choisit A comme représentant du groupe {AC}, B, D et
E pour les groupes singletons, on obtient alors l'automate
réduit dont la table des transitions est :
■
A est l'état de départ et E est l'état d'acceptation, le graphe
d'état correspondant est :
État a b
A B A
B B D
D B E
E B A
■
Lex/Flex est un outil de génération automatisée d’analyseur
lexical, à partir de la spécification des expressions régulières
pour décrire les modèles des unités lexicales.
■
Lex/Flex transforme les modèles (expressions régulières et
définitions régulières) en entrée en un diagramme de
transition et génére le code source correspondant, dans un
fichier appelé [Link].c, qui simule le diagramme de transition
généré.
■
Ce fichier écrit en langage C doit être compilé par le
compilateur du C pour produire un exécutable qui sera
l'analyseur lexical du langage décrit par les modèles en
question.
■
Plusieurs langages dérivés de Lex existent :
■ Flex produit du code écrit en C/C++
■
Utilisation de Lex :
■
Un fichier lex.l écrit en langage Lex, qui décrit l’analyseur
lexical à générer est présenté au compilateur Lex en
entrée.
■
Le compilateur Lex transforme lex.l en un programme
écrit en C dans un fichier appelé [Link].c.
■
Ce fichier est compilé par le compilateur C et produit un
fichier exécutable [Link] qui est le fichier du compilateur
exécutable, il prendra en paramètre un fichier écrit dans le
langage source et produira en sortie une séquence des
unités lexicales.
■
Utilisation de Lex :
■
Structure d’un programme Lex :
■
Un fichier de description pour Lex est formé de trois
parties, séparées par des lignes contenant seulement %%,
aligné à gauche, selon le schéma suivant :
// Parties déclarations
%{ //(variables, constantes, bibliothèques C, etc.)
%}
//expressions régulières, définitions régulières
%%
// Partie productions (expressions régulières)
%%
// code de service (fonctions utilitaires)
■
Structure d’un programme Lex :
■
La partie déclarations comporte les déclarations des
variables, des structures, des unions, des déclarations
régulières, des déclaration des bibliothèques en C …
■
La partie productions, les déclarations prennent la forme
suivante :
m 1 {action } 1 Les m sont des expressions régulières ou
i
■
Structure d’un programme Lex :
La 3ème partie contient des fonctions qui peuvent être
■
■
Structure d’un programme Lex :
■
Exemple 1 : Un programme Lex qui affiche le contenu de
son entrée standard vers l'écran.
%%
.|\n ECHO;
%%
■
Exemple 2 : un programme Lex qui supprime tout les
espaces et tabulations.
%%
[ \t] {/* supprime les espaces et tabulations */}
bye {exit(0);}
■
Structure d’un programme Lex :
■
Exemple 3 : Un programme Lex qui reconnaît les verbes
en anglais.
■
On considère la liste des verbes suivants :
is am are were
was be being been
do does did will
would should can could
has have had go
■
Structure d’un programme Lex :
■
Exemple 3 : Un programme Lex qui reconnaît les verbes
en anglais.
%{ will I
/* would I
* programme Lex qui reconnaît les verbes en Anglais should I
*/ can I
%} could I
%% has I
[\t ]+ /* ignorer les espaces et tabulations */ have I
is I had I
am l go {printf(''%s : is a verb\n'',
are I yytext);}
were I [a-zA-Z]+ {printf(''%s:is not a
was I verb\n'', yytext);}
be l .|\n {ECHO ; /* autres choses
beingbeen I ou retour à la ligne */}
do I %%
does I main()
did I {
12/02/2023
Prof. M. BENADDY Ben Njima
Compilation yylex() ; 84
Cheyma }
Le générateur d’analyseur lexicale Lex/Flex
■
Structure d’un programme Lex :
■
Remarques :
yylex() : la fonction principale du programme écrit en
■
LEX.
■
yytext : pointeur sur le début de la chaîne analysée
(unité lexicale)
■
Exécution :
■ Lex : lex verbes.l produit un fichier [Link].c
■
Flex : flex verbes.l produit un fichier [Link].c
■
gcc : gcc -o verbes [Link].c -lfl (lfl : library fast lex)
■
Structure d’un programme Lex :
■
Exercice d'application : écrire un programme en lex qui
reconnaît les identificateurs, mot clés et opérateurs en
PASCAL