Chapitre 4 Réalisation d`un analyseur lexical

Commentaires

Transcription

Chapitre 4 Réalisation d`un analyseur lexical
Chapitre 4
Réalisation d’un analyseur lexical
Jean Privat
Université du Québec à Montréal
INF5000 — Théorie et construction des compilateurs
Automne 2013
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
1 / 29
Analyse lexicale
Analyseur lexical
Donnée : une séquence de caractères
Résultat : une séquence de jetons (lexèmes)
Un jeton : un type (étiquette) & un texte &
une position (ligne/colonne)
for
i
= 1
to
for
id
eq int
to
Jean Privat (UQAM)
04—Analyseur lexical
10 do print i ...
INF5000 — Automne 2013
2 / 29
Génération d’analyseur lexical
Générateur d’analyseur lexical
Donnée : une description d’un langage
Résultat : le code source d’un analyseur
Exemple : SableCC4
Génère du Java (entre autres)
Description langage
Jean Privat (UQAM)
SableCC4
04—Analyseur lexical
Source Java
INF5000 — Automne 2013
3 / 29
Description de langage
Grammar demo ;
Lexer
letter = ’a ’ .. ’z ’ ;
digit = ’0 ’ . . ’9 ’ ;
i d e n t i f i e r = letter ( letter | digit )∗;
comma = ’ , ’ ;
b l a n k = ( ’ ’ | #9 | #10 | #13)+;
if = ’ if ’;
else = ’ else ’ ;
Parser
i d e n t i f i e r , comma , i f , e l s e ;
Ignored
blank ;
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
4 / 29
Sélection de jetons
Plusieurs séquençages en jetons sont souvent possibles
Séquence de caractères : ify 1 jeton : id ify
2 jetons : id if, id y
2 jetons : if if, id y
2 jetons : id i, id fy
3 jetons : id i, id f, id y
Pas de place à l’ambiguı̈té
Il faut des règles !
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
5 / 29
Règles de l’analyse lexicale
Règle 1
Le jeton le plus long gagne toujours
Exercice : Traitez les séquences suivantes
toto ,,i iiff iff i f
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
6 / 29
Règles de l’analyse lexicale
Règle 1
Le jeton le plus long gagne toujours
Exercice : Traitez les séquences suivantes
toto ,,i → 4 jetons : id toto, comma ,, comma ,, id i
iiff iff i f → 4 jetons : id iiff, id iff, id i, id f
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
6 / 29
Règles de l’analyse lexicale
Règle 2
Des jetons de même taille ne peuvent gagner ensemble
Exemple
Séquence de caractères : if 1 jeton, deux choix : id if ou if if
Solutions
Lex, SableCC3 : Ordre des déclarations importe
SableCC4 : Priorité d’inclusion
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
7 / 29
Priorité lexicale d’inclusion en SableCC4
Règle de l’inclusion lexicale
Une expression régulière strictement inclue dans une autre gagne
la priorité
Remarque : fait en général la bonne chose
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
8 / 29
Priorité lexicale d’inclusion en SableCC4
Grammar p r i o r i t e d i n c l u s i o n :
Lexer
i d e n t i f i e r = ( ’ a ’ . . ’ z ’ )+;
if = ’ if ’;
Token i d e n t i f i e r , i f ;
Ignored ’ ’ , #9, #10, #13;
if ⊂ identifier donc if à la priorité sur identifier pour une chaı̂ne
de même taille
Exercice : Traitez les séquences suivantes
i f if
iffy
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
9 / 29
Priorité lexicale d’inclusion en SableCC4
Grammar p r i o r i t e d i n c l u s i o n :
Lexer
i d e n t i f i e r = ( ’ a ’ . . ’ z ’ )+;
if = ’ if ’;
Token i d e n t i f i e r , i f ;
Ignored ’ ’ , #9, #10, #13;
if ⊂ identifier donc if à la priorité sur identifier pour une chaı̂ne
de même taille
Exercice : Traitez les séquences suivantes
i f → 2 jetons : id i, id f
if → 1 jeton : if if (priorité d’inclusion)
iffy → 1 jeton : id iffy
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
9 / 29
Déclarer les inclusions lexicales en
SableCC4
Déclaration de priorités
La directive Precedence permet de déclarer des priorités
Attention : on a en rarement besoin
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
10 / 29
Forcer la priorité lexicale en SableCC4
Grammar p r i o r i t e f o r c e e ;
Lexer
letter = ’a ’ .. ’z ’ ;
digit = ’0 ’ . . ’9 ’ ;
i d e n t i f i e r = letter ( letter | digit )∗;
h e x i n t e g e r = ( d i g i t | ’ a ’ . . ’ f ’ )+ E x c e p t h e x i n t e g e r
Token i d e n t i f i e r , h e x i n t e g e r ;
Exercice : traitez les séquences suivantes
z10 00ff1 fff 00fg1 Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
11 / 29
Forcer la priorité lexicale en SableCC4
Grammar p r i o r i t e f o r c e e ;
Lexer
letter = ’a ’ .. ’z ’ ;
digit = ’0 ’ . . ’9 ’ ;
i d e n t i f i e r = letter ( letter | digit )∗;
h e x i n t e g e r = ( d i g i t | ’ a ’ . . ’ f ’ )+ E x c e p t h e x i n t e g e r
Token i d e n t i f i e r , h e x i n t e g e r ;
Exercice : traitez les séquences suivantes
z10 → 1 jeton : identifier z10
00ff1 → 1 jeton : hexinteger 00ff1
fff → 1 jeton : identifier fff (priorité déclarée)
00fg1 → 2 jetons : hexinteger 00f, identifier g1
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
11 / 29
Fonctionnement d’un analyseur lexical
Éléments de base
Expressions régulières
Automates
Particularité
Ne plus reconnaı̂tre les mot d’un langage
(simple algorithme de décision oui/non)
Mais extraire des jetons d’une séquence de caractères
(possiblement seulement connue au fur et à mesure, voire infinie)
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
12 / 29
Un seul automate fini déterministe
Un automate fini déterministe unique
Un automate pour les reconnaı̂tre tous
Un automate pour les trouver
Un automate pour les extraire tous et en jetons les séquencer
Forger l’automate unique
Transformer l’expression régulière de chaque jeton en NFA
Marquer les états d’acceptation des NFA par le jeton
Regrouper tous les états de départ
Transformer en DFA
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
13 / 29
Exemple d’automate unique
Grammar automate :
Lexer
letter = ’a ’ .. ’z ’ ;
digit = ’0 ’ . . ’9 ’ ;
id = l e t t e r ( l e t t e r | digit )∗;
if = ’ if ’;
i n t = ( d i g i t )+;
f l o a t = ( d i g i t )+ ’ . ’ ( d i g i t )+;
dot = ’ . ’ ;
bl = ’ ’ ;
Token i d , i f , i n t , f l o a t , d o t ;
Ignored b l ;
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
14 / 29
Exemple d’automate unique (NFA)
0
ε
2
id
ε
ε
1
3
6
a..z
i
0..9
a..z,0..9
4
7
int
ε
ε
8
0..9
0..9
9
f
.
5
if
10
0..9
ε
12
14
.
''
13
dot
15
bl
''
0..9
11
float
Jean Privat (UQAM)
04—Analyseur lexical
0..9
INF5000 — Automne 2013
15 / 29
Exemple d’automate unique (DFA)
a..h,j..z
2,4
id
a..z,0..9
a..e,g..z,0..9
f
i
2,5
if
0..9
0,1,
3,6,8
12,14
0..9
.
''
7,9
int
a..z,0..9
.
10
2
id
0..9
0..9
11
float
13
dot
''
15
bl
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
16 / 29
Gestion des priorités
Définition de conflit
Un état d’acceptation du DFA unique est annoté de plusieurs
jetons
Résolution de conflit
Par priorité d’inclusion
Erreur sinon
Calcul des inclusions des tokens
Déduit de l’inclusion des états d’acceptations
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
17 / 29
Principe d’extraction de jetons
Avancer
Le plus loin possible dans l’automate
En mémorisant le dernier état d’acceptation rencontré
Si avancer est impossible, alors
Retourner le jeton du dernier état d’acceptation rencontré
Repartir de l’état de départ de l’automate
Commencer au caractère qui suit le jeton retourné
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
18 / 29
Algorithme d’extraction de jetons
Données : Un DFA D, une séquence de caractères S
Résultat : Une séquence de jetons J
debut = pos = 0 ; candidat = null ; E = départ(D);
Boucler
c = caractère numéro pos de S (ou EOF sinon);
pos + +;
E = successeur de E par la transition c (ou null sinon);
si E == null alors
si candidat == null alors retourner erreur lexicale;
si candidat n’est pas ignoré alors ajouter candidat à J;
si c == EOF alors retourner J;
E = départ(D) ; pos = debut = caractère après candidat;
candidat = null;
sinon si E accepte jeton j alors
candidat = new Jeton(j, debut, pos-1);
fin
fin
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
19 / 29
Algorithme d’extraction
Exercice : Traitez les séquences suivantes
if cond iffy10 iffy 11 12.13 14 . 15 1.2.3.4.5
1a2b3c4
1.a
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
20 / 29
Algorithme d’extraction
Exercice : Traitez les séquences suivantes
if cond iffy10 iffy 11 12.13 14 . 15 → 9 jetons : if if, id cond, id iffy10, id iffy, int 11,
float 12.13, int 14, dot ., int 15
1.2.3.4.5 → 5 jetons : float 1.2, dot ., float 3.4, dot ., int 5
1a2b3c4 → 2 jetons : int 1, id a2b3c4
1.a → 3 jetons : int 1, dot ., id a
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
20 / 29
Coût algorithmique
En pratique
Linéaire en la taille de la séquence de caractères
Au pire
Quadratique en la taille de la séquence de caractères
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
21 / 29
Pire coût algorithmique
Exemple de langage du pire coût
Grammar p i r e c o u t :
Lexer
a = ’a ’ ;
b = ’a ’∗ ’b ’ ;
Token a , b ;
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
22 / 29
Pire coût algorithmique (NFA)
ε
0
ε
1
2
a
b
4
b
a
3
Jean Privat (UQAM)
a
04—Analyseur lexical
INF5000 — Automne 2013
23 / 29
Pire coût algorithmique (DFA)
a
0,1,2
a
2,3
a
a
b
Jean Privat (UQAM)
04—Analyseur lexical
3
b
4
b
b
INF5000 — Automne 2013
24 / 29
Pire coût algorithmique
Exercice : Traitez les séquences suivantes & comptez les
tours de boucle
aaab aaa aaaaa mille ”a” suivis d’un ”b” ( aa..ab )
mille ”a” ( aa..a )
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
25 / 29
Pire coût algorithmique
Exercice : Traitez les séquences suivantes & comptez les
tours de boucle
aaab → 1 jeton b aaab ; 5 tours de boucle
aaa → 3 jetons a a ; 9 tours de boucle
aaaaa → 5 jetons a a ; 21 tours de boucle
mille ”a” suivis d’un ”b” ( aa..ab )
→ 1 gros jeton b ; 1002 tours de boucles
mille ”a” ( aa..a )
→ 1000 jetons a ; 501501 tours de boucles
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
25 / 29
Utilisation du générateur d’analyseur
SableCC4
Invocation de SableCC4
$ sablecc4 langage.sablecc -p pack.age
langage.sablecc est le fichier de description de langage
pack.age est le package racine des classes Java générées
les fichiers sont crées à partir du répertoire pack/age
Fichiers générées
pack/age/language_XXX/Lexer.java
la classe qui fait l’analyse lexicale
pack/age/language_XXX/Token.java
la classe racine des jetons
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
26 / 29
API principale des classes générées
Classe Lexer
Constructeur Lexer(Reader)
Initialise un nouvel analyseur syntaxique à partir d’une séquence
de caractères.
Méthode
Token next() throws LexerException, IOException
Retourne le jeton suivant
ou un jeton de type spécial TEnd à la fin de la séquence
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
27 / 29
API principale des classes générées
Classe Token
Méthode String getText()
Retourne la chaı̂ne de caractère du jeton
Méthode Type getType()
Retourne le type du jeton du jeton
Exemple : T_Integer pour le jeton integer
Attention, le type spécial TEnd n’a pas de souligné.
Méthodes int getLine() et int getPos()
Retournent la ligne et la colonne du jeton
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
28 / 29
Exemple d’utilisation d’un analyseur
p u b l i c c l a s s Demo {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
try {
F i l e R e a d e r f r = new F i l e R e a d e r ( a r g s [ 0 ] ) ;
L e x e r l e x e r = new L e x e r ( f r ) ;
Token t ;
do {
t = l e x e r . next ( ) ;
System . o u t . p r i n t l n ( ” [ ”+t . g e t L i n e ()+ ” , ”+
t . g e t P o s ()+ ” ] ”+t . getType ()+ ” ’ ”+
t . g e t T e x t ()+ ” ’ ” ) ;
} w h i l e ( t . getType ( ) != Node . Type . TEnd ) ;
} catch ( E x c e p t i o n e ) {
System . e r r . p r i n t l n ( e . g e t M e s s a g e ( ) + ” . ” ) ;
}}}
Jean Privat (UQAM)
04—Analyseur lexical
INF5000 — Automne 2013
29 / 29

Documents pareils