cddl 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cddl.gemspec +1 -1
- data/data/cddl.abnf +8 -5
- data/lib/cddl.rb +62 -38
- data/test/test-cddl.rb +94 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 167e4f338b7d73dd31d38e050c736fe9d8041984
|
4
|
+
data.tar.gz: 62c373480ad582423abcf9c5475371a11f08425b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f26f2048e7a77f12175e23430bf1a0c5271deaa4e0d499683f1d25785aec4765b70966af4b7c155469f68a2db7cb9540658909da1764b6f3a221eed4dcfb92d
|
7
|
+
data.tar.gz: 7e922d96378421546a660cfda5c1dc3ff54efa5ee218767323e1015570f875e829c196e5a90e4115be42c504c9c7d2f51d73b5a8d05f7e14f7d5946886b97cce
|
data/cddl.gemspec
CHANGED
data/data/cddl.abnf
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
cddl = S 1*rule
|
2
|
-
rule = typename S "=" S type S
|
3
|
-
/ groupname S "=" S group S
|
2
|
+
rule = typename [genericparm] S "=" S type S
|
3
|
+
/ groupname [genericparm] S "=" S group S
|
4
4
|
|
5
5
|
typename = id
|
6
6
|
groupname = id
|
7
7
|
|
8
|
+
genericparm = "<" S id S *("," S id S ) ">"
|
9
|
+
genericarg = "<" S type1 S *("," S type1 S ) ">"
|
10
|
+
|
8
11
|
type = type1 S *("/" S type1 S)
|
9
12
|
|
10
13
|
type1 = type2 [S (rangeop / annotator) S type2]
|
@@ -14,10 +17,10 @@ type1 = type2 [S (rangeop / annotator) S type2]
|
|
14
17
|
/ "{" S group S "}"
|
15
18
|
/ "[" S group S "]"
|
16
19
|
/ "&" S "(" S group S ")"
|
17
|
-
/ "&" S groupname
|
20
|
+
/ "&" S groupname [genericarg]
|
18
21
|
|
19
22
|
type2 = value
|
20
|
-
/ typename
|
23
|
+
/ typename [genericarg]
|
21
24
|
/ "(" type ")"
|
22
25
|
|
23
26
|
rangeop = "..." / ".."
|
@@ -28,7 +31,7 @@ group = "(" S *grpent S ")"
|
|
28
31
|
/ *grpent
|
29
32
|
|
30
33
|
grpent = [occur S] [memberkey S] type1 optcom
|
31
|
-
/ [occur S] groupname optcom ; always preempted by previous...
|
34
|
+
/ [occur S] groupname [genericarg] optcom ; always preempted by previous...
|
32
35
|
|
33
36
|
memberkey = type1 S "=>"
|
34
37
|
/ bareword S ":"
|
data/lib/cddl.rb
CHANGED
@@ -63,6 +63,8 @@ module CDDL
|
|
63
63
|
|
64
64
|
def rules
|
65
65
|
@rules = {}
|
66
|
+
@generics = {}
|
67
|
+
@bindings = [{}]
|
66
68
|
ast.each :rule do |rule|
|
67
69
|
rule_ast =
|
68
70
|
if rulename = rule.groupname
|
@@ -73,19 +75,28 @@ module CDDL
|
|
73
75
|
fail "Huh?"
|
74
76
|
end
|
75
77
|
n = rulename.to_s
|
76
|
-
if
|
77
|
-
|
78
|
-
|
79
|
-
if
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
if g = rule.genericparm
|
79
|
+
ids = g.children(:id).map(&:to_s)
|
80
|
+
# puts ["ids", ids].inspect
|
81
|
+
if b = @generics[n]
|
82
|
+
fail "Duplicate generics definition #{n} as #{rule_ast} (was #{b})"
|
83
|
+
end
|
84
|
+
@generics[n] = [rule_ast, ids]
|
85
|
+
else
|
86
|
+
if @rules[n]
|
87
|
+
a = strip_nodes(rule_ast).inspect
|
88
|
+
b = strip_nodes(@rules[n]).inspect
|
89
|
+
if a == b
|
90
|
+
warn "*** Warning: Identical redefinition of #{n} as #{a}"
|
91
|
+
else
|
92
|
+
fail "Duplicate rule definition #{n} as #{b} (was #{a})"
|
93
|
+
end
|
83
94
|
end
|
95
|
+
@rules[n] = rule_ast
|
84
96
|
end
|
85
|
-
@rules[n] = rule_ast
|
86
97
|
end
|
87
|
-
# pp @
|
88
|
-
@rootrule = @rules.keys.first
|
98
|
+
# pp @generics
|
99
|
+
@rootrule = @rules.keys.first # DRAFT: generics are ignored here.
|
89
100
|
# now process the rules...
|
90
101
|
@stage1 = {}
|
91
102
|
result = r_process(@rootrule, @rules[@rootrule])
|
@@ -428,12 +439,28 @@ module CDDL
|
|
428
439
|
w
|
429
440
|
end
|
430
441
|
|
431
|
-
|
442
|
+
def rule_lookup(name, canbegroup)
|
443
|
+
if b = @bindings.last[name]
|
444
|
+
b
|
445
|
+
else
|
446
|
+
r = @rules[name]
|
447
|
+
if r
|
448
|
+
t = r_process(name, r)
|
449
|
+
unless t[0] == :type1
|
450
|
+
fail "#{name} not a type #{t}" unless canbegroup && t[0] == :grpent
|
451
|
+
end
|
452
|
+
t
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
432
456
|
|
433
|
-
def r_process(n, r)
|
457
|
+
def r_process(n, r, bindings = {})
|
458
|
+
@bindings.push(bindings)
|
434
459
|
t = r[0]
|
435
460
|
# puts "Processing rule #{n} = #{t}"
|
436
|
-
@stage1[n] ||= [t, *r[1..-1].map {|e| send(t, e)}]
|
461
|
+
r = @stage1[n] ||= [t, *r[1..-1].map {|e| send(t, e)}]
|
462
|
+
@bindings.pop
|
463
|
+
r
|
437
464
|
end
|
438
465
|
|
439
466
|
def value(n)
|
@@ -482,7 +509,6 @@ module CDDL
|
|
482
509
|
t2[1..-1]
|
483
510
|
end
|
484
511
|
}.map {|mem|
|
485
|
-
# p mem
|
486
512
|
mem[1] *= occ[0]
|
487
513
|
mem[2] *= occ[1] # Does all the infinity magic
|
488
514
|
# p mem
|
@@ -497,35 +523,32 @@ module CDDL
|
|
497
523
|
end
|
498
524
|
end
|
499
525
|
|
500
|
-
def
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
else
|
507
|
-
[:string, name]
|
508
|
-
end
|
509
|
-
else
|
510
|
-
type1(n.type1)
|
511
|
-
end
|
526
|
+
def g_process(name, g, genericargs)
|
527
|
+
r, ids = g
|
528
|
+
args = genericargs.children(:type1).map {|x| type1(x, true)}
|
529
|
+
fail "number of args #{name} #{ids.size} #{args.size}" if ids.size != args.size
|
530
|
+
bindings = Hash[ids.zip(args)]
|
531
|
+
r_process("#{name}<#{genericargs._strip}>", r, bindings)
|
512
532
|
end
|
513
533
|
|
514
|
-
def type_recall(name, canbegroup)
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
534
|
+
def type_recall(name, canbegroup, genericargs)
|
535
|
+
# p genericargs, "GENERIC"
|
536
|
+
if genericargs && (generic = @generics[name])
|
537
|
+
t = g_process(name, generic, genericargs)
|
538
|
+
t
|
539
|
+
elsif !genericargs && (t = rule_lookup(name, canbegroup))
|
520
540
|
t
|
521
541
|
else
|
522
|
-
fail "Unknown type #{name}"
|
542
|
+
fail "Unknown type #{name} #{genericargs.inspect} #{@bindings} #{@abnf.ast?}"
|
523
543
|
end
|
524
544
|
end
|
525
545
|
|
526
|
-
def group_recall(name)
|
527
|
-
if
|
528
|
-
g =
|
546
|
+
def group_recall(name, genericargs)
|
547
|
+
if genericargs && (generic = @generics[name])
|
548
|
+
g = g_process(name, generic, genericargs)
|
549
|
+
fail "#{name} not a group" unless g[0] == :grpent
|
550
|
+
g[1..-1]
|
551
|
+
elsif !genericargs && (g = rule_lookup(name, true))
|
529
552
|
fail "#{name} not a group" unless g[0] == :grpent
|
530
553
|
g[1..-1]
|
531
554
|
else
|
@@ -539,7 +562,8 @@ module CDDL
|
|
539
562
|
elsif v = n.value
|
540
563
|
value(n)
|
541
564
|
elsif v = n.typename
|
542
|
-
|
565
|
+
ga = n.genericarg || (n.s && n.s.genericarg) # workaround
|
566
|
+
t = type_recall(v.to_s, canbegroup, ga)
|
543
567
|
if t[0] == :type1
|
544
568
|
if t.size == 2
|
545
569
|
t = t[1]
|
@@ -614,7 +638,7 @@ module CDDL
|
|
614
638
|
[type, *s]
|
615
639
|
when /\A&/
|
616
640
|
if gn = n.groupname
|
617
|
-
s = group_recall(gn.to_s).flatten(1)
|
641
|
+
s = group_recall(gn.to_s, n.genericarg).flatten(1)
|
618
642
|
else
|
619
643
|
@insides << :enum
|
620
644
|
s = n.children(:group).flat_map {|ch| group(ch)}
|
data/test/test-cddl.rb
CHANGED
@@ -373,7 +373,7 @@ HERE
|
|
373
373
|
assert_equal "foo", parser.generate
|
374
374
|
end
|
375
375
|
|
376
|
-
|
376
|
+
|
377
377
|
def test_validate_number_key
|
378
378
|
parser = CDDL::Parser.new <<HERE
|
379
379
|
test = [test1, test2, test3]
|
@@ -718,4 +718,97 @@ HERE
|
|
718
718
|
pp parser1.generate
|
719
719
|
end
|
720
720
|
|
721
|
+
|
722
|
+
def test_generic1
|
723
|
+
parser = CDDL::Parser.new <<HERE
|
724
|
+
d = a<1>
|
725
|
+
a<b> = b
|
726
|
+
HERE
|
727
|
+
assert_equal 1, parser.generate
|
728
|
+
end
|
729
|
+
|
730
|
+
def test_generic_group
|
731
|
+
parser = CDDL::Parser.new <<HERE
|
732
|
+
d = a<mygr>
|
733
|
+
a<gr> = { gr }
|
734
|
+
mygr = (
|
735
|
+
1 => 2
|
736
|
+
)
|
737
|
+
HERE
|
738
|
+
assert_equal({1 => 2}, parser.generate)
|
739
|
+
end
|
740
|
+
|
741
|
+
def test_generic_transitive
|
742
|
+
parser = CDDL::Parser.new <<HERE
|
743
|
+
d = a<mygr>
|
744
|
+
a<gr> = { b<gr> }
|
745
|
+
b<foo> = foo
|
746
|
+
mygr = (
|
747
|
+
1 => 2
|
748
|
+
)
|
749
|
+
HERE
|
750
|
+
assert_equal({1 => 2}, parser.generate)
|
751
|
+
end
|
752
|
+
|
753
|
+
def test_generic_realistic
|
754
|
+
parser = CDDL::Parser.new <<HERE
|
755
|
+
start = [request, response]
|
756
|
+
request = message<0>
|
757
|
+
response = message<1>
|
758
|
+
message<code> = {
|
759
|
+
code: code
|
760
|
+
data: "hallo data"
|
761
|
+
}
|
762
|
+
HERE
|
763
|
+
assert_equal([{"code"=>0, "data"=>"hallo data"},
|
764
|
+
{"code"=>1, "data"=>"hallo data"}], parser.generate)
|
765
|
+
end
|
766
|
+
|
767
|
+
def test_generic_enum
|
768
|
+
parser = CDDL::Parser.new <<HERE
|
769
|
+
color<foo> = &foo
|
770
|
+
color = color<colors>
|
771
|
+
basecolors = (
|
772
|
+
red: 1,
|
773
|
+
green: 2,
|
774
|
+
blue: 4,
|
775
|
+
lila,
|
776
|
+
)
|
777
|
+
lila = (
|
778
|
+
magenta: 5,
|
779
|
+
pink: 9,
|
780
|
+
purple: 10,
|
781
|
+
)
|
782
|
+
colors = (
|
783
|
+
black: 0,
|
784
|
+
basecolors,
|
785
|
+
yellow: 3,
|
786
|
+
cyan: 6,
|
787
|
+
white: 7,
|
788
|
+
orange: 8,
|
789
|
+
brown: 11,
|
790
|
+
grey: 12,
|
791
|
+
)
|
792
|
+
HERE
|
793
|
+
# brittle on type1 nesting optimization
|
794
|
+
assert_equal [:type1,
|
795
|
+
[:type1,
|
796
|
+
[:int, 0],
|
797
|
+
[:int, 1],
|
798
|
+
[:int, 2],
|
799
|
+
[:int, 4],
|
800
|
+
[:int, 5],
|
801
|
+
[:int, 9],
|
802
|
+
[:int, 10],
|
803
|
+
[:int, 3],
|
804
|
+
[:int, 6],
|
805
|
+
[:int, 7],
|
806
|
+
[:int, 8],
|
807
|
+
[:int, 11],
|
808
|
+
[:int, 12]]], parser.rules
|
809
|
+
10.times {
|
810
|
+
assert parser.generate.between?(0, 12)
|
811
|
+
}
|
812
|
+
end
|
813
|
+
|
721
814
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cddl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cbor-diag
|