IFT313
Introduction aux langages formels
Froduald Kabanza
Département d’informatique Université de Sherbrooke
planiart.usherbrooke.ca/kabanza/cours/ift313
Expressions régulières
IFT313 © Froduald Kabanza
2
Sujets couverts
• Rôle de l’analyseur lexical
• Langages réguliers
• Expressions régulières
IFT313 © Froduald Kabanza
3
Objectifs
• Savoir ce qu’un langage régulier.
• Être capable d’écrire une expression régulière décrivant un langage donné.
• Être capable de faire une recherche dans un fichier texte en utilisant grep.
• Être capable d’écrire un programme cherchant des patterns dans un fichier texte avec regex.
IFT313 © Froduald Kabanza
4
Références
[1] Sudkamp, T. A.. Languages and Machines. Third Edition Edition.
Addison-Wesley, 2005.
– Chapitre 2.
[2] Appel, A. and Palsberg, J. Modern Compiler Implementation in Java.
Second Edition. Cambridge, 2004.
– Sections 2.1 à 2.2
[3] Wolper, P. Introduction à la calculabilité, 3è édition. Dunod, 2006 – Chapitre 1
[4] Aho, A., Lam, M., Sethi R., Ullman J. Compilers: Principles, Techniques, and Tools, 2nd Edition. Addison Wesley, 2007.
– Sections 3.1 à 3.3
IFT313 © Froduald Kabanza
5
Rôle de l’analyseur lexical
- Nous avons vu que la phase “analyse” d’un compilateur com- prend:
+ L’analyse lexicale : diviser le code source en une suite d’unités lexicales (tokens).
+ L’analyse syntaxique : analyser la structure grammaticale du code source (de la suite de tokens)
+ Analyse sémantique : déterminer le sens du code source.
IFT313 © Froduald Kabanza
6
Rôle de l’analyseur lexical
- L’analyseur lexical lit une séquence de caractères et produit une séquence de tokens
.
- En même temps, l’analyseur lexical produit une table de symboles.
sourceCode Analyseur lexical Analyseur
lexical Analyseur
syntaxiqueAnalyseur syntaxique
Analyseur sémantiqueAnalyseur sémantique Table de
symbolesTable de symboles
token tokennext
Code cible
IFT313 © Froduald Kabanza
7
Qu’est-ce qu’une unité lexicale (token) ?
- Un token (unité lexicale) est une séquence de caractères pouvant être traitée comme une unité dans la grammaire d’un langage de program- mation.
- Exemples:
Type de token Séquence de caractères ID x, rate, position
NUM 60, 10
REAL 60.0
IF if
WHILE while
SEMI ;
LPAREN (
RPAREN )
ASSIGN =
IFT313 © Froduald Kabanza
8
Qu’est-ce qu’une unité lexicale (token) ?
- Les tokens comme IF, WHILE sont des mots-clés.
- Les mots-clés sont souvent réservés.
- Les tokens d’un langage de programmation incluent les identificateurs, les mots-clés, les nombres et les séparateurs ou terminaisons d’instructions (par exemple, ; /*)
- Les tokens sont les symboles terminaux d’une grammaire d’une langage de programmation.
- En général, un analyseur lexical ignore
- les espaces blancs (espaces, sauts de lignes et tabulation) entre les tokens et - les commentaires.
IFT313 © Froduald Kabanza 9
Chaîne de caractères unités lexicales
int a = 34; // commentaire
double /* commentaire */ b= 34.3900f;
<INT_DECLARATION> { ligne=1, pos=1}
<IDENTIFICATEUR> { ligne=1, pos=5, name=a}
<ASSIGN> { ligne=1, pos=7}
<INTEGER> { ligne=1, pos=9, value=34}
<DOUBLE_DECLAR> { ligne=2, pos=12}
<IDENTIFICATEUR> { ligne=2, pos=25, value=b}
<ASSIGN> { ligne=2, pos=26}
<DOUBLE> { ligne=2, pos=30, value=34.39}
IFT313 © Froduald Kabanza
10
Qu’est-ce qu’une unité lexicale (token) ?
- Nous allons spécifier les tokens d’un langage de programmation en util- isant une notation formelle appelée le langage des expressions régulières.
- Nous allons implémenter les analyseurs lexicaux qui reconnaissent de tels tokens en utilisant des outils formels appelés automates (à états) finis.
- La théorie des langages réguliers nous permettra d’établir une correspon- dance entre les deux formalismes.
IFT313 © Froduald Kabanza
11
Langages
- Le code source est une séquence de caractères (symboles), y compris les espaces, tabulations, sauts de lignes, etc.
- L’ensemble de tous les caractères possibles (symboles) est appelé un al- phabet.
- Un langage est un ensemble de mots ou chaînes de caractères (possible- ment infini) formé à partir d’un alphabet, selon une syntaxe bien précise.
IFT313 © Froduald Kabanza
12
Opérations sur les langages
- Il y a plusieurs opérations qu’on peut effectuer avec les langages.
- Soit L et M deux langages.
L U M = {s | s is in L or s is in M} union
L = {s | s is not in L } complément
LM= {s | s= s’s” for s’ in L and s” in M } concaténation
L* ={s | s’s’’ for s’ and s’’ in L U {ε}} Étoile (ou fermeture) de Kleen (ε représente la chaîne vide ‘’).
L+ =LL* Une ou plusieurs répétitions de L
…
IFT313 © Froduald Kabanza
13
Exemples d’opérations sur les langages
- Soit L = {A,B, … , Z, a,b,…,z}
- Soit D = {0,1,…,9}
- Alors
+ L* est l’ensemble des mots formé de lettres, y compris la chaîne vide ε (aussi noté ‘’).
+ L(L U D)* est l’ensemble de chaînes alphanumériques commençant par une lettre.
+ DD* est l’ensemble des entiers positifs.
IFT313 © Froduald Kabanza
14
C’est quoi un langage régulier ?
- Un langage régulier est un langage défini sur un alphabet fini en utilisant les opérations précédentes: union, concaténation, complément et ferme- ture de Kleen.
- Nous verrons bientôt d’autres définitions équivalentes :
Un langage régulier est celui défini par une expression régulière.
Un langage régulier est celui accepté par un automate fini.
Un langage régulier est celui généré par une grammaire régulière.
IFT313 © Froduald Kabanza
15
Expression régulières
- L’ensemble de tokens d’un langage de programmation est un langage régulier.
- Pour le spécifier, on utilise une notation d’expressions régulières.
- Chaque expression régulière r dénote un langage régulier L(r) , selon les règles suivantes :
IFT313 © Froduald Kabanza
16
Expression régulières
1 ε (ou ‘’) : L’expression régulière ε représente le langage {ε} (ou {‘’})
2 symbole (caractère) : Pour chaque symbole (caractère) a dans l’alpha- bet, l’expression régulière a représente le langage {a}, c-à-d., le lan- gage contenant juste le mot a.
- Étant donnés les expressions régulières r et s représentant, respectivement, les langages L(r) et L(s) :
3 r|s (alternation) est une expression régulière représentant L(r) U L(s).
4 rs (concaténation) est une expression régulière représentant L(r)L(s).
5 r* (zéro ou plusieurs répétitions) représente (L(r))*. 7 (r) est une expression régulière représentant L(r).
IFT313 © Froduald Kabanza
17
Exemples expressions régulières
· ((a|b)a)*
spécifie le langage
de mots de longueur paire terminés par un ‘a’{ ‘’, aa, ba, aaaa, baaa, aaba, baba, aaaaaa, …}
· (0|1)*0
spécifies l’ensemble de nombres binaires qui sont des multiples de 2.
IFT313 © Froduald Kabanza
18
Autres notations d’expressions régulières
· r+ ≡ rr*
· r? ≡ r| ε
· [a b c] ≡ (a|b|c)
· [a-g] ≡ a|b|…|f|g
· [^s] ≡ complément de l’ensemble
· ^ ≡ début de ligne
· $ ≡ fin de ligne
· “ab” ≡ la chaîne ab
· . ≡ N’importe quelle caractère sauf ‘\n’
· [a-zA-Z][a-zA-Z0-9]* : chaîne alphanumérique commençant par une lettre.
· [0-9]+ : un nombre entier positif.
Examples
IFT313 © Froduald Kabanza
19
Outils utilisant des expressions régulières
· grep
· regex (devoir 1)
· JFLEX (devoir 2)
IFT313 © Froduald Kabanza
20
Exemple de spécification pour JFLEX
- Une spécification typique de JFLEX décrit des expressions régulières an- notées de code Java pour traiter et renvoyer le token au parser.
IFT313 © Froduald Kabanza
21
Résumé
- Nous utiliserons des expressions régulières pour décrire les tokens du langages que nous voulons analyser, compiler, traduire ou traiter autrement.
- Pour la tâche de reconnaissance de tokens, les expressions régulières sont très ap- propriées. Elles décrivent “ce qu’il faut reconnaître” pour isoler un token, plutôt que “comment” les reconnaître.
- Toutefois, pour que le scanner puisse effectivement reconnaître les tokens, nous avons besoin d’un outil formel procédural, pouvant être implémenté comme un programme.
- Pour cela, nous utiliserons les automates à états finis.
- Les expressions régulières sont aussi utiles pour faire une recherche dans un fichier de texte, avec des outils tels que grep et regex et des éditeurs tels que emacs.