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.
Files changed (64) hide show
  1. checksums.yaml +4 -0
  2. data/COPYING +0 -0
  3. data/History.txt +14 -0
  4. data/Makefile +59 -0
  5. data/README +87 -40
  6. data/article.txt +838 -0
  7. data/{assert.rb → lib/assert.rb} +3 -3
  8. data/{reg.rb → lib/reg.rb} +11 -4
  9. data/lib/reg/version.rb +21 -0
  10. data/lib/regarray.rb +455 -0
  11. data/{regarrayold.rb → lib/regarrayold.rb} +33 -7
  12. data/lib/regbackref.rb +73 -0
  13. data/lib/regbind.rb +230 -0
  14. data/{regcase.rb → lib/regcase.rb} +15 -5
  15. data/lib/regcompiler.rb +2341 -0
  16. data/{regcore.rb → lib/regcore.rb} +196 -85
  17. data/{regdeferred.rb → lib/regdeferred.rb} +35 -4
  18. data/{regposition.rb → lib/regevent.rb} +36 -38
  19. data/lib/reggraphpoint.rb +28 -0
  20. data/lib/reghash.rb +631 -0
  21. data/lib/reginstrumentation.rb +36 -0
  22. data/{regitem_that.rb → lib/regitem_that.rb} +32 -11
  23. data/{regknows.rb → lib/regknows.rb} +4 -2
  24. data/{reglogic.rb → lib/reglogic.rb} +76 -59
  25. data/{reglookab.rb → lib/reglookab.rb} +31 -21
  26. data/lib/regmatchset.rb +323 -0
  27. data/{regold.rb → lib/regold.rb} +27 -27
  28. data/{regpath.rb → lib/regpath.rb} +91 -1
  29. data/lib/regposition.rb +79 -0
  30. data/lib/regprogress.rb +1522 -0
  31. data/lib/regrepeat.rb +307 -0
  32. data/lib/regreplace.rb +254 -0
  33. data/lib/regslicing.rb +581 -0
  34. data/lib/regsubseq.rb +72 -0
  35. data/lib/regsugar.rb +361 -0
  36. data/lib/regvar.rb +180 -0
  37. data/lib/regxform.rb +212 -0
  38. data/{trace.rb → lib/trace_during.rb} +6 -4
  39. data/lib/warning.rb +37 -0
  40. data/parser.txt +26 -8
  41. data/philosophy.txt +18 -0
  42. data/reg.gemspec +58 -25
  43. data/regguide.txt +18 -0
  44. data/test/andtest.rb +46 -0
  45. data/test/regcompiler_test.rb +346 -0
  46. data/test/regdemo.rb +20 -0
  47. data/{item_thattest.rb → test/regitem_thattest.rb} +2 -2
  48. data/test/regtest.rb +2125 -0
  49. data/test/test_all.rb +32 -0
  50. data/test/test_reg.rb +19 -0
  51. metadata +108 -73
  52. data/calc.reg +0 -73
  53. data/forward_to.rb +0 -49
  54. data/numberset.rb +0 -200
  55. data/regarray.rb +0 -675
  56. data/regbackref.rb +0 -126
  57. data/regbind.rb +0 -74
  58. data/reggrid.csv +1 -2
  59. data/reghash.rb +0 -318
  60. data/regprogress.rb +0 -1054
  61. data/regreplace.rb +0 -114
  62. data/regsugar.rb +0 -230
  63. data/regtest.rb +0 -1078
  64. data/regvar.rb +0 -76
@@ -0,0 +1,307 @@
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
+ require 'regarray'
20
+ module Reg
21
+
22
+ #--------------------------
23
+ class Repeat
24
+ include Reg,Backtrace,Multiple,Composite
25
+
26
+ attr :times
27
+
28
+ def max_matches; @times.end end
29
+
30
+ def regs(ri) @reg end
31
+
32
+ def initialize(reg,times)
33
+ Integer===times and times=times..times
34
+ times.exclude_end? and times=times.begin..times.end-1
35
+ assert times.begin <= times.end
36
+ assert times.begin < Infinity
37
+ assert times.begin >= 0
38
+ assert times.end >= 0
39
+ if Multiple===reg
40
+ class<<self
41
+ #alias mmatch mmatch_full #this doesn't work... why?
42
+ def mmatch(*xx) mmatch_full(*xx); end #have to do this instead
43
+ end
44
+ else
45
+ assert reg.itemrange==(1..1)
46
+ @itemrange=times
47
+ end
48
+ @reg,@times=reg,times
49
+ super
50
+ end
51
+
52
+ def itemrange
53
+ defined? @itemrange and return @itemrange
54
+
55
+ list=Thread.current[:$Reg__Repeat__irs_in_progress]||={}
56
+ list[__id__] and huh
57
+ list[__id__]=1
58
+ i=@reg.itemrange
59
+ rf,rl=i.first,i.last
60
+ tf,tl=times.first,times.last
61
+ @itemrange = rf*tf ..
62
+ if tl==0 or rl==0
63
+ 0
64
+ elsif tl==Infinity
65
+ #ought to emit warnings if trouble here...
66
+ #rl==Infinity and maybe trouble
67
+ #rf==0 and trouble
68
+ Infinity
69
+ elsif rl==Infinity
70
+ #...and here
71
+ #maybe trouble #... combinatorial explosion
72
+ Infinity
73
+ else
74
+ rl*tl
75
+ end
76
+ ensure
77
+ list.delete __id__ if list
78
+ end
79
+
80
+
81
+ def enough_matches? matchcnt,*bogus
82
+ @times===matchcnt
83
+ end
84
+
85
+ def inspect
86
+ "(#{@reg.inspect})"+
87
+ if @times.end==Infinity
88
+ if (0..1)===@times.begin
89
+ "."+%w[* +][@times.begin]
90
+ else
91
+ "+#{@times.begin}"
92
+ end
93
+ elsif @times.begin==0
94
+ "-#{@times.end}"
95
+ elsif @times.begin==@times.end
96
+ "*#{@times.begin}"
97
+ else
98
+ "*(#{@times.begin}..#{@times.end})"
99
+ end
100
+ end
101
+
102
+ def subregs; [@reg] end
103
+
104
+ private
105
+
106
+ end
107
+
108
+
109
+
110
+
111
+
112
+
113
+ #--------------------------
114
+ class None; end
115
+ class <<None #class as singleton instance
116
+ include Reg
117
+ def new; self end
118
+
119
+ def *(times)
120
+ times===0 ? Many[0] : self
121
+ end
122
+
123
+ def ~; Any; end
124
+
125
+ def &(other); self; end
126
+
127
+ def |(other) other.reg end
128
+ def ^(other) other.reg end
129
+
130
+ def ===(other); false; end
131
+ def matches_class; self; end
132
+ def inspect; "~_" end #hmmmm...
133
+ end
134
+
135
+
136
+ #--------------------------
137
+ class Any; end
138
+ class <<Any #maybe all this can be in Object's meta-class....
139
+ include Reg
140
+
141
+ #any is a singleton
142
+ def new; self end
143
+
144
+ def *(times)
145
+ Many.new(times)
146
+ end
147
+
148
+ def ~; None; end
149
+
150
+ def &(other)
151
+ if other.itemrange.first>=1
152
+ other.reg
153
+ else
154
+ And.new(self,other)
155
+ end
156
+ end
157
+
158
+ def |(other); self; end
159
+ def ^(other); ~other.reg end
160
+
161
+ def ===(other); true;end
162
+ def matches_class; ::Object end
163
+ def inspect; "_" end #hmmmm...
164
+ end
165
+
166
+
167
+
168
+ #--------------------------
169
+ module HasCmatch; end
170
+ module HasBmatch; end
171
+ class ManyClass
172
+ include Reg
173
+ include Multiple
174
+
175
+ class <<self
176
+ @@RAMs={}
177
+ alias uncached__new new
178
+ def new times=0..Infinity
179
+ Range===times and times.exclude_end? and times=times.begin..times.end-1
180
+ @@RAMs[times] ||= uncached__new times
181
+ end
182
+ alias [] new
183
+ end
184
+
185
+ def initialize(times=0..Infinity)
186
+ Integer===times and times=times..times
187
+ @times=times
188
+ extend @times.begin==@times.end ? HasBmatch : HasCmatch
189
+ # super
190
+ end
191
+
192
+ def mmatch(arr,start)
193
+ left=arr.size-start
194
+ beg=@times.begin
195
+ if beg==left ; [arr[start..-1],left]
196
+ elsif beg<left
197
+ SingleRepeatMatchSet.new([left,@times.end].min, -1, beg)
198
+ end
199
+ end
200
+
201
+ def subregs; [Any] end
202
+
203
+ def inspect
204
+ if @times.end.to_f.infinite?
205
+ if @times.begin.zero?
206
+ "__"
207
+ else
208
+ "(Any+#{@times.begin})"
209
+ end
210
+ elsif @times.begin==@times.end
211
+ "(Any*#{@times.begin})"
212
+ elsif @times.begin.zero?
213
+ "(Any-#{@times.end})"
214
+ else
215
+ "(Any*(#{@times}))"
216
+ end
217
+ end
218
+
219
+ def l; ManyLazyClass.new(@times) end
220
+ def g; self end
221
+
222
+ def itemrange; @times end
223
+ end
224
+
225
+ #--------------------------
226
+ class ManyLazyClass
227
+ include Reg
228
+ include Multiple
229
+
230
+ class <<self
231
+ @@RAMs={}
232
+ alias uncached__new new
233
+ def new times=0..Infinity
234
+ Range===times and times.exclude_end? and times=times.begin..times.end-1
235
+ @@RAMs[times] ||= uncached__new times
236
+ end
237
+ alias [] new
238
+ end
239
+
240
+ def initialize(times=0..Infinity)
241
+ Integer===times and times=times..times
242
+ @times=times
243
+ # super
244
+ end
245
+
246
+
247
+ def subregs; [Any] end
248
+
249
+ def inspect
250
+ if @times.end.to_f.infinite?
251
+ if @times.begin.zero?
252
+ "Many"
253
+ else
254
+ "(Any+#{@times.begin})"
255
+ end
256
+ elsif @times.begin==@times.end
257
+ "(Any*#{@times.begin})"
258
+ elsif @times.begin.zero?
259
+ "(Any-#{@times.end})"
260
+ else
261
+ "(Any*(#{@times}))"
262
+ end+".l"
263
+ end
264
+
265
+ def mmatch(arr,start)
266
+ left=arr.size-start
267
+ beg=@times.begin
268
+ if beg==left ; [arr[start..-1],left]
269
+ elsif beg<left
270
+ SingleRepeatMatchSet.new(beg, 1, [left,@times.end].min)
271
+ end
272
+ end
273
+
274
+ def g; ManyClass.new(@times) end
275
+ def l; self end
276
+
277
+ end
278
+
279
+
280
+ Many=ManyClass.new
281
+ class<<Many
282
+ extend Forwardable
283
+ def_delegators ManyClass, :new, :[]
284
+ end
285
+
286
+ #--------------------------
287
+ class <<::Object
288
+ _Objects_class=::Object.__id__
289
+ define_method :reg do
290
+ __id__==_Objects_class ? Any : Fixed.new(self)
291
+ end
292
+ end
293
+ OB=Any
294
+ OBS=Many
295
+
296
+ if false #traditional and uncomplicated version of OB and OBS
297
+ OB=::Object.reg
298
+ OBS=OB+0 #std abbreviation for 0 or more of anything
299
+ def OBS.inspect
300
+ "OBS"
301
+ end
302
+ def OB.inspect
303
+ "OB"
304
+ end
305
+ end
306
+
307
+ end
@@ -0,0 +1,254 @@
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
+ require 'ron/graphedge'
20
+
21
+ module Reg
22
+ module Reg
23
+
24
+ #turns a Reg that matches into a Reg that matches and
25
+ #replaces. (creates a Reg::Transform)
26
+ def >>(rep)
27
+ Transform.new(self,rep)
28
+ end
29
+
30
+ def finally(&block)
31
+ Finally.new(self,block)
32
+ end
33
+ end
34
+
35
+ class Finally
36
+ include Reg,Undoable,Composite
37
+
38
+ def initialize(reg,block=nil,&block2)
39
+ raise ArgumentError if block and block2
40
+ @reg,@block=reg,block||block2
41
+ super
42
+ end
43
+
44
+ def mmatch(progress)
45
+ progress.register_later progress(&@block) #shouldn't this be after mmatch?
46
+
47
+ @reg.mmatch progress
48
+ end
49
+
50
+ #forward most other things to @reg (but what??)
51
+ end
52
+
53
+
54
+ =begin contexts for a Reg::Transform
55
+ an element of a Reg::Array, Reg::Subseq or Reg::Repeat (sequence)
56
+ a key matcher in a Reg::Hash or similar
57
+ a value matcher in Reg::Hash or similar
58
+ a value matcher in Reg::Object
59
+ directly in a top-level matcher
60
+
61
+ but a Reg::Logical (Or, for instance) could be in any of above, and a Transform could be within.
62
+ =end
63
+
64
+ module TransformUndoable
65
+ include Undoable
66
+ end
67
+
68
+ class Transform
69
+ include Reg,TransformUndoable,Composite
70
+
71
+ def initialize(reg,rep)
72
+ Replace===rep or rep=Replace.make_replace( rep )
73
+ @left,@right=reg,rep
74
+ #@reg,@rep=reg,rep
75
+ super
76
+ end
77
+
78
+ attr_accessor :left,:right
79
+ #attr_reader :reg,:rep
80
+ alias reg left
81
+ alias rep right
82
+ alias from left
83
+ alias to right
84
+ alias from= left=
85
+ alias to= right=
86
+
87
+
88
+ def mmatch(progress)
89
+ origpos=progress.get_index
90
+ result=@reg.mmatch(progress) or return
91
+ MatchSet===result and return ReplaceMatchSet.new(self,progress,origpos,result)
92
+ replace origpos,result.last,progress
93
+ return result
94
+ end
95
+
96
+ def replace(origpos,len,progress)
97
+ Eventually===@rep and huh
98
+ progress.register_replace(origpos,len, @rep)
99
+ end
100
+
101
+ def subregs
102
+ [@left]
103
+ end
104
+ end
105
+
106
+ =begin
107
+ varieties of Reg::Replace: (replacement values)
108
+ Reg::BackrefLike
109
+ Reg::Bound ???
110
+ Reg::RepProc ... not invented yet
111
+ Reg::ItemThat... maybe not, but some sort of Deferred?
112
+ Reg::Equals (or Literal, it's descendant)
113
+ Reg::Fixed
114
+ Reg::Subseq... interpolate items
115
+ any other Object (as if wrapped in Reg::Fixed)
116
+ (Reg::Array inserts an array at that point. Reg::Subseq
117
+ inlines its items at that point. when used this way,
118
+ they are not matching anything, nor are the contents necessarily matchers.
119
+ they just serve as convenient container classes.)
120
+ (to actually insert a Reg::Array or anything that's special at this point,
121
+ wrap it in a Reg::Literal.)
122
+ Array (as if Reg::Array?)
123
+ Reg::Transform????
124
+ =end
125
+
126
+ module Replace
127
+ def self.evaluate(item,progress,gpoint) #at match time
128
+ huh
129
+ case item
130
+ when BackrefLike; item.formula_value(nil,progress)
131
+ when ItemThatLike; item.formula_value(gpoint.old_value,progress)
132
+ # when Bound; huh
133
+ # when Transform; huh????
134
+ when ::Reg::Array
135
+ assert gpoint.is_a?( GraphPoint::Array)
136
+ [item.regs]
137
+ when ::Reg::Subseq
138
+ assert gpoint.is_a?( GraphPoint::Array)
139
+ item.regs
140
+ when ::Array; huh 'like Reg::Array or Reg::Subseq?'
141
+ when ::Reg::Wrapper; item.unwrap
142
+ when Replace::Form; item.fill_out(progress,gpoint)
143
+ else item #like it was wrapped in Reg::Fixed
144
+ end
145
+ end
146
+
147
+ def self.make_replace item #at compile time
148
+ case item
149
+ when Deferred,Wrapper,BoundRef; Deferred.defang! item
150
+ #when ::Reg::Subseq; huh
151
+ #when ::Reg::Reg; huh #error?
152
+ else
153
+ needsinterp=false
154
+ Ron::GraphWalk.breadth_graphwalk(item){|cntr,datum,idx,idxtype|
155
+ Deferred.defang! datum
156
+ case datum
157
+ when Deferred,Wrapper,BoundRef #,Formula ??
158
+ needsinterp=true
159
+ end
160
+ }
161
+ needsinterp and item=Replace::Form.new(item)
162
+ end
163
+ item
164
+ end
165
+
166
+
167
+
168
+ class Form #kinda like a lisp form... as far as i understand them anyway
169
+ def initialize(repldata)
170
+ @repldata=repldata
171
+ rebuild_dupset
172
+ end
173
+
174
+ def initialize_copy(other)
175
+ @repldata=other.repldata.clone rescue other.repldata
176
+ rebuild_dupset
177
+ end
178
+
179
+ def _dump
180
+ Marshal.dump(@repldata)
181
+ end
182
+
183
+ def self.load(str)
184
+ new(Marshal.load(str))
185
+ end
186
+
187
+ def rebuild_dupset
188
+ cntrstack=[]
189
+ @alwaysdupit=Set[]
190
+ seen=Set[]
191
+ traverser=proc{|cntr,o,i,ty|
192
+ next if seen.include? o.__id__
193
+ seen<< o.__id__
194
+
195
+ cntrstack.push cntr.__id__ if cntr
196
+ case o
197
+ when Deferred,Literal; @alwaysdupit|=cntrstack
198
+ end
199
+ Ron::GraphWalk.traverse(o,&traverser)
200
+ cntrstack.pop
201
+ }
202
+ Ron::GraphWalk.traverse(repldata,&traverser)
203
+ end
204
+
205
+ attr :repldata
206
+
207
+ def repldata= repldata
208
+ @repldata=repldata
209
+ rebuild_dupset
210
+ end
211
+
212
+ def fill_out_simple(session,other)
213
+ incomplete=false
214
+ result=Ron::GraphWalk.breadth_graphcopy(@repldata) {|cntr,o,i,ty,useit|
215
+ useit[0]=true
216
+ newo=@alwaysdupit.include?(o.__id__) ? o.dup :
217
+ case o
218
+ # when ItemThatLike,RegThatLike;
219
+ # o.formula_value(other,session)
220
+ when Formula #if there's any Deferred items in @repldata, evaluate (#formula_value) them now
221
+ o.formula_value(other,session)
222
+ when Literal; o.unwrap #literal items should be unwrapped
223
+ when BoundRef; o.formula_value(other,session) #unreachable; BoundRefs are always Formulas currently
224
+ else useit[0]=false
225
+ end
226
+ incomplete=true if Formula===newo and not Literal===o
227
+ newo
228
+ }
229
+ result=Form.new result if incomplete and !session["final"]
230
+ return result
231
+ end
232
+
233
+ def fill_out(progress,gpoint)
234
+ Ron::GraphWalk.breadth_graphcopy(@repldata) {|cntr,o,i,ty,useit|
235
+ useit[0]=true
236
+ @alwaysdupit.include?(o.__id__) ? o.dup :
237
+ case o
238
+ when ItemThatLike,RegThatLike
239
+ o.formula_value(gpoint.old_value,progress)
240
+ when Deferred; huh #if there's any Deferred items in @repldata, evaluate (#formula_value) them now
241
+ o.formula_value(huh(nil),progress)
242
+ when Literal; o.unwrap #literal items should be unwrapped
243
+ else useit[0]=false
244
+ end
245
+ }
246
+
247
+
248
+ huh
249
+ end
250
+
251
+ end
252
+ end
253
+
254
+ end