reg 0.4.8 → 0.5.0a0

Sign up to get free protection for your applications and to get access to all the features.
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