jkf 0.4.3 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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