bracecomp 0.1.0

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 (5) hide show
  1. data/README +22 -0
  2. data/lib/bracecomp.rb +7 -0
  3. data/lib/bracecomp.tab.rb +301 -0
  4. data/lib/bracecomp.y +169 -0
  5. metadata +68 -0
data/README ADDED
@@ -0,0 +1,22 @@
1
+ = bracecomp
2
+
3
+ Copyright (c) 201q SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
4
+
5
+ == Description
6
+
7
+ Brace expansion library.
8
+
9
+ == Install
10
+
11
+ gem install bracecomp
12
+
13
+ == Example
14
+
15
+ require 'bracecomp'
16
+
17
+ p 'server-{a,b}-{07..10}'.expand
18
+ #=> ["server-a-07", "server-a-08", "server-a-09", "server-a-10", "server-b-07", "server-b-08", "server-b-09", "server-b-10"]
19
+
20
+ p 'zone-{a..c}'.expand
21
+ #=> ["zone-a", "zone-b", "zone-c"]
22
+
@@ -0,0 +1,7 @@
1
+ require 'bracecomp.tab'
2
+
3
+ class String
4
+ def expand
5
+ BraceComp.new(self).parse.expand
6
+ end
7
+ end
@@ -0,0 +1,301 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by racc 1.4.5
4
+ # from racc grammer file "bracecomp.y".
5
+ #
6
+
7
+ require 'racc/parser'
8
+
9
+
10
+
11
+ require 'strscan'
12
+
13
+
14
+ class BraceComp < Racc::Parser
15
+
16
+ module_eval <<'..end bracecomp.y modeval..idad4372d656', 'bracecomp.y', 50
17
+
18
+ attr_reader :tree
19
+
20
+ def initialize(obj)
21
+ @src = obj.is_a?(IO) ? obj.read : obj.to_s
22
+ @s = StringScanner.new(@src)
23
+ end
24
+ private :initialize
25
+
26
+ def scan
27
+ piece = nil
28
+
29
+ until @s.eos?
30
+ if (piece = @s.scan /\A\s+/)
31
+ # nothing to do
32
+ elsif (piece = @s.scan /\A[^{},]+/)
33
+ yield :WORD, piece
34
+ elsif (piece = @s.scan /\A[{},]/)
35
+ yield piece, piece
36
+ else
37
+ raise Racc::ParseError, 'parse error'
38
+ end
39
+ end
40
+
41
+ yield false, '$'
42
+ end
43
+ private :scan
44
+
45
+ def parse
46
+ begin
47
+ @tree = yyparse self, :scan
48
+ rescue Racc::ParseError
49
+ @tree = [@src]
50
+ end
51
+
52
+ self
53
+ end
54
+
55
+ def permutation(stack, ary = [], &block)
56
+ list = stack.shift
57
+
58
+ list.each do |i|
59
+ if stack.empty?
60
+ block.call(ary + [i])
61
+ else
62
+ permutation(stack, ary + [i], &block)
63
+ end
64
+ end
65
+
66
+ stack.unshift(list)
67
+ end
68
+ private :permutation
69
+
70
+ def swap(a, b)
71
+ [b, a]
72
+ end
73
+ private :swap
74
+
75
+ def expand_range(first, last, is_num)
76
+ reversed = false
77
+ format = nil
78
+
79
+ if is_num
80
+ if first =~ /\A0+/
81
+ format = "%0#{first.length}d"
82
+ end
83
+
84
+ first = first.to_i
85
+ last = last.to_i
86
+ end
87
+
88
+ if first > last
89
+ reversed = true
90
+ first, last = swap(first, last)
91
+ end
92
+
93
+ expanded = Range.new(first, last).to_a
94
+
95
+ if is_num and format
96
+ expanded = expanded.map {|i| format % i }
97
+ end
98
+
99
+ reversed ? expanded.reverse : expanded
100
+ end
101
+ private :expand_range
102
+
103
+ def expand
104
+ return nil unless @tree
105
+
106
+ src = ''
107
+ sets = []
108
+
109
+ @tree.each do |i|
110
+ if i.kind_of?(String)
111
+ src << i
112
+ else
113
+ i = i.map {|expr|
114
+ case expr
115
+ when /\A([a-zA-Z])\.\.([a-zA-Z])\Z/
116
+ expand_range($1, $2, false)
117
+ when /\A(\d+)\.\.(\d+)\Z/
118
+ expand_range($1, $2, true)
119
+ else
120
+ expr
121
+ end
122
+ }.flatten
123
+
124
+ sets << i
125
+ src << '%s'
126
+ end
127
+ end
128
+
129
+ expandeds = []
130
+
131
+ permutation(sets) do |seq|
132
+ expandeds << src % seq
133
+ end
134
+
135
+ expandeds
136
+ end
137
+ ..end bracecomp.y modeval..idad4372d656
138
+
139
+ ##### racc 1.4.5 generates ###
140
+
141
+ racc_reduce_table = [
142
+ 0, 0, :racc_error,
143
+ 0, 7, :_reduce_none,
144
+ 1, 7, :_reduce_none,
145
+ 1, 8, :_reduce_3,
146
+ 2, 8, :_reduce_4,
147
+ 1, 9, :_reduce_none,
148
+ 1, 9, :_reduce_none,
149
+ 1, 10, :_reduce_none,
150
+ 1, 10, :_reduce_none,
151
+ 1, 10, :_reduce_none,
152
+ 1, 10, :_reduce_none,
153
+ 3, 11, :_reduce_11,
154
+ 1, 12, :_reduce_12,
155
+ 3, 12, :_reduce_13,
156
+ 0, 13, :_reduce_14,
157
+ 1, 13, :_reduce_none ]
158
+
159
+ racc_reduce_n = 16
160
+
161
+ racc_shift_n = 19
162
+
163
+ racc_action_table = [
164
+ 2, 3, 4, 5, 2, 3, 4, 5, 15, 16,
165
+ 13, 11, 17, 11 ]
166
+
167
+ racc_action_check = [
168
+ 0, 0, 0, 0, 7, 7, 7, 7, 10, 10,
169
+ 6, 3, 13, 16 ]
170
+
171
+ racc_action_pointer = [
172
+ -2, nil, nil, 9, nil, nil, 10, 2, nil, nil,
173
+ 4, nil, nil, 12, nil, nil, 11, nil, nil ]
174
+
175
+ racc_action_default = [
176
+ -1, -6, -7, -8, -9, -10, -16, -2, -3, -5,
177
+ -16, -15, -12, -16, -4, -11, -14, 19, -13 ]
178
+
179
+ racc_goto_table = [
180
+ 12, 8, 7, 10, 6, nil, nil, nil, 14, nil,
181
+ nil, nil, nil, 18 ]
182
+
183
+ racc_goto_check = [
184
+ 7, 3, 2, 6, 1, nil, nil, nil, 3, nil,
185
+ nil, nil, nil, 7 ]
186
+
187
+ racc_goto_pointer = [
188
+ nil, 4, 2, 1, nil, nil, 0, -3 ]
189
+
190
+ racc_goto_default = [
191
+ nil, nil, nil, nil, 9, 1, nil, nil ]
192
+
193
+ racc_token_table = {
194
+ false => 0,
195
+ Object.new => 1,
196
+ :WORD => 2,
197
+ "{" => 3,
198
+ "}" => 4,
199
+ "," => 5 }
200
+
201
+ racc_use_result_var = false
202
+
203
+ racc_nt_base = 6
204
+
205
+ Racc_arg = [
206
+ racc_action_table,
207
+ racc_action_check,
208
+ racc_action_default,
209
+ racc_action_pointer,
210
+ racc_goto_table,
211
+ racc_goto_check,
212
+ racc_goto_default,
213
+ racc_goto_pointer,
214
+ racc_nt_base,
215
+ racc_reduce_table,
216
+ racc_token_table,
217
+ racc_shift_n,
218
+ racc_reduce_n,
219
+ racc_use_result_var ]
220
+
221
+ Racc_token_to_s_table = [
222
+ '$end',
223
+ 'error',
224
+ 'WORD',
225
+ '"{"',
226
+ '"}"',
227
+ '","',
228
+ '$start',
229
+ 'pattern',
230
+ 'strings',
231
+ 'string',
232
+ 'words_or_sign',
233
+ 'braced',
234
+ 'exprs',
235
+ 'expr']
236
+
237
+ Racc_debug_parser = false
238
+
239
+ ##### racc system variables end #####
240
+
241
+ # reduce 0 omitted
242
+
243
+ # reduce 1 omitted
244
+
245
+ # reduce 2 omitted
246
+
247
+ module_eval <<'.,.,', 'bracecomp.y', 10
248
+ def _reduce_3( val, _values)
249
+ [val[0]]
250
+ end
251
+ .,.,
252
+
253
+ module_eval <<'.,.,', 'bracecomp.y', 14
254
+ def _reduce_4( val, _values)
255
+ val[0] << val[1]
256
+ end
257
+ .,.,
258
+
259
+ # reduce 5 omitted
260
+
261
+ # reduce 6 omitted
262
+
263
+ # reduce 7 omitted
264
+
265
+ # reduce 8 omitted
266
+
267
+ # reduce 9 omitted
268
+
269
+ # reduce 10 omitted
270
+
271
+ module_eval <<'.,.,', 'bracecomp.y', 27
272
+ def _reduce_11( val, _values)
273
+ val[1]
274
+ end
275
+ .,.,
276
+
277
+ module_eval <<'.,.,', 'bracecomp.y', 32
278
+ def _reduce_12( val, _values)
279
+ [val[0]]
280
+ end
281
+ .,.,
282
+
283
+ module_eval <<'.,.,', 'bracecomp.y', 36
284
+ def _reduce_13( val, _values)
285
+ val[0] << val[2]
286
+ end
287
+ .,.,
288
+
289
+ module_eval <<'.,.,', 'bracecomp.y', 41
290
+ def _reduce_14( val, _values)
291
+ ''
292
+ end
293
+ .,.,
294
+
295
+ # reduce 15 omitted
296
+
297
+ def _reduce_none( val, _values)
298
+ val[0]
299
+ end
300
+
301
+ end # class BraceComp
@@ -0,0 +1,169 @@
1
+ class BraceComp
2
+ options no_result_var
3
+ rule
4
+ pattern :
5
+ | strings
6
+
7
+ strings : string
8
+ {
9
+ [val[0]]
10
+ }
11
+ | strings string
12
+ {
13
+ val[0] << val[1]
14
+ }
15
+
16
+ string : words_or_sign
17
+ | braced
18
+
19
+ words_or_sign : WORD
20
+ | '{'
21
+ | '}'
22
+ | ','
23
+
24
+ braced : '{' exprs '}'
25
+ {
26
+ val[1]
27
+ }
28
+
29
+ exprs : expr
30
+ {
31
+ [val[0]]
32
+ }
33
+ | exprs ',' expr
34
+ {
35
+ val[0] << val[2]
36
+ }
37
+
38
+ expr :
39
+ {
40
+ ''
41
+ }
42
+ | WORD
43
+ end
44
+
45
+ ---- header
46
+
47
+ require 'strscan'
48
+
49
+ ---- inner
50
+
51
+ attr_reader :tree
52
+
53
+ def initialize(obj)
54
+ @src = obj.is_a?(IO) ? obj.read : obj.to_s
55
+ @s = StringScanner.new(@src)
56
+ end
57
+ private :initialize
58
+
59
+ def scan
60
+ piece = nil
61
+
62
+ until @s.eos?
63
+ if (piece = @s.scan /\A\s+/)
64
+ # nothing to do
65
+ elsif (piece = @s.scan /\A[^{},]+/)
66
+ yield :WORD, piece
67
+ elsif (piece = @s.scan /\A[{},]/)
68
+ yield piece, piece
69
+ else
70
+ raise Racc::ParseError, 'parse error'
71
+ end
72
+ end
73
+
74
+ yield false, '$'
75
+ end
76
+ private :scan
77
+
78
+ def parse
79
+ begin
80
+ @tree = yyparse self, :scan
81
+ rescue Racc::ParseError
82
+ @tree = [@src]
83
+ end
84
+
85
+ self
86
+ end
87
+
88
+ def permutation(stack, ary = [], &block)
89
+ list = stack.shift
90
+
91
+ list.each do |i|
92
+ if stack.empty?
93
+ block.call(ary + [i])
94
+ else
95
+ permutation(stack, ary + [i], &block)
96
+ end
97
+ end
98
+
99
+ stack.unshift(list)
100
+ end
101
+ private :permutation
102
+
103
+ def swap(a, b)
104
+ [b, a]
105
+ end
106
+ private :swap
107
+
108
+ def expand_range(first, last, is_num)
109
+ reversed = false
110
+ format = nil
111
+
112
+ if is_num
113
+ if first =~ /\A0+/
114
+ format = "%0#{first.length}d"
115
+ end
116
+
117
+ first = first.to_i
118
+ last = last.to_i
119
+ end
120
+
121
+ if first > last
122
+ reversed = true
123
+ first, last = swap(first, last)
124
+ end
125
+
126
+ expanded = Range.new(first, last).to_a
127
+
128
+ if is_num and format
129
+ expanded = expanded.map {|i| format % i }
130
+ end
131
+
132
+ reversed ? expanded.reverse : expanded
133
+ end
134
+ private :expand_range
135
+
136
+ def expand
137
+ return nil unless @tree
138
+
139
+ src = ''
140
+ sets = []
141
+
142
+ @tree.each do |i|
143
+ if i.kind_of?(String)
144
+ src << i
145
+ else
146
+ i = i.map {|expr|
147
+ case expr
148
+ when /\A([a-zA-Z])\.\.([a-zA-Z])\Z/
149
+ expand_range($1, $2, false)
150
+ when /\A(\d+)\.\.(\d+)\Z/
151
+ expand_range($1, $2, true)
152
+ else
153
+ expr
154
+ end
155
+ }.flatten
156
+
157
+ sets << i
158
+ src << '%s'
159
+ end
160
+ end
161
+
162
+ expandeds = []
163
+
164
+ permutation(sets) do |seq|
165
+ expandeds << src % seq
166
+ end
167
+
168
+ expandeds
169
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bracecomp
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - winebarrel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-09-05 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description:
22
+ email: sgwr_dts@yahoo.co.jp
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - README
31
+ - lib/bracecomp.rb
32
+ - lib/bracecomp.tab.rb
33
+ - lib/bracecomp.y
34
+ homepage: https://bitbucket.org/winebarrel/bracecomp
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.7.2
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Brace expansion library.
67
+ test_files: []
68
+