cddlc 0.1.0 → 0.1.2
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 +7 -26
- data/cddlc.gemspec +2 -2
- data/data/rfc8727.cddl +946 -0
- data/data/rfc8927.cddl +96 -0
- data/data/rfc8990.cddl +213 -0
- data/data/rfc9052.cddl +154 -0
- data/data/rfc9053.cddl +21 -0
- data/data/rfc9054.cddl +13 -0
- data/data/rfc9090.cddl +14 -0
- data/data/rfc9115.cddl +99 -0
- data/data/rfc9164.cddl +32 -0
- data/data/rfc9165.cddl +35 -0
- data/data/rfc9171.cddl +334 -0
- data/data/rfc9173.cddl +36 -0
- data/data/rfc9177.cddl +6 -0
- data/data/rfc9202.cddl +6 -0
- data/data/rfc9203.cddl +11 -0
- data/data/rfc9237.cddl +27 -0
- data/data/rfc9277.cddl +11 -0
- data/data/rfc9290.cddl +37 -0
- data/data/rfc9321.cddl +67 -0
- data/data/rfc9338.cddl +34 -0
- data/lib/cddlc.rb +111 -5
- data/lib/parser/cddl-util.rb +1 -1
- data/lib/processor/cddl-expander.rb +13 -10
- data/lib/processor/cddl-undefined.rb +38 -0
- data/lib/processor/cddl-visitor.rb +2 -0
- data/lib/writer/cddl-writer.rb +38 -25
- metadata +23 -2
data/lib/cddlc.rb
CHANGED
@@ -3,6 +3,14 @@ require_relative "parser/cddl-util.rb"
|
|
3
3
|
class CDDL
|
4
4
|
@@parser = CDDLGRAMMARParser.new
|
5
5
|
|
6
|
+
DATA_DIR = Pathname.new(__FILE__) + "../../data/"
|
7
|
+
# empty string is for CDDL::DATA_DIR
|
8
|
+
CDDL_INCLUDE_PATH = ENV["CDDL_INCLUDE_PATH"] || ".:"
|
9
|
+
|
10
|
+
def self.cddl_include_path
|
11
|
+
CDDL_INCLUDE_PATH.split(":", -1).map {_1 == "" ? CDDL::DATA_DIR : Pathname.new(_1)}
|
12
|
+
end
|
13
|
+
|
6
14
|
def self.reason(parser, s)
|
7
15
|
reason = [parser.failure_reason]
|
8
16
|
parser.failure_reason =~ /^(Expected .+) after/m
|
@@ -14,21 +22,105 @@ class CDDL
|
|
14
22
|
reason.join("\n")
|
15
23
|
end
|
16
24
|
|
25
|
+
SAFE_FN = /\A[-._a-zA-Z0-9]+\z/
|
26
|
+
|
17
27
|
def self.from_cddl(s)
|
18
28
|
ast = @@parser.parse s
|
19
29
|
if !ast
|
20
30
|
fail self.reason(@@parser, s)
|
21
31
|
end
|
22
|
-
|
32
|
+
if $options.cddl2
|
33
|
+
directives = s.lines.grep(/^;# /).map(&:chomp).map{|l| l.sub(/^;#\s+/, '').split(/\s+/)}
|
34
|
+
# puts directives.to_yaml
|
35
|
+
end
|
36
|
+
ret = CDDL.new(ast, directives)
|
37
|
+
|
38
|
+
if $options.cddl2
|
39
|
+
ret.directives.each do |di|
|
40
|
+
preferred_tag = nil
|
41
|
+
case di
|
42
|
+
in ["include" => dir, docref]
|
43
|
+
in ["include" => dir, docref, "as", preferred_tag]
|
44
|
+
warn "** Ignoring namespace tag #{preferred_tag} for now"
|
45
|
+
in ["import" => dir, docref]
|
46
|
+
else
|
47
|
+
warn "** Can't parse include directive #{di.inspect}"
|
48
|
+
next
|
49
|
+
end
|
50
|
+
unless docref =~ SAFE_FN
|
51
|
+
warn "** skipping unsafe filename #{docref}"
|
52
|
+
next
|
53
|
+
end
|
54
|
+
puts "PREFERRED_TAG #{preferred_tag}" if $options.verbose
|
55
|
+
puts "DOCREF #{docref}" if $options.verbose
|
56
|
+
fn = docref.downcase << ".cddl"
|
57
|
+
|
58
|
+
io = nil
|
59
|
+
CDDL::cddl_include_path.each do |path|
|
60
|
+
begin
|
61
|
+
io = (path + fn).open
|
62
|
+
break
|
63
|
+
rescue Errno::ENOENT
|
64
|
+
next
|
65
|
+
end
|
66
|
+
end
|
67
|
+
unless io
|
68
|
+
warn "** include file #{fn} not found in #{CDDL::cddl_include_path.map(&:to_s)}"
|
69
|
+
next
|
70
|
+
end
|
71
|
+
|
72
|
+
include_file = io.read
|
73
|
+
included_cddl = CDDL.from_cddl(include_file)
|
74
|
+
# XXX: Should namespace that thing now! all names -> preferred_tag.name
|
75
|
+
# p included_cddl.rules.keys
|
76
|
+
# XXX: do once, first, to rename COSE_Key to RFC9052.COSE_Key
|
77
|
+
case dir
|
78
|
+
in "import"
|
79
|
+
warn "** IMPORTING #{fn}" if $options.verbose
|
80
|
+
require_relative '../lib/processor/cddl-undefined.rb'
|
81
|
+
loop do
|
82
|
+
undef_rule = ret.cddl_undefined # XXX square...
|
83
|
+
# p undef_rule
|
84
|
+
got_more = false
|
85
|
+
undef_rule.each do |name|
|
86
|
+
if rule = included_cddl.rules[name]
|
87
|
+
ret.rules[name] = rule # XXX must be namespaced!
|
88
|
+
warn "IMPORTED #{name} from #{fn}" if $options.verbose # ...: #{rule}...
|
89
|
+
got_more = true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
break unless got_more
|
93
|
+
end
|
94
|
+
in "include"
|
95
|
+
warn "** INCLUDING #{fn}" if $options.verbose
|
96
|
+
included_cddl.rules.each do |k, v|
|
97
|
+
if old = ret.rules[k]
|
98
|
+
if old != v
|
99
|
+
warn "** included rule #{k} = #{v} would overwrite #{old}"
|
100
|
+
end
|
101
|
+
else
|
102
|
+
ret.rules[k] = v
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
ret
|
23
109
|
end
|
24
110
|
|
25
|
-
attr_accessor :ast, :tree
|
26
|
-
def initialize(ast_)
|
111
|
+
attr_accessor :ast, :tree, :directives
|
112
|
+
def initialize(ast_, directives_ = [])
|
27
113
|
@ast = ast_
|
28
114
|
@tree = ast.ast
|
29
115
|
@rules = nil # only fill in if needed
|
116
|
+
@directives = directives_
|
117
|
+
end
|
118
|
+
|
119
|
+
def deep_clone
|
120
|
+
Marshal.load(Marshal.dump(self))
|
30
121
|
end
|
31
122
|
|
123
|
+
|
32
124
|
RULE_OP_TO_CHOICE = {"/=" => "tcho", "//=" => "gcho"}
|
33
125
|
|
34
126
|
def rules
|
@@ -45,7 +137,20 @@ class CDDL
|
|
45
137
|
fail unless name.size == 2
|
46
138
|
name = name[1]
|
47
139
|
when "gen"
|
48
|
-
|
140
|
+
require_relative "processor/cddl-visitor.rb"
|
141
|
+
parmnames = name[2..-1]
|
142
|
+
name = name[1] # XXX update val with parm/arg
|
143
|
+
val = ["parm", parmnames,
|
144
|
+
visit(val) do |p|
|
145
|
+
case p
|
146
|
+
in ["name", nm]
|
147
|
+
if ix = parmnames.index(nm)
|
148
|
+
[true, ["arg", ix]]
|
149
|
+
end
|
150
|
+
else
|
151
|
+
false
|
152
|
+
end
|
153
|
+
end]
|
49
154
|
else
|
50
155
|
fail name
|
51
156
|
end
|
@@ -68,7 +173,8 @@ class CDDL
|
|
68
173
|
|
69
174
|
def prelude
|
70
175
|
if @prelude.nil?
|
71
|
-
@prelude = CDDL.from_cddl(File.read(
|
176
|
+
@prelude = CDDL.from_cddl(File.read(DATA_DIR + "prelude.cddl"))
|
177
|
+
|
72
178
|
end
|
73
179
|
@prelude
|
74
180
|
end
|
data/lib/parser/cddl-util.rb
CHANGED
@@ -2,14 +2,13 @@ require_relative "../cddlc.rb"
|
|
2
2
|
require_relative "./cddl-visitor.rb"
|
3
3
|
|
4
4
|
class CDDL
|
5
|
-
def substitute(prod, parms,
|
6
|
-
subs = Hash[parms.zip(args)]
|
5
|
+
def substitute(prod, parms, subs, &block)
|
7
6
|
visit(prod) do |p, &block1|
|
8
7
|
case p
|
9
|
-
in ["gen", name, *gen_args]
|
8
|
+
in ["gen", name, *gen_args] # XXX
|
10
9
|
[true, gen_apply(name, gen_args, &block1)]
|
11
|
-
in ["
|
12
|
-
if replacement = subs[
|
10
|
+
in ["arg", num]
|
11
|
+
if replacement = subs[num]
|
13
12
|
[true, visit(expand_prod(replacement), &block)]
|
14
13
|
end
|
15
14
|
else
|
@@ -35,15 +34,19 @@ class CDDL
|
|
35
34
|
def expand_generics
|
36
35
|
@gen = {}
|
37
36
|
rules.each do |name, prod|
|
38
|
-
|
39
|
-
|
37
|
+
case prod
|
38
|
+
in ["parm", parmnames, type]
|
39
|
+
if prod[0] == "parm"
|
40
|
+
@gen[name] = [parmnames, type]
|
41
|
+
end
|
42
|
+
else
|
40
43
|
end
|
41
44
|
end
|
42
45
|
p @gen if $options.verbose
|
43
46
|
@gen.each do |k, v|
|
44
|
-
|
45
|
-
fail unless rules[
|
46
|
-
rules.delete(
|
47
|
+
parmnames = v[0]
|
48
|
+
fail unless rules[k] == ["parm", parmnames, v[1]]
|
49
|
+
rules.delete(k)
|
47
50
|
end
|
48
51
|
@new_rules = {}
|
49
52
|
rules.each do |name, prod|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative "../cddlc.rb"
|
2
|
+
require_relative "./cddl-visitor.rb"
|
3
|
+
require_relative "./cddl-expander.rb"
|
4
|
+
|
5
|
+
class CDDL
|
6
|
+
def cddl_extract_names(prod, &name_used)
|
7
|
+
visit(prod) do |p|
|
8
|
+
case p
|
9
|
+
in ["gen", name, *_gen_args]
|
10
|
+
name_used.call(name)
|
11
|
+
false
|
12
|
+
in ["name", name]
|
13
|
+
name_used.call(name)
|
14
|
+
false
|
15
|
+
else
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def cddl_add_used_by(prod, used)
|
22
|
+
cddl_extract_names(prod) do |name|
|
23
|
+
used[name] = true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cddl_undefined
|
28
|
+
# currently only works on expanded...
|
29
|
+
cddl2 = self.deep_clone # needs deep-clone
|
30
|
+
cddl2.expand_generics
|
31
|
+
used = {}
|
32
|
+
cddl2.rules.each do |k, v|
|
33
|
+
fail unless String === k
|
34
|
+
cddl2.cddl_add_used_by(v, used)
|
35
|
+
end
|
36
|
+
used.keys.reject {|name| cddl2.rules[name] || prelude.rules[name]}
|
37
|
+
end
|
38
|
+
end
|
data/lib/writer/cddl-writer.rb
CHANGED
@@ -2,11 +2,10 @@ require_relative "../cddlc.rb"
|
|
2
2
|
|
3
3
|
class CDDL
|
4
4
|
|
5
|
-
def write_lhs(k)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
in String
|
5
|
+
def write_lhs(k, parmnames)
|
6
|
+
if parmnames
|
7
|
+
"#{k}<#{parmnames.join(", ")}>"
|
8
|
+
else
|
10
9
|
k
|
11
10
|
end
|
12
11
|
end
|
@@ -26,35 +25,41 @@ class CDDL
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
def write_rhs(v, targetprec = 0, indent = 0)
|
28
|
+
def write_rhs(v, targetprec = 0, indent = 0, pn = [])
|
29
|
+
# pn = parmnames
|
30
30
|
# warn "** #{v.inspect}"
|
31
31
|
indent_p = " " * indent
|
32
32
|
indent += 1
|
33
33
|
indent_s = " " * indent
|
34
34
|
prec, ret =
|
35
35
|
case v
|
36
|
+
in ["parm", parmnames, type]
|
37
|
+
[4, write_rhs(type, 2, indent, parmnames)]
|
38
|
+
in ["arg", Integer => num]
|
39
|
+
[4, pn[num] || "id$#{num}"]
|
36
40
|
in ["name", id]
|
37
41
|
[4, id]
|
38
42
|
in ["gen", id, *parms] # oops -- namep vs. namea; ouch
|
39
|
-
[4, "#{id}<#{parms.map{write_rhs(_1, 2, indent)}.join(", ")}>"]
|
43
|
+
[4, "#{id}<#{parms.map{write_rhs(_1, 2, indent, pn)}.join(", ")}>"]
|
40
44
|
in ["tcho", *types]
|
41
|
-
[2, types.map{write_rhs(_1, 3, indent)}.join(" / ")]
|
45
|
+
[2, types.map{write_rhs(_1, 3, indent, pn)}.join(" / ")]
|
42
46
|
in ["gcho", *groups]
|
43
|
-
[0, groups.map{write_rhs(_1, 2, indent)}.join(" // ")]
|
47
|
+
[0, groups.map{write_rhs(_1, 2, indent, pn)}.join(" // ")]
|
44
48
|
in ["op", op, l, r]
|
45
|
-
[3, "#{write_rhs(l,
|
49
|
+
[3, "#{write_rhs(l, 4, indent, pn)} #{op} #{write_rhs(r, 4, indent, pn)}"]
|
50
|
+
# 3->4: work around cddl tool limitation
|
46
51
|
in ["map", group]
|
47
|
-
[
|
52
|
+
[3, "{#{write_rhs(group, 0, indent, pn)}}"] # 4->3: work around cddl tool limitation
|
48
53
|
in ["ary", group]
|
49
|
-
[
|
54
|
+
[3, "[#{write_rhs(group, 0, indent, pn)}]"] # 4->3: work around cddl tool limitation
|
50
55
|
in ["unwrap", namep]
|
51
|
-
[4, "~#{write_rhs(namep, 4, indent)}"]
|
56
|
+
[4, "~#{write_rhs(namep, 4, indent, pn)}"]
|
52
57
|
in ["enum", ["name", _name] => namep]
|
53
|
-
[4, "&#{write_rhs(namep, 4, indent)}"]
|
58
|
+
[4, "&#{write_rhs(namep, 4, indent, pn)}"]
|
54
59
|
in ["enum", ["gen", _name, *types] => namep]
|
55
|
-
[4, "&#{write_rhs(namep, 4, indent)})"]
|
60
|
+
[4, "&#{write_rhs(namep, 4, indent, pn)})"]
|
56
61
|
in ["enum", group]
|
57
|
-
[4, "&(#{write_rhs(group, 0, indent)})"]
|
62
|
+
[4, "&(#{write_rhs(group, 0, indent, pn)})"]
|
58
63
|
in ["prim"]
|
59
64
|
[4, "#"]
|
60
65
|
in ["prim", maj]
|
@@ -62,16 +67,16 @@ class CDDL
|
|
62
67
|
in ["prim", maj, min]
|
63
68
|
[4, "##{maj}.#{min}"]
|
64
69
|
in ["prim", 6, Integer => tag, type]
|
65
|
-
[4, "#6.#{tag}(#{write_rhs(type, 0, indent)})"]
|
70
|
+
[4, "#6.#{tag}(#{write_rhs(type, 0, indent, pn)})"]
|
66
71
|
in ["prim", 6, nil, type]
|
67
|
-
[4, "#6(#{write_rhs(type, 0, indent)})"]
|
72
|
+
[4, "#6(#{write_rhs(type, 0, indent, pn)})"]
|
68
73
|
# prim: extension for #6.<i>(t)
|
69
74
|
in ["seq", *groups]
|
70
75
|
case groups.size
|
71
76
|
when 0; [4, ""]
|
72
|
-
# when 1; "#{write_rhs(g[0], targetprec, indent)}"
|
77
|
+
# when 1; "#{write_rhs(g[0], targetprec, indent, pn)}"
|
73
78
|
else
|
74
|
-
[1, "\n#{indent_p}#{groups.map{write_rhs(_1, 1, indent)}.join(",\n#{indent_p}")},\n"]
|
79
|
+
[1, "\n#{indent_p}#{groups.map{write_rhs(_1, 1, indent, pn)}.join(",\n#{indent_p}")},\n"]
|
75
80
|
end
|
76
81
|
in ["rep", s, e, group]
|
77
82
|
occur = case [s, e]
|
@@ -82,13 +87,16 @@ class CDDL
|
|
82
87
|
else
|
83
88
|
"#{s}*#{e || ""}"
|
84
89
|
end
|
85
|
-
[1, "#{occur}#{write_rhs(group, 2, indent)}"]
|
90
|
+
[1, "#{occur}#{write_rhs(group, 2, indent, pn)}"]
|
86
91
|
in ["mem", nil, t2]
|
87
|
-
[2, write_rhs(t2, 2, indent)]
|
92
|
+
[2, write_rhs(t2, 2, indent, pn)]
|
88
93
|
in ["mem", t1, t2]
|
89
|
-
[2, "#{write_rhs(t1,
|
94
|
+
[2, "#{write_rhs(t1, 3, indent, pn)} => #{write_rhs(t2, 2, indent, pn)}"]
|
95
|
+
# 2->3: work around cddl tool limitation
|
96
|
+
in ["bytes", t]
|
97
|
+
[4, t] # XXX not very clean
|
90
98
|
in ["text", t]
|
91
|
-
[4, "\"#{t}\""]
|
99
|
+
[4, "\"#{t}\""] # XXX escape
|
92
100
|
in ["number", t]
|
93
101
|
[4, t.to_s]
|
94
102
|
end
|
@@ -97,7 +105,12 @@ class CDDL
|
|
97
105
|
|
98
106
|
def to_s
|
99
107
|
rules.map {|k, v|
|
100
|
-
|
108
|
+
parmnames = false
|
109
|
+
case v
|
110
|
+
in ["parm", parmnames, _type]
|
111
|
+
else
|
112
|
+
end
|
113
|
+
"#{write_lhs(k, parmnames)} = #{write_rhs(v, 2)}" # 2: parenthesize groups
|
101
114
|
}.join("\n")
|
102
115
|
end
|
103
116
|
|
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.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -76,10 +76,31 @@ files:
|
|
76
76
|
- bin/cddlc
|
77
77
|
- cddlc.gemspec
|
78
78
|
- data/prelude.cddl
|
79
|
+
- data/rfc8727.cddl
|
80
|
+
- data/rfc8927.cddl
|
81
|
+
- data/rfc8990.cddl
|
82
|
+
- data/rfc9052.cddl
|
83
|
+
- data/rfc9053.cddl
|
84
|
+
- data/rfc9054.cddl
|
85
|
+
- data/rfc9090.cddl
|
86
|
+
- data/rfc9115.cddl
|
87
|
+
- data/rfc9164.cddl
|
88
|
+
- data/rfc9165.cddl
|
89
|
+
- data/rfc9171.cddl
|
90
|
+
- data/rfc9173.cddl
|
91
|
+
- data/rfc9177.cddl
|
92
|
+
- data/rfc9202.cddl
|
93
|
+
- data/rfc9203.cddl
|
94
|
+
- data/rfc9237.cddl
|
95
|
+
- data/rfc9277.cddl
|
96
|
+
- data/rfc9290.cddl
|
97
|
+
- data/rfc9321.cddl
|
98
|
+
- data/rfc9338.cddl
|
79
99
|
- lib/cddlc.rb
|
80
100
|
- lib/parser/cddl-util.rb
|
81
101
|
- lib/parser/cddlgrammar.rb
|
82
102
|
- lib/processor/cddl-expander.rb
|
103
|
+
- lib/processor/cddl-undefined.rb
|
83
104
|
- lib/processor/cddl-visitor.rb
|
84
105
|
- lib/writer/cddl-writer.rb
|
85
106
|
homepage: http://github.com/cabo/cddlc
|