Académique Documents
Professionnel Documents
Culture Documents
Généralités
Expressions rationnelles
Automates finis
Analyseurs lexicaux
Rôle d'un analyseur lexical
lexèmes
analyseur analyseur
code source ...
lexical syntaxique
table des
symboles
... a = 4 * i + 1 ...
fin
debut
fin
debut
lettre | _ | chiffre
autre
11 12 13 return(gettoken(), install)
lettre
_
Identificateurs en C
Automates finis
autre
0 1 2 return(relop, lt)
<
=
3 return(relop, le)
>
autre
4 5 return(relop, gt)
=
= 6 return(relop, ge)
=
7 8 return(relop, eq)
!
9 = 10 return(relop, ne)
Opérateurs de comparaison
Automates finis
chiffre
1 chiffre
15 E|e
4
chiffre +|- chiffre autre
16 17 18 19
chiffre
. . chiffre
E|e
20 21
chiffre chiffre
2
23 autre
2
chiffre
24
chiffre
. .
autre
25 26
chiffre
1 2
a
a b
1 2 3
b a
a b
1 12 13
b a
Le résultat de l'algorithme
Généralisation
On peut admettre des transitions d'étiquette ε (transitions
spontanées).
Pour être déterministe, un automate ne doit pas contenir de
transitions spontanées.
Pour déterminiser, on adapte l'algorithme précédent :
- à l'étape 2 on prend l'ensemble des états atteignables depuis
I par un chemin de transitions spontanées ;
- à l'étape 3, V est l'ensemble des états atteignables depuis U
par un chemin étiqueté a
La construction récursive
On peut construire un automate fini équivalent à une
expression rationnelle : il reconnaît le même langage.
L'automate construit est tel que :
- il a un seul état initial i
- il a un seul état final f ≠ i
- aucune transition n'entre dans i
- aucune transition ne sort de f.
Pour ε et a, on prend:
ε a
union ε ε
ε ε
concaténation
ε ε
itération ε
ε ε
ε
Utilisation de Flex
spécification
flex lex.yy.c compilateur C
Flex
caractères
a.out lexèmes ...
(code source)
4 étapes :
- créer sous éditeur une spécification Flex (expressions
rationnelles)
- traiter cette spécification par la commande flex
- compiler le programme source C obtenu
- exécuter le programme exécutable obtenu
Spécifications Flex
Un programme Flex est fait de trois parties :
déclarations
%%
règles de traduction
%%
fonctions auxiliaires en C
Les règles de traduction sont de la forme
p1 { action1 }
p2 { action2 }
...
pn { actionn }
où chaque pi est une expression rationnelle et chaque action une suite
d'instructions en C.
Exemple
%{
/* Partie en langage C : définitions de constantes,
déclarations de variables globales, commentaires... */
%}
delim [ \t\n]
letter [a-zA-Z]
%%
{delim}* { /* pas d'action */ }
if { return IF ; }
then { return THEN ; }
else { return ELSE ; }
{letter}({letter}|[0-9])* { yyval = install_id() ;
return ID ; }
([0-9]+(\.[0-9]*)?|\.[0-9]+)((E|e)(\+|-)?[0-9]+)? {
yyval = install_num() ; return NUMBER ; }
Exemple
"<" { yyval = LT ; return RELOP ; }
"<=" { yyval = LE ; return RELOP ; }
%%
install_id() {
/* fonction installant dans la table des symboles le
lexème vers lequel pointe yytext et dont la longueur
est yylength. Renvoie un pointeur sur l'entrée dans
la table */
}
install_num() {
/* fonction calculant la valeur du lexème */
}
Spécifications Flex
Les commentaires /* ... */ ne peuvent être insérés que dans une portion
en C :
- dans la partie déclaration, seulement entre %{ et %} ;
- dans la partie règles, seulement dans les actions ;
- dans la partie fonctions auxiliaires, n'importe où.
Dans les règles
pi { actioni }
les expressions rationnelles pi ne peuvent pas contenir d'espaces blancs
(ou alors dé-spécialisés).
Dans la partie règles, si une règle commence par un espace blanc, elle
est interprétée comme du langage C et est insérée dans lex.yy.c au
début de la fonction qui renvoie le prochain lexème (utilisable pour
déclarer des variables locales).
Segmentation du code source
par l'analyseur lexical (1/2)
L'analyseur lexical produit par Flex
- commence à chercher les lexèmes au début du code source
;
- après chaque lexème reconnu, recommence à chercher les
lexèmes juste après.