IFT313 Introduction aux langages formels Froduald Kabanza Département d’informatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313 Convertir un AFN en un AFD Rappel IFT313 © Froduald Kabanza 2 Sujet couvert • Convertir un automate fini non-déterministe en un automate fini. déterministe. • Simuler un AFN IFT313 © Froduald Kabanza 3 Références [1] Sudkamp, T. A.. Languages and Machines. Third Edition Edition. Addison-Wesley, 2005. – Sections 5.6. [2] Appel, A. and Palsberg. J. Modern Compiler Implementation in Java. Second Edition. Cambridge, 2004. – Section 2.4 [3] Wolper, P. Introduction à la calculabilité, 3è édition. Dunod, 2006 – Section 2.6 [4] Aho, A., Lam, M., Sethi R., Ullman J. Compilers: Principles, Techniques, and Tools, 2nd Edition. Addison Wesley, 2007. – Sections 3.7.1 à 3.7.3 IFT313 © Froduald Kabanza 4 Élimination du non-déterminisme La méthode pour convertir un AFN en AFD est appelée « subset construction method » en anglais. La méthode consiste à grouper des ensembles d’états de l’AFN en un seul état de l’AFD : L’idée est de simuler l’exécution parallèle de l’AFN sur une entrée donnée. À chaque étape, nous avons un ensemble d’états dans lequel l’AFN pourrait se trouver si on considérait toutes ses exécutions nondéterministes. Ces états représentent un état de l’AFD. Nous allons encore utiliser cette technique plus tard pour l’analyse syntaxique LR. IFT313 © Froduald Kabanza 6 Idée de base Il y a deux différences fondamentales entre un AFN et un AFD : Transitions sur des chaînes de plus d’un caractère. Non-déterminisme: plusieurs transitions partant d’un même état, sur le même symbole. transitions sur la chaîne vide (‘’, aussi notée ε). Pour obtenir un AFD à partir d’un AFN: Nous commençons par remplacer des transitions sur des chaînes de plus d’un caractère. Nous éliminons ensuite les transitions non déterministes. IFT313 © Froduald Kabanza 7 Idée de base : transitions sur des chaînes L’exemple suivant illustre la procédure pour éliminer les transitions avec des chaînes de caractères: abc 1 1 IFT313 a 3 b 2 4 © Froduald Kabanza c 2 8 Idée de base : éliminer le non-déterminisme L’idée pour éliminer le non-déterminisme est de construire un AFD qui à chaque étape de son exécution mémorise les états dans lesquels l’AFD se trouverait potentiellement avec le même input. Donc un état de l’AFD est un sous-ensemble des états de l’AFN tel qu’illustré par les exemples suivants. (a) a 2 b 3 1 a a {1} {1,2} b b IFT313 a 1 a (b) a 2 {1,3} ε 3 a b a b {1,2,3} b [ab] 4 {4} [ab] a {3} © Froduald Kabanza 9 Fermeture-ε (ε-closure) Pour définir l’algorithme d’élimination du non-déterminisme plus formellement, la notion de ε-closure est nécessaire. Étant donné un ensemble S d’états de l’AFN, ε-closure(S) est l’ensemble des états atteignables dans l’automate, à partir d’un état dans S, et sans consommer un symbole d’entrée; c-à-d., en suivant seulement des transitions ε. Il va de soi que S est dans ε-closure(S). Par extension, pour un état z, ε-closure(z) = ε-closure({z}) IFT313 © Froduald Kabanza 10 Définitions préliminaires Soit succ(s,c) les états successeurs de s sous la transition c Par définition : ε-closure(S) = S {s | s dans succ(s’, ε) avec s’ dans S} On peut maintenant définir l’algorithme epsilon-closure IFT313 © Froduald Kabanza 11 Algorithme epsilonClosure Entrée : S : un sous-ensemble des états de l’AFN succ : la relation des transitions de l’AFN Sortie : ε-closure(S) Méthode : S1 = S do { S2= S1 ; // S2 devient S1 au début de l’itération S3 = {}; // S3 est l’ensemble des états atteignable à partir de S2 for (s in S2) S3 = union(S3, succ(s, ε)); S1 = union(S2,S3); } while (! S1.equals (S2)); // jusqu’à plus de nouvel état atteignable IFT313 © Froduald Kabanza 12 Algorithme replaceStringTransitions Entrée : Un AFN X1 =(N1,A,R1,n0,F) Sortie : Un AFN X2=(N2,A,R2,n0,F) avec transitions à un caractère ou ε Méthode : N2=N1; R2=R1 ; Pour toute transition (s, u,t) dans R2 telle que u =a1…ak (k>1) supprimer (s, u,t) de R2 ajouter des nouveaux états s1,s2,…,sk-1 dans N2 ajouter de nouvelles transitions (s, a1, s1),…,(sk-1,ak,t) à R2 IFT313 © Froduald Kabanza 13 Algorithme removeNondeterminism Entrée : Un AFN X =(N,A,R,n0,F) avec transitions à un caractère ou ε Sortie : Un AFD Y=(D,A,T,d0,P) Méthode : D = 2N // L’ensemble des sous-ensembles de N d0 = ε-closure(n0) P = {d dans D | l’interesction de d et F est non vide} // c-à-d., ensembles des états d ayant un état accepteur T est définie comme suit: Pour chaque a dans A et d dans D {n’|(n,a,n’) R}) T[d][a] = ε-closure ( nd // c-à-d.: T[d][a] est la fermeture-epsilon des états atteignable dans // l’automate X à partir d’un état dans d, le long d’une transition // étiquetée a. IFT313 © Froduald Kabanza 14 Algorithm removeNondeterminism Pour donner une description plus algorithmique : Dtrans(d,a) = epsilonClosure ( trans(n,a)) nd Où trans est la relation de transition de l’AFN X. Autrement dit, il y a une transition de di à dj, étiquetée a, si et seulement si dj=Dtrans(di,a) IFT313 © Froduald Kabanza 15 Algorithm removeNondeterminism Entrée : AFN (N,A,R,n0,F) Sortie : AFD (D,A,T,d0,P) Méthode : P {d dans D | l’interesction de d et F est non vide} //défini comme avant; d0 = ε-closure(n0) D={d0} et d0 est non marqué while (il y a un état non marqué d in D) { marquer d; for (chaque symbole a dans A) { d’= Dtrans(d,a); if (d’ D) {ajouter d’ comme état non marqué dans D;} T[d][a] = d’; }} IFT313 © Froduald Kabanza 16 Récapitulation constructDFAFromNFA(NFA) removeNondeterminism(replaceStringTransitions(NFA)). À la fin de la construction, les états de l’AFD sont remplacés par des nombres. D’autres simplifications sont effectuées sur l’AFD : minimisation. IFT313 © Froduald Kabanza 17 Exemple (AFN) f 2 i 1 ε ε ε 4 9 14 IF 3 a .. . z 0. .. 9 ε [a-z] 5 ε ε 10 8 ID ε NUM ε 13 7 6 [0-9] 12 0 .. . 11 9 15 ERROR IFT313 © Froduald Kabanza ε 18 Exemple (AFD correspondant) f {2,5,6,8,15} i ID [a-hj-z] {1,4,9,14} [0-9] other {3,6,7,8} [a-z0-9] [a-z0-9] {5,6,8,15} [a-z0-9] ID {10,11,13,15} [a-z0-9] NUM {11,12,13} IFT313 ID {6,7,8} [0-9] {15} IF NUM ERROR © Froduald Kabanza [0-9] 19 Récapitulation : produire un scanner à partir d’une liste d’expression régulières Approche : (1) Convertir les expressions régulières en AFNs. (2) Combiner les AFNs. (3) Convertir L’AFN global en AFD équivalent. (4) Appliquer le DFADriver à l’AFD pour reconnaître les tokens. L’étape 4 fait l’objet du devoir 1. Les étapes (1)-(3) sont laissés comme exercices de programmation. IFT313 © Froduald Kabanza 20 Algorithme NFASimulator La procédure de déterminisation d’un AFN est la composante principale d’un simulateur d’AFN. Entrée : Un AFN N (avec seulement des transitions sur un caractère ou sur ε) Une chaîne de caractères x terminée par le symbole EOF. Sortie : True si N accepte x. False sinon. Méthode : Faire la déterminization (subset construction) à la volée (on the fly), au fur et à mesure qu’on lit x, un caractère à la fois. IFT313 © Froduald Kabanza 21 Algorithme : NFA Simulator currentState = epsilonClosure({initialStateOfTheNFA}); currentChar = nextchar(); while ((currentChar!=EOF) && (currentState != NULL)){ currentState = Dtrans(currentState, currentChar); currentChar = nextChar(); } if (isFinalState(currentState)) && (currentChar == EOF) return True else return False IFT313 © Froduald Kabanza 22 Exercice Comment modifieriez-vous l’algorithme précédent pour reconnaître des tokens (c-à-d., trouver la plus longue sous-chaîne acceptée)? Laissé comme exercice. IFT313 © Froduald Kabanza 23 Vous devriez être capable de • Écrire un automate fini déterministe correspondant à un automate fini non déterministe. • Simuler un AFN. IFT313 © Froduald Kabanza 24 Prochaine leçon Minimiser un AFD IFT313 © Froduald Kabanza 25