reg 0.4.8 → 0.5.0a0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -0
- data/COPYING +0 -0
- data/History.txt +14 -0
- data/Makefile +59 -0
- data/README +87 -40
- data/article.txt +838 -0
- data/{assert.rb → lib/assert.rb} +3 -3
- data/{reg.rb → lib/reg.rb} +11 -4
- data/lib/reg/version.rb +21 -0
- data/lib/regarray.rb +455 -0
- data/{regarrayold.rb → lib/regarrayold.rb} +33 -7
- data/lib/regbackref.rb +73 -0
- data/lib/regbind.rb +230 -0
- data/{regcase.rb → lib/regcase.rb} +15 -5
- data/lib/regcompiler.rb +2341 -0
- data/{regcore.rb → lib/regcore.rb} +196 -85
- data/{regdeferred.rb → lib/regdeferred.rb} +35 -4
- data/{regposition.rb → lib/regevent.rb} +36 -38
- data/lib/reggraphpoint.rb +28 -0
- data/lib/reghash.rb +631 -0
- data/lib/reginstrumentation.rb +36 -0
- data/{regitem_that.rb → lib/regitem_that.rb} +32 -11
- data/{regknows.rb → lib/regknows.rb} +4 -2
- data/{reglogic.rb → lib/reglogic.rb} +76 -59
- data/{reglookab.rb → lib/reglookab.rb} +31 -21
- data/lib/regmatchset.rb +323 -0
- data/{regold.rb → lib/regold.rb} +27 -27
- data/{regpath.rb → lib/regpath.rb} +91 -1
- data/lib/regposition.rb +79 -0
- data/lib/regprogress.rb +1522 -0
- data/lib/regrepeat.rb +307 -0
- data/lib/regreplace.rb +254 -0
- data/lib/regslicing.rb +581 -0
- data/lib/regsubseq.rb +72 -0
- data/lib/regsugar.rb +361 -0
- data/lib/regvar.rb +180 -0
- data/lib/regxform.rb +212 -0
- data/{trace.rb → lib/trace_during.rb} +6 -4
- data/lib/warning.rb +37 -0
- data/parser.txt +26 -8
- data/philosophy.txt +18 -0
- data/reg.gemspec +58 -25
- data/regguide.txt +18 -0
- data/test/andtest.rb +46 -0
- data/test/regcompiler_test.rb +346 -0
- data/test/regdemo.rb +20 -0
- data/{item_thattest.rb → test/regitem_thattest.rb} +2 -2
- data/test/regtest.rb +2125 -0
- data/test/test_all.rb +32 -0
- data/test/test_reg.rb +19 -0
- metadata +108 -73
- data/calc.reg +0 -73
- data/forward_to.rb +0 -49
- data/numberset.rb +0 -200
- data/regarray.rb +0 -675
- data/regbackref.rb +0 -126
- data/regbind.rb +0 -74
- data/reggrid.csv +1 -2
- data/reghash.rb +0 -318
- data/regprogress.rb +0 -1054
- data/regreplace.rb +0 -114
- data/regsugar.rb +0 -230
- data/regtest.rb +0 -1078
- data/regvar.rb +0 -76
data/{assert.rb → lib/assert.rb}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin copyright
|
2
|
-
Copyright (C) 2004,2005 Caleb Clausen
|
2
|
+
Copyright (C) 2004,2005, 2016 Caleb Clausen
|
3
3
|
|
4
4
|
This library is free software; you can redistribute it and/or
|
5
5
|
modify it under the terms of the GNU Lesser General Public
|
@@ -18,14 +18,14 @@
|
|
18
18
|
|
19
19
|
module Kernel
|
20
20
|
def assert(expr,msg="assertion failed")
|
21
|
-
$Debug and (expr or raise msg)
|
21
|
+
defined? $Debug and $Debug and (expr or raise msg)
|
22
22
|
end
|
23
23
|
|
24
24
|
@@printed={}
|
25
25
|
def fixme(s)
|
26
26
|
unless @@printed[s]
|
27
27
|
@@printed[s]=1
|
28
|
-
$Debug and $stderr.print "FIXME: #{s}\n"
|
28
|
+
defined? $Debug and $Debug and $stderr.print "FIXME: #{s}\n"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/{reg.rb → lib/reg.rb}
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
=begin copyright
|
2
2
|
reg - the ruby extended grammar
|
3
|
-
Copyright (C) 2005,
|
3
|
+
Copyright (C) 2005, 2016 Caleb Clausen
|
4
4
|
|
5
5
|
This library is free software; you can redistribute it and/or
|
6
6
|
modify it under the terms of the GNU Lesser General Public
|
@@ -16,19 +16,26 @@
|
|
16
16
|
License along with this library; if not, write to the Free Software
|
17
17
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
18
|
=end
|
19
|
-
|
20
19
|
require 'regcore'
|
21
20
|
require 'reglogic'
|
22
21
|
require 'reghash'
|
23
22
|
require 'regarray'
|
23
|
+
require 'regrepeat'
|
24
|
+
require 'regsubseq'
|
24
25
|
#require 'regarrayold' #old bt engine
|
25
26
|
require 'regprogress' #new bt engine
|
26
27
|
#enable one engine or the other, but not both
|
27
28
|
|
29
|
+
require 'regevent'
|
30
|
+
require 'regbind'
|
31
|
+
require 'regreplace'
|
28
32
|
require 'regbackref'
|
29
33
|
require 'regitem_that'
|
30
34
|
require 'regknows'
|
31
35
|
require 'regsugar'
|
36
|
+
require 'regvar'
|
37
|
+
require 'regposition'
|
32
38
|
require 'regold' #will go away
|
33
|
-
|
34
|
-
|
39
|
+
|
40
|
+
require 'regcompiler' #engine, bah
|
41
|
+
#Kernel.instance_eval( &Reg::TLA_pirate)
|
data/lib/reg/version.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
=begin copyright
|
2
|
+
reg - the ruby extended grammar
|
3
|
+
Copyright (C) 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU Lesser General Public
|
7
|
+
License as published by the Free Software Foundation; either
|
8
|
+
version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
This library is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public
|
16
|
+
License along with this library; if not, write to the Free Software
|
17
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
=end
|
19
|
+
module Reg
|
20
|
+
VERSION="0.5.0a0"
|
21
|
+
end
|
data/lib/regarray.rb
ADDED
@@ -0,0 +1,455 @@
|
|
1
|
+
=begin copyright
|
2
|
+
reg - the ruby extended grammar
|
3
|
+
Copyright (C) 2005, 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU Lesser General Public
|
7
|
+
License as published by the Free Software Foundation; either
|
8
|
+
version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
This library is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public
|
16
|
+
License along with this library; if not, write to the Free Software
|
17
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
=end
|
19
|
+
|
20
|
+
require "assert"
|
21
|
+
require "pp"
|
22
|
+
require "forwardable"
|
23
|
+
require "regdeferred"
|
24
|
+
|
25
|
+
module Reg
|
26
|
+
module Reg
|
27
|
+
def itemrange; 1..1 end #default match 1 item
|
28
|
+
|
29
|
+
|
30
|
+
#create a (vector) Reg that will match this pattern repeatedly.
|
31
|
+
#(creates a Reg::Repeat.)
|
32
|
+
#the argument determines the number of times to match.
|
33
|
+
#times may be a positive integer, zero, Infinity, or a
|
34
|
+
#range over any of the above. if a range, the lower
|
35
|
+
#end may not be Infinity! Reg#- and Reg#+ are shortcuts
|
36
|
+
#for the most common cases of multiplting by a range.
|
37
|
+
#(at least 0 and at most Infinity.) watch out when
|
38
|
+
#multiplying with zero and Infinity (including in a
|
39
|
+
#range), as you can easily create a situation where
|
40
|
+
#the number of matches to enumerate explodes exponentionaly,
|
41
|
+
#or even is infinite. i won't say too much here except
|
42
|
+
#that these are generally the same sorts of problems you
|
43
|
+
#can run into with Regexps as well.
|
44
|
+
def *(times=0..Infinity)
|
45
|
+
Repeat.new(self,times)
|
46
|
+
end
|
47
|
+
|
48
|
+
#repeat this pattern up to atmost times. could match
|
49
|
+
#0 times as the minimum number of matches here is zero.
|
50
|
+
def -(atmost=1)
|
51
|
+
self*(0..atmost)
|
52
|
+
end
|
53
|
+
|
54
|
+
#repeat this pattern atleast times or more
|
55
|
+
def +(atleast=1)
|
56
|
+
self*(atleast..Infinity)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
#--------------------------
|
62
|
+
module Undoable
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
#--------------------------
|
67
|
+
module Composite
|
68
|
+
include Reg
|
69
|
+
def initialize(*args,&block)
|
70
|
+
at_construct_time(*args,&block)
|
71
|
+
# super
|
72
|
+
end
|
73
|
+
|
74
|
+
def at_construct_time(*a,&b); end #default does nothing
|
75
|
+
|
76
|
+
def visit_subregs()
|
77
|
+
todo=[self]
|
78
|
+
visited=Set[]
|
79
|
+
while node=todo.shift
|
80
|
+
next if visited[node.__id__]
|
81
|
+
yield node #visit this node
|
82
|
+
visited<<node.__id__
|
83
|
+
todo.push(*node.subregs) #schedule children to be visited
|
84
|
+
end
|
85
|
+
end
|
86
|
+
alias breadth_visit_subregs visit_subregs
|
87
|
+
|
88
|
+
def depth_visit_subregs(set=Set[],&visit)
|
89
|
+
set[self.__id__] and return
|
90
|
+
set<<self.__id__
|
91
|
+
subregs.each{|r| r.depth_visit_subregs(set,&visit) }
|
92
|
+
visit[self]
|
93
|
+
end
|
94
|
+
|
95
|
+
def undoable_infection
|
96
|
+
unless subregs.grep(Undoable).empty?
|
97
|
+
extend Undoable
|
98
|
+
class <<self
|
99
|
+
undef mmatch
|
100
|
+
alias mmatch mmatch_full
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def subregs
|
107
|
+
[@reg]
|
108
|
+
end
|
109
|
+
#includers should define #subregs if they don't have just a single @reg
|
110
|
+
|
111
|
+
protected
|
112
|
+
def multiple_infection(*regs)
|
113
|
+
regs.empty? and regs=subregs
|
114
|
+
regs.each{|reg|
|
115
|
+
reg.respond_to? :maybe_multiple and
|
116
|
+
reg.maybe_multiple(self)
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
#--------------------------
|
122
|
+
module Multiple
|
123
|
+
include Reg
|
124
|
+
def ===(other)
|
125
|
+
method_missing(:===, other)
|
126
|
+
end
|
127
|
+
=begin
|
128
|
+
def maybe_multiple(needsmult) #better name needed
|
129
|
+
assert( needsmult.respond_to?( :mmatch))
|
130
|
+
class <<needsmult
|
131
|
+
undef_method :mmatch
|
132
|
+
include Multiple
|
133
|
+
#alias mmatch mmatch_full #this doesn't work... why?
|
134
|
+
def mmatch(*xx) mmatch_full(*xx); end #have to do this instead
|
135
|
+
end
|
136
|
+
assert( needsmult.respond_to?( :mmatch))
|
137
|
+
end
|
138
|
+
|
139
|
+
def multiple_infection(*args) end #not needed?
|
140
|
+
#we're already multiple; no need to try to become multiple again
|
141
|
+
=end
|
142
|
+
def mmatch(*xx) #multiple match
|
143
|
+
abstract
|
144
|
+
end
|
145
|
+
|
146
|
+
#negated Reg::Multiple's are automatically lookaheads
|
147
|
+
def ~
|
148
|
+
~(Lookahead.new self)
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
def starts_with
|
153
|
+
abstract
|
154
|
+
end
|
155
|
+
|
156
|
+
def ends_with
|
157
|
+
abstract
|
158
|
+
end
|
159
|
+
|
160
|
+
def matches_class
|
161
|
+
raise 'multiple regs match no single class'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
#--------------------------
|
166
|
+
module Backtrace
|
167
|
+
# protected
|
168
|
+
|
169
|
+
def regs(ri) @regs[ri] end
|
170
|
+
|
171
|
+
def update_di(di,len); di+len; end
|
172
|
+
#--------------------------
|
173
|
+
$RegTraceEnable=$RegTraceDisable=nil
|
174
|
+
def trace_enabled?
|
175
|
+
@trace||=nil
|
176
|
+
$RegTraceEnable or (!$RegTraceDisable && @trace)
|
177
|
+
end
|
178
|
+
|
179
|
+
#--------------------------
|
180
|
+
def trace!
|
181
|
+
@trace=true
|
182
|
+
self
|
183
|
+
end
|
184
|
+
|
185
|
+
#--------------------------
|
186
|
+
def notrace!
|
187
|
+
@trace=false
|
188
|
+
self
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
#--------------------------
|
193
|
+
if false
|
194
|
+
class RR < ::Array
|
195
|
+
def inspect
|
196
|
+
[self,super].to_s
|
197
|
+
end
|
198
|
+
|
199
|
+
def rrflatten
|
200
|
+
result=[]
|
201
|
+
each{|i|
|
202
|
+
case i
|
203
|
+
when RR then result +=i.rrflatten
|
204
|
+
when Literal then result << i.unlit
|
205
|
+
else result << i
|
206
|
+
end
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
def +(other)
|
211
|
+
RR[*super]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
Result=RR
|
215
|
+
else
|
216
|
+
RR=::Array
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
#--------------------------
|
223
|
+
class Or
|
224
|
+
def mmatch(arr,start)
|
225
|
+
assert start <= arr.size
|
226
|
+
@regs.each_with_index {|reg,i|
|
227
|
+
reg===arr[start] and
|
228
|
+
return OrMatchSet.new(self,i,nil,1)
|
229
|
+
} unless start == arr.size
|
230
|
+
return nil
|
231
|
+
end
|
232
|
+
|
233
|
+
def itemrange
|
234
|
+
if true
|
235
|
+
min,max=Infinity,0
|
236
|
+
@regs.each {|r|
|
237
|
+
min=r.itemrange.first if Reg===r and min>r.itemrange.first
|
238
|
+
max=r.itemrange.last if Reg===r and max<r.itemrange.last
|
239
|
+
}
|
240
|
+
return min..max
|
241
|
+
else
|
242
|
+
limits=@regs.map{|r|
|
243
|
+
|
244
|
+
i=(r.respond_to? :itemrange)? r.itemrange : 1..1
|
245
|
+
[i.first,i.last]
|
246
|
+
}.transpose
|
247
|
+
limits.first.sort.first .. limits.last.sort.last
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
private
|
252
|
+
def mmatch_full(arr,start)
|
253
|
+
mat=nil
|
254
|
+
@regs.each_with_index{|r,i|
|
255
|
+
if r.respond_to? :mmatch
|
256
|
+
mat=r.mmatch(arr,start) or next
|
257
|
+
if mat.respond_to? :next_match
|
258
|
+
return OrMatchSet.new(self,i,mat,mat.next_match(arr,start).last)
|
259
|
+
else
|
260
|
+
return OrMatchSet.new(self,i,nil,mat.last)
|
261
|
+
end
|
262
|
+
else
|
263
|
+
r===arr[start] and
|
264
|
+
return OrMatchSet.new(self,i,nil,1)
|
265
|
+
end
|
266
|
+
}
|
267
|
+
|
268
|
+
assert mat.nil?
|
269
|
+
return nil
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
#--------------------------
|
274
|
+
class Xor
|
275
|
+
def clean_result
|
276
|
+
huh
|
277
|
+
end
|
278
|
+
|
279
|
+
def itemrange
|
280
|
+
#min,max=Infinity,0
|
281
|
+
#@regs.each {|r|
|
282
|
+
# min=[min,r.itemrange.first].sort.first
|
283
|
+
# max=[r.itemrange.last,max].sort.last
|
284
|
+
#}
|
285
|
+
#return min..max
|
286
|
+
limits=@regs.map{|r| i=r.itemrange; [i.first,i.last]}.transpose
|
287
|
+
limits.first.sort.first .. limits.last.sort.last
|
288
|
+
end
|
289
|
+
|
290
|
+
private
|
291
|
+
if false
|
292
|
+
def mmatch_full(arr,start)
|
293
|
+
mat=i=nil
|
294
|
+
count=0
|
295
|
+
@regs.each_with_index{|reg,idx|
|
296
|
+
if reg.respond_to? :mmatch
|
297
|
+
mat=reg.mmatch(arr,start) or next
|
298
|
+
else
|
299
|
+
reg===arr[start] or next
|
300
|
+
mat=[[arr[start]],1]
|
301
|
+
end
|
302
|
+
count==0 or return nil
|
303
|
+
count=1
|
304
|
+
assert mat
|
305
|
+
}
|
306
|
+
|
307
|
+
return nil unless mat
|
308
|
+
assert count==1
|
309
|
+
mat.respond_to? :next_match and return XorMatchSet.new(reg,idx,mat,huh)
|
310
|
+
|
311
|
+
a=RR[nil]*regs.size
|
312
|
+
a[idx]=mat[0]
|
313
|
+
mat[0]=a
|
314
|
+
assert huh
|
315
|
+
assert ::Array===mat.first.first
|
316
|
+
return mat
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def mmatch_full arr, start
|
321
|
+
found=nil
|
322
|
+
@regs.each{|reg|
|
323
|
+
if m=reg.mmatch(arr, start)
|
324
|
+
return if found
|
325
|
+
found=m
|
326
|
+
end
|
327
|
+
}
|
328
|
+
return found
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
#--------------------------
|
334
|
+
class And
|
335
|
+
include Backtrace #shouldn't this be included only when needed?
|
336
|
+
|
337
|
+
def update_di(di,len) di; end
|
338
|
+
|
339
|
+
|
340
|
+
def clean_result
|
341
|
+
huh
|
342
|
+
end
|
343
|
+
|
344
|
+
|
345
|
+
def enough_matches? matchcnt,*bogus
|
346
|
+
matchcnt==@regs.size
|
347
|
+
end
|
348
|
+
|
349
|
+
def itemrange
|
350
|
+
limits=@regs.map{|r| i=r.itemrange; [i.first,i.last]}.transpose
|
351
|
+
limits.first.sort.last .. limits.last.sort.last
|
352
|
+
end
|
353
|
+
|
354
|
+
private
|
355
|
+
def mmatch_full(arr,start)
|
356
|
+
#in this version, at least one of @regs is a multiple reg
|
357
|
+
assert( (0..arr.size).include?( start))
|
358
|
+
result,*bogus=huh.bt_match(arr,start,0,0,[RR[]])
|
359
|
+
result and AndMatchSet.new(self,result)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
#--------------------------
|
364
|
+
class Array
|
365
|
+
include Reg,Backtrace,Composite
|
366
|
+
|
367
|
+
def max_matches; @regs.size end
|
368
|
+
|
369
|
+
def initialize(*regs)
|
370
|
+
|
371
|
+
#inline subsequences and short fixed repetitions
|
372
|
+
iterate=proc{|list|
|
373
|
+
result=[]
|
374
|
+
list.each{|reg|
|
375
|
+
case reg
|
376
|
+
when Subseq
|
377
|
+
result.push(*iterate[reg.subregs])
|
378
|
+
when Repeat
|
379
|
+
rr=reg.times
|
380
|
+
if rr.first==rr.last and rr.first<=3
|
381
|
+
result.push(*iterate[[reg.regs(nil)]*rr.first])
|
382
|
+
else
|
383
|
+
result<<reg
|
384
|
+
end
|
385
|
+
else result<< Deferred.defang!(reg)
|
386
|
+
end
|
387
|
+
}
|
388
|
+
result
|
389
|
+
}
|
390
|
+
@regs=iterate[regs]
|
391
|
+
# p [:+, :[]]
|
392
|
+
super
|
393
|
+
end
|
394
|
+
|
395
|
+
class <<self
|
396
|
+
alias new__nobooleans new
|
397
|
+
def new(*args)
|
398
|
+
# args.detect{|o| /^(AND|X?OR)$/.sym===o } or return new__nobooleans(*args)
|
399
|
+
# +[/^(AND|X?OR)$/.sym.splitter].match(args)
|
400
|
+
Pair===args.first and return ::Reg::OrderedHash.new(*args)
|
401
|
+
new__nobooleans(*args)
|
402
|
+
end
|
403
|
+
alias [] new
|
404
|
+
end
|
405
|
+
|
406
|
+
def matches_class; ::Array end
|
407
|
+
|
408
|
+
def subitemrange
|
409
|
+
#add the ranges of the individual items
|
410
|
+
@subitemrange ||= #some caching...
|
411
|
+
begin
|
412
|
+
list=Thread.current[:$Reg__Subseq__subitemranges_in_progress]||={}
|
413
|
+
id=__id__
|
414
|
+
list[id] and throw(id.to_s.to_sym,0..Infinity)
|
415
|
+
list[id]=1
|
416
|
+
catch(id.to_s.to_sym){
|
417
|
+
@regs.inject(0){|sum,ob| sum+(Reg===ob ? ob.itemrange.begin : 1) } ..
|
418
|
+
@regs.inject(0){|sum,ob| sum+(Reg===ob ? ob.itemrange.end : 1) }
|
419
|
+
}
|
420
|
+
ensure
|
421
|
+
list.delete id
|
422
|
+
end
|
423
|
+
|
424
|
+
end
|
425
|
+
|
426
|
+
def multiple_infection(*args) end #never do anything for Reg::Array
|
427
|
+
|
428
|
+
def enough_matches? matchcnt,eof
|
429
|
+
matchcnt==@regs.size and eof
|
430
|
+
end
|
431
|
+
|
432
|
+
def +(reg)
|
433
|
+
if self.class==reg.class
|
434
|
+
self.class.new( *@regs+reg.regs )
|
435
|
+
else
|
436
|
+
super
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
def inspect
|
441
|
+
name="$RegInspectRecursing#{object_id}"
|
442
|
+
Thread.current[name] and return '+[...]'
|
443
|
+
Thread.current[name]=true
|
444
|
+
result="+["+ @regs.collect{|r| r.inspect}.join(', ') +"]"
|
445
|
+
Thread.current[name]=nil
|
446
|
+
result
|
447
|
+
end
|
448
|
+
|
449
|
+
def subregs; @regs.dup end
|
450
|
+
end
|
451
|
+
|
452
|
+
|
453
|
+
|
454
|
+
|
455
|
+
end
|