Analyse lexical

Transcription

Analyse lexical
Compilation
Analyse en deux phases
Analyse lexicale ("lexer" ou "scanner") :
transforme une suite de caractère en suite de lexèmes
Analyse lexical
Analyse syntaxique ou grammaticale ("parser") :
transforme une suite de lexèmes en arbre
Expressions régulières
Reconnaissance des unités lexicales
Génération automatique (lex)
Automates finis
Les deux analyses sont donc exécutées de façon entremêlée.
1
2
Enjeux
Unités lexicales et lexèmes
Définition unité lexicale : certaine information associé à une suite
de caractères. C'est un symbole terminal.
Domaine d'application plus large que celui de la compilation :
analyses des commandes, des requêtes, etc.
Exemples :
– Les chaînes <=, >=, <, > sont des opérateurs relationnels.
– Les chaînes toto, ind, tab, ajouter sont des identificateurs.
– Les chaînes if, else, while sont des mots clefs.
– Les symboles , . ; ( ) sont des séparateurs.
Un analyseur lexical est spécifié à l’aide d'une grammaire régulière,
tandis qu’un analyseur syntaxique est spécifié à l’aide d’une
grammaire non contextuelle.
Les expressions régulières sont un langage de description
d'automates ; elles sont utilisées dans de nombreux outils Unix
(emacs, grep...), et fournies en bibliothèque dans beaucoup des
langages de programmation (javascript, java, php, etc).
Définition. Un modèle ou motif est une règle associée à une unité
lexicale qui décrit l'ensemble des chaînes qui correspond à l'unité
lexicale.
Définition. Un lexème est la suite de caractère correspondant au modèle.
3
4
Unités lexicales et lexèmes
Théorie des langages : notions.
Soit l'alphabet Σ un ensemble fini non vide de caractères.
Un mot est une séquence de caractères (de Σ). On note :
Exemples :
• L'unité lexicale IDENT (identificateurs) a pour modèle :
toute suite non vide de caractères composée de chiffres, lettres ou du symbole "_"
et qui commencent par une lettre. Exemples : truc, i, a3, ajouter_valeur
–
–
–
–
–
–
• L'unité lexicale NOMBRE (entier signé) a pour modèle :
toute suite non vide de chiffres précédée éventuellement d'un seul caractère
parmi {+,-\}. Exemples : 12, 83204, +054, 57
• L'unité lexicale REEL a pour modèle : tout lexème correspondant à l'unité
lexicale NOMBRE suivi éventuellement d'un point et d'une suite (vide ou non)
de chiffres, le tout suivi éventuellement du caractère E ou e et d'un lexème
correspondant à l'unité lexicale NOMBRE. Cela peut également être un point
suivi d'une suite de chiffres, et éventuellement du caractère E ou e et d'un lexème
correspondant à l'unité lexicale NOMBRE.
Exemples : 12.4, 0.5e3, 10., -4e-1, -.103e+2
Un langage sur Σ est un sous-ensemble L de Σ*.
Exemples. Soit l'alphabet Σ ={a,b,c}
• Soit L1 l'ensemble des mots de Σ ayant autant de a que de b.
L1 est le langage infini {є, ab, ba, c, ccc, abccc, accbccbccccca,
aabb, baab, bbccccaccbcabcccacac, . . .}
Pour décrire le modèle ou motif d'une unité lexicale, on utilise des
expressions régulières.
5
є le mot vide,
uv la concaténation des mots u et v (є est l'élément neutre).
Σ* est l'ensemble infini de tous les mots sur Σ
Σ+ est l'ensemble infini des mots non vides, c'est à dire = Σ* - {є}
|m| est la longueur du mot m.
Σn l'ensemble des mots de longueur n.
6
• Soit L2 l'ensemble de tous les mots de Σ ayant exactement 4 a.
L2 est le langage infini {aaaa, abcabbbaacc, . . .}
Théorie des langages
Expressions régulières
Opérations sur les langages :
Les langages réguliers peuvent se décrire facilement à l'aide d'expressions
régulières.
Chaque expression régulière (ER) r dénote un langage L(r). Les expressions
régulières sont construites récursivement comme suit :
Supposons que r et s soient des expressions régulières dénotant respectivement les
langages L(r) et L(s).
On peut construire d'autres expressions régulières de trois manières :
1. (r) | (s) est une ER dénotant le langage L(r) union L(s)
2. (r) (s) est une ER dénotant le langage L(r) L(s)
3. (r)* est une ER dénotant le langage (L(r))*
Etant donné un langage, comment décrire tous les mots acceptables ?
Comment décrire un langage ?
Il existe plusieurs types de langage, certains étant plus facile à
décrire que d'autres. On s'intéresse ici aux langages réguliers (type
3 de Chomsky).
7
Remarques : pour économiser des parenthèses, les priorités sont :
priorité( * ) > priorité(concaténation) > priorité( | ).
Par exemple ab*|c = ((a)((b)*))|(c)
La concaténation est distributive par rapport à | . Par exemple r(s|t) = rs|rt
8
Expressions régulières
Expressions régulières
Exercices :
On ajoute à la notation :
• [abc] pour (a|b|c)
• [a1-a2] pour {c ∈ Σ, a1 ≤ c ∧ c ≤ a2}
• [^…]
pour le complément
• r?
pour r|є
• r+
pour rr*
• .
pour n'importe quel caractère
• Ecrire l'expression régulière pour représenter l'ensemble de tous
les mots formés de a et de b, ou le mot vide.
C'est à dire { є, a, b, ab, ba, aab, bbab, …}
• Ecrire l'expression régulière correspondant à : soit le mot a, soit
les mots formés de 0 ou plusieurs b suivi d'un c.
C'est à dire {a, c, bc, bbc, bbbc, bbbbc, . . }
• Ecrire une ou deux expressions équivalentes à ((є | a)b*) *
Exercices, écrire les expressions régulières pour représenter :
• Une suite de chiffres, exemples : {0, 15, 128, . . }
• Entiers hexadécimaux, exemples : {0xF14, 0x05, 0xff, . . }
• Nombres entiers, exemples : {58,+5, -99, . . }
• Nombres réels, exemples : {58, 3.14, 5E22, -3.14e-10, . . }
• Ecrire l'expression régulière pour représenter l'ensemble des mots
sur {a,b} ayant le facteur abb
• Ecrire l'expression régulière pour représenter l'ensemble des mots
sur {a,b} ayant exactement 3 a
9
10
Définitions régulières
Définitions régulières
Pour simplifier les notations, on peut donner des noms à certaines
expressions régulières.
Exemple :
lettre
chiffre
id
Une définition régulière est une séquence de définitions de la
forme :
d1  r1
d2  r2
...
dn  rn
Dans la quelle :
1. Chaque dj est un nouveau symbole qui n'est ni Σ, ni identique à
autre dk;
2. Chaque ri est une expression régulière sur l'alphabet
Σ  {d1,d2,…,di-1}
11
 [A-Za-z_]
 [0-9]
 {lettre} ({lettre} | {chiffre})*
Autre exemple :
chiffre
chiffres
nbr
 [0-9]
 {chiffre}+
 {chiffres} ("."{chiffres})?(E[+-]? {chiffres})?
Attention méta-symbole !!
12
Compilation
Reconnaissance des unités lexicales
Programme "analyseur lexical" reconnaît les unités lexicales.
Le principal client de l'analyseur lexical est l'analyseur syntaxique.
L'interface entre ces deux analyseurs est "uniteSuivante()", qui
renvoie à chaque appel l'unité lexicale suivante.
Reconnaissance des unités lexicales
L'analyseur lexical envoie vers l'analyseur syntaxique :
• la dernière unité lexicale reconnue,
• le (ou les) attribut(s) de l'unité lexicale,
• le lexème correspondant.
Intérêt des attributs. Par exemple pour : <=, >=, <, >, =, <> . l'analyseur
syntaxique a juste besoin de savoir que cela correspond à l'unité lexicale
OPREL. C'est lors de la génération de code que l'on aura besoin de distinguer
entre < et >= par exemple.
13
14
Reconnaissance des unités lexicales
Reconnaissance des unités lexicales
Exemple : grammaire de l'instruction if (de Pascal)
En plus l'analyseur lexical et l'analyseur syntaxique partagent
certaines données : les définitions des constantes définissant les
unités lexicales, la table de symboles, etc.
instr
Quelques considérations supplémentaires :
• L'analyseur lexical est "glouton" : prendre le lexème est le plus
long possible.
• Seul l'analyseur lexical accède au texte source.
• L'analyseur lexical acquiert le texte source un caractère à la fois.
• L'analyseur syntaxique n'acquiert ses données qu'à travers de
l'analyseur lexicale (uniteSuivante())
exp_bool
terme

|
|

|

|
if exp_bool then instr
if exp_bool then instr else instr

terme oprel terme
terme
id
nbre
Partie syntaxique
Exemple de fragment de source :
if vitesse > 65 then
15
16
Reconnaissance des unités lexicales
Reconnaissance des unités lexicales
Les terminaux de la grammaire (unités lexicales) sont :
if, then, else, oprel, id et nbre.
L'analyseur lexicale doit reconnaître les mots clés if, then et else,
ainsi que les lexèmes de oprel, id et nbre.
Les motifs de ces unités lexicales (décrits par les définitions
régulières) sont :
chiffre
chiffres
nbr
lettre
id
if
then
else
oprel
17









De plus, l'analyseur lexical doit ignorer les blancs, en utilisant la
définition régulière :
[0-9]
Partie lexicale
{chiffre}+
{chiffres} ("."{chiffres})?(E[+-]? {chiffres})?
[A-Za-z]
{lettre} ({lettre} |{chiffre})*
if
then
else
< | > | <= | >= | = | <>
blanc  (" " | \t | \n) +
18
Analyseurs
Reconnaissance des unités lexicales
Récapitulatif des lexèmes, unités lexicales et attributs à reconnaître :
LEXEME
UNITE
LEXICALE
VALEUR
ATTRIBUT
Un blanc
---
---
if
if
---
then
then
---
else
else
---
id
id
Pointeur vers table
nbre
nbre
Valeur du nombre
<
oprel
INF
<=
oprel
INFEGAL
=
oprel
EGAL
<>
oprel
NONEGAL
>
oprel
SUP
>=
oprel
SUPEGAL
19
Ecriture d'un analyseur lexicale.
Deux alternatives :
1. Analyse lexicale prédictive. Analyseur fait "à la main". On peut
éventuellement utiliser des diagrammes de transition.
2. Utiliser un générateur automatique d'analyseur lexicaux tel que
JFlex. Alternative la plus fréquente.
20
Diagrammes de transition
Diagrammes de transition
Exemple : diagramme de transition qui reconnaît les lexèmes de
l'unité lexicale oprel :
Une expression régulière peut se convertir (à la main ou
automatiquement) en un diagramme de transition.
Diagramme de transition : lors de la reconnaissance d'un lexème,
l'analyseur lexical passe par divers états.
De chaque état e sont issues une ou plusieurs flèches étiquetées par
des caractères. Une flèche étiquetée par c relie e à l'état e1 dans
lequel l'analyseur passera si le caractère c est lu dans le texte
source.
c
e
e1
Un état particulier représente l'état initial de l'analyseur.
Les états finaux (doubles cercles), correspondant à la
reconnaissance d'une unité lexicale.
21
22
Analyseurs lexicaux "en dur"
Analyseurs lexicaux programmés "en dur"
Les diagrammes de transition sont une aide pour l'écriture
d'analyseurs lexicaux. Par exemple, à partir du diagramme
précédent on peut obtenir un analyseur lexical de l'unité lexicale
oprel.
Analyseurs lexicaux "en dur"
Code d'un fragment de l'analyseur lexicale (unité lexicale oprel) :
public Yytoken uniteSuivante() {
/* le char c est "global" c = carac_suivant */
while (estBlanc(c))
/* etat = 0 */
c = lireCar();
if (c == '<') {
/* etat = 1 */
c = lireCar();
/* on avance la lecture */
if (c == '='){
/* etat = 2 */
c = lireCar();
return(new Yytoken(Common.OPREL,yytext());
}
else if (c == '>') {
/* etat = 3 */
c = lireCar();
return (new Yytoken(Common.OPREL,yytext());
}
else
/* etat = 4 */
return (new Yytoken(Common.OPREL,yytext());
else if (c == '=') {
/* etat = 5 */
c = lireCar();
return (new Yytoken(Common.OPREL,yytext());
}
/* suite page suivante */
Une manière de traiter le caractère lu en trop consiste en avoir une
variable contenant toujours le caractère prochain du texte source.
Exemple de fragment des fonctions auxiliaires :
public boolean estBlanc(char c) {
return c == ' ' || c == '\t' || c == '\n';
}
public boolean estLettre(char c) {
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z';
}
public boolean estChiffre(char c) {
return '0' <= c && c <= '9';
}
23
L'étoile signifie que la
reconnaissance requiert
la lecture d'un caractère
au-delà de la fin du lexème
24
Analyseurs lexicaux "en dur"
Mots clés
else if (c == '>') {
/* etat = 6 */
c = lireCar();
if (c == '=') {
/* etat = 7 */
c = lireCar();
return (new Yytoken(Common.OPREL,yytext());
}
else
/* etat = 8 */
return (new Yytoken(Common.OPREL,yytext());
}
/* else autres lexemes ou erreur */
}
Reconnaissance des mots clés.
Les mots clés appartiennent au langage défini par l'expression
régulière lettre(lettre|chiffre)*, tout comme les identificateurs.
Leur reconnaissance peut se faire de deux manières :
1. Soit on incorpore les mots clés au diagrammes de transition.
Exemple diagramme de transition pour le mot clé then :
début
25
t
h
e
n
ni lettre
ni chiffre
*
26
Mots clés
Compilation
Méthode plus utilisé
2. Soit on traite de la même manière les mots clés et les
identificateurs.
Dans ce cas on initialise la table de symboles avec les mots clés.
Ainsi le diagramme de transition pour les id et les mots clés est :
Génération automatique (lex)
lettre ou chiffre
début
lettre
autre
*
return(consultTableSymb())
Consulte la table de symboles et retourne
l'unité lexicale si le lexème n'est pas dans
la table, alors il le place
27
28
Constructeur d'analyseurs lexicaux Lex
Constructeur d'analyseurs lexicaux Lex
Le programme Lex permet de générer des analyseurs lexicaux.
Différentes versions existent selon le langage de programmation
utilisé : Lex, Flex, Ocamllex, JFlex, etc.
Un programme en JFlex se divise en trois parties séparées par %%
1. La première contient des définitions et initialisations utiles pour
le programme généré ; ce qui est écrit là sera inséré tel quel dans
ce programme généré.
2. La seconde contient des options, des définitions régulières et des
déclarations.
3. La troisième contient les règles et actions à appliquer lors de la
lecture du texte à analyser.
JFlex prend en entrée un ensemble d'expressions et produit le source
d'un programme Java qui est l'analyseur lexical correspondant
aux expressions régulières.
Forme d'un programme en JFlex :
définitions initialisations et classes en Java
%%
options, définitions régulières et déclarations
%%
règles {actions}
Par exemple
"monAnalyseur.flex"
29
30
Constructeur d'analyseurs lexicaux Lex
Constructeur d'analyseurs lexicaux Lex
Classe produite par Jflex :
Un premier exemple
Compter le nombre de "a" et "e" dans un texte.
monAnalyseur1.flex
monAnalyseur1.java (fragment)
Nom de la classe générée.
package testJFlex;
Par défaut : Yylex
%%
%class MonAnalyseur1
%standalone
%{ code inséré directement dans la classe %}
%{
// On désire compter le nb de "a" et "e"
// s'insere dans la classe MonAnalyseur1
public static int nbA = 0, nbE = 0;
%}
%%
a {nbA++; System.out.print(yytext()+"("+nbA+")");}
e {nbE++; System.out.print(yytext()+"("+nbE+")");}
Notez la partie : règle {action}
règle est une exp. régulière, le motif.
action est exécutée si le motif est reconnu
String yytex()
représente le lexème reconnu
31
32
package testJFlex;
/**
* This class is a scanner generated by JFlex 1.4.3
* ....
*/
class MonAnalyseur1 {
. . .
// On désire compter le nb de "a" et "e"
// s'insere dans la classe MonAnalyseur1
public static int nbA = 0, nbE = 0;
....
public static void main(String argv[]) {
. . .
MonAnalyseur1 scanner = null;
try {
scanner=new MonAnalyseur1(new java.io.FileReader(argv[i]));
while ( !scanner.zzAtEOF ) scanner.yylex();
}
catch (java.io.FileNotFoundException e) {
....
}
....
}
}
Constructeur d'analyseurs lexicaux Lex
Constructeur d'analyseurs lexicaux Lex
Le fonctionnement du filtrage.
La troisième partie de JFlex contient des lignes sous la forme Ri {Ai}.
Où Ri est une expression régulière et Ai une action :
Source à analyser :
monAnalyseur1.txt
le test est important.
Aussi la réussite, le courage, le bon sens.
R1
R2
...
Rn
Console d'exécution :
{A1}
{A2}
{An}
L'analyseur considère le texte à analyser comme une chaîne f, il
cherche le facteur gauche le plus long qui appartient à un Ri.
• Si f = gh et g  Ri, alors il effectue l'action Ai et recommence le
procédé avec h.
•
Les caractères non "filtrés"
sont affichés tels quels.
33
34
Si le facteur gauche g appartient à Ri et à Rj c'est l'action
correspondante au plus petit des deux indices i, j qui est effectuée.
• Si aucun facteur gauche non vide appartient à un Ri alors une lettre
de f est lue (consommée) puis recopiée en sortie.
Le processus est répété jusqu'à la fin du texte.
Constructeur d'analyseurs lexicaux Lex
Constructeur d'analyseurs lexicaux Lex
Expressions régulières en Lex :
35
x
Filtre le caractère 'x'
\x
Filtre le caractère 'x' littéralement
.
[xyz]
Expressions régulières en Lex :
{DEF}
où "DEF" est une définition régulière définie dans la
première partie
Tout caractère (byte) sauf newline
(R)
R. Les parenthèses déterminent une priorité.
"ensemble de caractères"; ici, l'expression filtre un
'x', ou un 'y', ou un 'z'
RS
R suivie par l'expression S. Concaténation
R|S
R ou S. Union"
[abj-oZ]
"ensemble de caractères" contenant un intervalle ; filtre 'a',
'b', ou n'importe quelle lettre entre de 'j' et 'o', ou 'Z'
R/S
R seulement si suivie par S. S n'est pas "consommé" par
l'analyseur.
[^A-Z]
Complément d'un "ensemble de caractères", i.e., un
caractère qui n'est pas dans l'ensemble A-Z.
Tout caractère SAUF une majuscule.
^R
R au début d'une ligne.
~R
[^A-Z\n]
(tout caractère sauf une majuscule) ou (un newline)
filtre tout jusqu'à trouver R. Le lexeme termine par R.
Exemple : ~(ab) filtre cdefaxab
R*
Zéro une ou plusieurs R, où R est une expression rationnelle
"s"
chaîne de caractères s.
R+
Une ou plusieurs R
<<EOF>>
fin du fichier
R?
Zéro ou une R
R{m,n}
E répété entre m et n fois
36
Exercice
Exercice: :compter
compter
lelenb
nbde
dechaînes
chaînes
("xx")
("xx")
Constructeur d'analyseurs lexicaux Lex
Constructeur d'analyseurs lexicaux
Lex
Console d'exécution
2ème exemple
Compter le nombre de minuscules, majuscules, blancs et autres.
3ème exemple
Analyser le fragment Pascal suivant :
monAnalyseur2.flex
if vitesse > 65 then
Et pour compter le nb de mots
package testJFlex;
commençant par majuscule ?
%%
%class MonAnalyseur2
%standalone
%{
static int minis = 0,majus = 0,autres =0,blancs =0;
%}
A exécuter à la fin
%eof{
System.out.println("Minuscules : "+minis+" Majuscules : "
+majus+" Autre : "+autres+" Blancs : "+blancs);
%eof}
Notez les motifs
%%
[a-z] {minis++;}
[A-Z] {majus++;}
[\ ] {blancs++;}
Console d'exécution pour le
\n
{}
source monAnalyseur1.txt
.
{autres++;}
37
Définitions régulières impliquées dans l'analyse :
sep
blanc
lettre
chiffre
id
nbre
[ \t\n]
{sep}+
[A-Za-z]
[0-9]
{lettre} ({lettre}|{chiffre})*
{chiffre}+ (\.{chiffre}+)?(E[+-]? {chiffre}+)?
38
Constructeur d'analyseurs lexicaux Lex
monAnalyseur3.flex
Constructeur d'analyseurs lexicaux Lex
Pour lancer JFlex avec Eclipse :
package testJFlex;
%%
%class MonAnalyseur3
%standalone
/* définitions régulières */
sep =
[ \t\n]
blanc =
{sep}+
lettre = [a-zA-Z]
chiffre = [0-9]
id =
{lettre}({lettre}|{chiffre})*
nbre =
{chiffre}+(\.{chiffre}+)?(E[+\-]?{chiffre}+)?
%%
{blanc}
{ /*pas d'action*/ }
if | then | else
{System.out.println("MR"+yytext());}
{id}
{System.out.println("ID"+yytext());}
{nbre}
{System.out.println("NBRE"+yytext());}
"<" | "<=" | ">" | "<>" | "="
{System.out.println("OPREL"+yytext());}
39






A la place de println, l'utilisation avec
un analyseur syntaxique requiert :
return(<unité lexicale>)
1. Télécharger jflex. Adresse : http://www.jflex.de/
2. Dans les propriétés de votre "projet" java d'Eclipse, faire
"AddExternalJAR" pour pointer vers "JFlex.jar"
3. Pour lancer jflex, exécuter la classe "Main" de "JFlex.jar". Vous
obtiendrez une fenêtre comme ceci :
40
Constructeur d'analyseurs lexicaux Lex
Constructeur d'analyseurs lexicaux Lex
Exercice : Évaluation d’expressions postfixées.
Si la génération de l'analyseur lexicale a réussi, alors vous pouvez
lancer la classe générée (si elle comporte le main).
Écrire un programme JFlex permettant d’évaluer des expressions
postfixées.
Vous devez spécifier le nom du fichier source dans l'argument du
main. Par exemple :
No ligne : %line, yyline
Exemple.
Source :
7 20 * 13 1 - 7 * +
9 2 / 10 +
9 + 2 9
1 1 1 +
3 a 5 + // commentaire reste
55 /* commentaire */
/* plus */ 14 /* compliqué */
41
42
Faire une deuxième version acceptant
des nombres réels. Ex :
3.14 5 +
1.3e-10 4.5 * 6 -
Ajouter les commentaires plus tard
Troisième version, continuer le traitement en
cas d'erreur. Ex :
"3 a 5 +" signale erreur mais retourne 8
Compilation
Automates finis
Comment JFlex fonctionne ? au moyen des automates finis
(implémentation des diagrammes de transition).
Les automates finis sont des "reconnaisseurs" ; il disent oui ou non à
propos d'une chaîne d'entrée.
Automates finis
Les automates finis (déterministes et non déterministes)
reconnaissent les langages réguliers décrits par des expressions
régulières.
Le schéma traditionnel d'un analyseur :
1. Chaque expression régulière est compilée en un automate,
2. L'ensemble des automates est fusionné en un seul automate
déterministe.
43
44
Automates finis
Automates finis
Un automate peut être représenté graphiquement par un diagramme
de transition.
Automate fini non déterministe (AFN) ou déterministe (AFD) :
• Ensemble fini d’états E ;
• Alphabet d’entrée fini ;
• Fonction de transition ;
• État initial q0 ;
• Ensemble d’états terminaux F ;
Remarquez que dans un AFN :
1. Le même symbole peut étiqueter des arcs sortant d'un état ;
2. Un arc peut être étiqueté par , la chaîne vide.
Exemple de langage : (a|b)*abb
AFD : : E E
• au plus une transition par couple état-lettre ;
AFN :
AFN : : E sous-ensemble de E ;
• plusieurs transitions possibles par couple ;
• possibilités de transitions vides ou -transitions.
début
Table de transition :
46
Automates finis
pour : N()
pour a : N(a)
b
a
0
1
b
Table de transition :
47
a
b
b
2
b
b
2
3
Exemple de mot accepté par
l'automate : ababb
chemin : 0,0,1,2,3
Etat \ Symbole
a
b
0
{0,1}
{0}
1
{2}
2
{3}
Exercice : écrire la
grammaire
équivalente
Construction d’un AFN à partir d’une expression régulière
(construction de Thompson)
Exemple même langage : (a|b)*abb
début
1
Automates finis
Remarquez que dans un AFD :
1. Il n'y a aucun arc étiqueté par  ;
2. Pour chaque état s et chaque symbole d'entrée a, il y a un seul arc
sortant de s étiqueté a.
AFD :
a
0
b
On dit qu'un automate fini accepte une chaîne s = c1 c2 … ck ss’il existe un chemin
entre l'état initail et un état terminal, composé de k flèches étiquetées c1, c2, …, ck.
45
Représentation graphique
sous la forme d'un
diagramme de transition
a
pour r | s : N(r | s )
3
a
a
pour rs : N(rs)
Etat \ Symbole
a
b
0
1
0
1
1
2
2
1
3
3
1
0
pour r* : N(r*)
48
Automates finis
Automates finis
On réalise d’abord une analyse syntaxique de l’expression régulière,
puis construction de Thompson.
Utilisation d’un AFN pour reconnaître un mot.
Il faut construire tous les chemins correspondants dans l’AFN.
Exemple : ababb
Exemple : r = (a|b)*abb
b
b
trans(T,a)
transitions partant de
l'ensemble d'états T sur
l'entrée a
-fermeture(T)
transitions partant de
l'ensemble d'états T par des
transitions
États numérotés suivant l’ordre de construction de l’automate.
49
50
Automates finis
Automates et Lex
Conversion d'un AFN en AFD.
Méthode : construire toutes les transitions possibles, complétées
par leur -fermeture.
Exemple : (a|b)*abb
Démarche d'analyse de Lex :
• Convertir en AFN chacune des expressions régulières à l'aide de
l'algorithme de Thompson.
• Fusionner les AFN en un seul AFN. On utilise les transitions.
• Convertir le AFN en AFD.
b
AFN
AFD
51
52

Documents pareils