回答編集履歴

2

誤記修正

2018/05/05 08:58

投稿

Thrush
Thrush

スコア58

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  >そのファイルの特徴、他形式のものとの違い、プログラミング言語との親和性等が知りたいです。
14
14
 
15
- フォーマットはほぼxmlそのままですので、気合で読めると思います。
15
+ フォーマットはほぼjsonそのままですので、気合で読めると思います。
16
16
 
17
17
 
18
18
 

1

詳細の追記

2018/05/05 08:58

投稿

Thrush
Thrush

スコア58

test CHANGED
@@ -1,5 +1,605 @@
1
1
  察するに、EBGuideのフォーマットですね
2
2
 
3
+
4
+
5
+ >gdata形式のファイルについて、具体的な取扱いに関する情報が載っているサイトをご存知ですか?
6
+
3
7
  フォーマットの情報は一般に公開されていません
4
8
 
9
+ 僕もElektrobitに問い合わせましたが、法人対応のみとのことで回答をもらえませんでした
10
+
11
+
12
+
13
+ >そのファイルの特徴、他形式のものとの違い、プログラミング言語との親和性等が知りたいです。
14
+
15
+ フォーマットはほぼxmlそのままですので、気合で読めると思います。
16
+
17
+
18
+
19
+ ↓ここがプロパティの実体の宣言で
20
+
21
+ ```ここに言語を入力
22
+
23
+ #2479056145 items :: dp_item_list : <object>
24
+
25
+ ```
26
+
27
+
28
+
29
+ ↓ここがオブジェクトの実体の宣言です。
30
+
31
+ ```
32
+
33
+ dp(int) : @de86b58e-a2a5-4779-b793-96c137480cc1
34
+
35
+ {
36
+
37
+ #3605065401 value :: int : 1;
38
+
39
+ #460587879 name :: string : "INT_test";
40
+
41
+ }
42
+
43
+ ```
44
+
45
+
46
+
47
+ 1つのプロパティは、オブジェクト、あるいは普通の数値や文字列を(通常)1つ持ちます。
48
+
49
+ 1つのオブジェクトは複数のプロパティを持ちます。
50
+
51
+ ただし、質問に記述されている例は1つのプロパティは複数のオブジェクトを配列として持つ特殊な例です。
52
+
53
+
54
+
5
- python(ply)やC++(flex/bison)でパースするしかないでしょう
55
+ 何らかの情報を抜き取りたい場合、python(ply)やC++(flex/bison)でパースするしかないと思います。
56
+
57
+ パーサジェネレータを使って遊んでいる人であれば、以下のコードが参考になるかもしれません。
58
+
59
+ (ちょっと前に書いてたやつなので、バグとかあったらごめんなさい)
60
+
61
+
62
+
63
+ ```python
64
+
65
+ #!/usr/bin/env python
66
+
67
+ import ply.lex as lex
68
+
69
+ from ply.lex import TOKEN
70
+
71
+
72
+
73
+ #
74
+
75
+ #PRINT = print
76
+
77
+ PRINT = lambda x : None
78
+
79
+
80
+
81
+ #---------------------------------------------------------------------
82
+
83
+ # define states
84
+
85
+ states = (
86
+
87
+ ('text', 'exclusive'),
88
+
89
+ ('version', 'exclusive'),
90
+
91
+ )
92
+
93
+
94
+
95
+ #---------------------------------------------------------------------
96
+
97
+ # define literals
98
+
99
+ literals = "()[]{}<>@#;,"
100
+
101
+
102
+
103
+ #---------------------------------------------------------------------
104
+
105
+ #define regular expression parts
106
+
107
+ def PAREN(t):
108
+
109
+ t = r'(' + t + r')'
110
+
111
+ return t
112
+
113
+ INTEGER_NUMBER_INTEGER = r'[+-]?[1-9][0-9]*[Ff]?|[+-]?0'
114
+
115
+ INTEGER_NUMBER_FLOAT = r'[+-]?[1-9][0-9]*[Ff]?|[+-]?0[fF]?'
116
+
117
+ INTEGER_NUMBER = PAREN(INTEGER_NUMBER_INTEGER) + "|" + PAREN(INTEGER_NUMBER_FLOAT );
118
+
119
+ REAL_NUMBER = PAREN(INTEGER_NUMBER_INTEGER) + r'?' + r'.[0-9]*[fF]?'
120
+
121
+ NUMBER = PAREN(REAL_NUMBER) + r'|' + PAREN(INTEGER_NUMBER)
122
+
123
+
124
+
125
+ #---------------------------------------------------------------------
126
+
127
+ # declare token
128
+
129
+ tokens = (
130
+
131
+ 'NUMBER',
132
+
133
+ 'EBGUIDE',
134
+
135
+ 'BOOL',
136
+
137
+ 'PROP_ID',
138
+
139
+ 'OBJ_ID',
140
+
141
+ "START_TEXT",
142
+
143
+ 'END_TEXT',
144
+
145
+ 'TEXT',
146
+
147
+ 'SYMBOL',
148
+
149
+ 'VERSION',
150
+
151
+ )
152
+
153
+
154
+
155
+ #---------------------------------------------------------------------
156
+
157
+ # defien ignore token
158
+
159
+ t_ignore = ' \t:'
160
+
161
+ t_text_ignore = ''
162
+
163
+ t_version_ignore = ''
164
+
165
+
166
+
167
+ #---------------------------------------------------------------------
168
+
169
+ # define token by RE
170
+
171
+ #t_EBGUIDE = r'EBGUIDE'
172
+
173
+
174
+
175
+ #---------------------------------------------------------------------
176
+
177
+ # define token as function by state
178
+
179
+
180
+
181
+ def t_ANY_newline(t):
182
+
183
+ r'\n+'
184
+
185
+ t.lexer.lineno += len(t.value)
186
+
187
+
188
+
189
+ @TOKEN(NUMBER)
190
+
191
+ def t_NUMBER(t):
192
+
193
+ PRINT(t.value)
194
+
195
+ t.value = t.value.replace("f", "")
196
+
197
+ t.value = t.value.replace("F", "")
198
+
199
+ t.value = float(t.value)
200
+
201
+ return t
202
+
203
+ def t_EBGUIDE(t):
204
+
205
+ r'EBGUIDE'
206
+
207
+ PRINT(t.value)
208
+
209
+ t.lexer.push_state("version")
210
+
211
+ return t
212
+
213
+ def t_BOOL(t):
214
+
215
+ r'true|false'
216
+
217
+ PRINT(t.value)
218
+
219
+ t.value = True if t.value == "true" else False
220
+
221
+ return t
222
+
223
+ def t_PROP_ID(t):
224
+
225
+ r'\#[0-9]+'
226
+
227
+ PRINT(t.value)
228
+
229
+ return t
230
+
231
+ def t_OBJ_ID(t):
232
+
233
+ r'@[a-zA-Z0-9\-]+'
234
+
235
+ PRINT(t.value)
236
+
237
+ return t
238
+
239
+ def t_START_TEXT(t):
240
+
241
+ r'"'
242
+
243
+ PRINT(t.value)
244
+
245
+ t.lexer.push_state("text")
246
+
247
+ def t_SYMBOL(t):
248
+
249
+ r'[a-zA-Z][a-zA-Z0-9_()\,]*'
250
+
251
+ PRINT(t.value)
252
+
253
+ return t
254
+
255
+
256
+
257
+ def t_text_TEXT(t):
258
+
259
+ r'([^"\]|\"|\)+'
260
+
261
+ PRINT(t.value)
262
+
263
+ return t
264
+
265
+ def t_text_END_TEXT(t):
266
+
267
+ r'"'
268
+
269
+ PRINT(t.value)
270
+
271
+ t.lexer.pop_state()
272
+
273
+
274
+
275
+ def t_version_VERSION(t):
276
+
277
+ r'[^;]+'
278
+
279
+ PRINT(t.value)
280
+
281
+ return t
282
+
283
+ def t_version_END_VERSION(t):
284
+
285
+ r';'
286
+
287
+ PRINT(t.value)
288
+
289
+ t.lexer.pop_state()
290
+
291
+ t.type = ';'
292
+
293
+ t.value = ';'
294
+
295
+ return t
296
+
297
+
298
+
299
+ #---------------------------------------------------------------------
300
+
301
+ # define error function
302
+
303
+ def t_ANY_error(t):
304
+
305
+ print("不正な文字 '%s'" % t.value[0])
306
+
307
+ print(t.lineno)
308
+
309
+ t.lexer.skip(1)
310
+
311
+
312
+
313
+ #---------------------------------------------------------------------
314
+
315
+ # declare instance
316
+
317
+ lex.lex(debug=0)
318
+
319
+
320
+
321
+ #---------------------------------------------------------------------
322
+
323
+ # main process
324
+
325
+
326
+
327
+ # debug main
328
+
329
+ def debug_main():
330
+
331
+ #data = open('test.txt').read()
332
+
333
+ data = input()
334
+
335
+ lex.input(data)
336
+
337
+ while(True):
338
+
339
+ tok = lex.token()
340
+
341
+ if not tok:
342
+
343
+ break
344
+
345
+
346
+
347
+ # debug entry point
348
+
349
+ if __name__ == "__main__":
350
+
351
+ debug_main()
352
+
353
+
354
+
355
+ ```
356
+
357
+
358
+
359
+ ```python
360
+
361
+ #!/usr/bin/env python
362
+
363
+ from ...ExImports import *
364
+
365
+ import ply.yacc as yacc
366
+
367
+ from .lex import tokens
368
+
369
+ from ..Common import *
370
+
371
+
372
+
373
+ def p_input(p):
374
+
375
+ 'input : EBGUIDE VERSION ";" file_root'
376
+
377
+ p[0] = p[4]
378
+
379
+
380
+
381
+ def p_flie_root(p):
382
+
383
+ 'file_root : OBJ_ID object'
384
+
385
+ p[0] = p[1]
386
+
387
+
388
+
389
+ def p_object(p):
390
+
391
+ 'object : "{" properties "}"'
392
+
393
+ p[0] = p[2]
394
+
395
+
396
+
397
+ def p_properties(p):
398
+
399
+ '''properties :
400
+
401
+ | properties simple_property
402
+
403
+ | properties data_binded_property
404
+
405
+ | properties nest_property'''
406
+
407
+ if (len(p) == 1):
408
+
409
+ p[0] = []
410
+
411
+ return
412
+
413
+ p[0] = p[1]
414
+
415
+ p[0].append(p[2])
416
+
417
+
418
+
419
+ def p_simple_property(p):
420
+
421
+ ''' simple_property : PROP_ID SYMBOL SYMBOL text ";"
422
+
423
+ | PROP_ID SYMBOL SYMBOL NUMBER ";"
424
+
425
+ | PROP_ID SYMBOL SYMBOL BOOL ";"
426
+
427
+ | PROP_ID text SYMBOL text ";"
428
+
429
+ | PROP_ID text SYMBOL NUMBER ";"
430
+
431
+ | PROP_ID text SYMBOL BOOL ";" '''
432
+
433
+ p[0] = p[1]
434
+
435
+ SimpleProperty(p[1], p[2], p[3], p[4])
436
+
437
+
438
+
439
+ def p_data_binded_property(p):
440
+
441
+ ''' data_binded_property : PROP_ID text SYMBOL prop_id ";" '''
442
+
443
+ p[0] = p[1]
444
+
445
+ SimpleProperty(p[1], p[2], p[3], p[4])
446
+
447
+
448
+
449
+ def p_nest_property(p):
450
+
451
+ ''' nest_property : PROP_ID SYMBOL SYMBOL OBJ_ID object
452
+
453
+ | PROP_ID SYMBOL SYMBOL array ";"
454
+
455
+ | PROP_ID text SYMBOL OBJ_ID ";"
456
+
457
+ | PROP_ID text SYMBOL OBJ_ID object
458
+
459
+ | PROP_ID text SYMBOL array ";"'''
460
+
461
+ p[0] = p[1]
462
+
463
+ SimpleProperty(p[1], p[2], p[3], p[4])
464
+
465
+
466
+
467
+ def p_text(p):
468
+
469
+ '''text :
470
+
471
+ | TEXT'''
472
+
473
+ p[0] = reduce(lambda x, y: x + y, p[1:], "")
474
+
475
+
476
+
477
+ def p_prop_id(p):
478
+
479
+ '''prop_id : PROP_ID
480
+
481
+ | OBJ_ID PROP_ID'''
482
+
483
+ p[0] = reduce(lambda x, y: x + y, p[1:], "")
484
+
485
+
486
+
487
+ def p_array(p):
488
+
489
+ '''array : array_header "[" "]"
490
+
491
+ | array_header "[" obj_array "]"
492
+
493
+ | array_header "[" int_array "]"
494
+
495
+ | array_header "[" text_array "]"
496
+
497
+ | array_header "[" obj_ref_array "]"
498
+
499
+ | array_header "[" prop_ref_array "]"'''
500
+
501
+ p[0] = p[4] if len(p) != 4 else []
502
+
503
+
504
+
505
+ def p_array_header(p):
506
+
507
+ 'array_header : "<" SYMBOL ">"'
508
+
509
+
510
+
511
+ def p_obj_array(p):
512
+
513
+ '''obj_array : nameless_obj
514
+
515
+ | obj_array "," nameless_obj'''
516
+
517
+ p[0] = [] if len(p) == 2 else p[1]
518
+
519
+ p[0].append(p[-1])
520
+
521
+
522
+
523
+ def p_int_array(p):
524
+
525
+ '''int_array : NUMBER
526
+
527
+ | int_array "," NUMBER'''
528
+
529
+ p[0] = [] if len(p) == 2 else p[1]
530
+
531
+ p[0].append(p[-1])
532
+
533
+
534
+
535
+ def p_text_array(p):
536
+
537
+ '''text_array : TEXT
538
+
539
+ | text_array "," TEXT'''
540
+
541
+ p[0] = [] if len(p) == 2 else p[1]
542
+
543
+ p[0].append(p[-1])
544
+
545
+
546
+
547
+ def p_obj_ref_array(p):
548
+
549
+ '''obj_ref_array : OBJ_ID
550
+
551
+ | obj_ref_array "," OBJ_ID'''
552
+
553
+ p[0] = [] if len(p) == 2 else p[1]
554
+
555
+ p[0].append(p[-1])
556
+
557
+
558
+
559
+ def p_prop_ref_array(p):
560
+
561
+ '''prop_ref_array : prop_id
562
+
563
+ | prop_ref_array "," prop_id '''
564
+
565
+ p[0] = [] if len(p) == 2 else p[1]
566
+
567
+ p[0].append(p[-1])
568
+
569
+
570
+
571
+ def p_nameless_obj(p):
572
+
573
+ 'nameless_obj : SYMBOL OBJ_ID object'
574
+
575
+ p[0] = p[3]
576
+
577
+
578
+
579
+ # syntax error
580
+
581
+ def p_error(p):
582
+
583
+ print ('Syntax error in input %s' %p)
584
+
585
+
586
+
587
+ parser = yacc.yacc()
588
+
589
+
590
+
591
+ # Debug
592
+
593
+ def parse(data, debug=0):
594
+
595
+ return yacc.parse(data, debug=debug)
596
+
597
+
598
+
599
+ if __name__ == '__main__':
600
+
601
+ data = open('test.txt').read()
602
+
603
+ result = parser.parse(data)
604
+
605
+ ```