Class: Rutile::NFA

Inherits:
Object
  • Object
show all
Defined in:
lib/rutile/nfa.rb

Defined Under Namespace

Classes: Node

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(str = [], opp = false, value = :transition_state, dummy: false) ⇒ NFA

Returns a new instance of NFA.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rutile/nfa.rb', line 69

def initialize(str = [], opp = false, value = :transition_state, dummy: false)
    if !(dummy)
        @nodes = Array.new(2) {|x| Node.new x }
        @start = @nodes.first.pos
        @end = @nodes.last.pos
    
        val = opp ? :not : @end
    
        if opp
            @nodes[@start].set_not [@end]
        end
        
        str.each do |char|
            if char == :dot
                throw Exception.new ("can't be not AND dot.") if val == :not
                @nodes[@start].set_not([val])
                @nodes[@start].empty("\n")
            else
                @nodes[@start].add(char, val)
            end
        end
    end
    
    @new_stack = []
    @old_stack = []
end

Instance Attribute Details

#endObject

Returns the value of attribute end.



67
68
69
# File 'lib/rutile/nfa.rb', line 67

def end
  @end
end

#new_stackObject

Returns the value of attribute new_stack.



67
68
69
# File 'lib/rutile/nfa.rb', line 67

def new_stack
  @new_stack
end

#nodesObject

Returns the value of attribute nodes.



67
68
69
# File 'lib/rutile/nfa.rb', line 67

def nodes
  @nodes
end

#old_stackObject

Returns the value of attribute old_stack.



67
68
69
# File 'lib/rutile/nfa.rb', line 67

def old_stack
  @old_stack
end

#startObject

Returns the value of attribute start.



67
68
69
# File 'lib/rutile/nfa.rb', line 67

def start
  @start
end

Class Method Details

.to_nfa(regex_raw, value) ⇒ Object



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/rutile/nfa.rb', line 206

def self::to_nfa(regex_raw, value)
    regex_raw = regex_raw.chars
    regex = []
    brackets = false
    while (!regex_raw.empty?)
        char = regex_raw.shift
        if brackets
            case char
            when "]"
                regex << :clb
                brackets = false
            when "\\"
                ch = regex_raw.shift
                case ch
                when 'd'
                    regex += "1234567890".chars
                when 'a'
                    regex += "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".chars
                when 'w'
                    regex += " \t".chars
                else
                    regex << ch
                end
            else
                regex << char
            end
        else
            case char
            when "."
                regex << :dot
            when "("
                regex << :opp
            when ")"
                regex << :clp
            when "*"
                regex << :ast
            when "+"
                regex << :plu
            when "?"
                regex << :que
            when "["
                brackets = true
                regex << :opb
            when "|"
                regex << :pip
            when "\\"
                regex << regex_raw.shift
            else
                regex << char
            end
        end
    end
    
    ret = create_nfa(regex)
    
    if (regex != [])
        throw Exception.new "malformed regex."
    end
    
    ret.set_val value
    
    return ret
end

Instance Method Details

#and(a) ⇒ Object



110
111
112
113
114
115
# File 'lib/rutile/nfa.rb', line 110

def and a
    a.nodes.each {|node| node.update_pos @nodes.size}
    @nodes[@end].add("", a.start + @nodes.size)
    @end = a.end + @nodes.size
    @nodes += a.nodes
end

#asterixObject



138
139
140
141
# File 'lib/rutile/nfa.rb', line 138

def asterix
    @nodes[@end].add("", @start)
    @nodes[@start].add("", @end)
end

#dupObject



153
154
155
156
157
158
159
160
161
# File 'lib/rutile/nfa.rb', line 153

def dup
    dupl = NFA.new(dummy: true)
    
    dupl.nodes = (@nodes.map {|node| node.dup}).to_a
    dupl.start = @start
    dupl.end   = @end
    
    return dupl
end

#feed(char) ⇒ Object



96
97
98
99
100
# File 'lib/rutile/nfa.rb', line 96

def feed(char)
    move(char)
    finalize
    return val
end

#or(a) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rutile/nfa.rb', line 117

def or a
    total_size = a.nodes.size + @nodes.size
    new_start = Node.new(total_size)
    new_end = Node.new(total_size + 1)
    
    a.nodes.each {|node| node.update_pos @nodes.size}
    
    new_start.add("",@start)
    new_start.add("",a.start + @nodes.size)
    
    @nodes[@end].add("", new_end.pos)
    a.nodes[a.end].add("", new_end.pos)
    
    @nodes += a.nodes
    @nodes += [new_start, new_end]
    
    
    @start = new_start.pos
    @end   = new_end.pos
end

#plusObject



147
148
149
150
151
# File 'lib/rutile/nfa.rb', line 147

def plus
    clone = self.dup
    clone.asterix
    self.and(clone)
end

#questionObject



143
144
145
# File 'lib/rutile/nfa.rb', line 143

def question
    @nodes[@start].add("", @end)
end

#resetObject



102
103
104
105
106
107
108
# File 'lib/rutile/nfa.rb', line 102

def reset
    @new_stack = []
    @old_stack = []
    e_closure(@start)
    finalize
    return val
end

#set_val(value) ⇒ Object



163
164
165
# File 'lib/rutile/nfa.rb', line 163

def set_val value
    @nodes[@end].value = value
end

#valObject



168
169
170
171
172
# File 'lib/rutile/nfa.rb', line 168

def val
    return @old_stack.map do |ind| 
        @nodes[ind].value
    end.to_a.uniq
end