sgfparser 0.0.1
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.
- data/CHANGES +4 -0
- data/README +5 -0
- data/Rakefile +31 -0
- data/lib/sgf_tools/parser.rb +261 -0
- data/lib/sgf_tools/parser.y +76 -0
- data/lib/sgf_tools/tokenizer.rb +87 -0
- data/lib/sgf_tools/tokenizer.rex +31 -0
- data/lib/sgf_tools.rb +6 -0
- data/lib/sgftools.rb +2 -0
- data/sgftools.gemspec +31 -0
- data/spec/parser_spec.rb +21 -0
- data/test/test_sgf_parse.rb +26 -0
- metadata +90 -0
data/CHANGES
ADDED
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Available options:
|
2
|
+
#
|
3
|
+
# rake test - Runs all test cases.
|
4
|
+
# rake package - Runs test cases and builds packages for distribution.
|
5
|
+
# rake rdoc - Builds API documentation in doc dir.
|
6
|
+
|
7
|
+
require 'rake'
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
require 'rake/gempackagetask'
|
10
|
+
|
11
|
+
task :default => :spec
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new do |rspec|
|
14
|
+
#rspec.ruby_opts="-w"
|
15
|
+
end
|
16
|
+
|
17
|
+
load(File.join(File.dirname(__FILE__), "sgftools.gemspec"))
|
18
|
+
Rake::GemPackageTask.new(SPEC) do |package|
|
19
|
+
# do nothing: I just need a gem but this block is required
|
20
|
+
end
|
21
|
+
|
22
|
+
file "lib/sgf_tools/parser.rb" => "lib/sgf_tools/parser.y" do
|
23
|
+
sh "racc -o lib/sgf_tools/parser.rb lib/sgf_tools/parser.y"
|
24
|
+
end
|
25
|
+
|
26
|
+
file "lib/sgf_tools/tokenizer.rb" => "lib/sgf_tools/tokenizer.rex" do
|
27
|
+
sh "rex -o lib/sgf_tools/tokenizer.rb lib/sgf_tools/tokenizer.rex"
|
28
|
+
end
|
29
|
+
|
30
|
+
task :build => ["lib/sgf_tools/parser.rb", "lib/sgf_tools/tokenizer.rb"]
|
31
|
+
|
@@ -0,0 +1,261 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by Racc 1.4.6
|
4
|
+
# from Racc grammer file "".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser.rb'
|
8
|
+
|
9
|
+
require 'sgf_tools/tokenizer'
|
10
|
+
|
11
|
+
module SgfTools
|
12
|
+
class Node
|
13
|
+
attr_accessor :properties
|
14
|
+
attr_accessor :branches
|
15
|
+
|
16
|
+
def initialize(prop, branches)
|
17
|
+
@properties = prop
|
18
|
+
@branches = branches
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
str = ""
|
23
|
+
str << @properties.inspect
|
24
|
+
if !@branches.nil? && @branches.size > 0
|
25
|
+
str << " (#{@branches.size} variation(s))"
|
26
|
+
end
|
27
|
+
str
|
28
|
+
end
|
29
|
+
|
30
|
+
def [](key)
|
31
|
+
@properties[key]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Parser < Racc::Parser
|
36
|
+
|
37
|
+
module_eval(<<'...end parser.y/module_eval...', 'parser.y', 58)
|
38
|
+
|
39
|
+
def parse_file(filename)
|
40
|
+
@tokenizer = SgfTokenizer.new
|
41
|
+
@tokenizer.load_file(filename)
|
42
|
+
do_parse
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_string(str)
|
46
|
+
@tokenizer = SgfTokenizer.new
|
47
|
+
@tokenizer.scan_evaluate(str)
|
48
|
+
do_parse
|
49
|
+
end
|
50
|
+
|
51
|
+
def next_token
|
52
|
+
@tokenizer.next_token
|
53
|
+
end
|
54
|
+
|
55
|
+
...end parser.y/module_eval...
|
56
|
+
##### State transition tables begin ###
|
57
|
+
|
58
|
+
racc_action_table = [
|
59
|
+
4, 15, 3, 3, 11, 8, 3, 16, 8, 9,
|
60
|
+
3, 15, 19, 20 ]
|
61
|
+
|
62
|
+
racc_action_check = [
|
63
|
+
1, 8, 1, 6, 6, 6, 10, 10, 3, 4,
|
64
|
+
0, 13, 15, 18 ]
|
65
|
+
|
66
|
+
racc_action_pointer = [
|
67
|
+
8, 0, nil, 4, 9, nil, 1, nil, -4, nil,
|
68
|
+
4, nil, nil, 6, nil, 6, nil, nil, 7, nil,
|
69
|
+
nil ]
|
70
|
+
|
71
|
+
racc_action_default = [
|
72
|
+
-14, -14, -1, -14, -14, -2, -14, -5, -7, 21,
|
73
|
+
-14, -3, -6, -8, -9, -14, -4, -10, -11, -12,
|
74
|
+
-13 ]
|
75
|
+
|
76
|
+
racc_goto_table = [
|
77
|
+
5, 1, 7, 14, 13, 12, 6, 10, 17, 5,
|
78
|
+
18 ]
|
79
|
+
|
80
|
+
racc_goto_check = [
|
81
|
+
2, 1, 4, 6, 5, 4, 3, 1, 6, 2,
|
82
|
+
7 ]
|
83
|
+
|
84
|
+
racc_goto_pointer = [
|
85
|
+
nil, 1, -1, 3, -1, -4, -5, -5 ]
|
86
|
+
|
87
|
+
racc_goto_default = [
|
88
|
+
nil, nil, 2, nil, nil, nil, nil, nil ]
|
89
|
+
|
90
|
+
racc_reduce_table = [
|
91
|
+
0, 0, :racc_error,
|
92
|
+
1, 8, :_reduce_1,
|
93
|
+
2, 8, :_reduce_2,
|
94
|
+
3, 9, :_reduce_3,
|
95
|
+
4, 9, :_reduce_4,
|
96
|
+
1, 10, :_reduce_5,
|
97
|
+
2, 10, :_reduce_6,
|
98
|
+
1, 11, :_reduce_7,
|
99
|
+
2, 11, :_reduce_8,
|
100
|
+
1, 12, :_reduce_9,
|
101
|
+
2, 12, :_reduce_10,
|
102
|
+
2, 13, :_reduce_11,
|
103
|
+
1, 14, :_reduce_12,
|
104
|
+
2, 14, :_reduce_13 ]
|
105
|
+
|
106
|
+
racc_reduce_n = 14
|
107
|
+
|
108
|
+
racc_shift_n = 21
|
109
|
+
|
110
|
+
racc_token_table = {
|
111
|
+
false => 0,
|
112
|
+
:error => 1,
|
113
|
+
"(" => 2,
|
114
|
+
")" => 3,
|
115
|
+
";" => 4,
|
116
|
+
:prop_ident => 5,
|
117
|
+
:prop_value => 6 }
|
118
|
+
|
119
|
+
racc_nt_base = 7
|
120
|
+
|
121
|
+
racc_use_result_var = true
|
122
|
+
|
123
|
+
Racc_arg = [
|
124
|
+
racc_action_table,
|
125
|
+
racc_action_check,
|
126
|
+
racc_action_default,
|
127
|
+
racc_action_pointer,
|
128
|
+
racc_goto_table,
|
129
|
+
racc_goto_check,
|
130
|
+
racc_goto_default,
|
131
|
+
racc_goto_pointer,
|
132
|
+
racc_nt_base,
|
133
|
+
racc_reduce_table,
|
134
|
+
racc_token_table,
|
135
|
+
racc_shift_n,
|
136
|
+
racc_reduce_n,
|
137
|
+
racc_use_result_var ]
|
138
|
+
|
139
|
+
Racc_token_to_s_table = [
|
140
|
+
"$end",
|
141
|
+
"error",
|
142
|
+
"\"(\"",
|
143
|
+
"\")\"",
|
144
|
+
"\";\"",
|
145
|
+
"prop_ident",
|
146
|
+
"prop_value",
|
147
|
+
"$start",
|
148
|
+
"collection",
|
149
|
+
"game_tree",
|
150
|
+
"sequence",
|
151
|
+
"node",
|
152
|
+
"properties",
|
153
|
+
"property",
|
154
|
+
"prop_list" ]
|
155
|
+
|
156
|
+
Racc_debug_parser = false
|
157
|
+
|
158
|
+
##### State transition tables end #####
|
159
|
+
|
160
|
+
# reduce 0 omitted
|
161
|
+
|
162
|
+
module_eval(<<'.,.,', 'parser.y', 3)
|
163
|
+
def _reduce_1(val, _values, result)
|
164
|
+
result = val
|
165
|
+
result
|
166
|
+
end
|
167
|
+
.,.,
|
168
|
+
|
169
|
+
module_eval(<<'.,.,', 'parser.y', 4)
|
170
|
+
def _reduce_2(val, _values, result)
|
171
|
+
result.push val[1]
|
172
|
+
result
|
173
|
+
end
|
174
|
+
.,.,
|
175
|
+
|
176
|
+
module_eval(<<'.,.,', 'parser.y', 6)
|
177
|
+
def _reduce_3(val, _values, result)
|
178
|
+
result = val[1]
|
179
|
+
result
|
180
|
+
end
|
181
|
+
.,.,
|
182
|
+
|
183
|
+
module_eval(<<'.,.,', 'parser.y', 9)
|
184
|
+
def _reduce_4(val, _values, result)
|
185
|
+
val[2][0].first.branches = val[2][1..-1]
|
186
|
+
result = val[1] + val[2][0]
|
187
|
+
|
188
|
+
result
|
189
|
+
end
|
190
|
+
.,.,
|
191
|
+
|
192
|
+
module_eval(<<'.,.,', 'parser.y', 13)
|
193
|
+
def _reduce_5(val, _values, result)
|
194
|
+
result = val
|
195
|
+
result
|
196
|
+
end
|
197
|
+
.,.,
|
198
|
+
|
199
|
+
module_eval(<<'.,.,', 'parser.y', 14)
|
200
|
+
def _reduce_6(val, _values, result)
|
201
|
+
result.push val[1]
|
202
|
+
result
|
203
|
+
end
|
204
|
+
.,.,
|
205
|
+
|
206
|
+
module_eval(<<'.,.,', 'parser.y', 16)
|
207
|
+
def _reduce_7(val, _values, result)
|
208
|
+
result = {}
|
209
|
+
result
|
210
|
+
end
|
211
|
+
.,.,
|
212
|
+
|
213
|
+
module_eval(<<'.,.,', 'parser.y', 17)
|
214
|
+
def _reduce_8(val, _values, result)
|
215
|
+
result = Node.new(val[1], nil)
|
216
|
+
result
|
217
|
+
end
|
218
|
+
.,.,
|
219
|
+
|
220
|
+
module_eval(<<'.,.,', 'parser.y', 19)
|
221
|
+
def _reduce_9(val, _values, result)
|
222
|
+
result = val[0]
|
223
|
+
result
|
224
|
+
end
|
225
|
+
.,.,
|
226
|
+
|
227
|
+
module_eval(<<'.,.,', 'parser.y', 20)
|
228
|
+
def _reduce_10(val, _values, result)
|
229
|
+
result.merge!(val[1])
|
230
|
+
result
|
231
|
+
end
|
232
|
+
.,.,
|
233
|
+
|
234
|
+
module_eval(<<'.,.,', 'parser.y', 22)
|
235
|
+
def _reduce_11(val, _values, result)
|
236
|
+
result = {val[0] => val[1]}
|
237
|
+
result
|
238
|
+
end
|
239
|
+
.,.,
|
240
|
+
|
241
|
+
module_eval(<<'.,.,', 'parser.y', 24)
|
242
|
+
def _reduce_12(val, _values, result)
|
243
|
+
result = val
|
244
|
+
result
|
245
|
+
end
|
246
|
+
.,.,
|
247
|
+
|
248
|
+
module_eval(<<'.,.,', 'parser.y', 25)
|
249
|
+
def _reduce_13(val, _values, result)
|
250
|
+
result.push val[1]
|
251
|
+
result
|
252
|
+
end
|
253
|
+
.,.,
|
254
|
+
|
255
|
+
def _reduce_none(val, _values, result)
|
256
|
+
val[0]
|
257
|
+
end
|
258
|
+
|
259
|
+
end # class Parser
|
260
|
+
|
261
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
class Parser
|
3
|
+
rule
|
4
|
+
collection: game_tree { result = val }
|
5
|
+
| collection game_tree { result.push val[1] }
|
6
|
+
|
7
|
+
game_tree: '(' sequence ')' { result = val[1] }
|
8
|
+
| '(' sequence collection ')'
|
9
|
+
{
|
10
|
+
val[2][0].first.branches = val[2][1..-1]
|
11
|
+
result = val[1] + val[2][0]
|
12
|
+
}
|
13
|
+
|
14
|
+
sequence: node { result = val }
|
15
|
+
| sequence node { result.push val[1] }
|
16
|
+
|
17
|
+
node: ';' { result = {} }
|
18
|
+
| ';' properties { result = Node.new(val[1], nil) }
|
19
|
+
|
20
|
+
properties: property { result = val[0] }
|
21
|
+
| properties property { result.merge!(val[1]) }
|
22
|
+
|
23
|
+
property: prop_ident prop_list { result = {val[0] => val[1]} }
|
24
|
+
|
25
|
+
prop_list: prop_value { result = val }
|
26
|
+
| prop_list prop_value { result.push val[1] }
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
---- header
|
31
|
+
require 'sgf_tools/tokenizer'
|
32
|
+
|
33
|
+
module SgfTools
|
34
|
+
class Node
|
35
|
+
attr_accessor :properties
|
36
|
+
attr_accessor :branches
|
37
|
+
|
38
|
+
def initialize(prop, branches)
|
39
|
+
@properties = prop
|
40
|
+
@branches = branches
|
41
|
+
end
|
42
|
+
|
43
|
+
def inspect
|
44
|
+
str = ""
|
45
|
+
str << @properties.inspect
|
46
|
+
if !@branches.nil? && @branches.size > 0
|
47
|
+
str << " (#{@branches.size} variation(s))"
|
48
|
+
end
|
49
|
+
str
|
50
|
+
end
|
51
|
+
|
52
|
+
def [](key)
|
53
|
+
@properties[key]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
---- inner
|
58
|
+
|
59
|
+
def parse_file(filename)
|
60
|
+
@tokenizer = SgfTokenizer.new
|
61
|
+
@tokenizer.load_file(filename)
|
62
|
+
do_parse
|
63
|
+
end
|
64
|
+
|
65
|
+
def parse_string(str)
|
66
|
+
@tokenizer = SgfTokenizer.new
|
67
|
+
@tokenizer.scan_evaluate(str)
|
68
|
+
do_parse
|
69
|
+
end
|
70
|
+
|
71
|
+
def next_token
|
72
|
+
@tokenizer.next_token
|
73
|
+
end
|
74
|
+
|
75
|
+
---- footer
|
76
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by rex 1.0.0
|
4
|
+
# from lexical definition file "lib/sgf_parser/tokenizer.rex".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser'
|
8
|
+
#
|
9
|
+
# sgf.rex
|
10
|
+
# lexical definition for sgf
|
11
|
+
#
|
12
|
+
# usage
|
13
|
+
# rex sgf.rex
|
14
|
+
#
|
15
|
+
|
16
|
+
class SgfTokenizer < Racc::Parser
|
17
|
+
require 'strscan'
|
18
|
+
|
19
|
+
class ScanError < StandardError ; end
|
20
|
+
|
21
|
+
attr_reader :lineno
|
22
|
+
attr_reader :filename
|
23
|
+
|
24
|
+
def scan_setup ; end
|
25
|
+
|
26
|
+
def action &block
|
27
|
+
yield
|
28
|
+
end
|
29
|
+
|
30
|
+
def scan_str( str )
|
31
|
+
scan_evaluate str
|
32
|
+
do_parse
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_file( filename )
|
36
|
+
@filename = filename
|
37
|
+
open(filename, "r") do |f|
|
38
|
+
scan_evaluate f.read
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def scan_file( filename )
|
43
|
+
load_file filename
|
44
|
+
do_parse
|
45
|
+
end
|
46
|
+
|
47
|
+
def next_token
|
48
|
+
@rex_tokens.shift
|
49
|
+
end
|
50
|
+
|
51
|
+
def scan_evaluate( str )
|
52
|
+
scan_setup
|
53
|
+
@rex_tokens = []
|
54
|
+
@lineno = 1
|
55
|
+
ss = StringScanner.new(str)
|
56
|
+
state = nil
|
57
|
+
until ss.eos?
|
58
|
+
text = ss.peek(1)
|
59
|
+
@lineno += 1 if text == "\n"
|
60
|
+
case state
|
61
|
+
when nil
|
62
|
+
case
|
63
|
+
when (text = ss.scan(/[A-Z]+/))
|
64
|
+
@rex_tokens.push action { [:prop_ident, text] }
|
65
|
+
|
66
|
+
when (text = ss.scan(/\[[^\]]*\]/))
|
67
|
+
@rex_tokens.push action { [:prop_value, text[1..-2]] }
|
68
|
+
|
69
|
+
when (text = ss.scan(/\s+/))
|
70
|
+
;
|
71
|
+
|
72
|
+
when (text = ss.scan(/./))
|
73
|
+
@rex_tokens.push action { [text, text] }
|
74
|
+
|
75
|
+
else
|
76
|
+
text = ss.string[ss.pos .. -1]
|
77
|
+
raise ScanError, "can not match: '" + text + "'"
|
78
|
+
end # if
|
79
|
+
|
80
|
+
else
|
81
|
+
raise ScanError, "undefined state: '" + state.to_s + "'"
|
82
|
+
end # case state
|
83
|
+
end # until ss
|
84
|
+
end # def scan_evaluate
|
85
|
+
|
86
|
+
end # class
|
87
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# sgf.rex
|
3
|
+
# lexical definition for sgf
|
4
|
+
#
|
5
|
+
# usage
|
6
|
+
# rex sgf.rex
|
7
|
+
#
|
8
|
+
|
9
|
+
class SgfTokenizer
|
10
|
+
|
11
|
+
macro
|
12
|
+
BLANK \s+
|
13
|
+
|
14
|
+
rule
|
15
|
+
|
16
|
+
# [:state] pattern [actions]
|
17
|
+
|
18
|
+
# PropIdent
|
19
|
+
[A-Z]+ { [:prop_ident, text] }
|
20
|
+
|
21
|
+
# PropValue
|
22
|
+
\[[^\]]*\] { [:prop_value, text[1..-2]] }
|
23
|
+
|
24
|
+
# skip
|
25
|
+
{BLANK} # no action
|
26
|
+
|
27
|
+
# identifier
|
28
|
+
. { [text, text] }
|
29
|
+
|
30
|
+
end
|
31
|
+
|
data/lib/sgf_tools.rb
ADDED
data/lib/sgftools.rb
ADDED
data/sgftools.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
DIR = File.dirname(__FILE__)
|
2
|
+
LIB = File.join(DIR, *%w[lib sgf_tools.rb])
|
3
|
+
VERSION = open(LIB) { |lib|
|
4
|
+
lib.each { |line|
|
5
|
+
if v = line[/^\s*VERSION\s*=\s*(['"])(\d\.\d\.\d)\1/, 2]
|
6
|
+
break v
|
7
|
+
end
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
SPEC = Gem::Specification.new do |s|
|
12
|
+
s.name = "sgfparser"
|
13
|
+
s.version = VERSION
|
14
|
+
s.platform = Gem::Platform::RUBY
|
15
|
+
s.authors = ["Pete Schwamb"]
|
16
|
+
s.email = ["pete@schwamb.net"]
|
17
|
+
s.homepage = "http://github.com/ps2/sgfparser"
|
18
|
+
s.summary = "A ruby library for working with SGF files"
|
19
|
+
s.description = <<-END_DESCRIPTION.gsub(/\s+/, " ").strip
|
20
|
+
This library reads sgf files, described at http://www.red-bean.com/sgf/
|
21
|
+
END_DESCRIPTION
|
22
|
+
|
23
|
+
s.required_rubygems_version = "~> 1.9.2"
|
24
|
+
s.required_rubygems_version = "~> 1.3.6"
|
25
|
+
|
26
|
+
s.add_development_dependency "rspec"
|
27
|
+
|
28
|
+
s.files = `git ls-files`.split("\n")
|
29
|
+
s.test_files = `git ls-files -- spec/*_spec.rb`.split("\n")
|
30
|
+
s.require_paths = %w[lib]
|
31
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'sgftools'
|
2
|
+
|
3
|
+
describe SgfTools::Parser do
|
4
|
+
|
5
|
+
it "should parse sgf with single game with branches" do
|
6
|
+
@simple_sgf = <<-END_OF_SGF
|
7
|
+
(;FF[4]C[root](;C[a];C[b](;C[c])
|
8
|
+
(;C[d];C[e]))
|
9
|
+
(;C[f](;C[g];C[h];C[i])
|
10
|
+
(;C[j])))
|
11
|
+
END_OF_SGF
|
12
|
+
p = SgfTools::Parser.new
|
13
|
+
game = p.parse_string(@simple_sgf).first
|
14
|
+
game.size.should == 4
|
15
|
+
game[0].branches.should == nil
|
16
|
+
game[1].branches.size.should == 1
|
17
|
+
game[2].branches.should == nil
|
18
|
+
game[1].branches[0].size.should == 4
|
19
|
+
game[1].branches[0][1].branches.size.should == 1
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'sgf_parser'
|
5
|
+
|
6
|
+
class SgfParserTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_parse_simple
|
9
|
+
p = SgfParser.new
|
10
|
+
simple_sgf = <<END_OF_SGF
|
11
|
+
(;FF[4]C[root](;C[a];C[b](;C[c])
|
12
|
+
(;C[d];C[e]))
|
13
|
+
(;C[f](;C[g];C[h];C[i])
|
14
|
+
(;C[j])))
|
15
|
+
END_OF_SGF
|
16
|
+
game = p.parse_string(simple_sgf).first
|
17
|
+
assert_equal(4, game.size)
|
18
|
+
assert_equal(nil, game[0].branches)
|
19
|
+
assert_equal(1, game[1].branches.size)
|
20
|
+
assert_equal(nil, game[2].branches)
|
21
|
+
assert_equal(4, game[1].branches[0].size)
|
22
|
+
assert_equal(1, game[1].branches[0][1].branches.size)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sgfparser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Pete Schwamb
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-10-22 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
description: This library reads sgf files, described at http://www.red-bean.com/sgf/
|
34
|
+
email:
|
35
|
+
- pete@schwamb.net
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- CHANGES
|
44
|
+
- README
|
45
|
+
- Rakefile
|
46
|
+
- lib/sgf_tools.rb
|
47
|
+
- lib/sgf_tools/parser.rb
|
48
|
+
- lib/sgf_tools/parser.y
|
49
|
+
- lib/sgf_tools/tokenizer.rb
|
50
|
+
- lib/sgf_tools/tokenizer.rex
|
51
|
+
- lib/sgftools.rb
|
52
|
+
- sgftools.gemspec
|
53
|
+
- spec/parser_spec.rb
|
54
|
+
- test/test_sgf_parse.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/ps2/sgfparser
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
segments:
|
78
|
+
- 1
|
79
|
+
- 3
|
80
|
+
- 6
|
81
|
+
version: 1.3.6
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.3.7
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: A ruby library for working with SGF files
|
89
|
+
test_files:
|
90
|
+
- spec/parser_spec.rb
|