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,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