Table of Contents

Etapa 2 - Transformarea Regex-urilor la AFD-uri

Update legat de upload: incarcati o arhiva ce contine atat fisierele sursa, cat si directorul de testare tests/ si script-ul checker.py.

Checker si teste: Checker proiect LFA.

Transformarea Regex-AFD ne permite operationalizarea expresiilor regulate, iar aceasta este o parte importanta atat dintr-un lexer cat si dintr-un parser.

In etapa 2, vom implementa aceasta transformare in doi pasi:

Implementarea transformarilor se bazeaza integral pe procedurile algoritmice prezentate la curs.

Pentru a realiza prima transformare, este necesar sa parsam o expresie regulata si sa construim arborele acesteia. Spre exemplu, expresia: ab|c* are asociat arborele: UNION(CONCAT(a,b),STAR(c)). Datorita regulilor de precenta ale operatorilor, construirea acestui arbore este mai complicata, iar aceast task va fi amanat pentru etapa finala. Pentru a simplifica problema parsarii, expresiile vor fi prezentate in forma prenex.

Descrierea inputului

UNION a b
UNION CONCAT a b STAR c
CONCAT UNION a b UNION c d
CONCAT STAR UNION a b UNION b c
STAR UNION CONCAT a b CONCAT b STAR d
CONCAT PLUS c UNION a PLUS b 

Cerinta si descrierea outputului

Implementarea voastra va primi un fisier de input <testxy.in> si un fisier de output <testxy.out>, va construi AFD-ul asociat expresiei regulate, iar apoi va afisa automatul in fisierul de output conform formatului de mai jos:

<alfabet>
<numar_stari>
<stare_initiala>
<lista_stari_finale>
<tranzitie_1>
<tranzitie_2>
...
<tranzitie_n>

Atentie: Implementarea va fi punctata doar in masura in care respecta cerinta (se construieste un AFD folosind algoritmii prezentati la curs).

Identitatea starilor

Implementarea algoritmului lui Thomson este complicata de faptul ca starile sunt reprezentate ca intregi. Spre exemplu, AFN-urile pentru expresiile 0 si 1 vor avea fiecare cate doua stari, cel mai probabil numerotate de la 0 la 1. Pentru a construi AFN-ul pentru 0|1, trebuie sa renumerotam starile tinand cont de:

Parsarea formei Prenex

Pentru a parsa forma Prenex, avem nevoie de o stiva care sa retina parti ale expresiei / operatii parsate deja. Vom interactiona in doua feluri cu stiva:

Implementarea voastra trebuie sa combine in mod eficient adaugarea cu reducerea.

Development si testare

Pentru a testa AFD-urile generate de voi, veti avea nevoie de o modalitate de afisare a acestora in text. Va sugeram sa adaugati la aceasta si o modalitate grafica. Atasam un script Python3 (draw_fa.zip) care poate fi folosit pentru a desena AFD-uri:

from,char,to
0,0,1
1,ε,2
2,ε,3
2,ε,f5
3,0,4
4,ε,3
4,ε,f5

Sugestii de implementare pentru Python

Sugestii de implementare pentru Haskell

———————————————————–

class FA t where
    fromList :: State s => Set Char -> s -> [(s,Char,s)] -> [s] -> t s
    states :: (State s) => t s -> [s]
    relabel :: (State s, State s') => (s -> s') -> t s -> t s'
    size :: (State s) => t s -> Integer
type NDelta a = Map (a,Char) (Set a)
data Nfa a = Nfa {nsigma :: Set Char, ninitial :: a, ndelta :: (NDelta a), nfin :: [a]}

Metodologia de testare

Odata generate AFD-urile de catre implementarea voastra si afisate in cadrul fisierlor de output, checker-ul etapei 2 compara rezultatele fata de o suita de AFD-uri de referinta, verificand pentru fiecare caz in parte daca automatele accepta acelasi limbaj. Mai multe detalii legate de checker gasiti pe pagina Checker proiect LFA.