Table des matières

Automate reconnaissant une expression

Présentation

Il est fréquent que l'on doive reconnaître dans un texte la présence d'expressions respectant un certain modèle. Le cas typique est la reconnaissance d'une adresse mail : On voudrait reconnaître quelque chose comme :

[des lettres, chiffres et points]@[au moins 3 lettres].[2 ou 3 lettres].

C'est le domaine des expressions régulières. L'expression régulière correspondant à ce qui est écrit au dessus serait :

[A-Za-z0-9.]+@[A-Za-z]{3,}.[A-Za-z]{2,3}

Notre but ici sera de produire un programme capable de reconnaître si une chaîne de caractère respecte une expression régulière très simple.

Exemple

soit l'expression "(aa*|b)c".

Voici quelques exemples qui valident l'expression ou non :

Utilisation d'un graphe

Pour modéliser l'expression, on réalise un automate qui a la forme d'un graphe. Voici le graphe pour le cas précédent.

Règles de fonctionnement

Le graphe étant défini, on se demande si une certaine chaîne est valide. Par exemple "aac" est-elle valide (la réponse devrait être oui).

  1. Au démarrage, on active le nœud initial,
  2. on active tous les nœuds qui peuvent être atteints depuis une un nœud actif par des arêtes sans étiquette,
  3. s'il reste un caractère à lire dans la chaîne à tester, on le lit. soit car se caractère.
    1. On note tous le nœuds pouvant être atteints depuis un nœud actif, par une arête dont l'étiquette est car.
    2. On désactive tous les nœuds, puis on active tous ceux que l'on vient de noter.
    3. On retourne au point 2.
  4. sinon, c'est terminé. Si le nœud final est actif, alors la chaîne testée est valide.
  5. À n'importe quel moment, s'il n'y a plus aucun nœud actif, on peut s'arrêter, la chaîne n'est pas valide.

Exemple de mis en œuvre

Test de la chaîne "aac".

De l'expression régulière au graphe

On se demande ici comment on peut obtenir le graphe.

La méthode consiste à créer des graphes élémentaires puis à les assemble pour des expressions plus complexe.

Simple lettre

Le graphe correspondant à l'expression "a“ est donné ci-dessus.

Alternative, OU

On a deux expressions "exp1" et exp2" représentée par les graphes G1 (en bleu) et G2 (en violet).

On souhaite obtenir le graphe représentant le choix exp1 OU exp2, que l'on notera "exp1|exp2".

J'ai marqué en pointillé les nœuds initiaux et finaux de G1 et G2 qui cessent de l'être une fois intégrés dans le graphe complet.

Étoile

On a une expression "exp" associée à son graphe g. On souhaite obtenir le graphe représentant la répétition indéterminée de "exp" ce que l'on notera "exp*".

Concaténation

On a deux expressions "exp1" et exp2" représentée par les graphes G1 (en bleu) et G2 (en violet).

On souhaite obtenir le graphe représentant la suite exp1 exp2 que l'on notera simplement "exp1exp2".

Pour vous entraîner, vous pouvez essayer d'appliquer ces règles pour retrouver le graphe de "(a*|b)c". Sachez cependant que l'application de ces règles de constructions peut conduire à ajouter des nœuds qui pourraient être supprimés. J'en ai supprimé pour alléger le graphe que j'ai donné en exemple. Vous n'obtiendrez donc pas exactement le même, mais ce sera tout comme.

Votre travail

  • Définir une classe de graphe permettant de construire à la main le graphe désiré et d'exécuter les règles de fonctionnement décrites plus haut afin de tester si telle chaîne de caractère est validée par le graphe.
  • Construire le graphe automatiquement à partir d'une expression régulière simple ne contenant que des symboles (par exemple des lettres), le symbole pour l'alternative | et le symbole étoile *, en utilisant les règles de construction ci-dessus.