|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # $Revision: 1.4 $ $Date: 2006/03/02 21:00:28 $ $Author: estrabd $  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package FLAT::Legacy::FA::NFA;  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
26
 | 
 use base 'FLAT::Legacy::FA';  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
179
 | 
    | 
| 
6
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
12
 | 
 use strict;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
    | 
| 
7
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
10
 | 
 use Carp;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
128
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
12
 | 
 use FLAT::Legacy::FA::DFA;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
    | 
| 
10
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
16
 | 
 use Data::Dumper;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10428
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
13
 | 
2277
 | 
 
 | 
 
 | 
  
2277
  
 | 
  
0
  
 | 
1823
 | 
   my $class = shift;  | 
| 
14
 | 
2277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9264
 | 
   bless {  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _START_STATE => undef,  # start states -> only 1!  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _STATES => [],          # Set of all states  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _FINAL_STATES => [],    # Set of final states, subset of _STATES  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _SYMBOLS => [],         # Symbols  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _TRANSITIONS => {},     # Transition table  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _EPSILON => 'epsilon',  # how an epsilon transition is represented  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }, $class;  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub jump_start {  | 
| 
25
 | 
1177
 | 
 
 | 
 
 | 
  
1177
  
 | 
  
0
  
 | 
976
 | 
   my $self = shift;  | 
| 
26
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1734
 | 
   my $NFA = FLAT::Legacy::FA::NFA->new();  | 
| 
27
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1294
 | 
   my $symbol = shift;  | 
| 
28
 | 
1177
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1638
 | 
   if (!defined($symbol)) {  | 
| 
29
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $symbol = $NFA->get_epsilon_symbol();  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
31
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1187
 | 
     chomp($symbol);  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
33
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23277
 | 
   my $newstart = crypt(rand 8,join('',[rand 8, rand 8]));  | 
| 
34
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14277
 | 
   my $newfinal = crypt(rand 8,join('',[rand 8, rand 8]));    | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add states  | 
| 
36
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2987
 | 
   $NFA->add_state($newstart,$newfinal);  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add symbol  | 
| 
38
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1839
 | 
   $NFA->add_symbol($symbol);  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # set start and final  | 
| 
40
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1980
 | 
   $NFA->set_start($newstart);  | 
| 
41
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1783
 | 
   $NFA->add_final($newfinal);  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add single transition  | 
| 
43
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1985
 | 
   $NFA->add_transition($newstart,$symbol,$newfinal);  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #return $NFA  | 
| 
45
 | 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2216
 | 
   return $NFA;  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub load_file {  | 
| 
49
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
50
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $file = shift;  | 
| 
51
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if (-e $file) {  | 
| 
52
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     open (NFA,"<$file");  | 
| 
53
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $string = undef;  | 
| 
54
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     while () {  | 
| 
55
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $string .= $_;  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
57
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     close (NFA);  | 
| 
58
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->load_string($string);  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub load_string {  | 
| 
63
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
64
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $string = shift;  | 
| 
65
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my @lines = split("\n",$string);  | 
| 
66
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $CURR_STATE = undef;  | 
| 
67
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   foreach (@lines) {  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # strip comments  | 
| 
69
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $_ =~ s/\s*#.*$//;  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # check if line is a state, transition, or keyword  | 
| 
71
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     if (m/^\s*([\w\d]*)\s*:\s*$/) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #print STDERR "Found transitions for state $1\n";  | 
| 
73
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $self->add_state($1);  | 
| 
74
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $CURR_STATE = $1;  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (m/^\s*([\w\d]*)\s*([\w\d,]*)\s*$/ && ! m/^$/) {  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # treat as transition  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #print STDERR "Input: '$1' goes to $2\n";  | 
| 
78
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my @s = split(',',$2);  | 
| 
79
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $self->add_transition($CURR_STATE,$1,@s);  | 
| 
80
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $self->add_symbol($1);  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (m/^\s*([\w\d]*)\s*::\s*([\w\d,]*)\s*$/ && ! m/^$/) {  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # Check for known header keywords  | 
| 
83
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $val = $2;  | 
| 
84
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($1 =~ m/START/i) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
85
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->set_start($val);  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } elsif ($1 =~ m/FINAL/i) {  | 
| 
87
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my @s = split(',',$val);  | 
| 
88
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self->add_final(@s);  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } elsif ($1 =~ m/EPSILON/i) {  | 
| 
90
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->set_epsilon($val);  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
92
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print STDERR "WARNING: $1 is not a valid header...\n";  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub clone {  | 
| 
99
 | 
1022
 | 
 
 | 
 
 | 
  
1022
  
 | 
  
0
  
 | 
741
 | 
   my $self = shift;  | 
| 
100
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1448
 | 
   my $NFA = FLAT::Legacy::FA::NFA->new();  | 
| 
101
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1902
 | 
   $NFA->add_state($self->get_states());  | 
| 
102
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2010
 | 
   $NFA->add_final($self->get_final());  | 
| 
103
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1859
 | 
   $NFA->add_symbol($self->get_symbols());  | 
| 
104
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1898
 | 
   $NFA->set_start($self->get_start());  | 
| 
105
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1633
 | 
   $NFA->set_epsilon($self->get_epsilon_symbol);  | 
| 
106
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1695
 | 
   foreach my $state ($self->get_states()) {  | 
| 
107
 | 
3881
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2575
 | 
     foreach my $symbol (keys %{$self->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
3881
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8720
 | 
    | 
| 
108
 | 
2838
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1937
 | 
       $NFA->add_transition($state,$symbol,@{$self->{_TRANSITIONS}{$state}{$symbol}});  | 
| 
 
 | 
2838
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4410
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
111
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1308
 | 
   return $NFA;  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub append_nfa {  | 
| 
115
 | 
1022
 | 
 
 | 
 
 | 
  
1022
  
 | 
  
0
  
 | 
1006
 | 
   my $self = shift;  | 
| 
116
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
751
 | 
   my $NFA = shift;  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # clone $NFA  | 
| 
118
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1482
 | 
   my $NFA1 = $NFA->clone();  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off self - ensures a single final state  | 
| 
120
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1623
 | 
   $self->pinch();  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off $NFA1 to ensure a single final state  | 
| 
122
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1328
 | 
   $NFA1->pinch();  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # ensure unique state names  | 
| 
124
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20049
 | 
   $self->ensure_unique_states($NFA1,crypt(rand 8,join('',[rand 8, rand 8])));  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # sychronize epsilon symbol  | 
| 
126
 | 
1022
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1785
 | 
   if ($NFA1->get_epsilon_symbol() ne $self->get_epsilon_symbol()) {  | 
| 
127
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $NFA1->rename_symbol($NFA1->get_epsilon_symbol(),$self->get_epsilon_symbol());    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }    | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new states from NFA1  | 
| 
130
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1864
 | 
   foreach my $state ($NFA1->get_states()) {  | 
| 
131
 | 
3902
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5667
 | 
     $self->add_state($state);  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new symbols from NFA1  | 
| 
134
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2242
 | 
   foreach my $symbol ($NFA1->get_symbols()) {   | 
| 
135
 | 
1201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1839
 | 
     $self->add_symbol($symbol);  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add transitions from NFA1  | 
| 
138
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
993
 | 
   foreach my $state (keys %{$NFA1->{_TRANSITIONS}}) {  | 
| 
 
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2567
 | 
    | 
| 
139
 | 
2880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1811
 | 
     foreach my $symbol (keys %{$NFA1->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
2880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5744
 | 
    | 
| 
140
 | 
2880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2079
 | 
       $self->add_transition($state,$symbol,@{$NFA1->{_TRANSITIONS}{$state}{$symbol}});  | 
| 
 
 | 
2880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4714
 | 
    | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # remove current final state and saves it for future reference  | 
| 
144
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1016
 | 
   my $oldfinal = pop(@{$self->{_FINAL_STATES}});  | 
| 
 
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1428
 | 
    | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new epsilon transition from the old final state of $self to the start state of NFA1  | 
| 
146
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1557
 | 
   $self->add_transition($oldfinal,$self->get_epsilon_symbol(),$NFA1->get_start());  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # mark the final state of NFA1 as the final state of $self  | 
| 
148
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1942
 | 
   $self->add_final($NFA1->get_final());  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # states not renumbered - can done explicity by user  | 
| 
150
 | 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5293
 | 
   return;  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub prepend_nfa {  | 
| 
154
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
155
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $NFA = shift;  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # clone $NFA  | 
| 
157
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $NFA1 = $NFA->clone();  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off self - ensures a single final state  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off self - ensures a single final state  | 
| 
160
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->pinch();  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off $NFA1 to ensure a single final state  | 
| 
162
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $NFA1->pinch();  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # ensure unique state names  | 
| 
164
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->ensure_unique_states($NFA1,crypt(rand 8,join('',[rand 8, rand 8])));  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # sychronize epsilon symbol  | 
| 
166
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if ($NFA1->get_epsilon_symbol() ne $self->get_epsilon_symbol()) {  | 
| 
167
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $NFA1->rename_symbol($NFA1->get_epsilon_symbol(),$self->get_epsilon_symbol());    | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }    | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new states from NFA1  | 
| 
170
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   foreach my $state ($NFA1->get_states()) {  | 
| 
171
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->add_state($state);  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new symbols from NFA1  | 
| 
174
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   foreach my $symbol ($NFA1->get_symbols()) {   | 
| 
175
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->add_symbol($symbol);  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add transitions from NFA1  | 
| 
178
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   foreach my $state (keys %{$NFA1->{_TRANSITIONS}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
179
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach my $symbol (keys %{$NFA1->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
180
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $self->add_transition($state,$symbol,@{$NFA1->{_TRANSITIONS}{$state}{$symbol}});  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # remove current final state of $NFA1 and saves it for future reference  | 
| 
184
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $oldfinal = pop(@{$NFA1->{_FINAL_STATES}});  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new epsilon transition from the old final state of $NFA1 to the start state of $self  | 
| 
186
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->add_transition($oldfinal,$self->get_epsilon_symbol(),$self->get_start());  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # mark the final state of NFA1 as the final state of $self  | 
| 
188
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->set_start($NFA1->get_start());  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # states not renumbered - can done explicity by user  | 
| 
190
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return;  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub or_nfa {  | 
| 
194
 | 
112
 | 
 
 | 
 
 | 
  
112
  
 | 
  
0
  
 | 
125
 | 
   my $self = shift;  | 
| 
195
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
125
 | 
   my $NFA1 = shift;  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off self - ensures a single final state  | 
| 
197
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
218
 | 
   $self->pinch();  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off $NFA1 to ensure a single final state  | 
| 
199
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
192
 | 
   $NFA1->pinch();  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # ensure unique state names  | 
| 
201
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2671
 | 
   $self->ensure_unique_states($NFA1,crypt(rand 8,join('',[rand 8, rand 8])));  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # sychronize epsilon symbol  | 
| 
203
 | 
112
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
233
 | 
   if ($NFA1->get_epsilon_symbol() ne $self->get_epsilon_symbol()) {  | 
| 
204
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $NFA1->rename_symbol($NFA1->get_epsilon_symbol(),$self->get_epsilon_symbol());    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }    | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new states from NFA1  | 
| 
207
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
261
 | 
   foreach my $state ($NFA1->get_states()) {  | 
| 
208
 | 
2154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3086
 | 
     $self->add_state($state);  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new symbols from NFA1  | 
| 
211
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
415
 | 
   foreach my $symbol ($NFA1->get_symbols()) {   | 
| 
212
 | 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
498
 | 
     $self->add_symbol($symbol);  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add transitions from NFA1  | 
| 
215
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
   foreach my $state (keys %{$NFA1->{_TRANSITIONS}}) {  | 
| 
 
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
720
 | 
    | 
| 
216
 | 
2042
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1322
 | 
     foreach my $symbol (keys %{$NFA1->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
2042
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4206
 | 
    | 
| 
217
 | 
2042
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1348
 | 
       $self->add_transition($state,$symbol,@{$NFA1->{_TRANSITIONS}{$state}{$symbol}});  | 
| 
 
 | 
2042
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3191
 | 
    | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # save old start states  | 
| 
221
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
388
 | 
   my $start1 = $self->get_start();  | 
| 
222
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
   my $start2 = $NFA1->get_start();  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # create new start state  | 
| 
224
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4508
 | 
   my $newstart = crypt(rand 8,join('',[rand 8, rand 8]));  | 
| 
225
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
338
 | 
   $self->add_state($newstart);  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # set this new state as the start  | 
| 
227
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
264
 | 
   $self->set_start($newstart);  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add the final state from NFA1   | 
| 
229
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
321
 | 
   $self->add_final($NFA1->get_final());  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # create transitions to old start states from new start state  | 
| 
231
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
279
 | 
   $self->add_transition($newstart,$self->get_epsilon_symbol(),$start1);  | 
| 
232
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
238
 | 
   $self->add_transition($newstart,$self->get_epsilon_symbol(),$start2);  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # the result is not pinched, but it is in PFA->or_pfa because the epsilon  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # transition is required to convert a PFA properly to an NFA...a similar  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # restriction may occur here...in this case, uncomment the following line  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #$self->pinch();  | 
| 
237
 | 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
299
 | 
   return;  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub kleene {  | 
| 
241
 | 
132
 | 
 
 | 
 
 | 
  
132
  
 | 
  
0
  
 | 
149
 | 
   my $self = shift;  | 
| 
242
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1963
 | 
   my $newstart = crypt(rand 8,join('',[rand 8, rand 8]));  | 
| 
243
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1525
 | 
   my $newfinal = crypt(rand 8,join('',[rand 8, rand 8]));    | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch off self - ensures a single final state  | 
| 
245
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
276
 | 
   $self->pinch();  | 
| 
246
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
259
 | 
   my $oldstart = $self->get_start();  | 
| 
247
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
   my $oldfinal = pop(@{$self->{_FINAL_STATES}});  | 
| 
 
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
238
 | 
    | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # add new states  | 
| 
249
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
274
 | 
   $self->add_state($newstart,$newfinal);  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # set start  | 
| 
251
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
249
 | 
   $self->set_start($newstart);  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # set final  | 
| 
253
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
255
 | 
   $self->add_final($newfinal);  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # $oldfinal->$oldstart  | 
| 
255
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
301
 | 
   $self->add_transition($oldfinal,$self->get_epsilon_symbol(),$oldstart);    | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # $newstart->$oldstart  | 
| 
257
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
224
 | 
   $self->add_transition($newstart,$self->get_epsilon_symbol(),$oldstart);  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # $oldfinal->$newstart  | 
| 
259
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
227
 | 
   $self->add_transition($oldfinal,$self->get_epsilon_symbol(),$newfinal);  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # $newstart->$newfinal  | 
| 
261
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
267
 | 
   $self->add_transition($newstart,$self->get_epsilon_symbol(),$newfinal);    | 
| 
262
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
213
 | 
   return;  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub pinch {  | 
| 
266
 | 
2400
 | 
 
 | 
 
 | 
  
2400
  
 | 
  
0
  
 | 
2036
 | 
   my $self = shift;  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # do only if there is more than one final state  | 
| 
268
 | 
2400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1615
 | 
   my $newfinal = join(',',@{$self->{_FINAL_STATES}});  | 
| 
 
 | 
2400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3895
 | 
    | 
| 
269
 | 
2400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3832
 | 
   $self->add_state($newfinal);  | 
| 
270
 | 
2400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1864
 | 
   while (@{$self->{_FINAL_STATES}}) {  | 
| 
 
 | 
4884
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6887
 | 
    | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # design decision - remove all final states so that the common  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # one is the only final state and all former final states have an  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # epsilon transition to it - could prove costly for NFA->to_dfa, so  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # this could change  | 
| 
275
 | 
2484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1770
 | 
     my $state = pop(@{$self->{_FINAL_STATES}});  | 
| 
 
 | 
2484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2699
 | 
    | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # add new transition unless it is to the final state itself  | 
| 
277
 | 
2484
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
4326
 | 
     if ($state ne $newfinal) {  | 
| 
278
 | 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
320
 | 
       $self->add_transition($state,$self->get_epsilon_symbol(),$newfinal)  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
281
 | 
2400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3600
 | 
   $self->add_final($newfinal);  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # FA->number_states() could be used here, but the user may not  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # want the states renamed, so it can be used explicitly  | 
| 
284
 | 
2400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1817
 | 
   return;  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub reverse {  | 
| 
288
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pinch  | 
| 
290
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->pinch();  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # make a distinct copy of self  | 
| 
292
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $NFA1 = $self->clone();  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # reset out $self->{_TRANSITIONS}  | 
| 
294
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->{_TRANSITIONS} = {};  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # swap start and final states  | 
| 
296
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $start = $self->get_start();  | 
| 
297
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->set_start(pop(@{$self->{_FINAL_STATES}}));  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
298
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->add_final($start);  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # cycle through transitions and reverse arcs  | 
| 
300
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   foreach my $state (keys %{$NFA1->{_TRANSITIONS}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
301
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach my $symbol (keys %{$NFA1->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
302
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       foreach my $destination (@{$NFA1->{_TRANSITIONS}{$state}{$symbol}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
303
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->add_transition($destination,$symbol,$state);  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
307
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return;  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub rename_state {  | 
| 
311
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
3
 | 
   my $self = shift;  | 
| 
312
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   my $oldname = shift;  | 
| 
313
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
   my $newname = shift;  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # make sure $oldname is an actual state in this FA  | 
| 
315
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   if (!$self->is_state($newname)) {  | 
| 
316
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     if ($self->is_state($oldname)) {  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # replace name in _STATES array  | 
| 
318
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       my $i = 0;  | 
| 
319
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       foreach ($self->get_states()) {  | 
| 
320
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 	if ($_ eq $oldname) {  | 
| 
321
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
           $self->{_STATES}[$i] = $newname;   | 
| 
322
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
        	  last;  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
324
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 	$i++;  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # replace name if start state  | 
| 
327
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
       if ($self->is_start($oldname)) {  | 
| 
328
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->set_start($newname);  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # replace transitions  | 
| 
331
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       foreach my $state (keys %{$self->{_TRANSITIONS}}) {  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
332
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
 	foreach my $symbol (keys %{$self->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
    | 
| 
333
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
 	  my $j = 0;  | 
| 
334
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
           foreach my $next (@{$self->{_TRANSITIONS}{$state}{$symbol}}) {  | 
| 
 
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
    | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # rename destination states  | 
| 
336
 | 
43
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
70
 | 
 	    if ($self->{_TRANSITIONS}{$state}{$symbol}[$j] eq $oldname) {  | 
| 
337
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	      $self->{_TRANSITIONS}{$state}{$symbol}[$j] = $newname;  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
339
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
             $j++;  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # rename start state  | 
| 
342
 | 
37
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
64
 | 
 	  if ($state eq $oldname) {  | 
| 
343
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
    	    $self->add_transition($newname,$symbol,@{$self->{_TRANSITIONS}{$state}{$symbol}});    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}	  | 
| 
346
 | 
37
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
63
 | 
         if ($state eq $oldname) {  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   	  # delete all transitions of old state  | 
| 
348
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 	  delete($self->{_TRANSITIONS}{$state});  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # replace final states  | 
| 
352
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
       $i = 0;  | 
| 
353
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       foreach ($self->get_final()) {  | 
| 
354
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	if ($_ eq $oldname) {  | 
| 
355
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
           $self->{_FINAL_STATES}[$i] = $newname;   | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
357
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 	$i++;  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #        | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
361
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       print STDERR "Warning: $oldname is not a current state\n";  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
364
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     print STDERR "Warning: $newname is a current state\n";    | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
366
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   return;  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # renames symbol  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub rename_symbol {  | 
| 
371
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
372
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $oldsymbol = shift;  | 
| 
373
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $newsymbol = shift;  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # make sure $oldsymbol is a symbol and do not bother if  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # $newsymbol ne $oldsymbol  | 
| 
376
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   if ($self->is_symbol($oldsymbol) && $newsymbol ne $oldsymbol) {  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # change in $self->{_SYMBOLS}  | 
| 
378
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $i = 0;  | 
| 
379
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach ($self->get_symbols()) {  | 
| 
380
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($_ eq $oldsymbol) {  | 
| 
381
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self->{_SYMBOLS}[$i] = $newsymbol;  | 
| 
382
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	last;  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
384
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $i++;  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # change in $self->{_TRANSITIONS}  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # replace transition symbols  | 
| 
388
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach my $state (keys %{$self->{_TRANSITIONS}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
389
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       foreach my $symbol (keys %{$self->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
390
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ($symbol eq $oldsymbol) {  | 
| 
391
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  $self->add_transition($state,$newsymbol,@{$self->{_TRANSITIONS}{$state}{$symbol}});  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
392
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  delete($self->{_TRANSITIONS}{$state}{$symbol});  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }	  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # also look at $self->{_EPSILON}  | 
| 
397
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($self->get_epsilon_symbol() eq $oldsymbol) {  | 
| 
398
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $self->set_epsilon($newsymbol);  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }           | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
401
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return;  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub add_transition {  | 
| 
405
 | 
19652
 | 
 
 | 
 
 | 
  
19652
  
 | 
  
0
  
 | 
15232
 | 
   my $self = shift;  | 
| 
406
 | 
19652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14751
 | 
   my $state = shift;  | 
| 
407
 | 
19652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13308
 | 
   my $symbol = shift;  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # adds state if not already added  | 
| 
409
 | 
19652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30671
 | 
   $self->add_state($state);  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # adds symbol if not already added  | 
| 
411
 | 
19652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31180
 | 
   $self->add_symbol($symbol);  | 
| 
412
 | 
19652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16735
 | 
   foreach my $next (@_) {  | 
| 
413
 | 
20729
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
13448
 | 
     if (!$self->is_member($next,@{$self->{_TRANSITIONS}{$state}{$symbol}})) {  | 
| 
 
 | 
20729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56727
 | 
    | 
| 
414
 | 
20729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13543
 | 
       push (@{$self->{_TRANSITIONS}{$state}{$symbol}},$next);  | 
| 
 
 | 
20729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38064
 | 
    | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
417
 | 
19652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34844
 | 
   return;  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_transition_on {  | 
| 
421
 | 
26950
 | 
 
 | 
 
 | 
  
26950
  
 | 
  
0
  
 | 
18933
 | 
   my $self = shift;  | 
| 
422
 | 
26950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18260
 | 
   my $state = shift;  | 
| 
423
 | 
26950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19223
 | 
   my $symbol = shift;  | 
| 
424
 | 
26950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25857
 | 
   my @ret = undef;  | 
| 
425
 | 
26950
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
43994
 | 
   if ($self->is_state($state) && $self->is_symbol($symbol)) {    | 
| 
426
 | 
26950
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
59444
 | 
     if (defined($self->{_TRANSITIONS}{$state}{$symbol})) {  | 
| 
427
 | 
10725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7583
 | 
       @ret = @{$self->{_TRANSITIONS}{$state}{$symbol}};  | 
| 
 
 | 
10725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28960
 | 
    | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
430
 | 
26950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
270943
 | 
   return @ret;    | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub set_epsilon {  | 
| 
434
 | 
1099
 | 
 
 | 
 
 | 
  
1099
  
 | 
  
0
  
 | 
953
 | 
   my $self = shift;  | 
| 
435
 | 
1099
 | 
 
 | 
 
 | 
 
 | 
 
 | 
949
 | 
   my $epsilon = shift;  | 
| 
436
 | 
1099
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1041
 | 
   $self->{_EPSILON} = $epsilon;  | 
| 
437
 | 
1099
 | 
 
 | 
 
 | 
 
 | 
 
 | 
903
 | 
   return;  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_epsilon_symbol {  | 
| 
441
 | 
43938
 | 
 
 | 
 
 | 
  
43938
  
 | 
  
0
  
 | 
33637
 | 
   my $self = shift;  | 
| 
442
 | 
43938
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89787
 | 
   return $self->{_EPSILON};  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_epsilon_transitions {  | 
| 
446
 | 
19713
 | 
 
 | 
 
 | 
  
19713
  
 | 
  
0
  
 | 
14968
 | 
   my $self = shift;  | 
| 
447
 | 
19713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14124
 | 
   my $state = shift;  | 
| 
448
 | 
19713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15743
 | 
   my @ret = ();  | 
| 
449
 | 
19713
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
31596
 | 
   if ($self->is_state($state)) {  | 
| 
450
 | 
19713
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
40584
 | 
     if (defined($self->{_TRANSITIONS}{$state}{$self->get_epsilon_symbol()})) {  | 
| 
451
 | 
12903
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9011
 | 
       @ret = @{$self->{_TRANSITIONS}{$state}{$self->get_epsilon_symbol()}};  | 
| 
 
 | 
12903
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16291
 | 
    | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
454
 | 
19713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
202450
 | 
   return @ret;    | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub delete_epsilon {  | 
| 
458
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
459
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   delete($self->{_EPSILON});  | 
| 
460
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return;  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub to_dfa {  | 
| 
464
 | 
120
 | 
 
 | 
 
 | 
  
120
  
 | 
  
0
  
 | 
795
 | 
   my $self = shift;  | 
| 
465
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
255
 | 
   my @Dstates = (); # stack of new states to find transitions for   | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # New DFA object reference  | 
| 
467
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
648
 | 
   my $DFA = FLAT::Legacy::FA::DFA->new();  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Initialize DFA start state by performing e-closure on the NFA start state  | 
| 
469
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
446
 | 
   my @Start = $self->epsilon_closure($self->get_start());  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Add this state to Dstates - subsets stored as anonymous arrays (no faking here!)  | 
| 
471
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
405
 | 
   push(@Dstates,[sort(@Start)]);  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Serialize subset into new state name - i.e, generate string-ified name  | 
| 
473
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
306
 | 
   my $ns = join('_',@Start);  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Add start state to DFA (placeholder Dtran not used)  | 
| 
475
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
372
 | 
   $DFA->set_start($ns);  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Add new state (serialized name) to DFA state array  | 
| 
477
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
264
 | 
   $DFA->add_state($ns);  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Check if start state is also final state, if so add  | 
| 
479
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
232
 | 
   foreach my $s (@Start) {  | 
| 
480
 | 
537
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
898
 | 
     if ($self->is_final($s) && !$DFA->is_final($ns)) {  | 
| 
481
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
       $DFA->add_final($ns);  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Loop until Dstate stack is exhausted  | 
| 
485
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
293
 | 
   while (@Dstates) {  | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # pop next state off to check  | 
| 
487
 | 
2034
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1828
 | 
     my @T = @{pop @Dstates};  | 
| 
 
 | 
2034
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4602
 | 
    | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Serialize subset into a string name  | 
| 
489
 | 
2034
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5338
 | 
     my $CURR_STATE = join('_',@T);  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # loop over each input symbol  | 
| 
491
 | 
2034
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4471
 | 
     foreach my $symbol ($self->get_symbols()) {  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # Obviously do not add the epsilon symbol to the dfa  | 
| 
493
 | 
6090
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
7813
 | 
       if ($symbol ne $self->get_epsilon_symbol()) {  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Add symbol - add_symbol ensures set of symbols is unique  | 
| 
495
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7377
 | 
 	$DFA->add_symbol($symbol);  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Get new subset of transition states  | 
| 
497
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6593
 | 
 	my @new = $self->epsilon_closure($self->move($symbol,(@T)));  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Serialize name of new state  | 
| 
499
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11946
 | 
 	$ns = join('_',@new);  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Add transition as long as $ns is not empty string  | 
| 
501
 | 
4056
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
13955
 | 
 	if ($ns !~ m/^$/) {  | 
| 
502
 | 
2541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7501
 | 
           $DFA->add_transition($CURR_STATE,$symbol,$ns);  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # Do only if this is a new state and it is not an empty string  | 
| 
504
 | 
2541
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
4790
 | 
 	  if (!$DFA->is_state($ns)) {  | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # add subset to @Dstates as an anonymous array  | 
| 
506
 | 
1914
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4384
 | 
             push(@Dstates,[@new]);  | 
| 
507
 | 
1914
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4164
 | 
             $DFA->add_state($ns);  | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # check to see if any NFA final states are in  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # the new DFA states  | 
| 
510
 | 
1914
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2029
 | 
 	    foreach my $s (@new) {  | 
| 
511
 | 
12966
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
18712
 | 
 	      if ($self->is_final($s) && !$DFA->is_final($ns)) {  | 
| 
512
 | 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
798
 | 
 		$DFA->add_final($ns);  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }	    | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
520
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
884
 | 
   return $DFA;  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub move {  | 
| 
524
 | 
4056
 | 
 
 | 
 
 | 
  
4056
  
 | 
  
0
  
 | 
3590
 | 
   my $self = shift;  | 
| 
525
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3007
 | 
   my $symbol = shift;  | 
| 
526
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7443
 | 
   my @subset = @_; # could be one state, could be a sub set of states...  | 
| 
527
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3977
 | 
   my @T = ();  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Loop over subset until exhausted  | 
| 
529
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5796
 | 
   while (@subset) {  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # get a state from the subset  | 
| 
531
 | 
26950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24782
 | 
     my $state = pop @subset;  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # get all transitions for $t, and put the in @u  | 
| 
533
 | 
26950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36005
 | 
     my @u = $self->get_transition_on($state,$symbol);  | 
| 
534
 | 
26950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31395
 | 
     foreach (@u) {  | 
| 
535
 | 
30013
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
57436
 | 
       if (defined($_)) {  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Add to new subset if not there already  | 
| 
537
 | 
13788
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26635
 | 
 	if (!$self->is_member($_,@T)) {  | 
| 
538
 | 
10667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22044
 | 
           push(@T,$_);  | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Returns ref to sorted subset array instead of list to preserve subset  | 
| 
544
 | 
4056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12219
 | 
   return sort(@T);   | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub epsilon_closure {  | 
| 
548
 | 
4176
 | 
 
 | 
 
 | 
  
4176
  
 | 
  
0
  
 | 
3760
 | 
   my $self = shift;  | 
| 
549
 | 
4176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5173
 | 
   my @subset = @_; # could be one state, could be a sub set of states...  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # initialize @closure with provided sub set  | 
| 
551
 | 
4176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4817
 | 
   my @closure = @subset;  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # loop over subset until exhausted  | 
| 
553
 | 
4176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6242
 | 
   while (@subset) {  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # get a state from the subset  | 
| 
555
 | 
19713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19262
 | 
     my $state = pop @subset;  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # get all epsilon transitions for $state, and put the in @u  | 
| 
557
 | 
19713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25561
 | 
     my @u = $self->get_epsilon_transitions($state);  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Loop over subset  | 
| 
559
 | 
19713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30268
 | 
     foreach (@u) {  | 
| 
560
 | 
19068
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
26380
 | 
       if (defined($_)) {  | 
| 
561
 | 
19068
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
36888
 | 
 	if (!$self->is_member($_,@closure)) {  | 
| 
562
 | 
8926
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8406
 | 
           push(@closure,$_);  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # Add state to states that must be checked for e-closure  | 
| 
564
 | 
8926
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15571
 | 
 	  push(@subset,$_);  | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Returns ref to sorted subset array instead of list to preserve subset  | 
| 
570
 | 
4176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15011
 | 
   return sort(@closure);   | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub info {  | 
| 
574
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
   my $self = shift;  | 
| 
575
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $out = '';   | 
| 
576
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= sprintf ("States         : ");  | 
| 
577
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   foreach ($self->get_states()) {  | 
| 
578
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $out .= sprintf "'$_' ";  | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
580
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= sprintf ("\nStart State    : '%s'\n",$self->get_start());  | 
| 
581
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= sprintf ("Final State(s) : ");  | 
| 
582
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   foreach ($self->get_final()) {  | 
| 
583
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $out .= sprintf "'$_' ";  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
585
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= sprintf ("\nAlphabet       : ");  | 
| 
586
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   foreach ($self->get_symbols()) {  | 
| 
587
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $out .= sprintf "'$_' ";  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
589
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   if (defined($self->get_epsilon_symbol())) {  | 
| 
590
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $out .= sprintf("\nEPSILON Symbol : '%s'",$self->get_epsilon_symbol());  | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }    | 
| 
592
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= sprintf ("\nTransitions    :\n");  | 
| 
593
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   foreach my $state ($self->get_states()) {  | 
| 
594
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     foreach my $symbol (keys %{$self->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
595
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       if ($symbol ne $self->get_epsilon_symbol()) {  | 
| 
596
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $out .= sprintf("\t('%s'),'%s' --> '%s'\n",$state,$symbol,join('\',\'',$self->get_transition_on($state,$symbol)));  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
598
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $out .= sprintf("\t('%s'),'%s' --> '%s'\n",$state,$symbol,join('\',\'',$self->get_epsilon_transitions($state)));        | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }    | 
| 
602
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $out;  | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub serialize {  | 
| 
606
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
   my $self = shift;  | 
| 
607
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $out = '';  | 
| 
608
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= sprintf("START :: %s\n",$self->get_start());  | 
| 
609
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= sprintf("FINAL :: %s\n",join(',',$self->get_final()));  | 
| 
610
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   if (defined($self->get_epsilon_symbol())) {  | 
| 
611
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $out .= sprintf("EPSILON :: %s\n",$self->get_epsilon_symbol());  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
613
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $out .= "\n";  | 
| 
614
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   foreach my $state ($self->get_states()) {  | 
| 
615
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $out .= sprintf("%s:\n",$state);  | 
| 
616
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     foreach my $symbol (keys %{$self->{_TRANSITIONS}{$state}}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
617
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       if ($symbol ne $self->get_epsilon_symbol()) {  | 
| 
618
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $out .= sprintf("$symbol %s\n",join(',',$self->get_transition_on($state,$symbol)));  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
620
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $out .= sprintf("$symbol %s\n",join(',',$self->get_epsilon_transitions($state)));        | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
623
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $out .= sprintf("\n");   | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
625
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $out;  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub generate_random {  | 
| 
629
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
   my $self = shift;  | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub generate_from_strings {  | 
| 
633
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
   my $self = shift;  | 
| 
634
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return "Coming soon!";  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |