use strict; sub state { my $c=shift; my $next=shift; my $alt=shift; my $visited=0; return {c => $c, next => $next, alt => $alt, visited => $visited}; } sub NFA { my $in=shift; my $out=shift; return {in => $in, out => $out}; } sub sym { my $c=shift; my $s=state($c, 0, 0); return NFA($s, $s); } sub dot { my $nfa1=shift; my $nfa2=shift; $nfa1->{out}{next}=$nfa2->{in}; return NFA($nfa1->{in}, $nfa2->{out}); } sub bar { my $nfa1=shift; my $nfa2=shift; my $s=state(256, $nfa1->{in}, $nfa2->{in}); my $t=state(256, 0, 0); $nfa1->{out}{next}=$nfa2->{out}{next}=$t; return NFA($s, $t); } sub que { my $nfa=shift; my $t=state(256, 0, 0); my $s=state(256, $nfa->{in}, $t); $nfa->{out}{next}=$t; return NFA($s, $t); } sub star { my $nfa=shift; my $s=state(256, 0, $nfa->{in}); $nfa->{out}{next}=$s; return NFA($s, $s); } sub plus { my $nfa=shift; my $s=state(256, 0, $nfa->{in}); $nfa->{out}{next}=$s; return NFA($nfa->{in}, $s); } sub acpt { my $nfa=shift; my $s=state(257, 0, 0); $nfa->{out}{next}=$s; return NFA($nfa->{in}, $s); } #example use my $nfa=acpt( dot( sym('a'), dot( star( dot( sym('b'), sym('b') ) ), sym('a') ) ) );