4 sub epsilon_closure
($nfa, $states) {
5 my @q = $states.members
;
7 # Why don't I just make @ret a set here, instead of grepping on
8 # it as if it were? Well, because if I do, then apparently
9 # it's not true that 2 == 2 anymore. Yes, very strange. Try it.
14 unless (@ret.grep:{ $state eq $_ }) {
27 sub scan
($nfa, $states, $tran) {
29 for ($states.members
) -> $state {
39 sub transitions
($nfa, $states) {
41 for ($states.members
) {
43 $ret.insert
($list.map: {.key
});
50 my @elem = $set.members
.sort;
52 return @elem.join(';');
55 sub nfa2dfa
($nfa, $start) {
56 my $inistate = epsilon_closure
($nfa, set
($start));
62 my $strstate = set2str
($state);
63 next if $seen.includes
($strstate);
64 $seen.insert
($strstate);
65 for transitions
($nfa, $state).members
-> $tran {
67 my $scan = scan
($nfa, $state, $tran);
68 my $newstate = epsilon_closure
($nfa, $scan);
69 $dfa{set2str
($state)}{$tran} = set2str
($newstate);
70 @q.push($newstate) unless $seen.includes
(set2str
($newstate));
74 return ($dfa, set2str
($inistate));
77 # nfa for /foo*[ba|oba]*[r|z]/
81 2 => [ 'o' => 2, '' => 3 ],
82 3 => [ '' => 4, '' => 7 ],
85 6 => [ '' => 3, '' => 11 ],
89 10 => [ '' => 3, '' => 11 ],
90 11 => [ 'r' => 'X', 'z' => 'X' ],
93 my ($dfa, $start) = nfa2dfa
($nfa, 0);
95 for $dfa.kv
-> $s, $t {
96 printf("%-13s : %s\n", $s, $t.perl
);