jkf 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,633 +1,627 @@
1
- module Jkf::Parser
2
- # Intersection of KIF and KI2
3
- module Kifuable
4
- protected
5
-
6
- # initialboard : (" " nonls nl)? ("+" nonls nl)? ikkatsuline+ ("+" nonls nl)?
7
- def parse_initialboard
8
- s0 = s1 = @current_pos
9
- if match_space == :failed
10
- @current_pos = s1
11
- else
12
- parse_nonls
13
- s2 = parse_nl
14
- @current_pos = s1 if s2 == :failed
15
- end
16
- s2 = @current_pos
17
- if match_str("+") == :failed
18
- @current_pos = s2
19
- else
20
- parse_nonls
21
- @current_pos = s2 if parse_nl == :failed
22
- end
23
- s4 = parse_ikkatsuline
24
- if s4 == :failed
25
- s3 = :failed
26
- else
27
- s3 = []
28
- while s4 != :failed
29
- s3 << s4
30
- s4 = parse_ikkatsuline
31
- end
32
- end
33
- if s3 == :failed
34
- @current_pos = s0
35
- :failed
36
- else
37
- s4 = @current_pos
38
- if match_str("+") == :failed
39
- @current_pos = s4
1
+ module Jkf
2
+ module Parser
3
+ # Intersection of KIF and KI2
4
+ module Kifuable
5
+ protected
6
+
7
+ # initialboard : (" " nonls nl)? ("+" nonls nl)? ikkatsuline+ ("+" nonls nl)?
8
+ def parse_initialboard
9
+ s0 = s1 = @scanner.pos
10
+ if match_space == :failed
11
+ @scanner.pos = s1
40
12
  else
41
13
  parse_nonls
42
- @current_pos = s4 if parse_nl == :failed
14
+ s2 = parse_nl
15
+ @scanner.pos = s1 if s2 == :failed
16
+ end
17
+ s2 = @scanner.pos
18
+ if match_str('+') == :failed
19
+ @scanner.pos = s2
20
+ else
21
+ parse_nonls
22
+ @scanner.pos = s2 if parse_nl == :failed
23
+ end
24
+ s4 = parse_ikkatsuline
25
+ if s4 == :failed
26
+ s3 = :failed
27
+ else
28
+ s3 = []
29
+ while s4 != :failed
30
+ s3 << s4
31
+ s4 = parse_ikkatsuline
32
+ end
43
33
  end
44
- @reported_pos = s0
45
- transform_initialboard(s3)
46
- end
47
- end
48
-
49
- # ikkatsuline : "|" masu:masu+ "|" nonls! nl
50
- def parse_ikkatsuline
51
- s0 = @current_pos
52
- if match_str("|") == :failed
53
- @current_pos = s0
54
- s0 = :failed
55
- else
56
- s3 = parse_masu
57
34
  if s3 == :failed
58
- s2 = :failed
35
+ @scanner.pos = s0
36
+ :failed
59
37
  else
60
- s2 = []
61
- while s3 != :failed
62
- s2 << s3
63
- s3 = parse_masu
38
+ s4 = @scanner.pos
39
+ if match_str('+') == :failed
40
+ @scanner.pos = s4
41
+ else
42
+ parse_nonls
43
+ @scanner.pos = s4 if parse_nl == :failed
64
44
  end
45
+ @reported_pos = s0
46
+ transform_initialboard(s3)
65
47
  end
66
- if s2 == :failed
67
- @current_pos = s0
48
+ end
49
+
50
+ # ikkatsuline : "|" masu:masu+ "|" nonls! nl
51
+ def parse_ikkatsuline
52
+ s0 = @scanner.pos
53
+ if match_str('|') == :failed
54
+ @scanner.pos = s0
68
55
  s0 = :failed
69
- elsif match_str("|") != :failed
70
- s4 = parse_nonls!
71
- if s4 == :failed
72
- @current_pos = s0
56
+ else
57
+ s3 = parse_masu
58
+ if s3 == :failed
59
+ s2 = :failed
60
+ else
61
+ s2 = []
62
+ while s3 != :failed
63
+ s2 << s3
64
+ s3 = parse_masu
65
+ end
66
+ end
67
+ if s2 == :failed
68
+ @scanner.pos = s0
73
69
  s0 = :failed
74
- elsif parse_nl != :failed
75
- @reported_pos = s0
76
- s0 = s2
70
+ elsif match_str('|') != :failed
71
+ s4 = parse_nonls!
72
+ if s4 == :failed
73
+ @scanner.pos = s0
74
+ s0 = :failed
75
+ elsif parse_nl != :failed
76
+ @reported_pos = s0
77
+ s0 = s2
78
+ else
79
+ @scanner.pos = s0
80
+ s0 = :failed
81
+ end
77
82
  else
78
- @current_pos = s0
83
+ @scanner.pos = s0
79
84
  s0 = :failed
80
85
  end
81
- else
82
- @current_pos = s0
83
- s0 = :failed
84
86
  end
85
- end
86
87
 
87
- s0
88
- end
88
+ s0
89
+ end
89
90
 
90
- # masu : teban piece | " ・"
91
- def parse_masu
92
- s0 = @current_pos
93
- s1 = parse_teban
94
- if s1 == :failed
95
- @current_pos = s0
96
- s0 = :failed
97
- else
98
- s2 = parse_piece
99
- if s2 == :failed
100
- @current_pos = s0
91
+ # masu : teban piece | " ・"
92
+ def parse_masu
93
+ s0 = @scanner.pos
94
+ s1 = parse_teban
95
+ if s1 == :failed
96
+ @scanner.pos = s0
101
97
  s0 = :failed
102
98
  else
103
- @reported_pos = s0
104
- s0 = { "color" => s1, "kind" => s2 }
99
+ s2 = parse_piece
100
+ if s2 == :failed
101
+ @scanner.pos = s0
102
+ s0 = :failed
103
+ else
104
+ @reported_pos = s0
105
+ s0 = { 'color' => s1, 'kind' => s2 }
106
+ end
105
107
  end
106
- end
107
- if s0 == :failed
108
- s0 = @current_pos
109
- s1 = match_str(" ・")
110
- if s1 != :failed
111
- @reported_pos = s0
112
- s1 = {}
108
+ if s0 == :failed
109
+ s0 = @scanner.pos
110
+ s1 = match_str(' ・')
111
+ if s1 != :failed
112
+ @reported_pos = s0
113
+ s1 = {}
114
+ end
115
+ s0 = s1
113
116
  end
114
- s0 = s1
115
- end
116
117
 
117
- s0
118
- end
118
+ s0
119
+ end
119
120
 
120
- # teban : (" " | "+" | "^") | ("v" | "V")
121
- def parse_teban
122
- s0 = @current_pos
123
- s1 = match_space
124
- if s1 == :failed
125
- s1 = match_str("+")
126
- s1 = match_str("^") if s1 == :failed
127
- end
128
- if s1 != :failed
129
- @reported_pos = s0
130
- s1 = 0
131
- end
132
- s0 = s1
133
- if s0 == :failed
134
- s0 = @current_pos
135
- s1 = match_str("v")
136
- s1 = match_str("V") if s1 == :failed
121
+ # teban : (" " | "+" | "^") | ("v" | "V")
122
+ def parse_teban
123
+ s0 = @scanner.pos
124
+ s1 = match_space
125
+ if s1 == :failed
126
+ s1 = match_str('+')
127
+ s1 = match_str('^') if s1 == :failed
128
+ end
137
129
  if s1 != :failed
138
130
  @reported_pos = s0
139
- s1 = 1
131
+ s1 = 0
140
132
  end
141
133
  s0 = s1
134
+ if s0 == :failed
135
+ s0 = @scanner.pos
136
+ s1 = match_str('v')
137
+ s1 = match_str('V') if s1 == :failed
138
+ if s1 != :failed
139
+ @reported_pos = s0
140
+ s1 = 1
141
+ end
142
+ s0 = s1
143
+ end
144
+ s0
142
145
  end
143
- s0
144
- end
145
146
 
146
- # pointer : "&" nonls nl
147
- def parse_pointer
148
- s0 = @current_pos
149
- s1 = match_str("&")
150
- if s1 == :failed
151
- @current_pos = s0
152
- s0 = :failed
153
- else
154
- s2 = parse_nonls
155
- s3 = parse_nl
156
- if s3 == :failed
157
- @current_pos = s0
147
+ # pointer : "&" nonls nl
148
+ def parse_pointer
149
+ s0 = @scanner.pos
150
+ s1 = match_str('&')
151
+ if s1 == :failed
152
+ @scanner.pos = s0
158
153
  s0 = :failed
159
154
  else
160
- s0 = [s1, s2, s3]
155
+ s2 = parse_nonls
156
+ s3 = parse_nl
157
+ if s3 == :failed
158
+ @scanner.pos = s0
159
+ s0 = :failed
160
+ else
161
+ s0 = [s1, s2, s3]
162
+ end
161
163
  end
164
+ s0
162
165
  end
163
- s0
164
- end
165
166
 
166
- # num : [123456789]
167
- def parse_num
168
- s0 = @current_pos
169
- s1 = match_regexp(/^[123456789]/)
170
- if s1 != :failed
171
- @reported_pos = s0
172
- s1 = zen2n(s1)
167
+ # num : [123456789]
168
+ def parse_num
169
+ s0 = @scanner.pos
170
+ s1 = match_regexp(/[123456789]/)
171
+ if s1 != :failed
172
+ @reported_pos = s0
173
+ s1 = zen2n(s1)
174
+ end
175
+ s1
173
176
  end
174
- s1
175
- end
176
177
 
177
- # numkan : [一二三四五六七八九]
178
- def parse_numkan
179
- s0 = @current_pos
180
- s1 = match_regexp(/^[一二三四五六七八九]/)
181
- if s1 != :failed
182
- @reported_pos = s0
183
- s1 = kan2n(s1)
178
+ # numkan : [一二三四五六七八九]
179
+ def parse_numkan
180
+ s0 = @scanner.pos
181
+ s1 = match_regexp(/[一二三四五六七八九]/)
182
+ if s1 != :failed
183
+ @reported_pos = s0
184
+ s1 = kan2n(s1)
185
+ end
186
+ s1
184
187
  end
185
- s1
186
- end
187
188
 
188
- # piece : "成"? [歩香桂銀金角飛王玉と杏圭全馬竜龍]
189
- def parse_piece
190
- s0 = @current_pos
191
- s1 = match_str("")
192
- s1 = "" if s1 == :failed
193
- s2 = match_regexp(/^[歩香桂銀金角飛王玉と杏圭全馬竜龍]/)
194
- if s2 == :failed
195
- @current_pos = s0
196
- :failed
197
- else
198
- @reported_pos = s0
199
- kind2csa(s1 + s2)
189
+ # piece : "成"? [歩香桂銀金角飛王玉と杏圭全馬竜龍]
190
+ def parse_piece
191
+ s0 = @scanner.pos
192
+ s1 = match_str('')
193
+ s1 = '' if s1 == :failed
194
+ s2 = match_regexp(/[歩香桂銀金角飛王玉と杏圭全馬竜龍]/)
195
+ if s2 == :failed
196
+ @scanner.pos = s0
197
+ :failed
198
+ else
199
+ @reported_pos = s0
200
+ kind2csa(s1 + s2)
201
+ end
200
202
  end
201
- end
202
203
 
203
- # result : "まで" [0-9]+ "手" (
204
- # "で" (turn "手の" (result_toryo | result_illegal)) |
205
- # result_timeup | result_chudan | result_jishogi |
206
- # result_sennichite | result_tsumi | result_fuzumi
207
- # ) nl
208
- def parse_result
209
- s0 = @current_pos
210
- if match_str("まで") == :failed
211
- @current_pos = s0
212
- :failed
213
- else
214
- s2 = match_digits!
215
- if s2 == :failed
216
- @current_pos = s0
204
+ # result : "まで" [0-9]+ "手" (
205
+ # "で" (turn "手の" (result_toryo | result_illegal)) |
206
+ # result_timeup | result_chudan | result_jishogi |
207
+ # result_sennichite | result_tsumi | result_fuzumi
208
+ # ) nl
209
+ def parse_result
210
+ s0 = @scanner.pos
211
+ if match_str('まで') == :failed
212
+ @scanner.pos = s0
217
213
  :failed
218
- elsif match_str("手") != :failed
219
- s4 = @current_pos
220
- if match_str("で") == :failed
221
- @current_pos = s4
222
- s4 = :failed
223
- elsif parse_turn != :failed
224
- if match_str("手の") == :failed
225
- @current_pos = s4
214
+ else
215
+ s2 = match_digits!
216
+ if s2 == :failed
217
+ @scanner.pos = s0
218
+ :failed
219
+ elsif match_str('手') != :failed
220
+ s4 = @scanner.pos
221
+ if match_str('で') == :failed
222
+ @scanner.pos = s4
226
223
  s4 = :failed
224
+ elsif parse_turn != :failed
225
+ if match_str('手の') == :failed
226
+ @scanner.pos = s4
227
+ s4 = :failed
228
+ else
229
+ s8 = parse_result_toryo
230
+ s8 = parse_result_illegal if s8 == :failed
231
+ s4 = if s8 == :failed
232
+ @scanner.pos = s4
233
+ :failed
234
+ else
235
+ @reported_pos = s4
236
+ s8
237
+ end
238
+ end
227
239
  else
228
- s8 = parse_result_toryo
229
- s8 = parse_result_illegal if s8 == :failed
230
- s4 = if s8 == :failed
231
- @current_pos = s4
232
- :failed
233
- else
234
- @reported_pos = s4
235
- s8
236
- end
240
+ @scanner.pos = s4
241
+ s4 = :failed
237
242
  end
238
- else
239
- @current_pos = s4
240
- s4 = :failed
241
- end
242
- if s4 == :failed
243
- s4 = parse_result_timeup
244
243
  if s4 == :failed
245
- s4 = parse_result_chudan
244
+ s4 = parse_result_timeup
246
245
  if s4 == :failed
247
- s4 = parse_result_jishogi
246
+ s4 = parse_result_chudan
248
247
  if s4 == :failed
249
- s4 = parse_result_sennichite
248
+ s4 = parse_result_jishogi
250
249
  if s4 == :failed
251
- s4 = parse_result_tsumi
252
- s4 = parse_result_fuzumi if s4 == :failed
250
+ s4 = parse_result_sennichite
251
+ if s4 == :failed
252
+ s4 = parse_result_tsumi
253
+ s4 = parse_result_fuzumi if s4 == :failed
254
+ end
253
255
  end
254
256
  end
255
257
  end
256
258
  end
257
- end
258
- if s4 == :failed
259
- @current_pos = s0
260
- :failed
261
- elsif parse_nl != :failed || eos?
262
- @reported_pos = s0
263
- s4
259
+ if s4 == :failed
260
+ @scanner.pos = s0
261
+ :failed
262
+ elsif parse_nl != :failed || eos?
263
+ @reported_pos = s0
264
+ s4
265
+ else
266
+ @scanner.pos = s0
267
+ :failed
268
+ end
264
269
  else
265
- @current_pos = s0
270
+ @scanner.pos = s0
266
271
  :failed
267
272
  end
268
- else
269
- @current_pos = s0
270
- :failed
271
273
  end
272
274
  end
273
- end
274
275
 
275
- # result_toryo : "勝ち"
276
- def parse_result_toryo
277
- s0 = @current_pos
278
- s1 = match_str("勝ち")
279
- if s1 == :failed
280
- @current_pos = s0
281
- :failed
282
- else
283
- @reported_pos = s0
284
- "TORYO"
276
+ # result_toryo : "勝ち"
277
+ def parse_result_toryo
278
+ s0 = @scanner.pos
279
+ s1 = match_str('勝ち')
280
+ if s1 == :failed
281
+ @scanner.pos = s0
282
+ :failed
283
+ else
284
+ @reported_pos = s0
285
+ 'TORYO'
286
+ end
285
287
  end
286
- end
287
288
 
288
- # result_illegal : "反則" ("勝ち" | "負け")
289
- def parse_result_illegal
290
- s0 = @current_pos
291
- if match_str("反則") == :failed
292
- @current_pos = s0
293
- :failed
294
- else
295
- s10 = @current_pos
296
- s11 = match_str("勝ち")
297
- if s11 != :failed
298
- @reported_pos = s10
299
- s11 = "ILLEGAL_ACTION"
300
- end
301
- s10 = s11
302
- if s10 == :failed
303
- s10 = @current_pos
304
- s11 = match_str("負け")
289
+ # result_illegal : "反則" ("勝ち" | "負け")
290
+ def parse_result_illegal
291
+ s0 = @scanner.pos
292
+ if match_str('反則') == :failed
293
+ @scanner.pos = s0
294
+ :failed
295
+ else
296
+ s10 = @scanner.pos
297
+ s11 = match_str('勝ち')
305
298
  if s11 != :failed
306
299
  @reported_pos = s10
307
- s11 = "ILLEGAL_MOVE"
300
+ s11 = 'ILLEGAL_ACTION'
308
301
  end
309
302
  s10 = s11
303
+ if s10 == :failed
304
+ s10 = @scanner.pos
305
+ s11 = match_str('負け')
306
+ if s11 != :failed
307
+ @reported_pos = s10
308
+ s11 = 'ILLEGAL_MOVE'
309
+ end
310
+ s10 = s11
311
+ end
312
+ if s10 == :failed
313
+ @scanner.pos = s0
314
+ :failed
315
+ else
316
+ @reported_pos = s0
317
+ s10
318
+ end
310
319
  end
311
- if s10 == :failed
312
- @current_pos = s0
313
- :failed
314
- else
320
+ end
321
+
322
+ # result_timeup : "で時間切れにより" turn "手の勝ち"
323
+ def parse_result_timeup
324
+ s0 = @scanner.pos
325
+ if match_str('で時間切れにより') != :failed && parse_turn != :failed && match_str('手の勝ち') != :failed
315
326
  @reported_pos = s0
316
- s10
327
+ 'TIME_UP'
328
+ else
329
+ @scanner.pos = s0
330
+ :failed
317
331
  end
318
332
  end
319
- end
320
333
 
321
- # result_timeup : "で時間切れにより" turn "手の勝ち"
322
- def parse_result_timeup
323
- s0 = @current_pos
324
- if match_str("で時間切れにより") == :failed
325
- @current_pos = s0
326
- :failed
327
- elsif parse_turn != :failed
328
- if match_str("手の勝ち") == :failed
329
- @current_pos = s0
334
+ # result_chudan : "で中断"
335
+ def parse_result_chudan
336
+ s0 = @scanner.pos
337
+ s1 = match_str('で中断')
338
+ if s1 == :failed
339
+ @scanner.pos = s0
330
340
  :failed
331
341
  else
332
342
  @reported_pos = s0
333
- "TIME_UP"
343
+ 'CHUDAN'
334
344
  end
335
- else
336
- @current_pos = s0
337
- :failed
338
345
  end
339
- end
340
346
 
341
- # result_chudan : "で中断"
342
- def parse_result_chudan
343
- s0 = @current_pos
344
- s1 = match_str("で中断")
345
- if s1 == :failed
346
- @current_pos = s0
347
- :failed
348
- else
349
- @reported_pos = s0
350
- "CHUDAN"
347
+ # result_jishogi : "で持将棋"
348
+ def parse_result_jishogi
349
+ s0 = @scanner.pos
350
+ s1 = match_str('で持将棋')
351
+ if s1 == :failed
352
+ @scanner.pos = s0
353
+ :failed
354
+ else
355
+ @reported_pos = s0
356
+ 'JISHOGI'
357
+ end
351
358
  end
352
- end
353
359
 
354
- # result_jishogi : "で持将棋"
355
- def parse_result_jishogi
356
- s0 = @current_pos
357
- s1 = match_str("で持将棋")
358
- if s1 == :failed
359
- @current_pos = s0
360
- :failed
361
- else
362
- @reported_pos = s0
363
- "JISHOGI"
360
+ # result_sennichite : "で千日手"
361
+ def parse_result_sennichite
362
+ s0 = @scanner.pos
363
+ s1 = match_str('で千日手')
364
+ if s1 == :failed
365
+ @scanner.pos = s0
366
+ :failed
367
+ else
368
+ @reported_pos = s0
369
+ 'SENNICHITE'
370
+ end
364
371
  end
365
- end
366
372
 
367
- # result_sennichite : "で千日手"
368
- def parse_result_sennichite
369
- s0 = @current_pos
370
- s1 = match_str("で千日手")
371
- if s1 == :failed
372
- @current_pos = s0
373
- :failed
374
- else
375
- @reported_pos = s0
376
- "SENNICHITE"
373
+ # result_tsumi : ""? "詰" "み"?
374
+ def parse_result_tsumi
375
+ s0 = @scanner.pos
376
+ match_str('で')
377
+ if match_str('詰') == :failed
378
+ @scanner.pos = s0
379
+ :failed
380
+ else
381
+ match_str('み')
382
+ @reported_pos = s0
383
+ 'TSUMI'
384
+ end
377
385
  end
378
- end
379
386
 
380
- # result_tsumi : ""? "詰" "み"?
381
- def parse_result_tsumi
382
- s0 = @current_pos
383
- match_str("で")
384
- if match_str("詰") == :failed
385
- @current_pos = s0
386
- :failed
387
- else
388
- match_str("み")
389
- @reported_pos = s0
390
- "TSUMI"
387
+ # result_fuzumi : "で不詰"
388
+ def parse_result_fuzumi
389
+ s0 = @scanner.pos
390
+ s1 = match_str('で不詰')
391
+ if s1 == :failed
392
+ @scanner.pos = s0
393
+ :failed
394
+ else
395
+ @reported_pos = s0
396
+ 'FUZUMI'
397
+ end
391
398
  end
392
- end
393
399
 
394
- # result_fuzumi : "で不詰"
395
- def parse_result_fuzumi
396
- s0 = @current_pos
397
- s1 = match_str("で不詰")
398
- if s1 == :failed
399
- @current_pos = s0
400
- :failed
401
- else
402
- @reported_pos = s0
403
- "FUZUMI"
400
+ # skipline : "#" nonls newline
401
+ def parse_skipline
402
+ s0 = @scanner.pos
403
+ s1 = match_str('#')
404
+ if s1 == :failed
405
+ @scanner.pos = s0
406
+ s0 = :failed
407
+ else
408
+ s2 = parse_nonls
409
+ s3 = parse_newline
410
+ s0 = if s3 == :failed
411
+ @scanner.pos = s0
412
+ :failed
413
+ else
414
+ [s1, s2, s3]
415
+ end
416
+ end
417
+ s0
404
418
  end
405
- end
406
-
407
- # skipline : "#" nonls newline
408
- def parse_skipline
409
- s0 = @current_pos
410
- s1 = match_str("#")
411
- if s1 == :failed
412
- @current_pos = s0
413
- s0 = :failed
414
- else
415
- s2 = parse_nonls
416
- s3 = parse_newline
417
- s0 = if s3 == :failed
418
- @current_pos = s0
419
- :failed
420
- else
421
- [s1, s2, s3]
422
- end
423
- end
424
- s0
425
- end
426
419
 
427
- # whitespace : " " | "\t"
428
- def parse_whitespace
429
- match_regexp(/^[ \t]/)
430
- end
431
-
432
- # newline : whitespace* ("\n" | "\r" "\n"?)
433
- def parse_newline
434
- s0 = @current_pos
435
- s1 = []
436
- s2 = parse_whitespace
437
- while s2 != :failed
438
- s1 << s2
439
- s2 = parse_whitespace
420
+ # whitespace : " " | "\t"
421
+ def parse_whitespace
422
+ match_regexp(/[ \t]/)
440
423
  end
441
- s2 = match_str("\n")
442
- if s2 == :failed
443
- s2 = @current_pos
444
- s3 = match_str("\r")
445
- s2 = if s3 == :failed
446
- @current_pos = s2
447
- :failed
448
- else
449
- s4 = match_str("\n")
450
- s4 = nil if s4 == :failed
451
- [s3, s4]
452
- end
453
- end
454
- if s2 == :failed
455
- @current_pos = s0
456
- :failed
457
- else
458
- [s1, s2]
459
- end
460
- end
461
424
 
462
- # nl : newline+ skipline*
463
- def parse_nl
464
- s0 = @current_pos
465
- s2 = parse_newline
466
- if s2 == :failed
467
- s1 = :failed
468
- else
425
+ # newline : whitespace* ("\n" | "\r" "\n"?)
426
+ def parse_newline
427
+ s0 = @scanner.pos
469
428
  s1 = []
429
+ s2 = parse_whitespace
470
430
  while s2 != :failed
471
431
  s1 << s2
472
- s2 = parse_newline
432
+ s2 = parse_whitespace
433
+ end
434
+ s2 = match_str("\n")
435
+ if s2 == :failed
436
+ s2 = @scanner.pos
437
+ s3 = match_str("\r")
438
+ s2 = if s3 == :failed
439
+ @scanner.pos = s2
440
+ :failed
441
+ else
442
+ s4 = match_str("\n")
443
+ s4 = nil if s4 == :failed
444
+ [s3, s4]
445
+ end
446
+ end
447
+ if s2 == :failed
448
+ @scanner.pos = s0
449
+ :failed
450
+ else
451
+ [s1, s2]
473
452
  end
474
453
  end
475
- if s1 == :failed
476
- @current_pos = s0
477
- :failed
478
- else
479
- s2 = []
480
- s3 = parse_skipline
481
- while s3 != :failed
482
- s2 << s3
454
+
455
+ # nl : newline+ skipline*
456
+ def parse_nl
457
+ s0 = @scanner.pos
458
+ s2 = parse_newline
459
+ if s2 == :failed
460
+ s1 = :failed
461
+ else
462
+ s1 = []
463
+ while s2 != :failed
464
+ s1 << s2
465
+ s2 = parse_newline
466
+ end
467
+ end
468
+ if s1 == :failed
469
+ @scanner.pos = s0
470
+ :failed
471
+ else
472
+ s2 = []
483
473
  s3 = parse_skipline
474
+ while s3 != :failed
475
+ s2 << s3
476
+ s3 = parse_skipline
477
+ end
478
+ [s1, s2]
484
479
  end
485
- [s1, s2]
486
480
  end
487
- end
488
481
 
489
- # nonl :
490
- def parse_nonl
491
- match_regexp(/^[^\r\n]/)
492
- end
482
+ # nonl :
483
+ def parse_nonl
484
+ match_regexp(/[^\r\n]/)
485
+ end
493
486
 
494
- # nonls : nonl*
495
- def parse_nonls
496
- stack = []
497
- matched = parse_nonl
498
- while matched != :failed
499
- stack << matched
487
+ # nonls : nonl*
488
+ def parse_nonls
489
+ stack = []
500
490
  matched = parse_nonl
491
+ while matched != :failed
492
+ stack << matched
493
+ matched = parse_nonl
494
+ end
495
+ stack
501
496
  end
502
- stack
503
- end
504
497
 
505
- # nonls! : nonl+
506
- def parse_nonls!
507
- matched = parse_nonls
508
- if matched.empty?
509
- :failed
510
- else
511
- matched
498
+ # nonls! : nonl+
499
+ def parse_nonls!
500
+ matched = parse_nonls
501
+ if matched.empty?
502
+ :failed
503
+ else
504
+ matched
505
+ end
512
506
  end
513
- end
514
507
 
515
- # transform header-data to jkf
516
- def transform_root_header_data(ret)
517
- if ret["header"]["手番"]
518
- ret["initial"]["data"]["color"] = "下先".include?(ret["header"]["手番"]) ? 0 : 1
519
- ret["header"].delete("手番")
520
- else
521
- ret["initial"]["data"]["color"] = 0
522
- end
523
- ret["initial"]["data"]["hands"] = [
524
- make_hand(ret["header"]["先手の持駒"] || ret["header"]["下手の持駒"]),
525
- make_hand(ret["header"]["後手の持駒"] || ret["header"]["上手の持駒"])
526
- ]
527
- %w(先手の持駒 下手の持駒 後手の持駒 上手の持駒).each do |key|
528
- ret["header"].delete(key)
508
+ # transform header-data to jkf
509
+ def transform_root_header_data(ret)
510
+ if ret['header']['手番']
511
+ ret['initial']['data']['color'] = '下先'.include?(ret['header']['手番']) ? 0 : 1
512
+ ret['header'].delete('手番')
513
+ else
514
+ ret['initial']['data']['color'] = 0
515
+ end
516
+ ret['initial']['data']['hands'] = [
517
+ make_hand(ret['header']['先手の持駒'] || ret['header']['下手の持駒']),
518
+ make_hand(ret['header']['後手の持駒'] || ret['header']['上手の持駒'])
519
+ ]
520
+ %w(先手の持駒 下手の持駒 後手の持駒 上手の持駒).each do |key|
521
+ ret['header'].delete(key)
522
+ end
529
523
  end
530
- end
531
524
 
532
- # transfrom forks to jkf
533
- def transform_root_forks(forks, moves)
534
- fork_stack = [{ "te" => 0, "moves" => moves }]
535
- forks.each do |f|
536
- now_fork = f
537
- _fork = fork_stack.pop
538
- _fork = fork_stack.pop while _fork["te"] > now_fork["te"]
539
- move = _fork["moves"][now_fork["te"] - _fork["te"]]
540
- move["forks"] ||= []
541
- move["forks"] << now_fork["moves"]
542
- fork_stack << _fork
543
- fork_stack << now_fork
525
+ # transfrom forks to jkf
526
+ def transform_root_forks(forks, moves)
527
+ fork_stack = [{ 'te' => 0, 'moves' => moves }]
528
+ forks.each do |f|
529
+ now_fork = f
530
+ fork = fork_stack.pop
531
+ fork = fork_stack.pop while fork['te'] > now_fork['te']
532
+ move = fork['moves'][now_fork['te'] - fork['te']]
533
+ move['forks'] ||= []
534
+ move['forks'] << now_fork['moves']
535
+ fork_stack << fork
536
+ fork_stack << now_fork
537
+ end
544
538
  end
545
- end
546
539
 
547
- # transform initialboard to jkf
548
- def transform_initialboard(lines)
549
- board = []
550
- 9.times do |i|
551
- line = []
552
- 9.times do |j|
553
- line << lines[j][8 - i]
540
+ # transform initialboard to jkf
541
+ def transform_initialboard(lines)
542
+ board = []
543
+ 9.times do |i|
544
+ line = []
545
+ 9.times do |j|
546
+ line << lines[j][8 - i]
547
+ end
548
+ board << line
554
549
  end
555
- board << line
550
+ { 'preset' => 'OTHER', 'data' => { 'board' => board } }
556
551
  end
557
- { "preset" => "OTHER", "data" => { "board" => board } }
558
- end
559
552
 
560
- # zenkaku number to number
561
- def zen2n(s)
562
- "0123456789".index(s)
563
- end
553
+ # zenkaku number to number
554
+ def zen2n(s)
555
+ '0123456789'.index(s)
556
+ end
564
557
 
565
- # kanji number to number (1)
566
- def kan2n(s)
567
- "〇一二三四五六七八九".index(s)
568
- end
558
+ # kanji number to number (1)
559
+ def kan2n(s)
560
+ '〇一二三四五六七八九'.index(s)
561
+ end
569
562
 
570
- # kanji number to number (2)
571
- def kan2n2(s)
572
- case s.length
573
- when 1
574
- "〇一二三四五六七八九十".index(s)
575
- when 2
576
- "〇一二三四五六七八九十".index(s[1]) + 10
577
- else
578
- raise "21以上の数値に対応していません"
563
+ # kanji number to number (2)
564
+ def kan2n2(s)
565
+ case s.length
566
+ when 1
567
+ '〇一二三四五六七八九十'.index(s)
568
+ when 2
569
+ '〇一二三四五六七八九十'.index(s[1]) + 10
570
+ else
571
+ raise '21以上の数値に対応していません'
572
+ end
579
573
  end
580
- end
581
574
 
582
- # kanji piece-type to csa
583
- def kind2csa(kind)
584
- if kind[0] == ""
585
- {
586
- "" => "NY",
587
- "" => "NK",
588
- "" => "NG"
589
- }[kind[1]]
590
- else
591
- {
592
- "" => "FU",
593
- "" => "KY",
594
- "" => "KE",
595
- "" => "GI",
596
- "" => "KI",
597
- "" => "KA",
598
- "" => "HI",
599
- "" => "OU",
600
- "" => "OU",
601
- "" => "TO",
602
- "" => "NY",
603
- "" => "NK",
604
- "" => "NG",
605
- "" => "UM",
606
- "" => "RY",
607
- "" => "RY"
608
- }[kind]
575
+ # kanji piece-type to csa
576
+ def kind2csa(kind)
577
+ if kind[0] == ''
578
+ {
579
+ '' => 'NY',
580
+ '' => 'NK',
581
+ '' => 'NG'
582
+ }[kind[1]]
583
+ else
584
+ {
585
+ '' => 'FU',
586
+ '' => 'KY',
587
+ '' => 'KE',
588
+ '' => 'GI',
589
+ '' => 'KI',
590
+ '' => 'KA',
591
+ '' => 'HI',
592
+ '' => 'OU',
593
+ '' => 'OU',
594
+ '' => 'TO',
595
+ '' => 'NY',
596
+ '' => 'NK',
597
+ '' => 'NG',
598
+ '' => 'UM',
599
+ '' => 'RY',
600
+ '' => 'RY'
601
+ }[kind]
602
+ end
609
603
  end
610
- end
611
604
 
612
- # preset string to jkf
613
- def preset2str(preset)
614
- {
615
- "平手" => "HIRATE",
616
- "香落ち" => "KY",
617
- "右香落ち" => "KY_R",
618
- "角落ち" => "KA",
619
- "飛車落ち" => "HI",
620
- "飛香落ち" => "HIKY",
621
- "二枚落ち" => "2",
622
- "三枚落ち" => "3",
623
- "四枚落ち" => "4",
624
- "五枚落ち" => "5",
625
- "左五枚落ち" => "5_L",
626
- "六枚落ち" => "6",
627
- "八枚落ち" => "8",
628
- "十枚落ち" => "10",
629
- "その他" => "OTHER"
630
- }[preset.gsub(/\s/, "")]
605
+ # preset string to jkf
606
+ def preset2str(preset)
607
+ {
608
+ '平手' => 'HIRATE',
609
+ '香落ち' => 'KY',
610
+ '右香落ち' => 'KY_R',
611
+ '角落ち' => 'KA',
612
+ '飛車落ち' => 'HI',
613
+ '飛香落ち' => 'HIKY',
614
+ '二枚落ち' => '2',
615
+ '三枚落ち' => '3',
616
+ '四枚落ち' => '4',
617
+ '五枚落ち' => '5',
618
+ '左五枚落ち' => '5_L',
619
+ '六枚落ち' => '6',
620
+ '八枚落ち' => '8',
621
+ '十枚落ち' => '10',
622
+ 'その他' => 'OTHER'
623
+ }[preset.gsub(/\s/, '')]
624
+ end
631
625
  end
632
626
  end
633
627
  end