Como você deseja "converter regex em DFA em menos de 30 minutos", suponho que você esteja trabalhando manualmente em exemplos relativamente pequenos.
Nesse caso, você pode usar o algoritmo de Brzozowski , que calcula diretamente o autômato Nerode de uma linguagem (que é conhecido por ser igual ao seu autômato determinístico mínimo). Baseia-se no cálculo direto das derivadas e também funciona para expressões regulares estendidas, permitindo interseção e complementação. A desvantagem desse algoritmo é que ele requer a verificação da equivalência das expressões computadas ao longo do caminho, um processo caro. Mas, na prática, e para pequenos exemplos, é muito eficiente.[1]
Quocientes à esquerda . Deixe ser uma língua do A * e deixe u ser uma palavra. Então
vocêLA∗u
A linguagem u - 1 Lé chamado dequociente de esquerda(oudeixou derivado) deL.
u−1L={v∈A∗∣uv∈L}
u−1LL
Autómato Nerode . O autômato Nerode de é o autômato determinístico A ( L ) = ( Q , A , ⋅ , L , F ) onde Q = { u - 1 L ∣ u ∈ A ∗ } , F = { u - 1 L ∣ u ∈ L } e a função de transição é definida, para cada a ∈LA(L)=(Q,A,⋅,L,F)Q = { u- 1L | u ∈ A∗}F= { u- 1L | u ∈ L } , pela fórmula
( u - 1 L ) ⋅ a = a - 1 ( u - 1 L ) = ( u a ) - 1 L
Cuidado com esta definição bastante abstrata. Cada estado de A é um quociente esquerdo de L por uma palavra e, portanto, é uma linguagem de A ∗ . O estado inicial é a linguagem L , e o conjunto de estados finais é o conjunto de todos os quocientes esquerda do L por uma palavra de L .a ∈ A
( u- 1L ) ⋅ a = a- 1( u- 1G ) = ( u um )- 1eu
UMAeuUMA∗eueueu
a , b
a−11a−1(L1∪L2)a−1(L1∩L2)=0=a−1L1∪u−1L2,=a−1L1∩u−1L2,a−1ba−1(L1∖L2)a−1L∗={10if a=bif a≠b=a−1L1∖u−1L2,=(a−1L)L∗
a−1(L1L2)={(a−1L1)L2(a−1L1)L2∪a−1L2si 1∉L1,si 1∈L1
L=(a(ab)∗)∗∪(ba)∗
1−1La−1L1b−1L1a−1L2b−1L2a−1L3b−1L3a−1L4b−1L4a−1L5b−1L5=L=L1=(ab)∗(a(ab)∗)∗=L2=a(ba)∗=L3=b(ab)∗(a(ab)∗)∗∪(ab)∗(a(ab)∗)∗=bL2∪L2=L4=∅=(ba)∗=L5=∅=a−1(bL2∪L2)=a−1L2=L4=b−1(bL2∪L2)=L2∪b−1L2=L2=∅=a(ba)∗=L3
which gives the following minimal automaton.
[1] J. Brzozowski, Derivatives of Regular Expressions, J.ACM 11(4), 481–494, 1964.
Edit. (April 5, 2015) I just discovered that a similar question: What algorithms exist for construction a DFA that recognizes the language described by a given regex? was asked on cstheory. The answer partly addresses complexity issues.
a(a|ab|ac)*a+
. Você pode traduzi-lo diretamente para um NDFA que reduza para um DFA ou normalizá-lo para algo que mapeie imediatamente para um DFA.