Devoirs Hebdomadaire N°10 |
|||||||||||||||||
|
|||||||||||||||||
M. Joseph DASSE BRIKA | |||||||||||||||||
|
|||||||||||||||||
Compilation des Expressions Régulières (E.R.) en Automates finis (A.F.) Expressions Régulières (E.R.) Définition (inductive) : soit I un ensemble fini de symboles (un alphabet)
Remarques :
Exemples d'ER :
I={a,b} E1= (a |
b)*abb E1 est
l'ensemble de toutes les suites de a et de b y compris de longueur 0
suivie de la chaîne abb. Analyse lexicale des E.R. Remarque :
On a écrit les prédicats ascii2carac/2 et lexER/2 pour réaliser l'analyse lexicale. lexER/2 retourne la liste des lexèmes de l'E.R. (caractères spéciaux et caractères de I): ascii2carac([] , []) . ascii2carac([ASCII|LASCII ], [C|LCARAC]) :- name(C , [ASCII]) , ascii2carac(LASCII, LCARAC) . % cette analyse lexicale (un peu particulière) des ER est donc spécifiée par : lexER(ER , LCARAC) :- name(ER , LASCII) , ascii2carac(LASCII, LCARAC). Analyse syntaxique des E.R. : Rappel : il faut d'abord analyser une ER pour vérifier qu'elle est correctement écrite (qu'elle est syntaxiquement correcte , qu'elle respecte la définition inductive). gram1 : une DCG pour les ER : er --> [X] , {member(X , I)}. er --> ['('] , er , [')'] . er --> er , ['|'] , er . er --> er , er. er --> er , ['*']. Remarques :
er --> tr , ['|'] , er . % L'ER est un
Terme Régulier (tr) ou une ER tr --> fr , tr . % Le tr est un
Facteur Régulier (fr) concaténé à un tr fr --> [X] , { not member(X , ['(' , '[' ,
'|' , '*' , ']' , ')']) } , fer. % X n'est pas un symbole spécial fer --> ['*'] , fer. %des *, au moins une QUESTION 1 : enregistrez gram2 dans un fichier Prolog avec les prédicats ascii2carac et lexER. et vérifiez que (a|b)*abb* est une ER bien écrite (syntaxiquement correcte). remarque : poser la question ?- lexER('(a|b)*abb*' , LCARAC) , er(LCARAC , []). On ajoute une règle dans la construction de E.R. : "sous E.R. optionnelle" : Définition (inductive) devient : soit I un ensemble fini de symboles (un alphabet)
QUESTION 2 : modifiez gram2 pour obtenir gram3 en introduisant cette nouvelle règle dans l'analyse syntaxique et vérifiez que (a|b)*a[b]b est une ER bien écrite (syntaxiquement correcte). Syntaxe Abstraite des ER : on a choisi la syntaxe abstraite suivante : (rappel : l'E.R. vide est notée [] en Prolog) Catégories syntaxiques : e , e1 , ... pour les éléments de ER a ,a1 , ... pour les éléments de I Définitions : e ::= a | conc(e1,e2) | ou(e1,e2) | star(e) CONSTRUCTION de l'arbre de syntaxe Abstraite d'une ER : Pendant l'analyse syntaxique on construit l'AST de l'ER analysée par : gram4 (gram3 augmentée de la construction de l'AST pendant l'analyse) er(ou(TAST
, EAST)) --> tr(TAST) , ['|'] , er(EAST) . tr(conc(FAST
, TAST)) --> fr(FAST) , tr(TAST) . fr(AST) --> [X] , { member(X , [a,b]) } ,
fer(ETOILE) , {zeroOUune(X , ETOILE , AST)}. fer('*') --> ['*'] , fer(_). %une ou
plusieurs * est équivalent à une zeroOUune(AST , * ,
star(AST)). QUESTION 3 : après avoir chargé gram4, quelle est la question pour obtenir l'AST de (a|b)*abb* ? Quel est cet AST ? On ajoute la régle de l'E.R. optionnelle, d'où la définition supplémentaire dans la syntaxe abstraite : e ::= a | conc(e1,e2) | ou(e1,e2) | star(e)| opt(e) QUESTION 4 : modifiez gram4 96+gram5 introduisant la règle de l'E.R. optionnelle dans l'analyse syntaxique et la construction de l'AST et vérifiez que (a|b)*a[b]b est une ER bien écrite (syntaxiquement correcte) et donnez son AST. Construction d'un Automates finis (A.F.) à partir d'une E.R. Automate Fini : Définition : un automate fini M est un quintuplet M = (S, I, d, s0, F)
exemple : M = ({s0,s1,s2,s3}, {a,b}, {d(s0,a)=s0 , d(s0,b)=s0 , d(s0,a)=s1, d(s1,b)=s2 , d(s2,b)=s3}, s0, {s3}) en Prolog on écrira : depart(s0). finals([s3]). % Attention les états finals forment un ensemble (représenté en prolog par une liste). d(s0,a,s0 ). Remarque : on peut représenter ces automates par un graphe, par exemple pour l'exemple précédent :
On généralise les transitions dans les Mouvements élémentaires d'un A.F. pour une chaîne de symboles : mve : SxI* ---> SxI* la relation qui fait passer l'AF de l'état s1 dans l'état s2 en "consommant" le premier symbole de la chaine en entrée par l'application d'une transition : mve(s1 , aC ) = (s2 , C) SSI d(s1 , a)=s2. Soit mv la fermeture de mve : mv : SxI* ---> SxI* : mv(s1 , a1a0a1a2...aNC ) = (sN+1 , C) SSI il existe une suite (s0 , a0a2...aNC) , (s1 , a1...aNC) , ... , (sN , C) pour i=0, ... , N , mve(si , ai...aNC) = (si+1 , ai+1...aNC) Définition : Reconnaissance d'une chaîne
Remarque :
Définition : Langage reconnu par un AF M=(S, I, d, s0, F)
en Prolog : |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 5: chargezl'AF de l'exemple et les prédicats de reconnaissance sous Prolog et vérifiezque la chaîne ababababababababaabb est reconnue par l'AF. ATTENTION : la chaîne ababababababababaabb doit être présentée sous forme d'une liste de symboles QUESTION 6: Donnez l'AF M01=(S , I , d , s0 , F) correspondant au graphe suivant i.e. précisez S , I , d , s0 et F : (l'état supportant une flèche est l'état de départ. Les états entourés d'un double cercle sont les états finals) et donnez deux exemples de chaînes acceptées par cet A.F. (chargez la version Prolog de l'A.F. et les prédicats de reconnaissance et montrez la reconnaissance de 2 chaînes en Prolog). |
|||||||||||||||||
![]() |
|||||||||||||||||
ER et AF : Théorème : il existe une ER qui décrit le langage reconnu par un AF et inversement on sait construire un AF qui reconnait le langage décrit par une ER. exemple : (a|b)*abb décrit le langage reconnu par |
|||||||||||||||||
![]() |
|||||||||||||||||
Construire un A.F. à partir d'une E.R. (compiler les ER en AF ) : On va utiliser l'algorithme de Thompson qui à chaque sous arbre de l'AST d'une E.R. fait correspondre un schéma d'A.F. L'algorithme de Thompson de transformation d'une ER en AF produit des AF "fortement" NON déterministes (beaucoup de transitions vides) et qui ont la particularité d'avoir un seul état terminal dont ne sort aucune transition. Rappel : A chaque définition de la syntaxe abstraite des ER correspond un schéma d'automate : |
|||||||||||||||||
Construction de Thompson | |||||||||||||||||
|
|||||||||||||||||
QUESTION 7 compléter le tableau ci dessus en donnant la construction pour la définition opt(E). | |||||||||||||||||
|
|||||||||||||||||
Règles d'inférence Prolog de Construction d'un A.F. à partir d'une E.R. : on définit -ER2AF-> : ER ---> AF qui à partir d'une E.R. construit un A.F. en Prolog :- op(777 , xfx , '-ER2AF->'). Dans 3 règles sur 4 on crée de nouveaux états. Il faut donc en Prolog un générateur de symboles , un prédicat qui retourne un nouveau symbole à chaque appel.: % générateur de symboles : etat9(S) :- retract(cpt(N)) , !, name(N , ASCII), name(S , [115 | ASCII]), N9 is N+1, assert(cpt(N9)). etat9(s0) :- assert(cpt(1)). % régles d'inférences en Prolog : |
|||||||||||||||||
construction A.F. Thompson |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 8 : ajoutez au programme ci dessus la règle d'inférence pour la définition opt(E) et montrez la réponse de Prolog à la question : ?- lexER('(a|b)*abb' , LCARAC) , er(AST , LCARAC , []) , AST '-ER2AF->' M. |
|||||||||||||||||
|
|||||||||||||||||
Tout ensemble et génération du "code" Prolog : il reste, en effet, à générer le code Prolog pour pouvoir reconnaitre si une chaîne est élément de l'ensemble décrit par une ER : reconn(ER , CHAINE). |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 9 : quelles réponses à ?- reconn('(a|b)*abb' , [a,b,a,b,a,b,a,b,a,b,a,b,a,b,b,a,b,b,b]) . ?- reconn('(a|b)*abb' , [a,b,a,b,a,b,a,b,a,b,a,b,a,b,b,a,b,b]) . |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 1: | |||||||||||||||||
L'expression (a|b)*abb* est une ER syntaxiquement correcte , en effet en posant cette question à prolog on obtient: | |||||||||||||||||
?- lexER('(a|b)*abb*' , LCARAC) , er(LCARAC
, []).
LCARAC = ['(', a, ('|'), b, ')', *, a, b, b, *] ; No |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 2: | |||||||||||||||||
On ajoute la règle "sous ER optionnelle" dans la construction des ER. Le programme modifié est donc celui-ci : | |||||||||||||||||
er --> tr , ['|'] , er . % L'ER est un Terme
Régulier (tr) ou une ER tr --> fr , tr . % Le tr est un Facteur Régulier (fr) concaténé
à un tr fr --> [X] , { not member(X , ['(' , '[' , '|' , '*' ,
']' , ')']) } , fer. % X n'est pas un symbole spécial fr --> ['['] ,er,[']']. fer --> ['*'] , fer. %des *, au moins une |
|||||||||||||||||
On vérifie bien que (a|b)*a[b]b est une ER bien écrite : | |||||||||||||||||
?- lexER('(a|b)*a[b]b' , LCARAC) , er(LCARAC
, []).
LCARAC = ['(', a, ('|'), b, ')', *, a, '[', b, ']', b] ; No |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 3: | |||||||||||||||||
La question pour obtenir l'AST de (a|b)*abb* est : | |||||||||||||||||
?- lexER('(a|b)*abb*' , LCAR) , er(AST , LCAR , []). | |||||||||||||||||
L'AST obtenu est : | |||||||||||||||||
conc(star(ou(a, b)), conc(a, conc(b, star(b)))) | |||||||||||||||||
L'éxécution PROLOG donne : | |||||||||||||||||
?- lexER('(a|b)*abb*' , LCAR) , er(AST ,
LCAR , []).
LCAR = ['(', a, ('|'), b, ')', *, a, b, b, *] No |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 4: | |||||||||||||||||
On modifie le programme gram4 pour obtenir gram5 en introduisant la règle de l'E.R. optionnelle dans l'analyse syntaxique et la construction de l'AST : | |||||||||||||||||
er --> tr , ['|'] , er . % L'ER est un Terme
Régulier (tr) ou une ER er --> tr. % L'ER est un Terme i.e. sans le symbole '|' sauf entre '(' et ')'
fr --> [X] , { not member(X , ['(' , '[' , '|' , '*' ,
']' , ')']) } , fer. % X n'est pas un symbole spécial fr --> ['['] ,er,[']']. fer --> ['*'] , fer. %des *, au moins une er(ou(TAST , EAST)) --> tr(TAST) , ['|'] , er(EAST) . tr(conc(FAST , TAST)) --> fr(FAST) , tr(TAST) . fr(AST) --> [X] , { member(X , [a,b]) } , fer(ETOILE) , {zeroOUune(X
, ETOILE , AST)}. fer('*') --> ['*'] , fer(_). %une ou plusieurs * est
équivalent à une zeroOUune(AST , * , star(AST)).
|
|||||||||||||||||
On vérifie bien que (a|b)*a[b]b est une ER bien écrite et on obtient sonAST par la question suivante : | |||||||||||||||||
?- lexER('(a|b)*a[b]b' , LCAR) , er(AST ,
LCAR , []).
LCAR = ['(', a, ('|'), b, ')', *, a, '[', b, ']', b] No |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 5: | |||||||||||||||||
On vérifie bien que la chaîne ababababababababaabb est reconnue par l'AF : | |||||||||||||||||
?-
reconnaissance([a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,a,b,b]).
Yes |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 6: | |||||||||||||||||
L'AF MO1 = (S , I , d , s0 , F) où : | |||||||||||||||||
S = {q0,q1,q2,q3,q4,q5} I = {0,1} d ={d(q0,0) = q1,d(q0,1) = q2,d(q1,1)=q3,d(q2,0)=q4,d(q3,0)=q4,d(q3,0)=q5,d(q4,1)=q3,d(q4,1)=q5} s0 = q0 F = {q5} |
|||||||||||||||||
En Prolog on écrit : | |||||||||||||||||
depart(q0).
finals([q5]). d(q0,0,q1). |
|||||||||||||||||
On choisit deux exemples de chaines acceptées par cette AF : | |||||||||||||||||
|
|||||||||||||||||
|
|||||||||||||||||
QUESTION 7: | |||||||||||||||||
On compléte le tableau en donnant la construction pour la définition opt(E) : | |||||||||||||||||
opt(E) |
![]() |
M= (SE v {sD,sf}, IE ,
dE v {d(sD,^)=sf , d(sD,^)=s , d(f,^)=s}, sD, {sf}) |
|||||||||||||||
|
|||||||||||||||||
QUESTION 8: | |||||||||||||||||
On ajoute au programme la règle d'inférence pour la définition opt(E) : | |||||||||||||||||
% régles d'inférences en Prolog :
%construction A.F. Thompson conc(E1 , E2) '-ER2AF->' m(S, I , [d(Sf1 , [] , SD2)|D],
SD1, [Sf2]) :- !, |
|||||||||||||||||
La réponse de Prolog à cette question est: | |||||||||||||||||
?- lexER('(a|b)*abb' , LCARAC) , er(AST ,
LCARAC , []) , AST '-ER2AF->' M.
LCARAC = ['(', a, ('|'), b, ')', *, a, b, b] Yes |
|||||||||||||||||
|
|||||||||||||||||
QUESTION 9: | |||||||||||||||||
Les réponses de ces deux questions sont : | |||||||||||||||||
?- reconn('(a|b)*abb' ,
[a,b,a,b,a,b,a,b,a,b,a,b,a,b,b,a,b,b,b]) .
No |
|||||||||||||||||
Cette expression ne respecte pas en effet toutes les règles de cette ER (le dernier b). | |||||||||||||||||
?- reconn('(a|b)*abb' ,
[a,b,a,b,a,b,a,b,a,b,a,b,a,b,b,a,b,b]) .
Yes |
|||||||||||||||||
Cette expression respecte bien toutes les règles de cette ER. | |||||||||||||||||
|
|||||||||||||||||
FIN_dh10 |
|||||||||||||||||
ACCUEIL CONTACT FAVORIS ANNALES DH1 DH2 DH3 DH4 DH5 DH6 DH7 DH8 DH9 DH10 DH11 DH12 DH13 DH14 DH15 DH16 |