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,581 @@
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
+ =begin
20
+ array_slicing=Reg::const
21
+ subseq_slicing=Reg::const
22
+ hash_slicing=Reg::const
23
+ object_slicing=Reg::const
24
+
25
+ slicing_elem=hash_slicing|array_slicing|object_slicing|1
26
+ array_slicing_elems=(slicing_elem|item_that(Integer)>=0|subseq_slicing).+
27
+
28
+ sequence_slicing=+[array_slicing_elems]
29
+ array_slicing.set! Reg::Slicing::Seq&sequence_slicing
30
+ subseq_slicing.set! Reg::Slicing::Subseq&sequence_slicing
31
+
32
+ map_slicing=+[+[OB,+[+[OB,slicing_elem].*]].*]
33
+ hash_slicing.set! Reg::Slicing::Hash&map_slicing
34
+ object_slicing.set! Reg::Slicing::Object&map_slicing
35
+
36
+
37
+
38
+
39
+
40
+ scalar=Integer|Float|String|Symbol|nil|true|false
41
+
42
+
43
+ huh range
44
+ huh proc,method,unboundmethod,thread,process,binding,file,io,class?,module?,continuation,dir,
45
+ threadgroup,mutex,conditionvariable,queue
46
+ object_graph=Reg::const
47
+ array_graph=+[object_graph.*]
48
+ hash_graph=+{object_graph=>object_graph}
49
+ object_graph.set! (scalar|array_graph|hash_graph|OB) & -{/^@/=>object_graph}
50
+ =end
51
+
52
+ =begin
53
+
54
+ slicings come in four basic varieties: sequence, subsequence, hash, and object
55
+ sequence slicings represent a way to carve up an array. the simplest form is
56
+ an array of integers, which represent the indexes at which to break the array
57
+ into pieces.
58
+ subsequence are very similar to sequence, but represent a subrange of the array.
59
+ hash slicings are an ordered list of pairs of hash key matchers and the
60
+ corresponding subhash of all keys of the pairs in the hash to be matched which matched that
61
+ key matcher-value matcher pair. the usual value in these subhashes is 1, but another
62
+ slicing is also allowed.
63
+ object slicings are similar to hash slicings except the keys and values are the
64
+ names and values of instance variables and (non-side-effect-containing) methods.
65
+
66
+ any slicing can contain another slicing (except that subsequences can only be in
67
+ other subsequences or sequences. this contained or sub-slicing tells you how to slice
68
+ up the sub item(s) at that point in the larger slicing.
69
+
70
+ Slicings::Progress state consists of 3 items:
71
+ a root slicing
72
+ a path from the root to the current slicing
73
+ a backtracking stack
74
+
75
+ the backtracking stack:
76
+ keep a stack of arrays of 3 things:
77
+ a path from the root to this node, (savedpath)
78
+ number of items to go back when match failure occurs (backcount)
79
+ number of levels to go up when match failure occurs (upcount)
80
+
81
+ upcount can never be decremented below zero. attempts to do so just leave it at zero
82
+ backcount cannot be changed unless upcount is zero?....unless savedpath and path are same?
83
+
84
+ (the first item is a stack, so this is a stack of stacks.)
85
+ on backtrack:
86
+ pop the last item off the backtracking stack, and using the values in it:
87
+ restore the path to savedpath
88
+ go up upcount times....? upcount even needed now?
89
+ delete the last backcount items in that level we just went up/down to
90
+
91
+ on bt_stop:
92
+ push a new array onto the backtracking stack, with
93
+ savedpath set to a (shallow) copy of the current path
94
+ upcount and backcount both 0
95
+
96
+ on newcontext: #used in these matchers: +[], -[], | & ^ repeat +{} -{} (~ la lb )?
97
+ make a new slicing, inserted at "current position" in the current slicing
98
+ update path to include newly created slicing
99
+
100
+ "current position" means
101
+ at the end of sequence and subseq slicings
102
+ in map slicings: inserted into last hash (with key of the 'current key') in the slicing
103
+ replacing the elem at the end of map slicings
104
+
105
+ 'current key'
106
+ i'm not sure where this comes from
107
+
108
+ on endcontext:
109
+ remove current slicing from path
110
+ "decrement" upcount?
111
+ (if upcount is already zero, zero out backcount...? no)
112
+
113
+ after a key (and friends...) matches the current pattern in hash and object matchers
114
+ push key and its value onto path
115
+ push onto path key with a tentative 'value' of nil,
116
+ to be replaced later once it is known
117
+
118
+ on match_attempt_success in Reg::Array or Reg::Subseq or logicals :
119
+ push the current cursor position onto current slicing
120
+
121
+ on match_attempt_fail in logicals (well or and xor, anyway):
122
+ push 0 onto current slicing
123
+ =end
124
+
125
+
126
+
127
+ =begin
128
+ module Reg
129
+ class Slicings<::Array
130
+ def initialize(pattern,*array)
131
+ @pattern=pattern
132
+ replace array
133
+ end
134
+
135
+ class Progress
136
+ def initialize(root)
137
+ @root=root
138
+ @path=Path[]
139
+ end
140
+
141
+ attr_reader :root,:path
142
+
143
+ def newcontext(pattern)
144
+ current.push pattern.slicing_type.new
145
+ huh 'modify path'
146
+ end
147
+
148
+ def endcontext
149
+ huh
150
+ end
151
+
152
+ def match_attempt_starting
153
+ huh
154
+ end
155
+
156
+ def match_attempt_fail
157
+ huh
158
+ end
159
+
160
+ def match_attempt_success
161
+ huh
162
+ end
163
+
164
+ def current
165
+ @path.last.last
166
+ end
167
+
168
+ def regsidx
169
+ current.size
170
+ end
171
+ alias ri regsidx
172
+ end
173
+
174
+ class Sequence<Slicings
175
+ def display
176
+ result={}
177
+ regs=@pattern.subregs
178
+ each_index{|i|
179
+ result[regs[i]]=self[i]
180
+ }
181
+
182
+ result
183
+ end
184
+
185
+ def inspect
186
+ "$[#{
187
+ idx=-1
188
+ map{|i|
189
+ idx+=1
190
+ @pattern.subregs[idx]+
191
+ "=>"+
192
+ i.inspect
193
+ }.join(", ")
194
+ }]"
195
+ end
196
+
197
+ def slice(other)
198
+ lasti=0
199
+ map{|i|
200
+ case i
201
+ when Integer:
202
+ other[lasti...i]
203
+ when Subseq:
204
+ i.slice other[lasti...i.last]
205
+ i=i.last
206
+ when Hash,Object,Array:
207
+ i.slice other[lasti]
208
+ i=lasti+1
209
+ else raise "hell"
210
+ end
211
+
212
+ assert i >= lasti
213
+
214
+ lasti=i
215
+ }
216
+ end
217
+
218
+ def delete_everything_after(int)
219
+ slice!(int+1..-1)
220
+ end
221
+ end
222
+ Array=Seq=Sequence
223
+
224
+ class Subsequence<Sequence
225
+ def inspect
226
+ super.sub /^\$/, "$-"
227
+ end
228
+ end
229
+ Subseq=Subsequence
230
+
231
+ class Map<Slicings
232
+
233
+ alias oldsize size
234
+ def size; oldsize/2 end
235
+
236
+ def add_pair(key,value)
237
+ assert oldsize%2==0
238
+ push(key,value)
239
+ assert oldsize%2==0
240
+ end
241
+ alias old_subseq_set []=
242
+ alias []= add_pair
243
+
244
+ def position_of?(key)
245
+ result=nil
246
+ (oldsize-2).step(0,-2){|i|
247
+ key==at(i) and break result=i
248
+ }
249
+ result
250
+ end
251
+
252
+ def [](key)
253
+ Integer===key and return slice(key*2,2)
254
+ Range===key and raise "hell"
255
+ pos=position_of?(key)
256
+ pos and return at(pos+1)
257
+ end
258
+
259
+ def first; slice 0..1 end
260
+ def shift; slice! 0..1 end
261
+ def unshift pair; old_subseq_set(0,0,pair) end
262
+
263
+ def last; slice -2..-1 end
264
+ def pop; slice! -2..-1 end
265
+ alias push concat
266
+ alias << push
267
+
268
+
269
+ def display
270
+ result={}
271
+ 0.step(oldsize-2,2){|i|
272
+ result[at(i)]=at(i+1)
273
+ }
274
+ result
275
+ end
276
+
277
+ def inspect
278
+ assert oldsize%2==0
279
+ sum=''
280
+ 0.step(oldsize-2,2){|i|
281
+ sum<<at(i).inspect+"=>"+at(i+1).inspect
282
+ }
283
+ "{["+sum+"]}"
284
+ end
285
+
286
+ def delete_everything_after(key)
287
+ slice!(position_of?(key)+2..-1)
288
+ end
289
+ end
290
+
291
+ class Object<Map
292
+
293
+ def inspect; "o"+inspect end
294
+
295
+ def slice other
296
+ huh
297
+ end
298
+ end
299
+
300
+ class Hash<Map
301
+
302
+ def inspect; "h"+inspect end
303
+
304
+ def slice other
305
+ huh
306
+ end
307
+ end
308
+
309
+
310
+ end
311
+ end
312
+
313
+ =end
314
+
315
+
316
+ #the following 10 classes need to support slicing:
317
+ #Reg::Array,Reg::Subseq,Reg::Logicals (all 3), Reg::LookAhead, Reg::LookBack,
318
+ #Reg::Object, Reg::Hash, Reg::RestrictHash
319
+
320
+
321
+ module Reg
322
+ class Slicing
323
+ def initialize(pattern)
324
+ assert Composite===pattern
325
+ @pattern=pattern
326
+ end
327
+
328
+ def self.for(pattern)
329
+ case pattern
330
+ when ::Reg::Object: Object
331
+ when ::Reg::Hash,::Reg::RestrictHash: Hash
332
+ when ::Reg::Array: Sequence
333
+ when ::Reg::And: And
334
+ when ::Reg::Or, ::Reg::Xor: Or
335
+ when ::Reg::LookAhead, ::Reg::LookBack: LookAB
336
+ when ::Reg::Composite: Subsequence
337
+ else nil
338
+ end
339
+ end
340
+
341
+ def subseq_length; 1 end
342
+
343
+ end
344
+
345
+ class Slicing
346
+ class Sequence<Slicing
347
+ def initialize(*args)
348
+ @subslicings=[]
349
+ @slicepoints=[]
350
+ super
351
+ end
352
+
353
+ attr :data, :subslicings
354
+ alias cursor data
355
+
356
+ def index_structure; Integer; end #matcher num
357
+
358
+ def delete_all_after idx
359
+ @subslicings.slice! idx..-1
360
+ @slicepoints.slice! idx..-1
361
+ end
362
+
363
+ def revert_cursor_to idx
364
+ cursor.pos=@slicepoints[idx]
365
+ end
366
+
367
+ def start_slicing sl,i
368
+ assert @subslicings.size==i
369
+ assert @slicepoints.size==i
370
+ @subslicings.push sl
371
+ @slicepoints.push slicing_length(sl)
372
+ end
373
+
374
+ def slicing_length sl
375
+ if sl.kind_of? Subsequence
376
+ :placeholder
377
+ else
378
+ (@slicepoints.last||0)+1
379
+ end
380
+ end
381
+
382
+ def finish_slicing sl
383
+ assert Subsequence===sl
384
+ assert @slicepoints.last==:placeholder
385
+ @slicepoints[-1]=sl.subseq_length
386
+
387
+ end
388
+ end
389
+ Array=Seq=Sequence
390
+
391
+ class Subsequence<Sequence
392
+ def subseq_length
393
+ subslicings.inject(0){|sum,sl| sum+(sl.subseq_length rescue 1) }
394
+ end
395
+ end
396
+ Subseq=Subsequence
397
+
398
+ class And<Subseq
399
+ def subseq_length
400
+ result=0
401
+ subslicings.each{|sl|
402
+ len=sl.subseq_length;
403
+ len>result and result=len
404
+ }
405
+ return result
406
+ end
407
+ end
408
+
409
+ class Or<Subseq
410
+ def start_slicing sl,i
411
+ huh
412
+ end
413
+
414
+ def finish_slicing sl
415
+ huh
416
+ end
417
+
418
+ def subseq_length
419
+ huh
420
+ end
421
+
422
+ end
423
+
424
+ class LookAB<Subseq
425
+ def subseq_length; 0 end
426
+ end
427
+
428
+ =begin internal structure of Map
429
+ Map_slicing=Reg::const
430
+ List_slicing=Reg::const
431
+ slicing=Map_slicing|List_slicing|nil
432
+
433
+ how_each_matcher_pair_sliced=+[Object, #key of matcher pair
434
+ -[Object, slicing,slicing].* #key from matching pair of data,key slicing, value slicing
435
+ -[Object, slicing,:placeholder]-1 #last value slicing might not be known yet
436
+ ]
437
+ how_each_literal_sliced=-[Object, slicing]
438
+ Map_slicing.set! -{
439
+ :@literals=>+[how_each_literal_sliced.*],
440
+ :@matchers=>+[how_each_matcher_pair_sliced.*],
441
+ :@ivar_literals=>+[how_each_literal_sliced.*].-, #in objects only
442
+ :@ivar_matchers=>+[how_each_matcher_pair_sliced.*].-, #in objects only
443
+ }
444
+
445
+ List_slicing.set! -{
446
+ :@slicepoints=>:sps<<+[
447
+ -[:lastint<<Integer, (Pos[-1]|:placeholder|item_that>=BR[:lastint]).la]+0,
448
+ :placeholder.reg.-]
449
+ :@subslicings=>+[slicing*BR[:sps].size]
450
+ }
451
+
452
+ =end
453
+ class Map<Slicing
454
+ def initialize(*args)
455
+ @literals=[]
456
+ @matchers=[]
457
+ super
458
+ end
459
+
460
+
461
+ end
462
+
463
+ class Hash<Map
464
+ def initialize(pattern,data)
465
+ @keys=data.keys.to_sequence
466
+ super(pattern)
467
+ end
468
+
469
+
470
+ def index_structure; +[Integer]|+[Integer*2,0.reg|1] end #literal matcher num | matcher pair num, data pair num, 0=key;1=value
471
+
472
+ def delete_all_after idx
473
+ if idx.size==3 #in a @matcher
474
+ @matchers.slice!(idx[0]..-1)
475
+ @matchers.last.slice!(1+3*idx[1]..-1)
476
+ idx[2].zero? and @matchers.last[-1]=:placeholder
477
+ else #in a @literal
478
+ @matchers=[]
479
+ @literals.slice!(2*idx[0]..-1)
480
+ end
481
+
482
+
483
+ huh
484
+ end
485
+
486
+ def cursor; @keys end
487
+
488
+ def reset_cursor; @keys.begin! end
489
+
490
+ def revert_cursor_to idx
491
+ cursor.pos= (idx.size==3 ? idx[1] : 0)
492
+ end
493
+
494
+ def start_literal_slicing sl
495
+ assert @matchers.empty?
496
+ @literals.push @keys[@literals.size/2], sl
497
+ end
498
+
499
+ def start_matcher_key_slicing sl
500
+ assert @matchers.last.last != :placeholder
501
+ @matchers.last.push @pattern.@matchers[(@matchers.size-1)/3],sl,:placeholder
502
+ assert @matchers.last.last == :placeholder
503
+ end
504
+
505
+ def start_matcher_val_slicing sl
506
+ assert @matchers.last.last == :placeholder
507
+ @matchers.last[-1]=sl
508
+ assert @matchers.last.last != :placeholder
509
+ end
510
+
511
+ def start_matcher_default_slicing sl
512
+ assert @literals.size/2==@pattern.@literals.size
513
+ if @matchers.size==@pattern.@matchers.size
514
+ @matchers.push [OB]
515
+ else
516
+ assert @matchers.size==@pattern.@matchers.size+1
517
+ end
518
+ k=huh
519
+ k=(@matchers.last.size-1)/3
520
+ @matchers.last.push @keys[k],nil,sl
521
+ end
522
+ end
523
+
524
+ class Object<Map
525
+ def initialize(pattern,data)
526
+ @ivarnames=data.instance_variables.to_sequence
527
+ @methnames=data.public_methods.to_sequence
528
+ super
529
+ end
530
+
531
+ def cursor; huh end
532
+
533
+ def delete_all_after idx
534
+ huh
535
+ end
536
+
537
+ def revert_cursor_to idx
538
+ huh
539
+ end
540
+
541
+ def start_slicing sl,i
542
+ huh
543
+ end
544
+
545
+ def finish_slicing sl
546
+ huh
547
+ end
548
+ end
549
+
550
+
551
+ class Path
552
+ def initialize
553
+ @indexes=[]
554
+ @slicings=[]
555
+ end
556
+
557
+ def dup
558
+ result=super
559
+ @indexes=@indexes.dup
560
+ @slicings=slicings.dup
561
+ result
562
+ end
563
+
564
+ def push slicing
565
+ @indexes.push 0
566
+ @slicings.push slicing
567
+ end
568
+
569
+ def pop
570
+ @indexes.pop
571
+ @slicings.pop
572
+ end
573
+
574
+ def index n=-1; @indexes[n] end
575
+ def index=n; @indexes[-1]=n end
576
+ def slicing n=-1; @slicings[n] end
577
+
578
+ def [](n); [@indexes[n],@slicings[n]] end
579
+ end
580
+ end
581
+ end