gps_pvt 0.9.4 → 0.10.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.
@@ -0,0 +1,903 @@
1
+ class ASN1::Parser
2
+
3
+ start ModuleDefinitionList
4
+
5
+ rule
6
+
7
+ ModuleDefinitionList :
8
+ ModuleDefinition
9
+ | ModuleDefinitionList ModuleDefinition {result.merge!(val[1])}
10
+
11
+ # 11.4
12
+ valuereference : identifier
13
+
14
+ # 11.5
15
+ modulereference : typereference
16
+
17
+ # 12. Module definition
18
+ ModuleDefinition :
19
+ ModuleIdentifier
20
+ DEFINITIONS
21
+ TagDefault
22
+ ExtensionDefault
23
+ ASSIGN
24
+ BEGIN
25
+ ModuleBody
26
+ END
27
+ {
28
+ result = {val[0] => val[6]}
29
+ }
30
+
31
+ ModuleIdentifier : modulereference DefinitiveIdentifier
32
+
33
+ DefinitiveIdentifier : LBRACE DefinitiveObjIdComponentList RBRACE |
34
+
35
+ DefinitiveObjIdComponentList :
36
+ DefinitiveObjIdComponent
37
+ | DefinitiveObjIdComponentList DefinitiveObjIdComponent
38
+
39
+ DefinitiveObjIdComponent :
40
+ NameForm
41
+ | DefinitiveNumberForm
42
+ | DefinitiveNameAndNumberForm
43
+
44
+ DefinitiveNumberForm : number
45
+
46
+ DefinitiveNameAndNumberForm : identifier LCBRACE DefinitiveNumberForm RCBRACE
47
+
48
+ TagDefault :
49
+ EXPLICIT TAGS {raise} # not supported
50
+ | IMPLICIT TAGS {raise} # not supported
51
+ | AUTOMATIC TAGS
52
+ | {raise} # not supported
53
+
54
+ ExtensionDefault :
55
+ EXTENSIBILITY IMPLIED
56
+ |
57
+
58
+ ModuleBody :
59
+ Exports Imports AssignmentList {result = val[2].merge(val[1] || {})}
60
+ |
61
+
62
+ Exports :
63
+ EXPORTS SymbolsExported SEMICOLON
64
+ | EXPORTS ALL SEMICOLON
65
+ |
66
+
67
+ SymbolsExported :
68
+ SymbolList
69
+ |
70
+
71
+ Imports :
72
+ IMPORTS SymbolsImported SEMICOLON {
73
+ result = Hash[*((val[1] || {}).collect{|k, v|
74
+ [k, {:typeref => [v, k]}]
75
+ }.flatten(1))]
76
+ }
77
+ |
78
+
79
+ SymbolsImported :
80
+ SymbolsFromModuleList
81
+ |
82
+
83
+ SymbolsFromModuleList :
84
+ SymbolsFromModule
85
+ | SymbolsFromModuleList SymbolsFromModule {result = result.merge(val[1])}
86
+
87
+ SymbolsFromModule : SymbolList FROM GlobalModuleReference {
88
+ result = Hash[*(val[0].collect{|v|
89
+ [v, val[2]]
90
+ }.flatten(1))]
91
+ }
92
+
93
+ GlobalModuleReference : modulereference AssignedIdentifier
94
+
95
+ AssignedIdentifier :
96
+ ObjectIdentifierValue
97
+ | DefinedValue
98
+ |
99
+
100
+ SymbolList :
101
+ Symbol {result = [val[0]]}
102
+ | SymbolList COMMA Symbol {result << val[2]}
103
+
104
+ Symbol :
105
+ Reference
106
+ | ParameterizedReference
107
+
108
+ Reference :
109
+ typereference
110
+ | valuereference
111
+ | objectclassreference
112
+ | objectreference
113
+ | objectsetreference
114
+
115
+ AssignmentList :
116
+ Assignment
117
+ | AssignmentList Assignment {result = result.merge(val[1])}
118
+
119
+ Assignment :
120
+ TypeAssignment
121
+ | ValueAssignment
122
+ #| XMLValueAssignment
123
+ /*| ValueSetTypeAssignment
124
+ | ObjectClassAssignment
125
+ | ObjectAssignment
126
+ | ObjectSetAssignment
127
+ | ParameterizedAssignment*/
128
+
129
+ # 13. Referencing type and value definitions
130
+ DefinedType :
131
+ /*ExternalTypeReference
132
+ |*/ Typereference
133
+ | ParameterizedType
134
+ | ParameterizedValueSetType
135
+ /*
136
+ DefinedValue :
137
+ ExternalValueReference
138
+ | Valuereference
139
+ | ParameterizedValue
140
+ */
141
+ DefinedValue : {raise}
142
+
143
+ # 15. Assigning types and values
144
+ TypeAssignment : typereference ASSIGN Type { # 15.1
145
+ result = {val[0] => val[2]}
146
+ }
147
+
148
+ ValueAssignment : valuereference Type ASSIGN Value { # 15.2
149
+ result = {val[0] => val[1].merge({:value => val[3]})}
150
+ }
151
+
152
+ ValueSetTypeAssignment : typereference Type ASSIGN ValueSet # 15.6
153
+
154
+ ValueSet : LBRACE ElementSetSpecs RBRACE # 15.7
155
+
156
+ # 16. Definition of types and values
157
+ Type : # 16.1
158
+ BuiltinType {
159
+ result = {:type => val[0]} if val[0].kind_of?(Symbol)
160
+ }
161
+ | ReferencedType {result = {:typeref => val[0]}}
162
+ | ConstrainedType
163
+
164
+ BuiltinType : # 16.2
165
+ BitStringType
166
+ | BooleanType
167
+ | CharacterStringType
168
+ | ChoiceType
169
+ #| EmbeddedPDVType
170
+ | EnumeratedType
171
+ #| ExternalType
172
+ | InstanceOfType
173
+ | IntegerType
174
+ | NullType
175
+ | ObjectClassFieldType
176
+ | ObjectIdentifierType
177
+ | OctetStringType
178
+ | RealType
179
+ #| RelativeOIDType
180
+ | SequenceType
181
+ | SequenceOfType
182
+ #| SetType
183
+ #| SetOfType
184
+ | TaggedType
185
+ | UTCTime # 43. Universal time
186
+
187
+ ReferencedType : # 16.3
188
+ DefinedType
189
+ | UsefulType
190
+ #| SelectionType
191
+ | TypeFromObject
192
+ | ValueSetFromObjects
193
+
194
+ NamedType : identifier Type {result = {:name => val[0]}.merge(val[1])} # 16.5
195
+
196
+ Value : # 16.7
197
+ BuiltinValue
198
+ #| ReferencedValue
199
+ | ObjectClassFieldValue
200
+
201
+ BuiltinValue : # 16.9
202
+ BitStringValue
203
+ | BooleanValue
204
+ | CharacterStringValue
205
+ | ChoiceValue
206
+ #| EmbeddedPDVValue
207
+ | EnumeratedValue
208
+ #| ExternalValue
209
+ #| InstanceOfValue
210
+ | IntegerValue
211
+ | NullValue
212
+ | ObjectIdentifierValue
213
+ | OctetStringValue
214
+ | RealValue
215
+ #| RelativeOIDValue
216
+ | SequenceValue
217
+ | SequenceOfValue
218
+ #| SetValue
219
+ #| SetOfValue
220
+ #| TaggedValue
221
+
222
+ #ReferencedValue : DefinedValue | ValueFromObject # 16.11
223
+ #ReferencedValue : identifier
224
+
225
+ # 17. Notation for the boolean type
226
+ BooleanType : BOOLEAN
227
+ BooleanValue : TRUE | FALSE
228
+
229
+ # 18. Notation for the integer type
230
+ IntegerType :
231
+ INTEGER {result = {:type => val[0]}}
232
+ | INTEGER LBRACE NamedNumberList RBRACE {result = {:type => [val[0], {:list => val[2]}]}}
233
+ NamedNumberList :
234
+ NamedNumber {result = val[0]}
235
+ | NamedNumberList COMMA NamedNumber {result.merge!(val[2])}
236
+ NamedNumber :
237
+ identifier LCBRACE SignedNumber RCBRACE {result = {val[0] => val[2]}}
238
+ | identifier LCBRACE DefinedValue RCBRACE
239
+ SignedNumber :
240
+ number
241
+ | MINUS number {result = -val[1]}
242
+
243
+ IntegerValue :
244
+ SignedNumber
245
+ | identifier
246
+
247
+ # 19. Notation for the enumerated type
248
+ EnumeratedType :
249
+ ENUMERATED LBRACE Enumerations RBRACE {
250
+ array = (val[2][0][0].clone rescue [])
251
+ val[2][0][1].each{|k, i| array.insert(i, k)} rescue nil
252
+ root_sorted = array.clone
253
+ additional_keys = []
254
+ val[2][1][0].each{|k|
255
+ additional_keys << (array[array.find_index(nil) || array.size] = k)
256
+ } rescue nil
257
+ val[2][1][1].each{|k, i|
258
+ raise if array[i]
259
+ additional_keys << (array[i] = k)
260
+ } rescue nil
261
+ result = {:type => [val[0], {
262
+ :root => Hash[*(root_sorted.collect.with_index{|k, i|
263
+ k ? [k, i] : nil
264
+ }.compact.flatten(1))]
265
+ }]}
266
+ result[:type][1][:additional] = Hash[*(additional_keys.collect{|k|
267
+ [k, array.find_index(k)]
268
+ }.flatten(1))] if val[2][1]
269
+ }
270
+ /*
271
+ Enumerations :
272
+ RootEnumeration
273
+ | RootEnumeration COMMA ELLIPSIS ExceptionSpec
274
+ | RootEnumeration COMMA ELLIPSIS ExceptionSpec COMMA AdditionalEnumeration
275
+ RootEnumeration : Enumeration
276
+ AdditionalEnumeration : Enumeration
277
+ */
278
+ Enumerations : # work around version
279
+ Enumeration {result = [val[0]]}
280
+ | Enumeration COMMA ELLIPSIS ExceptionSpec
281
+ {result = [val[0], []]}
282
+ | Enumeration COMMA ELLIPSIS ExceptionSpec
283
+ COMMA Enumeration
284
+ {result = [val[0], val[5]]}
285
+ Enumeration :
286
+ EnumerationItem {
287
+ result = [[], {}]
288
+ val[0].kind_of?(Symbol) ? (result[0] << val[0]) : result[1].merge!(val[0])
289
+ }
290
+ | Enumeration COMMA EnumerationItem {
291
+ val[2].kind_of?(Symbol) ? (result[0] << val[2]) : result[1].merge!(val[2])
292
+ }
293
+ EnumerationItem :
294
+ identifier
295
+ | NamedNumber
296
+
297
+ EnumeratedValue : identifier
298
+
299
+ # 20. Notation for the real type
300
+ RealType : REAL
301
+
302
+ RealValue :
303
+ NumericRealValue
304
+ | SpecialRealValue
305
+ NumericRealValue :
306
+ realnumber
307
+ | MINUS realnumber
308
+ | SequenceValue
309
+ SpecialRealValue : PLUS_INFINITY | MINUS_INFINITY
310
+
311
+ # 21. Notation for the bitstring
312
+ BitStringType :
313
+ BIT STRING {result = {:type => :BIT_STRING}}
314
+ | BIT STRING LBRACE NamedBitList RBRACE {result = {:type => [:BIT_STRING, {:list => val[3]}]}}
315
+ NamedBitList :
316
+ NamedBit {result = val[0]}
317
+ | NamedBitList COMMA NamedBit {result.merge!(val[2])}
318
+ NamedBit :
319
+ identifier LCBRACE number RCBRACE {result = {val[0] => val[2]}}
320
+ | identifier LCBRACE DefinedValue RCBRACE {result = {val[0] => val[2]}}
321
+
322
+ BitStringValue :
323
+ bstring
324
+ | hstring
325
+ | LBRACE IdentifierList RBRACE
326
+ | LBRACE RBRACE
327
+ | CONTAINING Value
328
+ IdentifierList :
329
+ identifier
330
+ | IdentifierList COMMA identifier
331
+
332
+ # 22. Notation for the octetstring type
333
+ OctetStringType : OCTET STRING {result = {:type => :OCTET_STRING}}
334
+ OctetStringValue :
335
+ bstring
336
+ | hstring
337
+ | CONTAINING Value
338
+
339
+ # 23. Notation for the null type
340
+ NullType : NULL
341
+ NullValue : NULL
342
+
343
+ # 24. Notation for sequence types
344
+ SequenceType :
345
+ /*SEQUENCE LBRACE RBRACE
346
+ | SEQUENCE LBRACE ExtensionAndException OptionalExtensionMarker RBRACE
347
+ |*/ SEQUENCE LBRACE ComponentTypeLists RBRACE {result = {:type => [val[0], val[2]]}}
348
+ /*
349
+ ExtensionAndException :
350
+ ELLIPSIS
351
+ | ELLIPSIS ExceptionSpec
352
+ OptionalExtensionMarker :
353
+ COMMA ELLIPSIS
354
+ |
355
+ ComponentTypeLists :
356
+ RootComponentTypeList
357
+ | RootComponentTypeList
358
+ COMMA ExtensionAndException ExtensionAdditions OptionalExtensionMarker
359
+ | RootComponentTypeList
360
+ COMMA ExtensionAndException ExtensionAdditions ExtensionEndMarker
361
+ COMMA RootComponentTypeList
362
+ | ExtensionAndException ExtensionAdditions ExtensionEndMarker
363
+ COMMA RootComponentTypeList
364
+ | ExtensionAndException ExtensionAdditions OptionalExtensionMarker
365
+ RootComponentTypeList : ComponentTypeList
366
+ ExtensionEndMarker : COMMA ELLIPSIS
367
+ */
368
+ ComponentTypeLists : # work around version
369
+ /* empty */ {result = {:root => []}}
370
+ | ComponentTypeList {result = {:root => val[0]}}
371
+ | ComponentTypeList COMMA ELLIPSIS ExceptionSpec ComponentTypeLists2
372
+ {result = {:root => val[0], :extension => []}.merge(val[4]){|k, v1, v2| v1 + v2}}
373
+ | ELLIPSIS ExceptionSpec ComponentTypeLists2
374
+ {result = {:root => [], :extension => []}.merge(val[2]){|k, v1, v2| v1 + v2}}
375
+ ComponentTypeLists2 : # work around version
376
+ /* empty */
377
+ {result = {}}
378
+ | COMMA ELLIPSIS
379
+ {result = {}}
380
+ | COMMA ELLIPSIS COMMA ComponentTypeList
381
+ {result = {:root => val[3]}}
382
+ | COMMA ExtensionAdditionList
383
+ {result = {:extension => val[1]}}
384
+ | COMMA ExtensionAdditionList COMMA ELLIPSIS
385
+ {result = {:extension => val[1]}}
386
+ | COMMA ExtensionAdditionList COMMA ELLIPSIS COMMA ComponentTypeList
387
+ {result = {:root => val[5], :extension => val[1]}}
388
+ /*ExtensionAdditions :
389
+ COMMA ExtensionAdditionList
390
+ | */
391
+ ExtensionAdditionList :
392
+ ExtensionAddition {result = [val[0]]}
393
+ | ExtensionAdditionList COMMA ExtensionAddition {result << val[2]}
394
+ ExtensionAddition :
395
+ ComponentType
396
+ | ExtensionAdditionGroup
397
+ ExtensionAdditionGroup :
398
+ LVBRACKET VersionNumber ComponentTypeList RVBRACKET
399
+ {result = {:group => val[2]}; result[:version] = val[1] if val[1]}
400
+ VersionNumber :
401
+ /* empty */
402
+ | number COLON
403
+ ComponentTypeList :
404
+ ComponentType {result = [val[0]]}
405
+ | ComponentTypeList COMMA ComponentType {result << val[2]}
406
+ ComponentType :
407
+ NamedType
408
+ | NamedType OPTIONAL {result = val[0].merge({:optional => true})}
409
+ | NamedType DEFAULT Value {result = val[0].merge({:default => val[2]})}
410
+ | COMPONENTS OF Type {result = val[2]; raise} /* TODO 24.4 says only root components of SEQUENCE are included */
411
+
412
+ SequenceValue :
413
+ LBRACE ComponentValueList RBRACE
414
+ | LBRACE RBRACE
415
+ ComponentValueList :
416
+ NamedValue
417
+ | ComponentValueList COMMA NamedValue
418
+
419
+ # 25 Notation for sequence-of types
420
+ SequenceOfType :
421
+ SEQUENCE OF SequenceOfType_t {
422
+ result = {:type => ["#{val[0]}_#{val[1]}".to_sym, val[2]]}
423
+ }
424
+ SequenceOfType_t : Type | NamedType
425
+
426
+ SequenceOfValue :
427
+ LBRACE ValueList RBRACE
428
+ | LBRACE NamedValueList RBRACE
429
+ | LBRACE RBRACE
430
+ ValueList :
431
+ Value
432
+ | ValueList COMMA Value
433
+ NamedValueList :
434
+ NamedValue
435
+ | NamedValueList COMMA NamedValue
436
+
437
+ # 28. Notation for choice types
438
+ ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE {
439
+ result = {:type => [val[0], val[2]]}
440
+ }
441
+ /*
442
+ AlternativeTypeLists :
443
+ RootAlternativeTypeList
444
+ | RootAlternativeTypeList
445
+ COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker
446
+ RootAlternativeTypeList : AlternativeTypeList
447
+ */
448
+ AlternativeTypeLists : # work around version
449
+ AlternativeTypeList {result = {:root => val[0]}}
450
+ | AlternativeTypeList COMMA ELLIPSIS ExceptionSpec
451
+ {result = {:root => val[0], :extension => []}}
452
+ | AlternativeTypeList COMMA ELLIPSIS ExceptionSpec COMMA ELLIPSIS
453
+ {result = {:root => val[0], :extension => []}}
454
+ | AlternativeTypeList COMMA ELLIPSIS ExceptionSpec COMMA ExtensionAdditionAlternativesList
455
+ {result = {:root => val[0], :extension => val[5]}}
456
+ | AlternativeTypeList COMMA ELLIPSIS ExceptionSpec COMMA ExtensionAdditionAlternativesList
457
+ COMMA ELLIPSIS
458
+ {result = {:root => val[0], :extension => val[5]}}
459
+ /*ExtensionAdditionAlternatives :
460
+ COMMA ExtensionAdditionAlternativesList
461
+ |*/
462
+ ExtensionAdditionAlternativesList :
463
+ ExtensionAdditionAlternative {result = [val[0]]}
464
+ | ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative {result << val[2]}
465
+ ExtensionAdditionAlternative :
466
+ ExtensionAdditionAlternativesGroup
467
+ | NamedType
468
+ ExtensionAdditionAlternativesGroup :
469
+ LVBRACKET VersionNumber AlternativeTypeList RVBRACKET
470
+ {result = {:group => val[2]}; result[:version] = val[1] if val[1]}
471
+ AlternativeTypeList :
472
+ NamedType {result = [val[0]]}
473
+ | AlternativeTypeList COMMA NamedType {result << val[2]}
474
+
475
+ ChoiceValue : identifier COLON Value
476
+
477
+ # 30. Notation for tagged types
478
+ TaggedType :
479
+ Tag Type
480
+ | Tag IMPLICIT Type
481
+ | Tag EXPLICIT Type
482
+ Tag : LBRACKET Class ClassNumber RBRACKET
483
+ ClassNumber :
484
+ number
485
+ | DefinedValue
486
+ Class :
487
+ UNIVERSAL
488
+ | APPLICATION
489
+ | PRIVATE
490
+ |
491
+
492
+ #TaggedValue : Value
493
+
494
+ # 31. Notation for the object identifier type
495
+ ObjectIdentifierType : OBJECT IDENTIFIER
496
+
497
+ ObjectIdentifierValue :
498
+ LBRACE ObjIdComponentsList RBRACE
499
+ | LBRACKET DefinedValue ObjIdComponentsList RBRACKET
500
+ ObjIdComponentsList :
501
+ ObjIdComponents
502
+ | ObjIdComponentsList ObjIdComponents
503
+ ObjIdComponents :
504
+ NameForm
505
+ | NumberForm
506
+ | NameAndNumberForm
507
+ | DefinedValue
508
+ NameForm : identifier
509
+ NumberForm :
510
+ number
511
+ | DefinedValue
512
+ NameAndNumberForm : identifier LCBRACE NumberForm RCBRACE
513
+
514
+ # 36. Notation for character string types
515
+ CharacterStringType :
516
+ RestrictedCharacterStringType
517
+ | UnrestrictedCharacterStringType
518
+ CharacterStringValue :
519
+ RestrictedCharacterStringValue
520
+ | UnrestrictedCharacterStringValue
521
+
522
+ # 37. Definition of restricted character string types
523
+ RestrictedCharacterStringType :
524
+ /*BMPString
525
+ | GeneralString
526
+ | GraphicString
527
+ |*/ IA5String
528
+ /*| ISO646String*/
529
+ | NumericString
530
+ | PrintableString
531
+ /*| TeletexString
532
+ | T61String
533
+ | UniversalString
534
+ | UTF8String
535
+ | VideotexString*/
536
+ | VisibleString
537
+
538
+ RestrictedCharacterStringValue :
539
+ cstring
540
+ | CharacterStringList
541
+ | Quadruple
542
+ | Tuple
543
+ CharacterStringList : LBRACE CharSyms RBRACE
544
+ CharSyms :
545
+ CharsDefn
546
+ | CharSyms COMMA CharsDefn
547
+ CharsDefn :
548
+ cstring
549
+ | Quadruple
550
+ | Tuple
551
+ | DefinedValue
552
+ Quadruple : LBRACE Group COMMA Plane COMMA Row COMMA Cell RBRACE
553
+ Group : number
554
+ Plane : number
555
+ Row : number
556
+ Cell : number
557
+ Tuple : LBRACE TableColumn COMMA TableRow RBRACE
558
+ TableColumn : number
559
+ TableRow : number
560
+
561
+ # 40. Definition of unrestricted character string types
562
+ UnrestrictedCharacterStringType : CHARACTER STRING
563
+
564
+ UnrestrictedCharacterStringValue : SequenceValue
565
+
566
+ # 41. Notation for types defined in clauses 42 to 44
567
+ UsefulType : typereference
568
+
569
+ # 45. Constrained types
570
+ ConstrainedType :
571
+ Type Constraint {
572
+ type_name, type_opt = val[0][:type]
573
+ type_opt = constraint_hash(type_opt ? [:and, type_opt, val[1]] : val[1])
574
+ result = val[0].merge({:type => [type_name, type_opt]})
575
+ }
576
+ | TypeWithConstraint
577
+ TypeWithConstraint :
578
+ TypeWithConstraint_p TypeWithConstraint_c OF TypeWithConstraint_t {
579
+ raise if val[0] == :SET # not supported
580
+ result = {:type => ["#{val[0]}_OF".to_sym, val[3].merge(constraint_hash(val[1]))]}
581
+ }
582
+ TypeWithConstraint_p : SET | SEQUENCE
583
+ TypeWithConstraint_c : Constraint | SizeConstraint
584
+ TypeWithConstraint_t : Type | NamedType
585
+ Constraint : LCBRACE ConstraintSpec ExceptionSpec RCBRACE {
586
+ result = val[1]
587
+ }
588
+ ConstraintSpec :
589
+ SubtypeConstraint
590
+ #| GeneralConstraint
591
+ SubtypeConstraint : ElementSetSpecs
592
+
593
+ # 46. Element set specification
594
+ ElementSetSpecs :
595
+ RootElementSetSpec
596
+ | RootElementSetSpec COMMA ELLIPSIS {
597
+ result = [:extensible, val[0]]
598
+ }
599
+ | RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec {
600
+ result = [:extensible, val[0], val[4]]
601
+ }
602
+ RootElementSetSpec : ElementSetSpec
603
+ AdditionalElementSetSpec : ElementSetSpec {
604
+ raise if val[0].flatten.include?(:extensible)
605
+ }
606
+ ElementSetSpec :
607
+ Unions
608
+ #| ALL Exclusions
609
+ | ALL EXCEPT Elements {
610
+ raise if val[2].flatten.include?(:extensible)
611
+ result = case val[2][0]
612
+ when :and; [:not, val[2]]
613
+ when :not; (val[2][1].kind_of?(Array)) ? val[2][1] : [:or, val[2][1]]
614
+ when :or; [:not, (val[2].size == 2) ? val[2][1] : val[2]]
615
+ end
616
+ }
617
+ Unions :
618
+ Intersections
619
+ #| UElems UnionMark Intersections
620
+ | Unions UnionMark Intersections {
621
+ elms = ((val[0][0] == :or) ? val[0][1..-1] : [val[0]]) \
622
+ + ((val[2][0] == :or) ? val[2][1..-1] : [val[2]])
623
+ elm_hash = {}
624
+ elms.reject!{|elm|
625
+ elm_hash.merge!(elm){|k, v, v_|
626
+ [v].flatten(1) + [v_].flatten(1)
627
+ } if (elm.kind_of?(Hash) && (elm.keys.size == 1))
628
+ }
629
+ result = [:or] + elms + elm_hash.collect{|k, v| {k => v}}
630
+ }
631
+ #UElems : Unions
632
+ Intersections :
633
+ IntersectionElements
634
+ #| IElems IntersectionMark IntersectionElements
635
+ | Intersections IntersectionMark IntersectionElements {
636
+ result = [:and] + ((val[0][0] == :and) ? val[0][1..-1] : [val[0]]) \
637
+ + ((val[2][0] == :and) ? val[2][1..-1] : [val[2]])
638
+ }
639
+ #IElems : Intersections
640
+ IntersectionElements :
641
+ Elements
642
+ #| Elems Exclusions
643
+ | Elements EXCEPT Elements {
644
+ raise if val[2].flatten.include?(:extensible)
645
+ val[2] = case val[2][0]
646
+ when :and; [:not, val[2]]
647
+ when :not; (val[2][1].kind_of?(Array)) ? val[2][1] : [:or, val[2][1]]
648
+ when :or; [:not, (val[2].size == 2) ? val[2][1] : val[2]]
649
+ end
650
+ result = [:and] + ((val[0][0] == :and) ? val[0][1..-1] : [val[0]]) \
651
+ + ((val[2][0] == :and) ? val[2][1..-1] : [val[2]])
652
+ }
653
+ #Elems : Elements
654
+ #Exclusions : EXCEPT Elements
655
+ UnionMark : VBAR | UNION
656
+ IntersectionMark : HAT | INTERSECTION
657
+ Elements : # always return Array[op, arg[0], ...]
658
+ SubtypeElements {result = [:or, val[0]]}
659
+ #| ObjectSetElements
660
+ | LCBRACE ElementSetSpec RCBRACE {result = val[1]}
661
+
662
+ # 47. Subtype elements
663
+ SubtypeElements :
664
+ SingleValue # 47.2
665
+ #| ContainedSubtype # 47.3
666
+ | ValueRange # 47.4
667
+ | PermittedAlphabet # 47.5
668
+ | SizeConstraint # 47.6
669
+ #| TypeConstraint # 47.7
670
+ #| InnerTypeConstraints # 47.8
671
+ #| PatternConstraint # 47.9
672
+
673
+ SingleValue : Value {result = {:value => val[0]}}
674
+
675
+ #ContainedSubtype : Includes Type
676
+ #Includes : INCLUDES |
677
+
678
+ ValueRange : LowerEndpoint RANGE_SEP UpperEndpoint {
679
+ range = val.values_at(0, 2).collect{|item|
680
+ item.empty? ? nil : item
681
+ }.compact
682
+ range = {:and => range} if range.size > 1
683
+ result = {:value => range}
684
+ }
685
+ LowerEndpoint :
686
+ LowerEndValue {result = (val[0] == :MIN) ? [] : [:>=, val[0]]}
687
+ | LowerEndValue LT {result = (val[0] == :MIN) ? [] : [:>, val[0]]}
688
+ UpperEndpoint :
689
+ UpperEndValue {result = (val[0] == :MAX) ? [] : [:<=, val[0]]}
690
+ | LT UpperEndValue {result = (val[0] == :MAX) ? [] : [:<, val[0]]}
691
+ LowerEndValue : Value | MIN
692
+ UpperEndValue : Value | MAX
693
+
694
+ SizeConstraint :
695
+ SIZE Constraint {
696
+ iter_proc = proc{|tree|
697
+ case tree
698
+ when Hash
699
+ raise unless (tree.keys - [:value]).empty?
700
+ next {:size => tree[:value]}
701
+ when Array
702
+ tree[1..-1] = tree[1..-1].collect{|v| iter_proc.call(v)}
703
+ end
704
+ tree
705
+ }
706
+ result = iter_proc.call(val[1])
707
+ }
708
+
709
+ #TypeConstraint : Type
710
+
711
+ PermittedAlphabet :
712
+ FROM Constraint {
713
+ iter_proc = proc{|tree|
714
+ case tree
715
+ when Hash
716
+ raise unless (tree.keys - [:value]).empty?
717
+ next {:from => tree[:value]}
718
+ when Array
719
+ tree[1..-1] = tree[1..-1].collect{|v| iter_proc.call(v)}
720
+ end
721
+ tree
722
+ }
723
+ result = iter_proc.call(val[1])
724
+ }
725
+
726
+ # 49. The exception identifier
727
+ ExceptionSpec :
728
+ EXCMARK ExceptionIdentification {raise} # Not implemented
729
+ |
730
+ ExceptionIdentification :
731
+ SignedNumber
732
+ | DefinedValue
733
+ | Type COLON Value
734
+ end
735
+
736
+ ---- header
737
+
738
+ require 'strscan'
739
+
740
+ ---- inner
741
+
742
+ RESERVED_WORDS = proc{
743
+ keys =(<<-__TEXT__).gsub(/\s+/, ' ').gsub(/^\s+|\s+$/, '').split(' ')
744
+ ABSENT ABSTRACT-SYNTAX ALL APPLICATION AUTOMATIC BEGIN BIT BMPString BOOLEAN BY
745
+ CHARACTER CHOICE CLASS COMPONENT COMPONENTS CONSTRAINED CONTAINING DEFAULT DEFINITIONS EMBEDDED
746
+ ENCODED END ENUMERATED EXCEPT EXPLICIT EXPORTS EXTENSIBILITY EXTERNAL FALSE FROM
747
+ GeneralizedTime GeneralString GraphicString IA5String IDENTIFIER IMPLICIT IMPLIED IMPORTS INCLUDES INSTANCE
748
+ INTEGER INTERSECTION ISO646String MAX MIN MINUS-INFINITY NULL NumericString OBJECT ObjectDescriptor
749
+ OCTET OF OPTIONAL PATTERN PDV PLUS-INFINITY PRESENT PrintableString PRIVATE REAL
750
+ RELATIVE-OID SEQUENCE SET SIZE STRING SYNTAX T61String TAGS TeletexString TRUE
751
+ TYPE-IDENTIFIER UNION UNIQUE UNIVERSAL UniversalString UTCTime UTF8String VideotexString VisibleString WITH
752
+ __TEXT__
753
+ Hash[*(keys.collect{|k|
754
+ [k, k.gsub(/\-/, '_').to_sym]
755
+ }.flatten(1))].merge({
756
+ '[[' => :LVBRACKET,
757
+ ']]' => :RVBRACKET,
758
+ '[' => :LBRACKET,
759
+ ']' => :RBRACKET,
760
+ '{' => :LBRACE,
761
+ '}' => :RBRACE,
762
+ '(' => :LCBRACE,
763
+ ')' => :RCBRACE,
764
+ ',' => :COMMA,
765
+ ';' => :SEMICOLON,
766
+ '::=' => :ASSIGN,
767
+ ':' => :COLON,
768
+ '-' => :MINUS,
769
+ '...' => :ELLIPSIS,
770
+ '..' => :RANGE_SEP,
771
+ '|' => :VBAR,
772
+ '^' => :HAT,
773
+ '<' => :LT,
774
+ '!' => :EXCMARK,
775
+ })
776
+ }.call
777
+
778
+ REGEXP_PATTERN = /(?:
779
+ (\s+|--[^\n]*|\/\*[^\*]*\*\/)
780
+ | (#{RESERVED_WORDS.collect{|k, sym|
781
+ Regexp::escape(k) + (k =~ /^[\w\-]+$/ ? '\b(?!\-)' : '')
782
+ }.join('|')})
783
+ | ([A-Z][-\w]*)
784
+ | ([a-z][-\w]*)
785
+ | (\d+)
786
+ | \"((?:\"\"|[^\"])*)\"
787
+ )/mxo
788
+
789
+ def next_token
790
+ return @stack.shift unless @stack.empty?
791
+
792
+ while (token = @scanner.scan(REGEXP_PATTERN))
793
+ if @scanner[1]
794
+ next # comment or whitespace
795
+ elsif @scanner[2]
796
+ return [RESERVED_WORDS[token]] * 2
797
+ elsif @scanner[3]
798
+ return [:typereference, token.to_sym]
799
+ elsif @scanner[4]
800
+ return [:identifier, token.to_sym]
801
+ elsif @scanner[5]
802
+ return [:number, token.to_i]
803
+ elsif @scanner[6]
804
+ return [:cstring, @scanner[6]]
805
+ end
806
+
807
+ raise #'Internal error'
808
+ end
809
+
810
+ return nil if @scanner.eos?
811
+
812
+ raise "Parse error before #{@scanner.string.slice(@scanner.pos, 40)}"
813
+ end
814
+
815
+ attr_accessor :yydebug
816
+ attr_reader :error, :backtrace
817
+
818
+ def parse(str)
819
+ @scanner = StringScanner::new(str)
820
+ @stack = []
821
+ @lastpos = 0
822
+ @pos = 0
823
+
824
+ tree = nil
825
+ begin
826
+ tree = do_parse
827
+ rescue Racc::ParseError => e # ASN1Error
828
+ @error = e.to_s
829
+ @backtrace = e.backtrace
830
+ p [e, @scanner.string.slice(@scanner.pos, 40)]
831
+ return nil
832
+ end
833
+
834
+ return tree
835
+ end
836
+
837
+ def constraint_hash(array)
838
+ array[1..-1] = array[1..-1].collect{|elm|
839
+ elm.kind_of?(Array) ? constraint_hash(elm) : elm
840
+ }
841
+ case array[0]
842
+ when :and
843
+ elm_hash = {}
844
+ array[1..-1] = array[1..-1].reject{|elm|
845
+ if (elm.keys & [:and, :not, :or]).empty? then
846
+ elm_hash.merge!(elm){|k, v, v_|
847
+ {:and => (v[:and] rescue [v].flatten(1)) \
848
+ + (v_[:and] rescue [v_].flatten(1))}
849
+ }
850
+ end
851
+ } + [elm_hash]
852
+ (array.size == 2) ? array[1] : {:and => array[1..-1]}
853
+ when :not
854
+ if array[1].size == 1 then
855
+ k, v = array[1].to_a[0]
856
+ return {k => (v[:not] rescue false) ? v[:not] : {:not => v}} \
857
+ unless [:and, :or].include?(k)
858
+ end
859
+ {:not => array[1]}
860
+ when :or
861
+ (array.size == 2) ? array[1] : {:or => array[1..-1]}
862
+ when :extensible
863
+ if array[2] then # root and extensible
864
+ keys = array[1].keys | array[2].keys
865
+ if keys.size == 1 then
866
+ k = keys[0]
867
+ return {k => {:root => array[1][k], :additional => array[2][k]}} \
868
+ unless [:and, :not, :or].include?(k)
869
+ end
870
+ {:root => array[1], :additional => array[2]}
871
+ else # root only
872
+ if array[1].size == 1 then
873
+ k, v = array[1].to_a[0]
874
+ return {k => (v[:root] rescue false) ? v : {:root => v}} \
875
+ unless [:and, :not, :or].include?(k)
876
+ end
877
+ {:root => array[1]}
878
+ end
879
+ else
880
+ raise
881
+ end
882
+ end
883
+
884
+ ---- footer
885
+
886
+ if $0 == __FILE__ then
887
+ require 'json'
888
+ parser = ASN1::Parser::new
889
+ opts = []
890
+ ARGV.reject!{|arg|
891
+ next false unless arg =~ /^--([^=]+)=?/
892
+ k, v = [$1.to_sym, $' == '' ? true : $']
893
+ opts << [k, v]
894
+ }
895
+ parser.yydebug = true if opts.any?([:debug, true])
896
+ tree = {}
897
+ (ARGV.empty? ? ['-'] : ARGV).each{|f|
898
+ $stderr.print "Reading #{f == '-' ? '$stdin' : f} ... "
899
+ tree.merge!(parser.parse((f == '-' ? $stdin : open(f)).read))
900
+ $stderr.puts "done."
901
+ }
902
+ print JSON::pretty_generate(tree)
903
+ end