Principes des lang. de progr.
INE 11
Michel Mauny
Inria-Paris
prénom.nom@inria.fr
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 1 / 22
Analyse lexicale
1 Expressions rationnelles
2 Automates finis
3 OCamllex
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 2 / 22
Analyse lexicale : reconnaître les «mots»
Première phase d’un compilateur ou interprète
analyseur sémantique analyseur syntaxique analyseur lexical programme
source (flux de caractères)
Flux de lexèmes
Arbre de syntaxe dite superficielle
Arbre de syntaxe dite profonde
générateur
Code objet
Analyse lexicale : reconnaître les «mots»
Première phase d’un compilateur ou interprète analyseur peut être écrit à la main
le plus souvent produit automatiquement à partir d’un générateur spécifié à partir d’expressions rationnelles
exécution : simulation d’unautomate fini déterministe Domaine bien étudié
théorie bien comprise littérature abondante générateurs performants Renouveau des automates
vérification de conformité de XML vis-à-vis de DTD automates d’arbres pour traitement du XML
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 4 / 22
Lexèmes (les «mots»)
Exemple
whilei<>jdo(∗commentaire∗) if i>jthen
i:=i−j
Résultat while kwd, i ident, 6= kwd, j ident, do kwd, if kwd,. . . Représentation OCaml
typetoken=FOR|WHILE|DO| DONE|IF | THEN| ELSE| ...
| EQUAL|COLONEQUAL|PLUS|MINUS|STAR| SLASH| ...
| GREATER|SMALLER|SMALLERGREATER| ...
| IDENTofstring|INTofint| FLOAToffloat| ...
Résultat OCaml
WHILE;IDENT("i");SMALLERGREATER;IDENT("j");DO;IF;. . .
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 5 / 22
Expressions rationnelles
Exemple 1 : entiers naturels
chiffre::= ’0’ | ’1’ | ’2’ | ... | ’7’ | ’8’ | ’9’
naturel::=chiffre chiffre∗
Exemple 2 : identificateurs OCaml
majuscule::= [’A’−’Z’] minuscule::= [’a’−’z’]
lettre ::= majuscule|minuscule
constr ::= majuscule(lettre |chiffre| ’_’)∗ ident ::= minuscule(lettre |chiffre| ’_’)∗
Expressions rationnelles
Définition
Expressions rationnelles
SoitΣalphabet. Une expression rationnellee est : a∈Σ
la concaténation de deux e.r.e1e2 lemot videnoté
une alternativee1|e2
une itératione∗ Notations
e1e2|e3e4 sera lu comme(e1e2)|(e3e4) e1e2∗|e3 sera lu comme(e1(e2∗))|e3
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 7 / 22
Expressions rationnelles
Formes dites dérivées (notations définissables) e?≡e|
e+≡ee∗ [abc]≡(a|b|c)
[a1-a2]≡ l’un des éléments deΣcompris entrea1eta2 (Σtotalement ordonné)
[ˆabc]≡l’un des éléments du complémentaire de{a,b,c}dansΣ
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 8 / 22
Une expression représente un langage
Définition
Langage représenté par une expression rationnelle
L(e)est défini par :L() ={}
L(a) ={a}, oùa∈Σ
L(e1e2) ={m1m2avecm1∈ L(e1)etm2∈ L(e2)} L(e1|e2) =L(e1)∪ L(e2)
L(e∗) = {} ∪ L(e)∪ L(ee)∪. . .
= S∞
i=0L(ei)
Usage
Utilisations
analyse lexicale (compilation de langages de programmation) éditeurs de texte
motifs à rechercher dans fichiers / données (Unix, Web) DTD (qui indique la forme de documents HTML)
bibliothèques de langages (awk, Perl, Python, OCaml, PHP, . . . ) pour traitement de fichiers texte
. . .
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 10 / 22
Automates finis
Définition
Automate fini déterministe (DFA)
C’est la donnée de :un alphabet finiΣ;
un ensemble fini d’étatsQ;
une fonction de transitionδ:Q×Σ→Q; un état initialp0;
un ensemble d’états finauxF ⊂Q.
Automate fini non déterministe (NFA) δ:Q×(Σ∪ {})→ P(Q)
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 11 / 22
Automates finis non déterministes
Automate fini non déterministe
Comment interpréter un automate fini non déterministe ? maintenir plusieurs états en même temps
Suggère
un algorithme de déterminisation
Déterminisation : de NFA vers DFA
À déterminiser
Mieux faire ? oui : minimiser (regrouper états équivalents) ou construire directement un automate déterministe (eventuellement minimal)
Résultat
Voir littérature
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 13 / 22
Compilation d’expressions rationnelles
Traduire les expressions rationnelles en automates non-déterministes Si l’expression est on produit
a∈Σ MN
M|N
M∗
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 14 / 22
Génération d’analyseurs
Comment produire un analyseur à partir d’une spécification traduction d’expressions rationnelles en automates finis non-déterministes
déterminisation minimisation
Génération directe de l’automate fini déterministe minimal
OCamllex
Générateur d’analyseurs lexicauxocamllex monlexer.mllproduitmonlexer.ml tables ou fonctions récursives (option) Structure
{header}
let ident=regexp...
rule next1arg1...argn= parseregexp{action}
| ...
| regexp{action} andnext_k arg1...argm=
parse ...
and ...
{trailer}
→Prélude recopié tel quel dans le fichier produit
→Définitions d’expressions rationnelles.
nexti : ... → Lexing.lexbuf → τ
lexbuf : Lexing.lexbuf est un paramètre implicite Les analyseurs sont mutuellement récursifs.
Lorsque plusieursregexpreconnaissent le même préfixe de l’entrée, c’est le cas qui reconnaîtl’entrée la plus longuequi est choisi
→Postlude recopié tel quel dans le fichier produit
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 16 / 22
Utilisation
Fonctions générées analyseurs :
next_token : [ types des paramètres → ] Lexing. lexbuf → τ création debuffers :
Lexing.from_channel : in_channel → lexbuf Lexing.from_string : string → lexbuf
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 17 / 22
Exemple : source
naturel.mll
{ exceptionErreur}
let chiffre_non_nul= [’1’−’9’]
rule nat=parse
| chiffre_non_nul(’0’ |chiffre_non_nul)∗
{ int_of_string (Lexing.lexemelexbuf) }
| [’ ’ ’\n’ ’\t’]
{ natlexbuf }
| _{ raise Erreur(∗le cas _ doit venir en dernier ∗) } { }
Exemple : source
naturel.mll
{ exceptionErreur}
let chiffre_non_nul= [’1’−’9’]
rule nat=parse
| chiffre_non_nul(’0’ |chiffre_non_nul)∗asstr { int_of_string str}
| [’ ’ ’\n’ ’\t’]
{ natlexbuf }
| _{ raise Erreur(∗le cas _ doit venir en dernier ∗) } { }
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 19 / 22
Compilation vers des tables
$ ocamllex naturel.mll
4 states, 267 transitions, table size 1092 bytes
$ cat naturel.ml exceptionErreur
let __ocaml_lex_tables= {... les tables de l’automate ...} let recnat lexbuf=__ocaml_lex_nat_rec lexbuf0 and__ocaml_lex_nat_rec lexbuf __ocaml_lex_state=
matchLexing.engine __ocaml_lex_tables __ocaml_lex_state lexbufwith
| 0 →
let str=Lexing.sub_lexeme lexbuf
lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_curr_posin ( int_of_string str)
| 1 → ( nat lexbuf)
| 2 → ( raise Erreur)
| __ocaml_lex_state→
lexbuf.Lexing.refill_buff lexbuf;
__ocaml_lex_nat_rec lexbuf __ocaml_lex_state
;;
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 20 / 22
Exemple : utilisation
$ocaml
OCaml version...
##load "naturel.cmo";;
#Naturel.nat;;
−: Lexing. lexbuf →int
#Naturel.nat(Lexing.from_string "1234abcd");;
−:int= 1234
#letbuf=Lexing.from_string "1234abcd";;
val buf : Lexing. lexbuf = { ... }
#Naturel.nat buf;;
−: int = 1234
#Naturel.nat buf;;
Exception: Naturel. Erreur .
Conclusion
analyse lexicale, motifs à rechercher expressions rationnelles = automates finis
génération automatique de code performant à partir de spécifications utilisant des expressions rationnelles.
Michel Mauny (Inria-Paris) INE 11 prénom.nom@inria.fr 22 / 22