cddlc 0.0.4 → 0.1.0
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.
- checksums.yaml +4 -4
- data/bin/cddlc +46 -1
- data/cddlc.gemspec +2 -2
- data/data/prelude.cddl +45 -0
- data/lib/cddlc.rb +8 -2
- data/lib/processor/cddl-expander.rb +56 -0
- data/lib/processor/cddl-visitor.rb +42 -0
- data/lib/writer/cddl-writer.rb +104 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 119d5084051bfbc6889d6a9b36e22308cbb580c9d71b738e4c99ea2f908496cb
|
4
|
+
data.tar.gz: 33fafda14412916c5883260cb64bea2793785e359d833e6d9cee37cf76260186
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5936c13d4bca770fbcd628851f14a604e27a95e5c1c76329eb81932e7d9c7e72edf898d4989176baffa1d99a88f827e981fad338bb731560eb5547dba69342b
|
7
|
+
data.tar.gz: d3fe1f230d47841385cc12dd7cf3092c0feae0326ca6889eefb889ceb55903cac6919075cfaf2879961c185adf695df218cb2e1df418a781e6098bf4269d4d49
|
data/bin/cddlc
CHANGED
@@ -52,7 +52,13 @@ begin
|
|
52
52
|
opts.on("-r", "--[no-]rules", "Process rules") do |v|
|
53
53
|
$options.rules = v
|
54
54
|
end
|
55
|
-
opts.on("-
|
55
|
+
opts.on("-x", "--[no-]expand", "Expand generics") do |v|
|
56
|
+
$options.expand_generics = v
|
57
|
+
end
|
58
|
+
opts.on("-u", "--[no-]undefined", "Note undefined names") do |v|
|
59
|
+
$options.note_undefined = v
|
60
|
+
end
|
61
|
+
opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :enum, :cddl], "Target format") do |v|
|
56
62
|
$options.target = v
|
57
63
|
end
|
58
64
|
end
|
@@ -70,11 +76,18 @@ cddl_file = ARGF.read
|
|
70
76
|
|
71
77
|
cddl = CDDL.from_cddl(cddl_file)
|
72
78
|
result = if $options.rules
|
79
|
+
if $options.expand_generics
|
80
|
+
require_relative "../lib/processor/cddl-expander.rb"
|
81
|
+
cddl.expand_generics
|
82
|
+
end
|
73
83
|
cddl.rules
|
74
84
|
else
|
85
|
+
warn "** can't expand in tree; use -r flag as well" if $options.expand_generics
|
75
86
|
cddl.tree
|
76
87
|
end
|
77
88
|
|
89
|
+
warn "** can't note undefined for target != cddl" if $options.note_undefined && $options.target != :cddl
|
90
|
+
|
78
91
|
case $options.target
|
79
92
|
when :basic, nil
|
80
93
|
pp result
|
@@ -100,6 +113,38 @@ when :enum
|
|
100
113
|
end
|
101
114
|
end
|
102
115
|
end
|
116
|
+
when :cddl
|
117
|
+
require_relative '../lib/writer/cddl-writer.rb'
|
118
|
+
if $options.note_undefined
|
119
|
+
require_relative "../lib/processor/cddl-visitor.rb"
|
120
|
+
used = {}
|
121
|
+
gen_used = {}
|
122
|
+
def_gen = {}
|
123
|
+
cddl.rules.each do |k, v|
|
124
|
+
def_gen[k[0]] = true if Array === k
|
125
|
+
cddl.visit(v) do |p, &block|
|
126
|
+
case p
|
127
|
+
in ["gen", name, *_gen_args]
|
128
|
+
gen_used[name] = true
|
129
|
+
in ["name", name]
|
130
|
+
used[name] = true
|
131
|
+
else
|
132
|
+
false
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
used.each do |k, v|
|
137
|
+
unless cddl.rules[k] || cddl.prelude.rules[k]
|
138
|
+
puts ";;; *** undefined: #{k}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
gen_used.each do |k, v|
|
142
|
+
unless def_gen[k]
|
143
|
+
puts ";;; *** undefined: #{k}<>"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
puts cddl.to_s
|
103
148
|
else
|
104
149
|
warn ["Unknown target format: ", $options.target].inspect
|
105
150
|
end
|
data/cddlc.gemspec
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "cddlc"
|
3
|
-
s.version = "0.0
|
3
|
+
s.version = "0.1.0"
|
4
4
|
s.summary = "CDDL (Concise Data Definition Language) converters and miscellaneous tools"
|
5
5
|
s.description = %q{cddlc implements converters and miscellaneous tools for CDDL, RFC 8610}
|
6
6
|
s.author = "Carsten Bormann"
|
7
7
|
s.email = "cabo@tzi.org"
|
8
8
|
s.license = "MIT"
|
9
9
|
s.homepage = "http://github.com/cabo/cddlc"
|
10
|
-
s.files = Dir['lib/**/*.rb'] + %w(cddlc.gemspec) + Dir['bin/**/*.rb']
|
10
|
+
s.files = Dir['lib/**/*.rb'] + %w(cddlc.gemspec data/prelude.cddl) + Dir['bin/**/*.rb']
|
11
11
|
s.executables = Dir['bin/*'].map {|x| File.basename(x)}
|
12
12
|
s.required_ruby_version = '>= 1.9.2'
|
13
13
|
|
data/data/prelude.cddl
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
any = #
|
2
|
+
|
3
|
+
uint = #0
|
4
|
+
nint = #1
|
5
|
+
int = uint / nint
|
6
|
+
|
7
|
+
bstr = #2
|
8
|
+
bytes = bstr
|
9
|
+
tstr = #3
|
10
|
+
text = tstr
|
11
|
+
|
12
|
+
tdate = #6.0(tstr)
|
13
|
+
time = #6.1(number)
|
14
|
+
number = int / float
|
15
|
+
biguint = #6.2(bstr)
|
16
|
+
bignint = #6.3(bstr)
|
17
|
+
bigint = biguint / bignint
|
18
|
+
integer = int / bigint
|
19
|
+
unsigned = uint / biguint
|
20
|
+
decfrac = #6.4([e10: int, m: integer])
|
21
|
+
bigfloat = #6.5([e2: int, m: integer])
|
22
|
+
eb64url = #6.21(any)
|
23
|
+
eb64legacy = #6.22(any)
|
24
|
+
eb16 = #6.23(any)
|
25
|
+
encoded-cbor = #6.24(bstr)
|
26
|
+
uri = #6.32(tstr)
|
27
|
+
b64url = #6.33(tstr)
|
28
|
+
b64legacy = #6.34(tstr)
|
29
|
+
regexp = #6.35(tstr)
|
30
|
+
mime-message = #6.36(tstr)
|
31
|
+
cbor-any = #6.55799(any)
|
32
|
+
|
33
|
+
float16 = #7.25
|
34
|
+
float32 = #7.26
|
35
|
+
float64 = #7.27
|
36
|
+
float16-32 = float16 / float32
|
37
|
+
float32-64 = float32 / float64
|
38
|
+
float = float16-32 / float64
|
39
|
+
|
40
|
+
false = #7.20
|
41
|
+
true = #7.21
|
42
|
+
bool = false / true
|
43
|
+
nil = #7.22
|
44
|
+
null = nil
|
45
|
+
undefined = #7.23
|
data/lib/cddlc.rb
CHANGED
@@ -50,8 +50,8 @@ class CDDL
|
|
50
50
|
fail name
|
51
51
|
end
|
52
52
|
@rules[name] =
|
53
|
-
if old = @rules[name]
|
54
|
-
fail "duplicate rule for name #{name}" unless cho
|
53
|
+
if (old = @rules[name]) && old != val
|
54
|
+
fail "duplicate rule for name #{name} #{old.inspect} #{val.inspect}" unless cho
|
55
55
|
if Array === old && old[0] == cho
|
56
56
|
old.dup << val
|
57
57
|
else
|
@@ -66,4 +66,10 @@ class CDDL
|
|
66
66
|
@rules
|
67
67
|
end
|
68
68
|
|
69
|
+
def prelude
|
70
|
+
if @prelude.nil?
|
71
|
+
@prelude = CDDL.from_cddl(File.read(Pathname.new(__FILE__) + "../../data/prelude.cddl"))
|
72
|
+
end
|
73
|
+
@prelude
|
74
|
+
end
|
69
75
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative "../cddlc.rb"
|
2
|
+
require_relative "./cddl-visitor.rb"
|
3
|
+
|
4
|
+
class CDDL
|
5
|
+
def substitute(prod, parms, args, &block)
|
6
|
+
subs = Hash[parms.zip(args)]
|
7
|
+
visit(prod) do |p, &block1|
|
8
|
+
case p
|
9
|
+
in ["gen", name, *gen_args]
|
10
|
+
[true, gen_apply(name, gen_args, &block1)]
|
11
|
+
in ["name", name]
|
12
|
+
if replacement = subs[name]
|
13
|
+
[true, visit(expand_prod(replacement), &block)]
|
14
|
+
end
|
15
|
+
else
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def gen_apply(gen_name, gen_args, &block)
|
21
|
+
gen_parms, gen_prod = @gen[gen_name]
|
22
|
+
fail "** no generic for #{gen_name}<#{gen_args}>" unless gen_parms
|
23
|
+
substitute(gen_prod, gen_parms, gen_args, &block)
|
24
|
+
end
|
25
|
+
def expand_prod(prod)
|
26
|
+
visit(prod) do |p, &block|
|
27
|
+
case p
|
28
|
+
in ["gen", name, *gen_args]
|
29
|
+
[true, gen_apply(name, gen_args, &block)]
|
30
|
+
else
|
31
|
+
[false]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
def expand_generics
|
36
|
+
@gen = {}
|
37
|
+
rules.each do |name, prod|
|
38
|
+
if Array === name
|
39
|
+
@gen[name[0]] = [name[1..-1], prod]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
p @gen if $options.verbose
|
43
|
+
@gen.each do |k, v|
|
44
|
+
namep = v[0]
|
45
|
+
fail unless rules[[k, *namep]] == v[1]
|
46
|
+
rules.delete([k, *namep])
|
47
|
+
end
|
48
|
+
@new_rules = {}
|
49
|
+
rules.each do |name, prod|
|
50
|
+
fail if Array === name
|
51
|
+
@new_rules[name] = expand_prod(prod)
|
52
|
+
end
|
53
|
+
p @new_rules if $options.verbose
|
54
|
+
@rules = @new_rules
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative "../cddlc.rb"
|
2
|
+
|
3
|
+
class CDDL
|
4
|
+
def visit_all(prod_array, &block)
|
5
|
+
prod_array.map {|prod| visit(prod, &block)}
|
6
|
+
end
|
7
|
+
def visit(prod, &block)
|
8
|
+
done, ret = block.call(prod, &block)
|
9
|
+
if done
|
10
|
+
return ret
|
11
|
+
end
|
12
|
+
|
13
|
+
case prod
|
14
|
+
in ["gen", name, *types]
|
15
|
+
["gen", name, *visit_all(types, &block)]
|
16
|
+
in ["op", op, *prods]
|
17
|
+
["op", op, *visit_all(prods, &block)]
|
18
|
+
in ["map", prod]
|
19
|
+
["map", visit(prod, &block)]
|
20
|
+
in ["ary", prod]
|
21
|
+
["ary", visit(prod, &block)]
|
22
|
+
in ["gcho", *prods]
|
23
|
+
["gcho", *visit_all(prods, &block)]
|
24
|
+
in ["tcho", *prods]
|
25
|
+
["tcho", *visit_all(prods, &block)]
|
26
|
+
in ["seq", *prods]
|
27
|
+
["seq", *visit_all(prods, &block)]
|
28
|
+
in ["enum", prod]
|
29
|
+
["enum", visit(prod, &block)]
|
30
|
+
in ["unwrap", prod]
|
31
|
+
["unwrap", visit(prod, &block)] # XXX, this may need to be bottled in a rule
|
32
|
+
in ["prim", Array => prod, *prods]
|
33
|
+
["prim", visit(prod, &block), *visit_all(prods, &block)]
|
34
|
+
in ["mem", *prods]
|
35
|
+
["mem", *visit_all(prods, &block)]
|
36
|
+
in ["rep", s, e, prod]
|
37
|
+
["rep", s, e, visit(prod, &block)]
|
38
|
+
else
|
39
|
+
prod
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require_relative "../cddlc.rb"
|
2
|
+
|
3
|
+
class CDDL
|
4
|
+
|
5
|
+
def write_lhs(k)
|
6
|
+
case k
|
7
|
+
in [id, *parms]
|
8
|
+
"#{id}<#{parms.join(", ")}>"
|
9
|
+
in String
|
10
|
+
k
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# precedence:
|
15
|
+
# 0: // gcho
|
16
|
+
# 1: , seq
|
17
|
+
# 2: / tcho -> (type1)
|
18
|
+
# 3: (type1) .xxx op -> type2
|
19
|
+
# 4: type2
|
20
|
+
|
21
|
+
def prec_check(inner, targetprec, prec, indent_s)
|
22
|
+
if targetprec > prec
|
23
|
+
"(#{inner.gsub("\n", "\n" << indent_s)})" # XXX embedded byte strings
|
24
|
+
else
|
25
|
+
inner
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def write_rhs(v, targetprec = 0, indent = 0)
|
30
|
+
# warn "** #{v.inspect}"
|
31
|
+
indent_p = " " * indent
|
32
|
+
indent += 1
|
33
|
+
indent_s = " " * indent
|
34
|
+
prec, ret =
|
35
|
+
case v
|
36
|
+
in ["name", id]
|
37
|
+
[4, id]
|
38
|
+
in ["gen", id, *parms] # oops -- namep vs. namea; ouch
|
39
|
+
[4, "#{id}<#{parms.map{write_rhs(_1, 2, indent)}.join(", ")}>"]
|
40
|
+
in ["tcho", *types]
|
41
|
+
[2, types.map{write_rhs(_1, 3, indent)}.join(" / ")]
|
42
|
+
in ["gcho", *groups]
|
43
|
+
[0, groups.map{write_rhs(_1, 2, indent)}.join(" // ")]
|
44
|
+
in ["op", op, l, r]
|
45
|
+
[3, "#{write_rhs(l, 3, indent)} #{op} #{write_rhs(r, 3, indent)}"]
|
46
|
+
in ["map", group]
|
47
|
+
[4, "{#{write_rhs(group, 0, indent)}}"]
|
48
|
+
in ["ary", group]
|
49
|
+
[4, "[#{write_rhs(group, 0, indent)}]"]
|
50
|
+
in ["unwrap", namep]
|
51
|
+
[4, "~#{write_rhs(namep, 4, indent)}"]
|
52
|
+
in ["enum", ["name", _name] => namep]
|
53
|
+
[4, "&#{write_rhs(namep, 4, indent)}"]
|
54
|
+
in ["enum", ["gen", _name, *types] => namep]
|
55
|
+
[4, "&#{write_rhs(namep, 4, indent)})"]
|
56
|
+
in ["enum", group]
|
57
|
+
[4, "&(#{write_rhs(group, 0, indent)})"]
|
58
|
+
in ["prim"]
|
59
|
+
[4, "#"]
|
60
|
+
in ["prim", maj]
|
61
|
+
[4, "##{maj}"]
|
62
|
+
in ["prim", maj, min]
|
63
|
+
[4, "##{maj}.#{min}"]
|
64
|
+
in ["prim", 6, Integer => tag, type]
|
65
|
+
[4, "#6.#{tag}(#{write_rhs(type, 0, indent)})"]
|
66
|
+
in ["prim", 6, nil, type]
|
67
|
+
[4, "#6(#{write_rhs(type, 0, indent)})"]
|
68
|
+
# prim: extension for #6.<i>(t)
|
69
|
+
in ["seq", *groups]
|
70
|
+
case groups.size
|
71
|
+
when 0; [4, ""]
|
72
|
+
# when 1; "#{write_rhs(g[0], targetprec, indent)}"
|
73
|
+
else
|
74
|
+
[1, "\n#{indent_p}#{groups.map{write_rhs(_1, 1, indent)}.join(",\n#{indent_p}")},\n"]
|
75
|
+
end
|
76
|
+
in ["rep", s, e, group]
|
77
|
+
occur = case [s, e]
|
78
|
+
in [1, 1]; ""
|
79
|
+
in [0, 1]; "? "
|
80
|
+
in [0, false]; "* "
|
81
|
+
in [1, false]; "+ "
|
82
|
+
else
|
83
|
+
"#{s}*#{e || ""}"
|
84
|
+
end
|
85
|
+
[1, "#{occur}#{write_rhs(group, 2, indent)}"]
|
86
|
+
in ["mem", nil, t2]
|
87
|
+
[2, write_rhs(t2, 2, indent)]
|
88
|
+
in ["mem", t1, t2]
|
89
|
+
[2, "#{write_rhs(t1, 2, indent)} => #{write_rhs(t2, 2, indent)}"]
|
90
|
+
in ["text", t]
|
91
|
+
[4, "\"#{t}\""] # XXX escape
|
92
|
+
in ["number", t]
|
93
|
+
[4, t.to_s]
|
94
|
+
end
|
95
|
+
prec_check(ret, targetprec, prec, indent_s)
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_s
|
99
|
+
rules.map {|k, v|
|
100
|
+
"#{write_lhs(k)} = #{write_rhs(v, 2)}" # 2: parenthesize groups
|
101
|
+
}.join("\n")
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cddlc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.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:
|
11
|
+
date: 2023-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -75,9 +75,13 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- bin/cddlc
|
77
77
|
- cddlc.gemspec
|
78
|
+
- data/prelude.cddl
|
78
79
|
- lib/cddlc.rb
|
79
80
|
- lib/parser/cddl-util.rb
|
80
81
|
- lib/parser/cddlgrammar.rb
|
82
|
+
- lib/processor/cddl-expander.rb
|
83
|
+
- lib/processor/cddl-visitor.rb
|
84
|
+
- lib/writer/cddl-writer.rb
|
81
85
|
homepage: http://github.com/cabo/cddlc
|
82
86
|
licenses:
|
83
87
|
- MIT
|
@@ -97,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
101
|
- !ruby/object:Gem::Version
|
98
102
|
version: '0'
|
99
103
|
requirements: []
|
100
|
-
rubygems_version: 3.2
|
104
|
+
rubygems_version: 3.4.2
|
101
105
|
signing_key:
|
102
106
|
specification_version: 4
|
103
107
|
summary: CDDL (Concise Data Definition Language) converters and miscellaneous tools
|