cddl 0.1.0 → 0.8.8

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.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/bin/cddl +80 -23
  3. data/cddl.gemspec +4 -2
  4. data/data/cddl.abnf +50 -20
  5. data/data/prelude.cddl +9 -3
  6. data/lib/cbor-pp-play.rb +13 -0
  7. data/lib/cbor-pp.rb +213 -0
  8. data/lib/cddl.rb +1001 -163
  9. data/test/test-cddl.rb +1620 -93
  10. data/test-data/7071-concise-cut.cddl +48 -0
  11. data/test-data/7071-concise.cddl +1 -1
  12. data/test-data/7071-verbose.cddl +1 -1
  13. data/test-data/a.cddl +9 -0
  14. data/test-data/ambig.cddl +2 -0
  15. data/test-data/b.cddl +3 -0
  16. data/test-data/badaddr.cddl +1 -0
  17. data/test-data/basic_syntax_example.cddl +7 -0
  18. data/test-data/cdni-ct.cddl +72 -0
  19. data/test-data/cose.cddl +68 -0
  20. data/test-data/dcaf.cddl +58 -0
  21. data/test-data/dcaf1.cddl +48 -0
  22. data/test-data/dotsize.cddl +7 -0
  23. data/test-data/extractor-demo.cddl +14 -0
  24. data/test-data/grasp-01-extract.cddl +91 -0
  25. data/test-data/grasp-01-test.cddl +90 -0
  26. data/test-data/grasp-01.cddl +90 -0
  27. data/test-data/grasp-09.cddl +108 -0
  28. data/test-data/grasp-v1.cddl +97 -0
  29. data/test-data/grasp-v2X.cddl +89 -0
  30. data/test-data/ifmap-base-2.0v17.cddl +392 -0
  31. data/test-data/ifmap-base-2.2v9_fh-cabo.cddl +149 -0
  32. data/test-data/ifmap-metadata-2.2v9_fh-cabo.cddl +239 -0
  33. data/test-data/ifmap2.cddl +21 -0
  34. data/test-data/jcr-ex.cddl +42 -0
  35. data/test-data/kevin5.cddl +5 -0
  36. data/test-data/map-group.cddl +13 -0
  37. data/test-data/mapkey.cddl +2 -0
  38. data/test-data/minimal.cddl +1 -0
  39. data/test-data/patch1.cddl +13 -0
  40. data/test-data/reused_named_group.cddl +14 -0
  41. data/test-data/structure.cddl +9 -0
  42. data/test-data/toerless0.cddl +14 -0
  43. data/test-data/toerless1.cddl +11 -0
  44. data/test-data/two_anonymous_groups.cddl +13 -0
  45. data/test-data/wrong1.cddl +17 -0
  46. data/test-data/wrong1a.cddl +23 -0
  47. data/test-data/wrong2.cddl +17 -0
  48. data/test-data/wrong2a.cddl +17 -0
  49. data/test-data/xmlmig.cddl +15 -0
  50. metadata +72 -5
@@ -0,0 +1,149 @@
1
+ messages = request / response
2
+
3
+ request = new-session-request / end-session / renew-session / publish-request / search-request / subscribe-request / poll-request
4
+ / purge-publisher-request / $ExtendedRequestTypes
5
+
6
+ error-code = "AccessDenied" / "Failure" / "InvalidIdentifier" / "InvalidIdentifierType" /
7
+ "IdentifierTooLong" / "InvalidMetadata" / "InvalidSchemaVersion" / "InvalidSessionID" /
8
+ "MetadataTooLong" / "SearchResultsTooBig" / "PollResultsTooBig" / "SystemError" / $ExtendedErrorCodeTypes
9
+
10
+ error-result =
11
+ ("ifmap", "error-result",
12
+ [ ],
13
+ [ ? "name", ? tstr,
14
+ "error-code", error-code,
15
+ "error-string", tstr
16
+ ])
17
+
18
+ poll-result = ("", "poll-result", [], [ *(search-result // error-result)])
19
+
20
+ response-choice = (error-result // poll-result // search-result // subscribe-received //
21
+ publish-received // purge-publisher-received // new-session-result //
22
+ renew-session-result // end-session-result // $ExtendedResponses )
23
+
24
+ purge-publisher-received =
25
+ ("", "purge-publisher-received", [], [])
26
+
27
+ purge-publisher-request =
28
+ ["ifmap", "purge-publisher",
29
+ [ "ifmap-publisher-id", tstr,
30
+ session-attributes
31
+ ],
32
+ []]
33
+
34
+ ; needs to be constructed according to IF-MAP Filter syntax
35
+ filter-type = tstr
36
+
37
+ poll-request =
38
+ ["ifmap", "poll",
39
+ [ session-attributes,
40
+ validation-attributes
41
+ ],
42
+ []]
43
+
44
+ subscribe-received =
45
+ ("", "subscribe-received", [], [])
46
+
47
+ subscribe-request =
48
+ ["ifmap", "subscribe",
49
+ [ session-attributes,
50
+ validation-attributes
51
+ ],
52
+ [ 1*(subscribe-update // subscribe-delete)
53
+ ]]
54
+
55
+ subscribe-delete =
56
+ ("", "delete",
57
+ [ "name", tstr,
58
+ ],
59
+ [])
60
+
61
+ subscribe-update =
62
+ ("", "update",
63
+ [ "match-links", filter-type,
64
+ "max-depth", uint,
65
+ "terminal-identifier-type", tstr,
66
+ "max-size", uint,
67
+ "result-filter", filter-type,
68
+ "name", tstr,
69
+ ],
70
+ [ $$identifier ])
71
+ search-request =
72
+ ["ifmap", "search",
73
+ [ session-attributes,
74
+ validation-attributes,
75
+ "match-links", filter-type,
76
+ "max-depth", uint,
77
+ "terminal-identifier-type", tstr,
78
+ "max-size", uint,
79
+ "result-filter", filter-type
80
+ ],
81
+ [ $$identifier
82
+ ]]
83
+
84
+ search-result =
85
+ ("", "search-result",
86
+ ["name", tstr],
87
+ [ *result-item])
88
+
89
+ result-item =
90
+ ("", "result-item",
91
+ [],
92
+ [ 1*2 $$identifier,
93
+ "metadata", metadata-list-type
94
+ ])
95
+
96
+ publish-request =
97
+ ["ifmap", "publish",
98
+ [ session-attributes,
99
+ ? validation-attributes
100
+ ],
101
+ [+ (update-request // notify-request // delete-request) ]]
102
+
103
+ update-request =
104
+ ("", "update", [ ? lifetime-attributes],
105
+ [ 1*2 $$identifier, metadata-list-type ])
106
+ notify-request = ("", "notify", [ ? lifetime-attributes], [ 1*2 $$identifier])
107
+ delete-request = ("", "delete", [ "filter", tstr], [])
108
+
109
+ publish-received =
110
+ ("", "publish-received", [], [])
111
+
112
+ renew-session = ["ifmap", "renew-session", [ ? session-attributes ], []]
113
+ renew-session-result = ("", "renew-session-result", [], [])
114
+
115
+ end-session = ["ifmap", "end-session", [], []]
116
+ end-session-result =
117
+ ("", "end-session-result", [], [])
118
+
119
+ new-session-request =
120
+ ["ifmap", "new-session",
121
+ [ ? ("max-poll-result-size", uint)],
122
+ []]
123
+
124
+ new-session-result =
125
+ ("", "new-session-result",
126
+ [ session-attributes,
127
+ "ifmap-publisher-id", tstr,
128
+ "max-poll-result-size", uint,
129
+ ],
130
+ [])
131
+
132
+ session-attributes = (
133
+ "session-id", tstr
134
+ )
135
+
136
+ validation-attributes = (
137
+ "validation", ("None" / "BaseOnly" / "MetadataOnly" / "All")
138
+ )
139
+
140
+ lifetime-attributes = (
141
+ "lifetime", ("session" / "forever")
142
+ )
143
+
144
+ response =
145
+ ["ifmap", "response",
146
+ [ ? validation-attributes ],
147
+ [ response-choice ]]
148
+
149
+ metadata-list-type = ["", "metadata", [], [ *$$metadata ]]
@@ -0,0 +1,239 @@
1
+
2
+
3
+ $$metadata //= (access-request-device // access-request-ip // access-request-mac //
4
+ authenticated-as // authenticated-by // capability // device-attribute //
5
+ device-characteristic // device-ip // discovered-by // enforcement-report //
6
+ event // ip-mac // layer2-information // location // request-for-investigation //
7
+ role // unexpected-behavior // wlan-information)
8
+
9
+
10
+ client-time = ("opmeta", "client-time",
11
+ [ single-value-metadata-attributes,
12
+ "current-time", tdate
13
+ ], [])
14
+
15
+ ; list every capability explicitly?
16
+ server-capability = ("opmeta", "server-capability",
17
+ [ single-value-metadata-attributes,
18
+ ],
19
+ [
20
+ ["", "capability", [], tstr],
21
+ ]
22
+ )
23
+ $$metadata //= (client-time // server-capability)
24
+
25
+ adm-dom = (
26
+ "administrative-domain", tstr,
27
+ )
28
+
29
+ access-request =
30
+ ("ifmap", "access-request",
31
+ [ ? adm-dom,
32
+ "name", tstr
33
+ ],
34
+ [])
35
+
36
+ device = ("ifmap", "device", [], [device-type])
37
+ device-type =( ("ifmap","aik-name", [], tstr) //
38
+ ("ifmap","name", [], tstr))
39
+
40
+ identity = ("ifmap", "identity",
41
+ [ ? adm-dom,
42
+ "name", tstr,
43
+ "type", ("aik-name" / "distinguished-name" / "dns-name" / "email-address" /
44
+ "hip-hit" / "kerberos-principal" / "trusted-platform-module" /
45
+ "username" / "other"),
46
+ "other-type-definition", tstr
47
+ ],
48
+ [])
49
+
50
+ ip-address = ("ifmap", "ip-address",
51
+ [ ? adm-dom,
52
+ "value", tstr,
53
+ "type", &("IPv4" / "IPv6")
54
+ ],
55
+ [])
56
+
57
+ mac-address = ("ifmap", "mac-address",
58
+ [ ? adm-dom,
59
+ "value", tstr,
60
+ ],
61
+ [])
62
+
63
+ $$identifier //= ( access-request // device // identity // ip-address // mac-address )
64
+
65
+ metadata-attributes = (
66
+ "ifmap-publisher-id", tstr,
67
+ "ifmap-timestamp", tdate,
68
+ "ifmap-timestamp-fraction", tstr
69
+ )
70
+
71
+ single-value-metadata-attributes = (
72
+ ? metadata-attributes,
73
+ "ifmap-cardinality", "singleValue"
74
+ )
75
+
76
+ multi-value-metadata-attributes = (
77
+ ? metadata-attributes,
78
+ "ifmap-cardinality", "multiValue"
79
+ )
80
+
81
+ access-request-device = ("meta", "access-request-device",
82
+ [ single-value-metadata-attributes ], [])
83
+
84
+ access-request-ip = ("meta", "access-request-ip",
85
+ [ single-value-metadata-attributes ], [])
86
+
87
+ access-request-mac = ("meta", "access-request-mac",
88
+ [ single-value-metadata-attributes ], [])
89
+
90
+ authenticated-as = ("meta", "authenticated-as",
91
+ [ single-value-metadata-attributes ], [])
92
+
93
+ authenticated-by = ("meta", "authenticated-by",
94
+ [ single-value-metadata-attributes ], [])
95
+
96
+ capability = ("meta", "capability",
97
+ [ multi-value-metadata-attributes ],
98
+ [ ? adm-dom,
99
+ "name", tstr
100
+ ])
101
+
102
+ device-attribute = ("meta", "device-attribute",
103
+ [ multi-value-metadata-attributes ],
104
+ [ "name", tstr
105
+ ])
106
+
107
+ administrative-domain = ("ifmap", "administrative-domain", [], tstr)
108
+ manufacturer = ("", "manufacturer", [], tstr)
109
+ model = ("", "model", [], tstr)
110
+ os = ("", "os", [], tstr)
111
+ os-version = ("", "os-version", [], tstr)
112
+ type = ("", "type", [],
113
+ ("p2p" / "cve" / "botnet infection" / "worm infection" / "excessive flows" /
114
+ "behavioral change" / "policy violation" / "other"))
115
+ discovered-time = ("", "discovered-time", [], tdate)
116
+ discoverer-id = ("", "discoverer-id", [], tstr)
117
+ discovery-method = ("", "discovery-method", [], tstr)
118
+ name = ("", "name", [], tstr)
119
+ magnitude = ("", "magnitude", [], 0..100)
120
+ confidence = ("", "confidence", [], 0..100)
121
+ significance = ("", "significance", [], ("critical" / "important" / "informational"))
122
+ information = ("", "information", [], tstr)
123
+ vulnerability-uri = ("", "vulnerability-uri", [], uri)
124
+ enforcement-action = ("", "enforcement-action", [], tstr)
125
+ other-type-definition = ("", "other-type-definition", [], tstr)
126
+ enforcement-reason = ("", "enforcement-reason", [], tstr)
127
+ start-time = ("", "start-time", [], tdate)
128
+ end-time = ("", "end-time", [], tdate)
129
+ dhcp-server = ("", "dhcp-server", [], tstr)
130
+ vlan = ("", "vlan", [], uint)
131
+ vlan-name = ("", "vlan-name", [], uint)
132
+ port = ("", "port", [], uint)
133
+ location-information = ("", "location-information",
134
+ ( "type", tstr,
135
+ "value", tstr), [])
136
+ qualifier = ("", "qualifier", [], tstr)
137
+
138
+ device-characteristic = ("meta", "device-characteristic",
139
+ [ multi-value-metadata-attributes ],
140
+ [ ? manufacturer,
141
+ ? model,
142
+ ? os,
143
+ ? os-version,
144
+ * type,
145
+ discovered-time,
146
+ discoverer-id,
147
+ + discovery-method
148
+ ])
149
+
150
+ device-ip = ("meta", "device-ip",
151
+ [ single-value-metadata-attributes ], [ device, ip-address])
152
+
153
+ discovered-by = ("meta", "discovered-by",
154
+ [ single-value-metadata-attributes ], [])
155
+
156
+ enforcement-report = ("meta", "enforcement-report",
157
+ [ multi-value-metadata-attributes ],
158
+ [ enforcement-action,
159
+ other-type-definition,
160
+ enforcement-reason
161
+ ])
162
+
163
+ event = ("meta", "event",
164
+ [ multi-value-metadata-attributes ],
165
+ [ name,
166
+ discovered-time,
167
+ discoverer-id,
168
+ magnitude,
169
+ confidence,
170
+ significance,
171
+ ? type,
172
+ ? other-type-definition,
173
+ ? information,
174
+ ? vulnerability-uri
175
+ ])
176
+
177
+ ip-mac = ("meta", "ip-mac",
178
+ [ multi-value-metadata-attributes ],
179
+ [ ? start-time,
180
+ ? end-time,
181
+ ? dhcp-server
182
+ ])
183
+
184
+ layer2-information = ("meta", "layer2-information",
185
+ [ multi-value-metadata-attributes ],
186
+ [ ? vlan,
187
+ ? vlan-name,
188
+ ? port,
189
+ ? adm-dom
190
+ ])
191
+
192
+ location = ("meta", "location",
193
+ [ multi-value-metadata-attributes ],
194
+ [ discovered-time,
195
+ discoverer-id,
196
+ + location-information
197
+ ])
198
+
199
+ request-for-investigation = ("meta", "request-for-investigation",
200
+ [ multi-value-metadata-attributes ],
201
+ [ ? qualifier ])
202
+
203
+ role = ("meta", "role",
204
+ [ multi-value-metadata-attributes ],
205
+ [ ? administrative-domain,
206
+ name
207
+ ])
208
+
209
+ unexpected-behavior = ("meta", "unexpected-behavior",
210
+ [ multi-value-metadata-attributes ],
211
+ [ discovered-time,
212
+ discoverer-id,
213
+ ? information,
214
+ magnitude,
215
+ ? confidence,
216
+ significance,
217
+ ? type
218
+ ])
219
+
220
+ wlan-security-type = "open" / "wep" / "tkip" / "ccmp" / "bip" / "other"
221
+
222
+ ssid = ("", "ssid", [], tstr)
223
+ ssid-unicast-security = ("", "ssid-unicast-security",
224
+ [ ? other-type-definition ],
225
+ [ wlan-security-type ])
226
+ ssid-group-security = ("", "ssid-group-security",
227
+ [ ? other-type-definition ],
228
+ [ wlan-security-type ])
229
+ ssid-management-security = ("", "ssid-management-security",
230
+ [ ? other-type-definition ],
231
+ [ wlan-security-type ])
232
+
233
+ wlan-information = ("meta", "wlan-information",
234
+ [ single-value-metadata-attributes ],
235
+ [ ? ssid,
236
+ + ssid-unicast-security,
237
+ ssid-group-security,
238
+ + ssid-management-security
239
+ ])
@@ -0,0 +1,21 @@
1
+ response =
2
+ ["ifmap", "response",
3
+ [ ? validation-attributes ],
4
+ [ response-choice ]]
5
+
6
+ response-choice = (
7
+ error-result // poll-result // search-result // subscribe-received //
8
+ publish-received // purge-publisher-received // new-session-result //
9
+ renew-session-result // end-session-result
10
+ )
11
+
12
+ error-result = 1
13
+ poll-result = 2
14
+ search-result = 3
15
+ subscribe-received = 4
16
+ publish-received = 5
17
+ purge-publisher-received = 6
18
+ new-session-result = 7
19
+ renew-session-result = 8
20
+ end-session-result = 9
21
+ validation-attributes = (10, 11)
@@ -0,0 +1,42 @@
1
+ root = nameserver / entity ; just to root things here
2
+
3
+ nameserver = {
4
+ name: fqdn,
5
+ ipAddresses: [* ipaddress],
6
+ common,
7
+ }
8
+
9
+ entity = {
10
+ names: [* string],
11
+ roles: [* string],
12
+ postalAddress: [* string],
13
+ emails: [* email],
14
+ phones: {
15
+ office: [* phone],
16
+ fax: [* phone],
17
+ mobile: [* phone],
18
+ },
19
+ common,
20
+ }
21
+
22
+ common = (
23
+ handle: string,
24
+ status: [* string],
25
+ remarks: [* string],
26
+ uris: [* { type: string, "uri": uri }],
27
+ port43: fqdn,
28
+ sponsoredBy: string,
29
+ resoldBy: string,
30
+ registrationBy: string,
31
+ registrationDate: tdate,
32
+ lastChangedDate: tdate,
33
+ lastChangedBy: string,
34
+ )
35
+
36
+ string = tstr
37
+ email = tstr
38
+ phone = tstr
39
+ fqdn = tstr
40
+ ipaddress = ip4 / ip6
41
+ ip4 = bstr ; could pull a #2.4 here, but don't
42
+ ip6 = bstr ; could pull a #2.16 here, but don't
@@ -0,0 +1,5 @@
1
+ top = { topgroup }
2
+
3
+ topgroup = ( first: tstr, second: tstr,
4
+ (option1: uint //
5
+ option2: uint) )
@@ -0,0 +1,13 @@
1
+ map = {
2
+ first_group,
3
+ ? second_group,
4
+ }
5
+
6
+ first_group = ( e1, e2,)
7
+ second_group = (e3, e4, e5)
8
+
9
+ e1 = (1: uint)
10
+ e2 = (2: tstr)
11
+ e3 = (3: tdate)
12
+ e4 = (4: tstr)
13
+ e5 = (5: uint)
@@ -0,0 +1,2 @@
1
+ foo = { foo: bool, "foob" => bar, * tstr => uint }
2
+ bar = "blba"
@@ -0,0 +1 @@
1
+ foo = #
@@ -0,0 +1,13 @@
1
+ CellList = {
2
+ + CellID => {
3
+ SlotframeID: leafref
4
+ SlotOffset: uint
5
+ ChannelOffset: uint
6
+ LinkType: enumeration
7
+ CelType: enumeration
8
+ }
9
+ }
10
+
11
+ CellID = uint
12
+ leafref = tstr ; TBD
13
+ enumeration = uint ; TBD
@@ -0,0 +1,14 @@
1
+ info = (
2
+ age: int,
3
+ name: tstr,
4
+ )
5
+ person = {
6
+ info,
7
+ employer: tstr,
8
+ }
9
+ dog = {
10
+ info,
11
+ collar: color,
12
+ }
13
+
14
+ color = "blue"
@@ -0,0 +1,9 @@
1
+ Geography = [
2
+ city : tstr
3
+ gpsCoordinates : GpsCoordinates
4
+ ]
5
+
6
+ GpsCoordinates = {
7
+ longitude : uint ; multiplied by 10^7
8
+ latitude : uint ; multiplied by 10^7
9
+ }
@@ -0,0 +1,14 @@
1
+
2
+ foo = { 1*relement }
3
+
4
+ context-element = 4711
5
+
6
+ relement = $$relement .within relement-generic
7
+
8
+ relement-generic = ( relement-codepoint => relement-value ) ; [1]
9
+ relement-codepoint = uint ; [1]
10
+ relement-value = any ; [1]
11
+
12
+ $$relement //= ( &(sender-loop-count:1) => 1..255 ) ; [2]
13
+ $$relement //= ( &(srv-element:2) => context-element ) ; [2]
14
+
@@ -0,0 +1,11 @@
1
+ foo = foo-specific .within foo-generic
2
+ foo-specific = { 1*$$relement }
3
+ foo-generic = { 1*relement-generic }
4
+
5
+ relement-generic = ( relement-codepoint => relement-value ) ; [1]
6
+ relement-codepoint = uint ; [1]
7
+ relement-value = any ; [1]
8
+
9
+ $$relement //= ( &(sender-loop-count:1) => 1..255 ) ; [2]
10
+ $$relement //= ( &(srv-element:2) => context-element ) ; [2]
11
+ context-element = "and so on"
@@ -0,0 +1,13 @@
1
+ person = {(
2
+ age: int,
3
+ name: tstr,
4
+ collar: color,
5
+ )}
6
+
7
+ dog = {(
8
+ age: int,
9
+ name: tstr,
10
+ employer: tstr,
11
+ )}
12
+
13
+ color = "red"
@@ -0,0 +1,17 @@
1
+ reputation-object = {
2
+ application: tstr
3
+ reputons: [* reputon]
4
+
5
+
6
+ reputon = {
7
+ rater: tstr
8
+ assertion: tstr
9
+ rated: tstr
10
+ rating: float16
11
+ ? confidence: float16
12
+ ? normal-rating: float16
13
+ ? sample-size: uint
14
+ ? generated: uint
15
+ ? expires: uint
16
+ * any: any
17
+ }
@@ -0,0 +1,23 @@
1
+ reputation-object = {
2
+ application: tstr
3
+ ? confidence: float16
4
+ ? normal-rating: float16
5
+ ? sample-size: uint
6
+ ? generated: uint
7
+ ? expires: uint
8
+ * any: any
9
+ reputons: [* reputon]
10
+
11
+
12
+ reputon = {
13
+ rater: tstr
14
+ assertion: tstr
15
+ rated: tstr
16
+ rating: float16
17
+ ? confidence: float16
18
+ ? normal-rating: float16
19
+ ? sample-size: uint
20
+ ? generated: uint
21
+ ? expires: uint
22
+ * any: any
23
+ }
@@ -0,0 +1,17 @@
1
+ reputation-object = {
2
+ application: tstr
3
+ reputons: [* reputon]
4
+ }
5
+
6
+ reputon =
7
+ rater: tstr
8
+ assertion: tstr
9
+ rated: tstr
10
+ rating: float16
11
+ ? confidence: float16
12
+ ? normal-rating: float16
13
+ ? sample-size: uint
14
+ ? generated: uint
15
+ ? expires: uint
16
+ * any: any
17
+ }
@@ -0,0 +1,17 @@
1
+ reputation-object = {
2
+ application: tstr
3
+ reputons: [* reputon]
4
+ }
5
+
6
+ reputon = {
7
+ rater: tstr
8
+ assertion: tstr
9
+ rated: tstr
10
+ rating: float16
11
+ ? confidence: float16
12
+ ? normal-rating: float16
13
+ ? sample-size: uint
14
+ ? generated: uint
15
+ ? expires: uint
16
+ * any: any
17
+
@@ -0,0 +1,15 @@
1
+ element = [ns, gi, attr, elts]
2
+
3
+ ns = text / nil
4
+ ; can be name syntax or URI
5
+
6
+ gi = text ; name syntax
7
+
8
+ attr = { * label => any }
9
+
10
+ label = text / int
11
+
12
+ elts = value / [* element]
13
+ ; could allow values inside array for mixed content
14
+
15
+ value = int / text