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,212 @@
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 'reg'
20
+ require 'regcompiler' #but then breaks it!
21
+
22
+ #use of this file breaks the compiler.
23
+ #only trees are supported. maybe dags if you're lucky.
24
+ #not full graphs.
25
+ #array matchers are not supported currently.
26
+
27
+ module Reg
28
+ module Reg
29
+ def xform!(datum,changed={})
30
+ datum or fail
31
+ Thread.current[:Reg_xform_session]=session={}
32
+ changed.merge!(session) if self===datum
33
+ ensure
34
+ Thread.current[:Reg_xform_session]=nil
35
+ end
36
+ end
37
+
38
+ class Bound
39
+ def === other #this is a hack
40
+ result= @reg===other
41
+ session=Thread.current[:Reg_xform_session]
42
+ if result and session and !session.has_key? @name
43
+ session[@name]=other
44
+ end
45
+ return result
46
+ end
47
+
48
+ def formula_value other,session #another hack...
49
+ result= @reg.formula_value other,session
50
+
51
+ if session and !session.has_key? @name
52
+ session[@name]=result
53
+ end
54
+ return result
55
+ end
56
+ end
57
+
58
+ class BoundRef
59
+ def inspect
60
+ "~:#{name}"
61
+ end
62
+ def === other #this is a hack
63
+ session=Thread.current[:Reg_xform_session]
64
+ if session and session.has_key? @name
65
+ session[@name]==other
66
+ else raise NameNotBound #name not bound yet? that's an error
67
+ end
68
+ end
69
+
70
+ def formula_value(other,session)
71
+ warn "warning: BoundRef #{inspect} value missing" if !session.has_key?(name) and session["final"]
72
+ session.fetch(name,session["final"] ? nil : self)
73
+ end
74
+ end
75
+
76
+ module Formula #more hackery
77
+ def % other
78
+ if Symbol===other
79
+ Reg::Bound.new(self,other)
80
+ else
81
+ super
82
+ end
83
+ end
84
+ end
85
+
86
+ module Composite
87
+ def at_construct_time(*args)
88
+ #do nothing, no infections at all are appropriate when using this file
89
+ end
90
+ end
91
+
92
+ class NameNotBound<RuntimeError; end
93
+ class ReplacingNilError<RuntimeError; end
94
+
95
+ class Transform
96
+ def inspect
97
+ from.inspect+" >> "+to.inspect
98
+ end
99
+ def === other #this is a hack
100
+ result= from===other
101
+ session=Thread.current[:Reg_xform_session]
102
+ if result and session
103
+ raise ReplacingNilError,"replaces of nil or false are not allowed" unless other
104
+ locals={:self=>other}
105
+ if $&
106
+ locals[:$&]=$&
107
+ locals[:$`]=$`
108
+ locals[:$']=$'
109
+ $&.to_a.each_with_index{|br,i| locals[:"$#{i}"]=br }
110
+ end
111
+ session.each_pair{|name,val| locals[name]=val if ::Symbol===name } #hacky... names shouldn't need to be frozen here
112
+ session[other.__id__]=WithBoundRefValues.new(to,locals)
113
+
114
+ =begin
115
+ case to
116
+ when Replace::Form; to.fill_out_simple(locals,other) #should handle Literals as well...
117
+ when BoundRef; to.formula_value(other,locals) #must be eval'd early...?
118
+ when Formula; WithBoundRefValues.new(to,locals)
119
+ else to
120
+ end
121
+ =end
122
+ end
123
+ return result
124
+ end
125
+ end
126
+
127
+ class Replace::Form
128
+ def formula_value other,session
129
+ fill_out_simple session,other
130
+ end
131
+ end
132
+
133
+ class And
134
+ def === other #hack around bugs in AndMachine
135
+ @regs.each{|reg| return unless reg===other }
136
+ return other||true
137
+ end
138
+ def multiple_infection(*args) end #hacky, never do anything for Reg::And
139
+ end
140
+
141
+ class Or
142
+ def multiple_infection(*args) end #hacky, never do anything for Reg::Or
143
+ end
144
+ class Hash
145
+ def multiple_infection(*args) end #hacky, never do anything for Reg::Hash
146
+ end
147
+ class Object
148
+ def multiple_infection(*args) end #hacky, never do anything for Reg::Object
149
+ end
150
+ class Trace
151
+ def multiple_infection(*args) end #hacky, never do anything for Reg::Trace
152
+ end
153
+ class BP
154
+ def multiple_infection(*args) end #hacky, never do anything for Reg::BreakPoint
155
+ end
156
+
157
+ class Finally
158
+ def ===(other)
159
+ result= @reg===other
160
+ session=Thread.current[:Reg_xform_session]
161
+ if result and session
162
+ session["finally"]||=[]
163
+ session["finally"]<<[@block,other]
164
+ end
165
+ result
166
+ end
167
+ end
168
+
169
+ class<<Object
170
+ alias new__without_nested_nil_replacer_fix new
171
+ IMMEDIATES=[nil,false,true,0,:symbol,Class]
172
+ def new *args
173
+ hash= (::Hash===args.last ? args.pop : {})
174
+ replacing_immediate,normal={},{}
175
+ hash.each_pair{|keymtr,valmtr|
176
+ if ::Reg::Transform===valmtr and !IMMEDIATES.grep(valmtr).empty? and ::Symbol===keymtr
177
+ transform=valmtr
178
+ normal[keymtr]=transform.from
179
+ replacing_immediate[keymtr]=transform.to
180
+ else
181
+ normal[keymtr]=valmtr
182
+ end
183
+ }
184
+ args.push normal
185
+ result=new__without_nested_nil_replacer_fix(*args)
186
+ unless replacing_immediate.empty?
187
+ result=result.finally{|x,session|
188
+ replacing_immediate.each_pair{|key,to|
189
+ x.send "#{key}=",to.formula_value(x.send(key),session)
190
+ }
191
+ }
192
+ end
193
+ return result
194
+ end
195
+ end
196
+ end
197
+
198
+ tests=proc{
199
+ require 'test/unit'
200
+ class XformTests<Test::Unit::TestCase
201
+ alias assert_op assert_operator
202
+ def test_and_with_bound_and_replace
203
+ assert_op String>>"bop", :===, "sdfsdf"
204
+ assert String>>"bop" === "sdfsdf"
205
+ assert_op +{ :body=>String >> 'bop' }, :===, {:body => "23423"}
206
+ assert_op (/sdfgdf/ | Hash )%:top & +{ :body=>String >> 'bop' }, :===, {:body => "23423"}
207
+ assert_op( (((/7869/ | Hash )%:top) & +{ :body=>String >> 'sdf' }) | Symbol, :===, Hash[:body, "4564563"] )
208
+ assert_op( ((((/7869/ | Hash )%:top) & +{ :body=>String >> 'sdf' }) | Symbol).trace, :===, Hash[:body, "4564563"] )
209
+ end
210
+ end
211
+ }
212
+ tests[] if __FILE__==$0
@@ -1,6 +1,6 @@
1
1
  =begin copyright
2
2
  reg - the ruby extended grammar
3
- Copyright (C) 2005 Caleb Clausen
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
@@ -20,7 +20,7 @@
20
20
 
21
21
  module Kernel
22
22
  private
23
- def trace(traces)
23
+ def trace_during(traces)
24
24
  if Proc===traces
25
25
  handler=traces
26
26
  traces=nil
@@ -38,8 +38,10 @@ private
38
38
  result=yield
39
39
  ensure
40
40
  #attempt to remain debuggable while restoring the old trace func
41
- set_trace_func((defined? DEBUGGER__ and (DEBUGGER__.context.method:trace_func).to_proc))
41
+ set_trace_func(
42
+ (defined? DEBUGGER__ and (DEBUGGER__.context.method:trace_func).to_proc)
43
+ )
42
44
  end
43
45
  result
44
46
  end
45
- end
47
+ end
@@ -0,0 +1,37 @@
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 Kernel
20
+ def warning(msg)
21
+ (
22
+ (defined? $Debug) && $Debug or
23
+ (defined? $DEBUG) && $DEBUG or
24
+ (defined? $VERBOSE) && $VERBOSE
25
+ ) or return
26
+
27
+ #emit each warning only once
28
+ @@seenit__||={}
29
+ clr=caller[0]
30
+ callerid,mname=clr.match(/^(.*:[0-9]+)(?::in (.*))?$/)[1..2]
31
+ mname=mname[1..-2] if /^`.*'$/===mname
32
+ @@seenit__[callerid] and return
33
+ @@seenit__[callerid]=1
34
+
35
+ warn [callerid,": warning: (",mname,") ",msg].join
36
+ end
37
+ end
data/parser.txt CHANGED
@@ -1,3 +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
1
19
  Lalr(n) parsing with reg
2
20
 
3
21
  Yesterday, I introduced my the Ruby Extended Grammar, a pattern matching
@@ -48,11 +66,11 @@ The heart of the parser are its grammar rules, reproduced here:
48
66
 
49
67
  #last element is always lookahead
50
68
  Reduce=
51
- -[ -[:p, '(', exp, ')'].sub {PrintExp.new BR[2]}, OB ] | # p(exp)
52
- -[ -['(', exp, ')'] .sub {BR[1]}, OB ] | # (exp)
53
- -[ -[exp, leftop, exp] .sub {OpExp.new *BR[0..2]}, regproc{lowerop(BR[1])} ] | # exp+exp
69
+ -[ -[:p, '(', exp, ')'].sub {PrintExp.new BR(2)}, OB ] | # p(exp)
70
+ -[ -['(', exp, ')'] .sub {BR(1)}, OB ] | # (exp)
71
+ -[ -[exp, leftop, exp] .sub {OpExp.new *BR(0..2)}, regproc{lowerop(BR(1))} ] | # exp+exp
54
72
  -[ exp, -[';'] .sub [], :EOI ] | #elide final trailing ;
55
- -[ -[name, '=', exp] .sub {AssignExp.new BR[0],BR[2]}, lowerop('=') ] #name=exp
73
+ -[ -[name, '=', exp] .sub {AssignExp.new BR(0),BR(2)}, lowerop('=') ] #name=exp
56
74
 
57
75
  Precedence is handled by the middle rule. This rule reduces infix operator
58
76
  expressions (except =). It only matches if the lookahead does not contain a
@@ -157,11 +175,11 @@ end
157
175
 
158
176
  #last element is always lookahead
159
177
  Reduce=
160
- -[ -[:p, '(', exp, ')'].sub {PrintExp.new BR[2]}, OB ] | # p(exp)
161
- -[ -['(', exp, ')'] .sub {BR[1]}, OB ] | # (exp)
162
- -[ -[exp, leftop, exp] .sub {OpExp.new *BR[0..2]}, regproc{lowerop(BR[1])} ] | # exp+exp
178
+ -[ -[:p, '(', exp, ')'].sub {PrintExp.new BR(2)}, OB ] | # p(exp)
179
+ -[ -['(', exp, ')'] .sub {BR(1)}, OB ] | # (exp)
180
+ -[ -[exp, leftop, exp] .sub {OpExp.new *BR(0..2)}, regproc{lowerop(BR[1])} ] | # exp+exp
163
181
  -[ exp, -[';'] .sub [], :EOI ] | #elide final trailing ;
164
- -[ -[name, '=', exp] .sub {AssignExp.new BR[0],BR[2]}, lowerop('=') ] #name=exp
182
+ -[ -[name, '=', exp] .sub {AssignExp.new BR(0),BR(2)}, lowerop('=') ] #name=exp
165
183
 
166
184
  #last element of stack is always lookahead
167
185
  def reduceloop(stack)
@@ -1,3 +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
1
19
 
2
20
 
3
21
  That's a long story, and well worth telling.
@@ -1,29 +1,62 @@
1
- require 'rubygems'
1
+ # -*- encoding: utf-8 -*-
2
+ =begin copyright
3
+ reg - the ruby extended grammar
4
+ Copyright (C) 2016 Caleb Clausen
2
5
 
3
- spec = Gem::Specification.new do |s|
4
- s.name = 'reg'
5
- s.rubyforge_project = 'reg'
6
- s.version = '0.4.8'
7
- s.summary = 'The reg pattern matching/replacement language'
8
- s.files = %w[item_thattest.rb regbackref.rb regknows.rb regtest.rb
9
- numberset.rb regbind.rb reglogic.rb regvar.rb
10
- COPYING parser.txt regcase.rb reglookab.rb
11
- README regcore.rb regold.rb reg.gemspec reggrid.csv
12
- assert.rb philosophy.txt regdeferred.rb regpath.rb
13
- regposition.rb trace.rb calc.reg reg.rb
14
- regguide.txt regprogress.rb reghash.rb regreplace.rb
15
- forward_to.rb regarray.rb regarrayold.rb regitem_that.rb regsugar.rb]
16
- s.require_path = '.'
17
- s.has_rdoc = false
18
- s.requirements=["none"]
19
- s.add_dependency("sequence", [">= 0.2.3"])
20
- s.author = 'Caleb Clausen'
21
- s.email = 'caleb @at@ inforadical.net'
22
- s.homepage = 'http://github.com/coatl/reg'
23
- end
6
+ This library is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU Lesser General Public
8
+ License as published by the Free Software Foundation; either
9
+ version 2.1 of the License, or (at your option) any later version.
10
+
11
+ This library is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public
17
+ License along with this library; if not, write to the Free Software
18
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ =end
20
+ dir=File.dirname(__FILE__)
21
+ require "#{dir}/lib/reg/version"
22
+ Reg::Description=open("#{dir}/README"){|f| f.read[/\A.*?\n\n.*?\n\n/m] } #customized
23
+ Reg::Latest_changes="###"+open("#{dir}/History.txt"){|f| f.read[/\A===(.*?)(?====)/m,1] }
24
+
25
+ Gem::Specification.new do |s|
26
+ s.name = "reg"
27
+ s.version = Reg::VERSION
28
+
29
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
30
+ s.authors = ["Caleb Clausen"]
31
+ s.date = Time.now.strftime("%Y-%m-%d")
32
+ s.email = %q{caleb (at) inforadical (dot) net}
33
+ s.extra_rdoc_files = ["README", "COPYING"]
34
+ s.files = `git ls-files`.split-['Rakefile']
35
+ s.files.reject!{|fn| %r{^ramblings/}===fn }
36
+ s.has_rdoc = true
37
+ s.homepage = %{http://github.com/coatl/reg}
38
+ s.rdoc_options = %w[--main README]
39
+ s.require_paths = ["lib"]
40
+ s.rubyforge_project = %q{reg}
41
+ s.rubygems_version = %q{1.3.0}
42
+ s.test_files = %w[test/test_all.rb]
43
+ s.summary = "Reg is a library for pattern matching in ruby data structures."
44
+ s.description = Reg::Description
45
+ s.license = 'LGPL-2.1'
24
46
 
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 2
25
50
 
26
- if $0==__FILE__
27
- # Gem::manage_gems
28
- Gem::Builder.new(spec).build
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<sequence>, [">= 0.2.4"])
53
+ s.add_runtime_dependency(%q<Ron>, [">= 0.1.2"])
54
+ else
55
+ s.add_dependency(%q<sequence>, [">= 0.2.4"])
56
+ s.add_dependency(%q<Ron>, [">= 0.1.2"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<sequence>, [">= 0.2.4"])
60
+ s.add_dependency(%q<Ron>, [">= 0.1.2"])
61
+ end
29
62
  end
@@ -1,3 +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
1
19
  Note: this document is half skeleton right now. Eventually, I'll
2
20
  flesh this out into a more user-accessable description of Reg.
3
21