gps_pvt 0.9.4 → 0.10.0

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