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