Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
1. Introduction
JFlex est un générateur d'analyseurs lexicaux pour Java. Il génère automatiquement un programme écrit
en Java. Cette génération se fait à partir d'un fichier de spécifications qui doit suivre une certaines
syntaxe.
Analyseur lexicale
Un analyseur lexical découpe un flot d'entrée de caractères en unités lexicales (tokens), comme par
exemple les entiers, les commentaires, les mots-clés. Ces unités lexicales correspondent à des
expressions régulières.
L'analyse lexicale correspond donc à une détection de ces unités lexicales. De plus, pour chaque unité
lexicale reconnue, on retient sa classe et sa valeur qui seront utilisés dans la construction de l'arbre de
syntaxe.
Code de l'utilisateur
%%
Options et déclarations de macros
%%
Règles lexicales
Code de l'utilisateur
La première partie contient du code Java qui se retrouvera dans le fichier généré, copié tel quel en début
de fichier. Essentiellement, le code écrit ici contiendra des chargements de packages et de librairies.
%class nom; demande à Jflex de nommer le fichier produit «nom.java». La classe contenue dans
le fichier sera elle aussi nommé «nom».
%cup; permet d'utiliser Jflex avec CUP (générateur d'analyseurs syntaxiques).
%line et %column; permet de compter les lignes et les colonnes dans les variables yyline et
yycolum. Cela peut être utile lorsque l'on veut indiquer où se trouve une erreur dans le fichier
d'entrée.
%standalone; permet d'utiliser Jflex seul. Ainsi, la classe généré contiendra une fonction
main.Dans la suite du TP, on utilisera toujours cette option car pour le moment on utilisera
JFLex seul.
%eof {
code
%eof } permet de préciser le code ou le token que l'on souhaite envoyer lorsque la fin de fichier
est rencontrée ;
%{
code
%} le code est inséré en début de la classe générée ;
Les déclarations de macros permettent des abréviations dans la définition des règles lexicales. Par
exemple : ENTIER = [0-9] +. Ainsi on pourra utiliser par la suite l'expression régulière [0-9]+ en notant
simplement ENTIER.
Règles lexicales
La troisième partie contient les règles basés sur des expressions régulières. Une règle à base
d'expressions régulières a pour syntaxe :
expression { action }
Les actions associés aux règles correspondent à du code java exécuté lorsque la règle s'applique.
Dans l'exemple ci-dessous, l'action est simplement d'afficher le mot ENTIER lorsque un entier est lu
dans l'entrée. L'action pourrait aussi ne comporter aucune instruction, l'analyseur boucle sans rien faire
et va chercher de nouveau une règle à appliquer.
Exemple :
Le fichier suivant produit un analyseur lexicale qui affiche ENTIER pour chaque suite de chiffres
repérée, et FLECHE pour chaque suite de caractères ‘->’ :
%%
%class exo5
%unicode
%standalone
integer=[0-9]+
%%
{integer} {System.out.println("ENTIER") ;}
"->" {System.out.println("FLECHE") ;}
Pour l’instant, on affiche juste les lexèmes, mais plus tard, on connectera JFLEX à un générateur
d’analyseur syntaxique CUP.
Remarques : Les blancs et les tabulations sont ignorés par jflex pour la définition des
expressions régulières (on peut donc les utiliser pour rendre les expressions plus lisibles), sauf
quand ils sont entre guillemets ou crochets.
Règles lexicales
Cette dernière section associe à des expressions régulières une action que l'analyseur généré doit
effectuer quand il rencontre un symbole reconnu par une de ces expressions régulières. Une telle
association est appelée règle lexicale.
Syntaxe
Les expressions régulières utilisées sont celles introduites en section précédente. On peut faire
précéder une expression régulière par ^ pour spécifier que cette expression régulière ne doit être
reconnue qu'en début de ligne.
Une action est de la forme <code Java>. On associe une action à une expression.
Travail à réaliser
Exercice1
En utilisant JFlex, générer un analyseur lexical qui affiche et compte le nombre d’entiers et de
réels dans un fichier texte
Exercice2
Ecrire une spécification JFlex permettant de calculer le nombre de consonnes, de voyelles et de
caractère de ponctuation dans un fichier
Exercice3
Ecrire une spécification JFlex permettant de calculer la moyenne des entiers rencontrés dans un
fichier
Exercice4
Écrire une spécification JFlex permettant de calculer le résultat d’une expression arithmétique.
On supposera que les opérateurs sont associatifs à gauche et qu’ils ont la même priorité
Exemple : 34+12*2=(34+12)*2=46*2=92
Exercice5
Créer un analyseur lexical qui supprime les commentaires commençant par //.
Exercice6
Écrire une spécification JFlex permettant de vérifier le bon parenthésage d’un fichier. On
supposera que l’on utilise que la paire ()
Exercice7
Écrire une spécification JFlex permettant de vérifier le bon parenthésage d’un fichier. On
supposera que l’on utilise que les paires (), [],{}
2. Les automates
L’analyse lexicale utilise des automates. Partant des expressions réguilères, JFlex procède en 3
étapes :
— construction d’un automate non détermiste (NFA = Non-deterministic Finite Automaton)
— déterminisation. : Obtention d’un premier DFA (Deterministic Finite Automaton)
— calcul d’un automate déterministe minimal
Lors de l’exécution de jflex, le nombre d’états de chacun des automates est d’ailleurs affiché.
Il est possible de visualiser les automates construits par JFlex en mode texte avec l’option --dump,
ou en mode graphique avec l’option --dot (dot/graphviz est un ensemble d’outils permettant la
visualisation de graphes)
Taper dans l’invite de commande : java –jar jflex-full-1.7.0.jar –dot exemple.txt pour compiler.
Travail à réaliser
Exercice8
Construire en utilisant JFLEX un automate pour l’ensemble de mots qui se termine par abb et
afficher l’automate à l’aide de l’outil GraphViz.
Exercice9
Donner un programme d’analyseur lexical qui simule l’automate ci-dessous.
Exercice10
Construire un automate déterministe pour le langage L des identificateurs, composés d’une lettre
au moins, éventuellement suivie de chiffres, de lettres et de ‘_’, et sa longueur ne doit pas
dépasser 10 caractères.