Upload
truonglien
View
214
Download
0
Embed Size (px)
Citation preview
- 1 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Objectif pédagogique
Acquérir les techniques de bases pour la définition et le traitement « source to source »• des textes• des langages de programmation • et des documents structurés
Organisation
Les cours "COMPILATION" et "LANGAGES & DOCUMENTS" partagent• une introduction à la Compilation• l'analyse lexicale des textes • la programmation LEX..• les exemples issus de sources HTML, X(HT)ML, CSS etc.
- 3 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
1946
Plankalkül
1949
Short Code
1951
A-0
1952
Autocode1954
Flow-matic1956
IPL 1957
Fortran
Math-Matic1958
Fortran II
Ial1959
Lisp 1.5
1960
Algol 60
Cobol 1962
Apl
Fortran IV. .
Simula1963
Joss
1964
Apl-360
Basic
PL/1
1965
Snobol 3
1966
Fortran 66
Lisp 2
Iswim
1967
Snobol 4
Simula 67
Bcpl1968
Algol 68
Altran
Cobol ANSI.
Logo
Refal1969.
B
1970
Forth.
Pascal -CDC6000.
Mumps défini.
1972
Plankalkül
C.
Prolog.
Intercal.
1973
Comal
1974
Cobol ANSI.
Langages de programmation par dates 1975
Tiny Basic
Basic Altair
Scheme.
Ratfor
1976
futur PostScript.
1977
Mumps -ANSI. .
Pascal PDP-11
IDL.
Icon
Bourne Shell.
1978
Awk.
Fortran 77. 1979
Rexx.
1980
Smalltalk-80
Modula-2
1981
Common LISP .
1982
ISO Pascal.
Objective C.
1983
Ada.
C++
Turbo Pascal.
1984
Apl 2.
Clipper.
1984
Apl 2.
Clipper.1985
Postscript.1986
Smalltalk/V
Turbo Prolog.
Actor.
Eiffel.
C++ achevé.
1987
Hypertalk.
Perl.
SQL 87.1988
Oberon
Tcl.1989
ANSI C.
C++ 2.0 -.
Modula 3.
Miranda.
1990
C++ 2.1.
Fortran 90.
J.
Haskell.
1991
Python.
Visual Basic.1992
Dylan.
Disco.
1993
AppleScript.
Self.
Lua.1994
Java.
Ruby. 1995
Ada 95
Php.
Delphi. 1996
NetRexx.
JavaScript.1997
ECMAScript.
Rebol. 1998
Erlang1999
C Standard 99.2000
C Scharp (C#).
D.2001
Aspect J.
Scriptol.
SuperX++. 2003
Factor
2004
Php 5.
Scala.
Boo.
2005
Scriptol Interpreter.
Seed7.
- 4 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Définition du "source"
• Formelle validation
robustesse
• Opérationnelle mise en œuvre
utilisation d'outils
• Inductive composition des traitements
transportabilité
évolutivité
- 5 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Objectifs pédagogiques
Donner une introduction au processus de compilation dans sa partie avant.
Définir les principales phases de la partie avant: analyse lexicale, syntaxique et sémantique.
Rappeller les bases et les résultats théoriques qui fondent l’implémentation des analyseurs lexicaux et syntaxiques.
Permettre l’utilisation des générateurs de typelex et yacc
Initier à l’utilisation des techniques de la compilation pour des applications « source to source », en particulier les transformations de documents.
- 6 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Références bibliographiques
• Compilateurs: Principes, techniques et outils, A. Aho, R. Sethi, J. Ullman; InterEditions (1991)
• Lex & Yacc, JR Lewine, T. Mason, D. Brown; O’Reilly & Associates, Inc (1992)
• A first course using ANSI C, LEX and YACC, J. P. Bennett,2nd edition, McGraw Hill (1996)
• Modern Compilation Implementation, A. Appel; Cambridge University Press (1998)
• The Essence of Compilers, R. Hunter, Prentice hall (1999)
• Compilateurs, D.Grune et all, Dunod (2002)
• Crafting a Compiler, C.Fischer, R.LeBlanc, Benjamin Cummings Series (1988)
Autres Cours ESSI
• Petit Précis de Lex. J. Farré; Notes de TP ESSI-2 (1998)• Petit Précis de Yacc. J. Farré; Notes de TP ESSI-2 (1998)
Liens Web
• Cours de Compilation du MIT (format .ppt en Anglais)
lecture3: grammaires, arbres, langages, analyseurs
lecture4: construction SLR
lecture5: construction LR(1)
lecture6: construction LALR(1)
lecture7: sémantique statique.
- 7 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Autres Références
sur les grammaires et les automates
• Introduction to Automata Theory and Computation, Hopcroft, J. Ullman, Addison Wesley (1979)
• An Introduction to Formal Language Theory, R. Moll, M. Arbib, A. Kfoury, Springer-Verlag, (1988)
• Eléments d’algorithmique, D. Beauquier, J. Berstel, P. Chrétienne, Masson (1992)
Liens Web
• il suffit de demander• Cours de Compilation du MIT (format .ppt en Anglais)
lecture3: grammaires, arbres, langages, analyseurs
lecture4: construction SLR
lecture5: construction LR(1)
lecture6: construction LALR(1)
lecture7: sémantique statique.
- 8 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Historique
Les premiers compilateurs datent des années 50. Dans le contexte de l’état de l’art de l’époque, ce sont des programmes difficiles à réaliser. Le premier compilateur Fortran [Backus et al, 1957] est estimé à un travail de 18 hommes-années.Les progrès effectués en matière d’écriture de compilateurs sont considérables; ils sont dus principalement à deux causes:
▼ la compréhension et la définition formelle des tâches à réaliser, ainsi que la découverte des fondements théoriques de ces tâches qui apportent des résultats utilisables en pratique.▼ Les avancées méthodologiques dans la production des grands logiciels, ainsi que le développement d’outils logiciels puissants et fiables.
Aujourd’hui, on estime à un semestre-étudiant(e) le volume de travail nécessaire à la réalisation d’un compilateur standard; et ce, en dépit du cas particulier du langage Ada, dont le premier compilateur fut beaucoup plus difficile à valider que prévu en 1983.
Modèle Analyse et Synthèse
Les compilateurs actuels sont le plus souvent conçus sur le modèle Analyse et Synthèse qui consiste à dissocier deux parties distinctes:
▼ La partie Avant ou Frontale(« front-end ») qui analyse le programme source, conformément à la définition du langage compilé, indépendamment du langage cible.▼ La partie Arrière ou Finale (« back-end ») qui produit le code généré, conformément à la définition du langage cible, indépendamment du langage source.▼ Les deux parties communiquent entre elles via une ou plusieurs structures de données intermédiaire, le plus souvent des tables et/ou des arbres; une approche plus moderne utilise une communication de type API Java .
- 9 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Logiciels cousins des compilateurs
De nombreux outils logiciels analysent des programmes sources:▼ Editeurs structurés▼ Paragrapheurs (ou formateurs)▼ Contrôleurs statiques▼ Interprètes, assembleurs, éditeurs de liens, etc.
Applications utilisant des techniques de compilation
De nombreuses applications font appel aux techniques éprouvées de la compilation, notamment celles de la partie avant:
▼ Traitement de texte▼ Calcul symbolique▼ Compression et encryptage des données▼ Navigateurs (« Browser »)▼ XSLT▼ Génération de documentation (Doxygen)▼ Compilateurs de circuits (silicium)
Passes
On appelle passe, le processus consistant à parcourir en totalité, une fois, la représentation correspondant au texte source d’origine.Pendant une passe, on peut exécuter les traitements correspondant à une ou plusieurs phases de la compilation. Ces phases sont alors traitées séquentiellement ou entrelacées.Le nombre minimum de passes nécessaires à la compilation d’un langage dépend de sa définition:
▼ une seule passe pour le langage PASCAL▼ trois passes au moins pour le langage Ada
- 10 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Fonctionnalités de l ’analyse lexicale
c’est la phase 1 du processus de compilation; ses principales fonctions consistent à :
▼ lire le texte source ▼ analyser ce texte conformément à la définition lexicale du langage compilé▼ découper le flot d’entrée en unités lexicales:
♠ mots clés ou réservés♠ constantes entières, réelles, …♠ identificateurs♠ séparateurs, opérateurs, etc.
▼ éliminer certaines unités inutiles pour la compilation: ♠ espaces et caractères spéciaux, ♠ commentaires, etc.
Flot d ’entrée
le texte source, caractère par caractère
Flot de sortie
des unités lexicales ou lexèmes (« tokens »)
Interactions
l’analyseur lexical entretient des interactions avec les composants suivants:
▼ le gestionnaire de la table des symboles, qui mémorise et identifie les identificateurs▼ l’analyseur syntaxique, qui reçoit le flot des lexèmes▼ une mémorisation du texte source pour l’environnement de développement: éditeurs, messages d’erreurs, debuggers, ...
- 11 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Processeurs Unix utilisant des expressions régulières
• sed – stream editor
• awk – pattern scanning langage
• grep – pattern matching for limited exp.
• egrep - pattern matching for extended exp.
• fgrep – pattern matching for string
• regex, regcmp – compile regular expression
• find, emacs, etc.
Expressions Régulières sous Unix
• Basic RE
• Extended RE
BRE +Concaténation , *, +, ?
• Internationalized RE
extension du jeu de caractères
Autres utilisations des Expressions Régulières
• Perl, Python, Java, PhP, JavaScript
• DTD, XPath, XSLT, etc.
- 12 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Fonctionnalités de l ’analyse syntaxique
c’est la phase 2 du processus de compilation; ses principales fonctions consistent à :
▼ lire le flot de lexèmes issu de l’analyse lexicale ▼ analyser ce flot conformément à la définition syntaxique du langage compilé▼ produire une donnée codant la structure syntaxique reconnue.▼ produire d’éventuels messages en cas d’erreur de syntaxe
Flot d’entrée
Le flot de sortie du lexical, lexèmes par lexèmes
Flot de sortie
Une structure intermédiaire (arbres ou code) et d’éventuels messages d’erreurs
Interactions
l’analyseur syntaxique entretient des interactions avec les composants suivants:
▼ le gestionnaire de la table des symboles▼ le gestionnaire d’erreurs syntaxiques▼ l’analyseur sémantique qui reçoit le flot émis▼ l’environnement de développement: éditeurs structurés, messages d’erreurs, debuggers, etc en établissant une correspondance entre le code intermédiaire et le texte source d’origine
- 13 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Sémantique statique pour Ada83
le contrôle de type pour des programmes Ada comprend les opérations suivantes:
▼ importation du contexte de compilation ▼ calcul de la portée des identificateurs de l’unité de compilation▼ calcul de la visibilité en fonction des mécanismes d’importations, de masquages, d’homonymie, et de surcharge▼ instanciation des génériques▼ identification, cad. résolution des noms étendus▼ contrôle du typage
Résolution de la surcharge en Ada
▼ algorithme original en 3 passes: descente, montée, descente sur l’arbre de dérivation▼ algorithme amélioré en 2 passes: montée, descente.
Résolution de l'héritage en Java, C++, Ada95
▼ construction de la relation d'héritage▼ résolution du typage et de la surcharge▼ résolution des envois de messages
- 14 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Transparent 10
Structures et langages intermédiaires
Arbresde dérivation de syntaxe abstraiteattribués
Graphesd'importationd'héritaged'optimisation de code
Tablesde symbolesvisibilité typage
Langages triplets, quadruplets, polonaisemachine abstraite
- 15 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Historique et Etat de l ’art
Le couple Lex & Yacc [1975 & 74] est le premier essai concluant pour réaliser un métacompilateur utilisable en pratique.
▼ Au niveau lexical:● la génération est complète● les performances sont quasi optimum● le format rigide et la syntaxe ont mal vieilli● les messages d’erreurs sont pauvres ou inexistants
▼Au niveau syntaxique● la génération se fait à partir de grammaires sous-classes des LR(1)● les performances obtenues sont optimum● la gestion des erreurs est problématique
▼Au niveau sémantique● la traduction est synchronisée par la syntaxe car elle est fondée sur un seul attribut synthétisé.
Les originaux Lex et Yacc ont été revisités plusieurs fois, et récemment par GNU, sous le nom de Flex et Bison. Ces versions corrigent certains défauts, mais ne révolutionnent pas les produits.
D’autres essais ont été réalisés dans des cadres théoriques, notamment à l’aide des Grammaires d’Attributs [Knuth, 1968] mais ces expériences de laboratoires ont manqué soit de performances, soit de diffusion, pour être réellement utilisables en pratique.
- 18 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Définition lexicale Ada norme 83
▼ vocabulaire terminal : ISO norme 646 - 7 bits▼ séparateurs: caractère espace, de formatage, fin de ligne▼ unités lexicales:
● 16 délimiteurs simples: & ‘ ( ) * + , - . / : ; < > = |● 10 délimiteurs doubles: => .. ** := /= >= <= << >> <>● 63 mots clés réservés : abort, abs, .., with, xor● les identificateurs● les littéraux
♠ numériques♠ décimaux♠ basés♠ caractères♠ chaînes
● les commentaires
Règles de reconnaissance
▼ majuscules et minuscules sont confondues▼ toute unité est reconnue « on-line » dans le flot en entrée sans recours à l’analyse syntaxique:
=> les opérateurs sont reconnus comme les autres délimiteurs
=> les opérateurs préfixés (par ex ¨+ ¨) sont reconnus comme des chaînes littérales
=> les attributs (par ex. first, last) et les types de base (par ex INTEGER, FLOAT) sont reconnus comme des identificateurs
- 19 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Définition lexicale de Java
▼ vocabulaire terminal : Unicode 1.1.5▼ séparateurs: espace, tabulation, fin de ligne▼ unités lexicales:
● 9 délimiteurs simples: [ ] { } ( ) , . ; ● 37 opérateurs simples ou doubles:● 50 mots clés réservés : abstract , . . , while● les identificateurs● les littéraux ,
♠ entiers♠ flottants♠ booléens♠ référence♠ caractères♠ chaînes
● les commentaires
Règles de reconnaissance
▼ majuscules et minuscules sont différenciées▼ toute unité est reconnue « on-line » dans le flot en entrée sans recours à l’analyse syntaxique:▼ on cherche l'unité la plus longue (reconnaissance "greedy")
- 22 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Propriétés des langages rationnels
Théorème (définition): L est un langage rationnel ssi:
▼ L peut être défini par une expression régulière (forme de Kleene)▼ il existe une grammaire G linéaire à gauche (à droite), et L = L(G)▼ il existe un automate fini A qui reconnaît L ♦
Théorème (déterminisation): Soit A un automate fini non déterministe qui reconnaît L, il existe un algorithme permettant d'obtenir un automate fini déterministe qui reconnaît L ♦
Théorème (minimisation): Tout langage rationnel est reconnu par un automate fini déterministe minimal en nombre d'états . Cet automate est unique à un isomorphisme prés ♦
Théorème (clôture): Les langages rationnels sont clos pour les opérations suivantes: concaténation, union, répétition, intersection, complémentaire ♦
Théorème (décidabilité): Pour les langages rationnels, définis par une grammaire régulière G ou un automate fini A, les questions suivantes sont décidables:
▼ tester si L(G) ou L(A) est vide▼ tester si L(G1) = L(G2) ou L(A1)=L(A2) ♦
Remarque: On peut étendre les expressions régulières via des méta-opérateurs pour augmenter les facilités de description de l’utilisateur sans en modifier la puissance théorique (cf les définitions de lex, chap. 3)
- 23 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Processus de reconnaissance
▼ définition: un ensemble R de règles: Expk => Actionk
▼ résolution des ambiguïtés:● on reconnaît le plus long motif possible (en entrée)● en cas de motifs multiples, on choisit celui qui correspond au premier modèle dans l’ordre des règles
Reconnaissance par Automate fini non déterministe (AFND)
▼ on construit un AFND à partir de R▼ l ’analyseur à générer est la programmation d’un algorithme simulant le fonctionnement d’un AFND▼ complexités dans le pire des cas:
● en place: O(|R|) = temps de construction de AFND● en temps: O(|R| * |source|)
Reconnaissance par Automate fini déterministe (AFD)
▼ on construit un AFD soit en déterminisant l’AFND ci-dessus, soit directement à partir de R▼ l’analyseur à générer est la programmation d ’un algorithme simulant le fonctionnement d’un AFD▼ complexités dans le pire des cas:
● en place: O(|2R|) = temps de construction de AFD● en temps: O(|source|)
Reconnaissance Paresseuse
▼ on utilise un AFD sans construire à priori l’ensemble des transitions; elles ne sont calculées que sur demande.▼ complexités en pratique:
● en place: O(|R|)● en temps: O(|source|)
- 25 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Généalogie
Lex a été créée par les laboratoires Bell sous Unix en 1975Il existe une version GNU dénommée Flex, qui améliore les fonctionnalités de Lex et qui peut être utilisée en mode compatible Lex.Il existe des versions spécifiques de Lex ou Flex pour :
● Ada● Eiffel, C++● Java
Entrée de lex:
L’entrée de lex est une grammaire lexicale, cad un ensemble de règles lexicales associant:
▼ des expressions régulières étendues pour augmenter le confort de l’utilisateur▼ des actions sémantiques programmées en C
Sorties
Lex construit un source C lex.yy.c, qui implémente unanalyseur lexical sur la base d’un automate fini déterministe réduit correspondant à la grammaire lexicale donnée en entrée. La compilation du source lex.yy.c génère une fonction de découpage: yylex()
Interactions
▼ avec Yacc, via la fonction yylex()▼ avec la table des symboles, via la programmation en C
Utilisations sous unix
$ lex anal.lex $ flex anal.lex => lex.yy.c$ cc lex.yy.c -ll $ gcc lex.yy.c -lfl => yylex()
- 26 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Expressions régulières
▼ en forme de Kleene via des méta-opérateursinfixe • (pour la concaténation, le point est toujours
omis en Lex)infixe | (alternative ou choix entre termes)postfixe(répétition 0 ou plusieurs fois d’un terme)( ) pour les priorités entre opérateurs
▼ exemple: les identificateurs CLettre_Tiret = a|b|..|z|A|..|Z|_Lettre _Tiret _Chiffre = Lettre_Tiret | 0|..|9 Id = Lettre _Tiret • Lettre _Tiret _ChiffreId = (a|b|..|z|A|..|Z|_)•(a|b|..|z|A|..|Z|_| 0|..|9)
Expressions régulières étendues
▼ méta-opérateurs de confort[ ] pour les énumérations associées à -+ pour la répétition une fois ou plus? pour 0 ou 1 fois
. comme caractère « joker » sauf \n^ pour le complémentaire dans un [ ]
▼exemples● les chiffres: [0-9]● les lettres: [a-zA-Z]● les entiers: [0-9]+● les identificateurs C: [a-zA-Z_] [a-zA-Z0-9_]*● les chaines de caractères sans " : \" [^ "]* \" ● les chaines de caractères Ada avec " : \" ([^ "] | \"\")* \" ● les commentaires lignes Ada: - - .*
- 27 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Exemples de définitions
Minuscule [a-z]Majuscule [A-Z]NonLettre [^a-zA-Z]Lettre ({Minuscule}|{Majuscule})Chiffre [0-9]Mot {Lettre}+Motdauplus7L {Lettre}{1, 7}Entier [0-9]+EntierSigné (("-"|"+")?{Entier})
Exemples d’expressions
(i|I)nt(eger)? /* deux formes dont un raccourci */(c|C)har(acter)? /* avec ou sans capitale */--.* /* les commentaires ada sur une ligne */[ \t\n]+ /* des caractères à ignorer en général */" " |\t |\n ; /* idem ci_dessus */
Quelques erreurs classiques (lexicales ou sémantiques ?)
exp; reconnaît exp;[class|public] reconnaît c l a s s p u b i |[^"class"] reconnaît tout sauf a c l s "
ALPHA ({L}|{C}) les () sont obligatoires pour l’*
ID {L}( {ALPHA} ) * les {} toujours
MC class public => « unreconnizable rule »
<ETAT> exp => « unreconnizable rule »
- 28 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Définitions lex
C’est l'association de symboles à des expressions étendues:Lettre [a-z A-Z]Chiffre [0-9]Alphanum ({Lettre}|{Chiffre})
Les définitions doivent tenir sur une seule ligne! Ni retour chariot, ni espace dans les expressions
Syntaxe des Règles de lex
Une Règle est une Expression (éventuellement associée) à une Action
▼ les Expressions commencent en début de ligne
▼ pas de commentaire en début de ligne, seulement après les Actions
▼ un espace au moins ou mieux une tabulation entre les Expressions et les Actions
▼ l’opérateur | indique que l’action associée est celle de la ligne suivante:
begin |end printf(« mot clé ») ;
▼ les actions sont des instructions C qui doivent être regroupées dans un bloc instruction {}
▼ l’absence d’action ou ";" => action vide, cad: empèche la recopie par défaut de l'unité reconnue sur la sortie
- 29 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Compilation des définitions Lex
• toutes les définitions sont substituées dans les expressions régulières des règles• soit R l'ensemble de règles {Ei->Ai} trié dans l'ordre du source lex
Exécution des règles Lex
• le flot d'entrée est analysé séquentiellement de gauche à droite• deux curseurs parcours le flot:
▼ CD, pour le début du lexème courant▼ CC, pour le caractère courant
• on avance CC pour obtenir la plus longue chaîne possible reconnue par une expression Ei de R• s'il existe plusieurs Ei possibles pour la chaîne la plus longue reconnue, on choisit la première dans l'ordre du source (Ek)• on exécute les actions Ak, associées à Ek• si aucune expression ne reconnaît le caractère CC, on recopie le caractère courant sur le flot de sortie. • tant que le flot d'entrée n'est pas vide, les curseurs CD et CC sont positionnés à CC+1
Application aux reconnaissances lexicales
• on reconnaît ensemble les mots réservés, les chaînes de caractères et les commentaires dans un langage:
▼ si une chaîne contient un mot réservé, il n’est pas reconnu car la chaîne est un lexème plus long▼ Idem pour les commentaires▼ Et ce, quelque soit l’ordre des expressions dans le code Lex
- 30 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Espaces ou tabulations
ni en début de ligne, ni dans les expressions régulièresobligatoires entre expressions et actions
commentaires
seulement en fin de lignes dans la section Règles
Substitution des { }
attention aux priorités après substitution
Passage à la ligne impossible dans une expression
Le fichier d'entrée doit se terminer par un retour chariot
Quelques erreurs classiques (lexicales ou sémantiques ?)
exp; reconnaît exp;[class|public] reconnaît c l a s s p u b i |[^"class"] reconnaît tout sauf c l a s s"
ALPHA ({L}|{C}) les () sont obligatoires pour l’*
ID {L}( {ALPHA} ) * les {} toujours
MC class public => « unreconnizable rule »
<ETAT> exp => « unreconnizable rule »
- 31 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Contexte gauche inclusif
%s ASUIVRE%%……. /* actifs aussi dans l'état ASUIVRE */debut {BEGIN ASUIVRE ;}< ASUIVRE >suite {BEGIN 0 ;}
Contexte gauche exclusif
%x ASUIVRE%%……. /* NON actifs dans l'état ASUIVRE */debut {BEGIN ASUIVRE;}< ASUIVRE >suite {BEGIN INITIAL;}
0 INCBEGIN
EXCR ss <>ou av
<INITIAL>BEGIN
R ss <>ou av
<INITIAL>
R av<EXC>
- 32 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Recouvrement de lexèmes
%%mot-composé {nmotComp++; REJECT;}mot {nmot++; REJECT;}composé {nmot++; REJECT;}
● => coût élevé en raison du retour arrière
Redécouper avec un autre état
%%mot {BEGIN AUTRE_ETAT; yyless(0); }
Redécouper des lexèmes
%% chaînes avec \ " \" [ ^ " ]* \ " {if (yytext[yyleng-2] == ‘ \\ ’) {
yyless(yyleng -1); /* garder le " */yymore() ; /* append la suite */
} else { . . . . /* traitement de la chaîne */ }
Traitement général, puis spécifique
%%{MC} {styleMC(); ECHO; REJECT;}class {traiterClasse();}
- 33 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
PILE DES ETATS
%s OK A B
%option stack
a|b {yy_push_state(OK);
yy_push_state(A); }
<A>a ECHO;
yy_push_state(B);
<B>b yy_pop_state();
BEGIN(yy_top_state() );
End Of File
<QUOTE><<EOF>> {
error (« quote non ferméé");
yyterminate();
}
<<EOF>> {if(YY_START==OK) printf("OK\n");
else printf("KO\n");
yyterminate(); }
- 34 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Compilation des définitions Lex
• "Preprocessing" toutes les définitions sont substituées dans les expressions régulières des règles
• "Base de Règles" soit R l'ensemble de règles {Ei->Ai} trié dans l'ordre du source lex
Exécution des règles Lex
• le flot d'entrée est analysé séquentiellement de gauche à droite• au départ, l'analyseur est dans l'état INITIAL ou 0
Itération• on évalue la Base de Règles "ACTIVES" RA pour l'Etat Courant• deux curseurs parcours le flot:
▼ CD, pour le début du lexème courant▼ CC, pour le caractère courant
• on avance CC pour obtenir la plus longue chaîne possible reconnue par une expression Ei de RA • s'il existe plusieurs Ei possibles pour la chaîne la plus longue reconnue, on choisit la première dans l'ordre du source (Ek)• on exécute les actions Ak, associées à Ek, y compris
▼d'éventuels changements d'Etat (par BEGIN ou yy_push_state)▼retour arrière par REJECT▼modification des entrées/sorties par yyless, yymore▼arret par yyterminate()
• si aucune expression ne reconnaît le caractère CC, on recopie le caractère courant sur le flot de sortie. • tant que le flot d'entrée n'est pas vide, les curseurs CD et CC sont positionnés à CC+1
Application aux reconnaissances lexicales
• on reconnaît ensemble les mots réservés, les chaînes de caractères et les commentaires dans un langage:
▼ si une chaîne contient un mot réservé, il n’est pas reconnu car la chaîne est un lexème plus long▼ Idem pour les commentaires▼ Et ce, quelque soit l’ordre des expressions dans le code Lex
- 35 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
voir http://flex.sourceforge.net/manual/Patterns.html
échappements caractères
\176 // le caractère ~ en Octal\x7E // le caractère ~ en Hexa
options de matching: i –i (casse) x –x (blancs) s –s(retour chariot
dans .)
(?i:ab7) == ([aA][bB]7)(?-i:aB) == (aB)(?x:a b) == ("ab")(?x:a\ b) == (?x:a" "b) == ("a b")(?s:.) == [\x00-\xFF](?-s:.) == [^\n](?ix-s:a . b) == ([Aa][^\n][bB])
classes de caractères
[:alpha:] [:upper:] [:lower:] [:xdigit:] [[:alnum:]] == [[:alpha:][:digit:]] == [a-zA-Z0-9][[:blank:] [:punct:]] // des séparateurs
négation de classes
[:^alpha:]
- 36 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Options LEX
/* LEX gère la ligne courante */%option yylineno
/* pour utiliser la pile des états LEX */%option stack
YY_USER_
// routine à exécuter avant le début de l'analyse LEX
#define YY_USER_INIT printf("#Règles: %d\n",YY_NUM_RULES);
// routine à exécuter avant chaque action LEX (règle reconnue)
#define YY_USER_ACTION printf("Règle active: %d =>", yy_act);
- 37 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
#include en lex avec les buffers multiples
%{
#define MAX_INCL 10 // version récursive
int incl_stack_ptr= 0 ; YY_BUFFER_STATE incl_stack[MAX_INCL] ;
%}
FILENAME [a-zA-Z0-9$_\/.\-]+
%x INCL
%%
\#include[ \t]+\" {BEGIN INCL;}
<INCL>\"[ \t\n]+ {BEGIN 0;}
<INCL>{FILENAME} {
if (incl_stack_ptr >= MAX_INCL) {fprintf( stderr, "Trop d'includes "); exit(1);}
incl_stack[incl_stack_ptr++] = YY_CURRENT_BUFFER;
yyin = fopen(yytext, "r");
if (!yyin) {fprintf( stderr, "\nImpossible d'ouvrir le fichier%s\n", yytext); exit(1);}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE) );
BEGIN 0;
}
<<EOF>> { if (--incl_stack_ptr < 0) yyterminate();
else { yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer( incl_stack[incl_stack_ptr] ); }
BEGIN INCL; // pas encore vu la fin" de #include
}
%%
- 39 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Vocabulaire utilisé
lettre majuscule: + lettre minuscule
+ chiffre+ tiret
Définition
▼ commence par (au moins) une lettre▼ continue par 0 ou plusieurs caractères alphanumériques
● qui peuvent être précédés par un tiret
Identificateurs corrects
XX1XxX_11X _X_x
Identificateurs incorrects
X+1X_XX_X__X
0 Identl
l | c
_
Id2l | c
- 40 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Vocabulaire utilisé
lettre majuscule
+ lettre minuscule+ chiffre
+ tiret+dollar
Définition
▼ commence par (au moins) une lettre ou tiret ou dollar▼ continue par 0 ou plusieurs caractères alphanumériques
Identificateurs corrects
XX1Xx_X_11$_X__
Identificateurs incorrects
X+1X
0 Ident
l | c| $ | _
l | $ | _
- 41 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Vocabulaire utilisé
tout l’alphabet sauf \n
Définition
▼ commence par "▼ continue par 0 ou plusieurs caractères :
● chaque " dans la chaîne doit être doublé "" ▼ ne contient pas de fin de ligne
▼ se termine par "
Reconnaissance correcte
""
" "
"xxxxxx xx xxxxx """""" """" "
Reconnaissance incorrecte
"xxxxxx"+++" xx"++" xxxxx "
"xxxxxx"
0 Ch"
. | ""
"
Err
\n
- 42 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Vocabulaire utilisétout l’alphabet
Définition ▼ Définition
▼ commence par "▼ continue par 0 ou plusieurs caractères :
● chaque " dans la chaîne doit être backslashé \" ▼ se termine par " qui ne doit pas être backslashé
Reconnaissance correcte
""
" ""xxxxx xx xxxx ""\""" \"\" " "xxxx
xx"
Reconnaissance incorrecte
"xxxxxx"+++" xx"++" xxxxx "" \\" "" \"
- 43 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Vocabulaire utilisé
tout l’alphabet
Définition
▼ commence par "▼ continue par 0 ou plusieurs caractères :
● chaque " dans la chaîne doit être backslashé \" ▼ se termine par " qui ne doit pas être backslashé
Reconnaissance correcte
""
" "
"xxxxx xx xxxx ""\""" \"\" " " \\\" \\"
Reconnaissance incorrecte
"xxxxxx"+++" xx"++" xxxxx "" \\" "" \"
0 Cha"
. | \n
"
Sla
\
[^"\\]
- 44 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Quelques mots clés de C (en minuscules obligatoirement):
auto | extern | static | typedef | register |short | int | long | char | float | double | struct | union | sizeof |if | else | do | while | for | case | switch | default |return | break | continue | goto
Les identificateurs de C (en minuscules ou majuscules):
• commence par une Lettre ou un Tiret• se poursuit éventuellement par une Lettre , un Chiffre ou un Tiret
- 45 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Commentaires en C(/* */)
▼ texte entre entre /* et */▼ sur une ou plusieurs lignes▼ ne contiennent pas */▼ mais peuvent contenir * si pas suivie de /
Automate Fini ND
Automate Fini D
0 COM/*
. | \n
0 COM/*
tout sauf *
*
/
ET
tout sauf * et /
- 46 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Commentaires en C(/* */)
▼ texte entre entre /* et */▼ sur une ou plusieurs lignes▼ ne contiennent pas */▼ mais peuvent contenir * si pas suivie de /
Automate Fini ND
Automate Fini D
0 COM/*
. | \n
0 COM/*
tout sauf *
*
/
ET
tout sauf * et /
- 47 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Commentaires en C(/* */)
▼ texte entre entre /* et */▼ sur une ou plusieurs lignes▼ ne contiennent pas */▼ mais peuvent contenir * si pas suivie de /
Automate Fini ND
Automate Fini D
0 COM/*
. | \n
0 COM/*
tout sauf *
*
/
ET
tout sauf * et /
- 48 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Commentaires en C(/* */)
▼ texte entre entre /* et */▼ sur une ou plusieurs lignes▼ ne contiennent pas */▼ mais peuvent contenir * si pas suivie de /
Automate Fini ND
Automate Fini D
0 COM/*
. | \n
0 COM/*
tout sauf *
*
/
ET
tout sauf * et /
- 51 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Automate Fini ND pour les chaînes
0 Cha"
. | \n
"
- 52 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Automate Fini ND pour les chaînes
0 Cha"
. | \n
"
- 53 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Automate Fini ND pour les chaînes
Automate Fini D équivalent
- 54 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Automate Fini Déterministe pour les chaînes
chaînes correctes:
" \\ "
" \\\" "
chaînes incorrectes:
" \"
" \\\ "
0 CHA"
"
. | \n
\
tout sauf \ et "
SLA
- 55 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Spécification:
▼ lire un texte en entrée▼ reconnaître les mots comme des suites de caractères séparées par des espaces ou des tabulations ou des fins de ligne▼ décompter les mots et les lignes lus dans le texte▼ décompter tous les caractères y compris les caractères spéciaux: espaces, tabulations, fin de ligne.
- 56 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Processeurs Unix utilisant des expressions régulières
• sed – stream editor
• awk – pattern scanning langage
• grep – pattern matching for limited exp.
• egrep - pattern matching for extended exp.
• fgrep – pattern matching for string
• regex, regcmp – compile regular expression
• find
• emacs
• etc.
Autres utilisations des Expressions Régulières
• Perl, Python, Java
• PhP, JavaScript
• Dreamweaver
• DTD, XPath, XSD, XSLT, etc.
- 57 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Exemples sous egrep
egrep '[A-Z][a-zA-Z]{5,}' Noms.txt
/* lignes qui contiennent des noms de 6 lettres au moins commençant par une majuscule */
egrep '([a-zA-Z]+)\1' Noms.txt
/* lignes qui contiennent des mots de la forme ww */
egrep '([a-zA-Z]+).\1' Noms.txt
/* lignes qui contiennent des mots de la forme wxw */
egrep -c '<[^<>]+>' Source.html
/* compter les balises html */
egrep -c '<[^/\!][^<>]+>' Source.html
/* compter les balises ni fermantes ni commentaires */
Standard POSIX (voir Wikipédia)
[:space:] [:blank:] [:punct:]
[:alpha:] [:lower:] [:upper:]
[:digit:] [:alnum:]
Options sous grep
> grep -E /* expressions étendues comme egrep */
grep -P /* expressions Perl ou PCRE*/
Perl Compatible Regular Expressions
sous Emacs \( \) \|
- 58 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
modèle de code Java à compléter
// ici conversion Franc-Euro
import java.util.regex.Pattern;import java.util.regex.Matcher;
public class ConversionMonnaie {
String expreg = "([0-9]+\\.[0-9]{2})([FE])";String monnaie;float montant;
Pattern p = Pattern.compile(expreg);Matcher m = p.matcher(args[0]);
try {if (m.find()) {
montant = (newFloat(m.group(1))).floatValue(); monnaie = m.group(2) ;
// etc.
- 59 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
modèle de code Python à compléter
// ici conversion Franc-Euro
import re ;
expreg = re.compile('([0-9]+\.[0-9]{2})([FE])')m = expreg .match(line)
if m :montant = m.group(1)monnaie = m.group(2) ;
// etc.
- 60 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Exemples sous Perl
perl -ne 'print if/[A-Z][a-zA-Z]{5,}/;' Noms.txt
/* imprime les lignes qui contiennent des noms de 6 lettres au moins commençant par une majuscule */
perl -ne 'print if /([a-zA-Z]+)\1//;' Noms.txt
/* imprime les lignes qui contiennent des mots de la forme ww en les effaçant*/
- 61 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
Exemples sous Perl
perl -ne 'tr/a-z/A-Z/;print;' Noms.txt
/* imprime le fichier en majuscules */
perl -ne 'print if m&[A-Z][a-zA-Z]{5,}&;' Noms.txt
/* imprime les lignes qui contiennent des noms de 6 lettres au moins commençant par une majuscule */
perl -ne 'print if s/([a-zA-Z]+)\1//;' Noms.txt
/* imprime les lignes qui contiennent des mots de la forme ww en les effaçant*/
Conversion de monnaie (script partiel)
$reponse=<STDIN> ;
chomp($reponse); // enlève le \n final
if ( $reponse = ~ m/[0-9]+\.[0-9]{2}) ([FE])/ )
{
$montant = $1 ;
$monnaie = $2 ;
// etc.
- 62 -
16/09/2014
Langages et Documents - Traitement Lexical des Textes SI-4– 2008-09 Paul Franchi
replace avec des "exp reg"function SyntaxColored(js){if (!js || !js.replace) return "";js=js.replace(/\r/g,'\n');js=js.replace(/</g,'<').replace(/>/g,'>');
var parens = /([\]\[(){}]+)/g;var comments = /(\/\/.+|\/\*(.|\n)+?\*\/)/g;var keywords = /\b(function|var|if|isNaN|return|if|else|for|while|new|continue|switch|case|true|false|prototype|constructor|caller|Number|Date|Object|String|Function|Array|RegExp|Boolean|Math)\b/g;var strings = /((["'])(?:.*?(?:[^\\](?:\\\\)*|[^\\]))?\2)/g;var numbers = /\b(-?(?:\d+|\d*\.\d+)\b)/g;
js=js.replace(strings,'<span class="string">$1<\/span>');js=js.replace(parens,'<span class="paren">$1<\/span>');js=js.replace(numbers,'<span class="number">$1<\/span>');js=js.replace(keywords,'<span class="keyword">$1<\/span>');js=js.replace(comments,'<span class="comment">$1<\/span>');if (document.all) js=js.replace(/\n/g,"<br>").replace(/ /g," ").replace(/\t/g," "); //IE-specific hackjs=js.replace(/<\/span>\n/g,"<\/span> \n");
return js;