cddlc 0.1.6 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30602affec27761888bf5f3094ac596e21cbf80fa9726f2476210ed8b419b981
4
- data.tar.gz: 4742739b320591da0f59be4732d4c0957acbfc80a1ca699caeda5943007b3d0a
3
+ metadata.gz: ea4f2c1a1ecedae6a543bebad045a0063e3b7103b757306a8f1da1fea694c3ca
4
+ data.tar.gz: 247a51f6016e133358fb37e524e0692eec3c84104ea63137b9549e3164ff65ad
5
5
  SHA512:
6
- metadata.gz: 9a726e557db0da91370c0c3f22ab31fc7f494d0c6902874b8129c3afb40bffd95855d7785be15f105a3cdc62831a79048daa919f714267e83bd372cf3c455bd1
7
- data.tar.gz: a1b74234c1195480fa40eb2e298dcbb2450c07e12e282fbb0606733cf60c716f280a224f33ba5f9baa9e80d0cb1829dff526bbe78f492ae9e7f30a1bff8cc68b
6
+ metadata.gz: 1d039d6618590fea6f3baaf19888583afdddcab37887cb4e9fb24b56c1fcf52455964426c8ea8325f2d57fa67e19008c05de791278664c094e3da500455387d8
7
+ data.tar.gz: be73e1a03f41bb0052eac06e1fac77bddb3ef55eade8e2b8f0e4c9f625cd5c7bd928a5b464a693e07826521135bd402583d32d801908a95c2749c9f3508eb253
data/bin/cddlc CHANGED
@@ -15,7 +15,7 @@ def named_keys(tree)
15
15
  when "rep"
16
16
  named_keys(tree[3])
17
17
  when "mem"
18
- key = tree[1]
18
+ key = tree[2]
19
19
  if Array === key && key[0] == "name"
20
20
  [key[1]]
21
21
  end
@@ -55,6 +55,9 @@ begin
55
55
  opts.on("-x", "--[no-]expand", "Expand generics") do |v|
56
56
  $options.expand_generics = v
57
57
  end
58
+ opts.on("-f", "--[no-]flattening", "Flattening") do |v|
59
+ $options.flattening = v
60
+ end
58
61
  opts.on("-u", "--[no-]undefined", "Note undefined names") do |v|
59
62
  $options.note_undefined = v
60
63
  end
@@ -82,6 +85,11 @@ rescue Exception => e
82
85
  exit 1
83
86
  end
84
87
 
88
+ if ($options.expand_generics || $options.flattening) && !$options.rules
89
+ warn "** can't expand or flatten in tree; adding -r flag"
90
+ $options.rules = true
91
+ end
92
+
85
93
  cddl_file = ""
86
94
  if $options.start
87
95
  cddl_file << "$.start.$ = #{$options.start}\n"
@@ -117,15 +125,20 @@ else
117
125
  cddl_file << ARGF.read
118
126
  end
119
127
 
128
+
120
129
  cddl = CDDL.from_cddl(cddl_file)
121
130
  result = if $options.rules
122
131
  if $options.expand_generics
123
132
  require_relative "../lib/processor/cddl-expander.rb"
124
133
  cddl.expand_generics
125
134
  end
135
+ if $options.flattening
136
+ require_relative "../lib/processor/cddl-flattening.rb"
137
+ cddl.flattening
138
+ warn "*** done flattening" if $options.verbose
139
+ end
126
140
  cddl.rules
127
141
  else
128
- warn "** can't expand in tree; use -r flag as well" if $options.expand_generics
129
142
  cddl.tree
130
143
  end
131
144
 
data/cddlc.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cddlc"
3
- s.version = "0.1.6"
3
+ s.version = "0.2.1"
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"
data/lib/cddlc.rb CHANGED
@@ -55,6 +55,7 @@ class CDDL
55
55
  SAFE_FN = /\A[-._a-zA-Z0-9]+\z/
56
56
  IMPINC = /\A(?:import|include)\z/
57
57
  IDENTIFIER_RE = /\A[A-Za-z@_$]([-.]*[A-Za-z@_$0-9])*\z/
58
+ INT_RE = /\A0|[-]?[1-9][0-9]*\z/
58
59
 
59
60
  def self.from_cddl(s)
60
61
  ast = @@parser.parse s
@@ -1812,7 +1812,9 @@ module CDDLGRAMMAR
1812
1812
  end
1813
1813
 
1814
1814
  module Grpent2
1815
- def ast() repwrap(elements[0], ["mem", elements[1].elements ? elements[1].memberkey.ast : nil, elements[2].ast]) end
1815
+ def ast()
1816
+ repwrap(elements[0], ["mem", *elements[1].elements ? elements[1].memberkey.ast : [false, nil],
1817
+ elements[2].ast]) end
1816
1818
  end
1817
1819
 
1818
1820
  module Grpent3
@@ -2012,7 +2014,7 @@ module CDDLGRAMMAR
2012
2014
  end
2013
2015
 
2014
2016
  module Memberkey2
2015
- def ast() type1.ast end
2017
+ def ast() [!!elements[2].elements, type1.ast] end
2016
2018
  end
2017
2019
 
2018
2020
  module Memberkey3
@@ -2027,7 +2029,7 @@ module CDDLGRAMMAR
2027
2029
  end
2028
2030
 
2029
2031
  module Memberkey4
2030
- def ast() ["text", bareword.text_value] end
2032
+ def ast() [true, ["text", bareword.text_value]] end
2031
2033
  end
2032
2034
 
2033
2035
  module Memberkey5
@@ -2042,7 +2044,7 @@ module CDDLGRAMMAR
2042
2044
  end
2043
2045
 
2044
2046
  module Memberkey6
2045
- def ast() value.ast end
2047
+ def ast() [true, value.ast] end
2046
2048
  end
2047
2049
 
2048
2050
  def _nt_memberkey
@@ -3148,15 +3150,9 @@ module CDDLGRAMMAR
3148
3150
  r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
3149
3151
  r0 = r3
3150
3152
  else
3151
- if has_terminal?(@regexps[gr = '\A[€-􏿽]'] ||= Regexp.new(gr), :regexp, index)
3152
- r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
3153
- r4.extend(SCHAR3)
3154
- r4.extend(SCHAR3)
3155
- @index += 1
3156
- else
3157
- terminal_parse_failure('[€-􏿽]')
3158
- r4 = nil
3159
- end
3153
+ r4 = _nt_NONASCII
3154
+ r4.extend(SCHAR3)
3155
+ r4.extend(SCHAR3)
3160
3156
  if r4
3161
3157
  r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
3162
3158
  r0 = r4
@@ -3951,40 +3947,46 @@ module CDDLGRAMMAR
3951
3947
  r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
3952
3948
  r0 = r2
3953
3949
  else
3954
- if has_terminal?(@regexps[gr = '\A[\\]-􏿽]'] ||= Regexp.new(gr), :regexp, index)
3950
+ if has_terminal?(@regexps[gr = '\A[\\]-~]'] ||= Regexp.new(gr), :regexp, index)
3955
3951
  r3 = true
3956
3952
  @index += 1
3957
3953
  else
3958
- terminal_parse_failure('[\\]-􏿽]')
3954
+ terminal_parse_failure('[\\]-~]')
3959
3955
  r3 = nil
3960
3956
  end
3961
3957
  if r3
3962
3958
  r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
3963
3959
  r0 = r3
3964
3960
  else
3965
- r4 = _nt_SESC
3961
+ r4 = _nt_NONASCII
3966
3962
  if r4
3967
3963
  r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
3968
3964
  r0 = r4
3969
3965
  else
3970
- if (match_len = has_terminal?("\\'", false, index))
3971
- r5 = instantiate_node(SyntaxNode,input, index...(index + match_len))
3972
- @index += match_len
3973
- else
3974
- terminal_parse_failure('"\\\\\'"')
3975
- r5 = nil
3976
- end
3966
+ r5 = _nt_SESC
3977
3967
  if r5
3978
3968
  r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
3979
3969
  r0 = r5
3980
3970
  else
3981
- r6 = _nt_CRLF
3971
+ if (match_len = has_terminal?("\\'", false, index))
3972
+ r6 = instantiate_node(SyntaxNode,input, index...(index + match_len))
3973
+ @index += match_len
3974
+ else
3975
+ terminal_parse_failure('"\\\\\'"')
3976
+ r6 = nil
3977
+ end
3982
3978
  if r6
3983
3979
  r6 = SyntaxNode.new(input, (index-1)...index) if r6 == true
3984
3980
  r0 = r6
3985
3981
  else
3986
- @index = i0
3987
- r0 = nil
3982
+ r7 = _nt_CRLF
3983
+ if r7
3984
+ r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
3985
+ r0 = r7
3986
+ else
3987
+ @index = i0
3988
+ r0 = nil
3989
+ end
3988
3990
  end
3989
3991
  end
3990
3992
  end
@@ -4623,11 +4625,49 @@ module CDDLGRAMMAR
4623
4625
  r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
4624
4626
  r0 = r1
4625
4627
  else
4626
- if has_terminal?(@regexps[gr = '\A[€-􏿽]'] ||= Regexp.new(gr), :regexp, index)
4628
+ r2 = _nt_NONASCII
4629
+ if r2
4630
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
4631
+ r0 = r2
4632
+ else
4633
+ @index = i0
4634
+ r0 = nil
4635
+ end
4636
+ end
4637
+
4638
+ node_cache[:PCHAR][start_index] = r0
4639
+
4640
+ r0
4641
+ end
4642
+
4643
+ def _nt_NONASCII
4644
+ start_index = index
4645
+ if node_cache[:NONASCII].has_key?(index)
4646
+ cached = node_cache[:NONASCII][index]
4647
+ if cached
4648
+ node_cache[:NONASCII][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
4649
+ @index = cached.interval.end
4650
+ end
4651
+ return cached
4652
+ end
4653
+
4654
+ i0 = index
4655
+ if has_terminal?(@regexps[gr = '\A[ -퟿]'] ||= Regexp.new(gr), :regexp, index)
4656
+ r1 = true
4657
+ @index += 1
4658
+ else
4659
+ terminal_parse_failure('[ -퟿]')
4660
+ r1 = nil
4661
+ end
4662
+ if r1
4663
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
4664
+ r0 = r1
4665
+ else
4666
+ if has_terminal?(@regexps[gr = '\A[-􏿽]'] ||= Regexp.new(gr), :regexp, index)
4627
4667
  r2 = true
4628
4668
  @index += 1
4629
4669
  else
4630
- terminal_parse_failure('[€-􏿽]')
4670
+ terminal_parse_failure('[-􏿽]')
4631
4671
  r2 = nil
4632
4672
  end
4633
4673
  if r2
@@ -4639,7 +4679,7 @@ module CDDLGRAMMAR
4639
4679
  end
4640
4680
  end
4641
4681
 
4642
- node_cache[:PCHAR][start_index] = r0
4682
+ node_cache[:NONASCII][start_index] = r0
4643
4683
 
4644
4684
  r0
4645
4685
  end
@@ -0,0 +1,98 @@
1
+ require_relative "../cddlc.rb"
2
+ require_relative "./cddl-visitor.rb"
3
+
4
+ class CDDL
5
+ MOGRIFIED_ID_RE = /\A\$\.[A-Za-z@_$]([-.]*[A-Za-z@_$0-9])*\z/
6
+ def flattening_key_name(key, value, env = nil)
7
+ case key
8
+ in ["enum", ["mem", _cut, ["text", IDENTIFIER_RE => text], _]]
9
+ [false, text]
10
+ in ["text", IDENTIFIER_RE => text]
11
+ [false, text]
12
+ in ["number", INT_RE => intval] if env
13
+ [true, "$.#{env}$#{intval}"]
14
+ else
15
+ [false]
16
+ end
17
+ end
18
+ def flattening_occurrences
19
+ symtab = Hash.new { |h, k| h[k] = [] }
20
+ rules.each do |name, prod|
21
+ visit(prod) do |here|
22
+ case here
23
+ in ["mem", _cut, key, value]
24
+ _labeled, keyname = flattening_key_name(key, value, false)
25
+ if keyname
26
+ symtab[keyname] << [name, value]
27
+ false
28
+ end
29
+ else
30
+ false
31
+ end
32
+ end
33
+ end
34
+ symtab_replacements = Hash[symtab.map do |k, v|
35
+ s = Set[*v.map{_2}]
36
+ # warn "** #{k} #{s.inspect}"
37
+ if s.size == 1
38
+ [k, [[v.map{|k, v| k}.join("|"), s.first]]]
39
+ end
40
+ end.compact]
41
+ # warn "** symtab_replacements: #{symtab_replacements.inspect}" if $options.verbose
42
+ symtab.merge(symtab_replacements)
43
+ end
44
+ def flattening_mogrify(name, prod, symtab, alias_rules)
45
+ step1 = visit(prod) do |here|
46
+ case here
47
+ in ["mem", cut, key, value]
48
+ ### mogrify
49
+ labeled, keyname = flattening_key_name(key, value, name)
50
+ if keyname
51
+ new_name =
52
+ unless labeled
53
+ syment = symtab[keyname]
54
+ fail keyname unless Array === syment
55
+ if syment.size == 1
56
+ "$.#{keyname}"
57
+ else
58
+ "$.#{name}$#{keyname}"
59
+ end
60
+ else
61
+ keyname
62
+ end
63
+ new_value2 = flattening_mogrify(new_name, value, symtab, alias_rules)
64
+ if ar = alias_rules[new_name]
65
+ fail [:ALIAS_RULES, ar, new_value].inspect if ar != new_value2
66
+ else
67
+ alias_rules[new_name] = new_value2
68
+ end
69
+ [true, ["mem", cut, key, ["name", new_name]]]
70
+ end
71
+ else
72
+ false
73
+ end
74
+ end
75
+ step2 = visit(step1) do |here|
76
+ case here
77
+ in ["enum", ["mem", _cut, ["text", IDENTIFIER_RE], ["name", MOGRIFIED_ID_RE => new_name]]]
78
+ [true, ["name", new_name]]
79
+ else
80
+ false
81
+ end
82
+ end
83
+ step2
84
+ end
85
+ def flattening_replace(symtab)
86
+ alias_rules = {}
87
+ new_rules = Hash[rules.map do |name, prod|
88
+ [name,
89
+ flattening_mogrify(name, prod, symtab, alias_rules)]
90
+ end]
91
+ new_rules.merge(alias_rules)
92
+ end
93
+ def flattening
94
+ symtab = flattening_occurrences
95
+ PP.pp(["*** SYMTAB", symtab], STDERR) if $options.verbose
96
+ rules.replace(flattening_replace(symtab))
97
+ end
98
+ end
@@ -33,8 +33,8 @@ class CDDL
33
33
  ["unwrap", visit(prod, &block)] # XXX, this may need to be bottled in a rule
34
34
  in ["prim", prod, *prods]
35
35
  ["prim", visit(prod, &block), *visit_all(prods, &block)]
36
- in ["mem", *prods]
37
- ["mem", *visit_all(prods, &block)]
36
+ in ["mem", cut, *prods]
37
+ ["mem", cut, *visit_all(prods, &block)]
38
38
  in ["rep", s, e, prod]
39
39
  ["rep", s, e, visit(prod, &block)]
40
40
  else
@@ -90,10 +90,14 @@ class CDDL
90
90
  "#{s}*#{e || ""}"
91
91
  end
92
92
  [1, "#{occur}#{write_rhs(group, 2, indent, pn)}"]
93
- in ["mem", nil, t2]
93
+ in ["mem", false, nil, t2]
94
94
  [2, write_rhs(t2, 2, indent, pn)]
95
- in ["mem", t1, t2]
96
- [2, "#{write_rhs(t1, 3, indent, pn)} => #{write_rhs(t2, 2, indent, pn)}"]
95
+ in ["mem", true, ["text", IDENTIFIER_RE => bareword], t2]
96
+ [2, "#{bareword}: #{write_rhs(t2, 2, indent, pn)}"]
97
+ in ["mem", true, ["number", INT_RE => bareword], t2]
98
+ [2, "#{bareword}: #{write_rhs(t2, 2, indent, pn)}"]
99
+ in ["mem", cut, t1, t2]
100
+ [2, "#{write_rhs(t1, 3, indent, pn)} #{cut ? "^" : ""}=> #{write_rhs(t2, 2, indent, pn)}"]
97
101
  # 2->3: work around cddl tool limitation
98
102
  in ["bytes", t]
99
103
  [4, t] # XXX not very clean
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.6
4
+ version: 0.2.1
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-03-10 00:00:00.000000000 Z
11
+ date: 2023-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -101,6 +101,7 @@ files:
101
101
  - lib/parser/cddl-util.rb
102
102
  - lib/parser/cddlgrammar.rb
103
103
  - lib/processor/cddl-expander.rb
104
+ - lib/processor/cddl-flattening.rb
104
105
  - lib/processor/cddl-undefined.rb
105
106
  - lib/processor/cddl-visitor.rb
106
107
  - lib/writer/cddl-writer.rb
@@ -123,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
124
  - !ruby/object:Gem::Version
124
125
  version: '0'
125
126
  requirements: []
126
- rubygems_version: 3.4.6
127
+ rubygems_version: 3.4.10
127
128
  signing_key:
128
129
  specification_version: 4
129
130
  summary: CDDL (Concise Data Definition Language) converters and miscellaneous tools