draft-ietf-cbor-cddl-06.txt   draft-ietf-cbor-cddl-07.txt 
CBOR H. Birkholz CBOR H. Birkholz
Internet-Draft Fraunhofer SIT Internet-Draft Fraunhofer SIT
Intended status: Standards Track C. Vigano Intended status: Standards Track C. Vigano
Expires: May 23, 2019 Universitaet Bremen Expires: August 17, 2019 Universitaet Bremen
C. Bormann C. Bormann
Universitaet Bremen TZI Universitaet Bremen TZI
November 19, 2018 February 13, 2019
Concise data definition language (CDDL): a notational convention to Concise data definition language (CDDL): a notational convention to
express CBOR and JSON data structures express CBOR and JSON data structures
draft-ietf-cbor-cddl-06 draft-ietf-cbor-cddl-07
Abstract Abstract
This document proposes a notational convention to express CBOR data This document proposes a notational convention to express CBOR data
structures (RFC 7049, Concise Binary Object Representation). Its structures (RFC 7049, Concise Binary Object Representation). Its
main goal is to provide an easy and unambiguous way to express main goal is to provide an easy and unambiguous way to express
structures for protocol messages and data formats that use CBOR or structures for protocol messages and data formats that use CBOR or
JSON. JSON.
Status of This Memo Status of This Memo
skipping to change at page 1, line 38 skipping to change at page 1, line 38
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on May 23, 2019. This Internet-Draft will expire on August 17, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the Copyright (c) 2019 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License. described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Requirements notation . . . . . . . . . . . . . . . . . . 4 1.1. Requirements notation . . . . . . . . . . . . . . . . . . 4
1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4
2. The Style of Data Structure Specification . . . . . . . . . . 4 2. The Style of Data Structure Specification . . . . . . . . . . 4
2.1. Groups and Composition in CDDL . . . . . . . . . . . . . 6 2.1. Groups and Composition in CDDL . . . . . . . . . . . . . 6
2.1.1. Usage . . . . . . . . . . . . . . . . . . . . . . . . 8 2.1.1. Usage . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.2. Syntax . . . . . . . . . . . . . . . . . . . . . . . 9 2.1.2. Syntax . . . . . . . . . . . . . . . . . . . . . . . 9
2.2. Types . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2. Types . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1. Values . . . . . . . . . . . . . . . . . . . . . . . 9 2.2.1. Values . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.2. Choices . . . . . . . . . . . . . . . . . . . . . . . 10 2.2.2. Choices . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.3. Representation Types . . . . . . . . . . . . . . . . 12 2.2.3. Representation Types . . . . . . . . . . . . . . . . 12
2.2.4. Root type . . . . . . . . . . . . . . . . . . . . . . 13 2.2.4. Root type . . . . . . . . . . . . . . . . . . . . . . 13
3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1. General conventions . . . . . . . . . . . . . . . . . . . 13 3.1. General conventions . . . . . . . . . . . . . . . . . . . 13
3.2. Occurrence . . . . . . . . . . . . . . . . . . . . . . . 15 3.2. Occurrence . . . . . . . . . . . . . . . . . . . . . . . 15
3.3. Predefined names for types . . . . . . . . . . . . . . . 16 3.3. Predefined names for types . . . . . . . . . . . . . . . 16
skipping to change at page 3, line 8 skipping to change at page 3, line 8
4. Making Use of CDDL . . . . . . . . . . . . . . . . . . . . . 33 4. Making Use of CDDL . . . . . . . . . . . . . . . . . . . . . 33
4.1. As a guide to a human user . . . . . . . . . . . . . . . 33 4.1. As a guide to a human user . . . . . . . . . . . . . . . 33
4.2. For automated checking of CBOR data structure . . . . . . 34 4.2. For automated checking of CBOR data structure . . . . . . 34
4.3. For data analysis tools . . . . . . . . . . . . . . . . . 34 4.3. For data analysis tools . . . . . . . . . . . . . . . . . 34
5. Security considerations . . . . . . . . . . . . . . . . . . . 34 5. Security considerations . . . . . . . . . . . . . . . . . . . 34
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 35 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 35
6.1. CDDL control operator registry . . . . . . . . . . . . . 35 6.1. CDDL control operator registry . . . . . . . . . . . . . 35
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 36 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 36
7.1. Normative References . . . . . . . . . . . . . . . . . . 36 7.1. Normative References . . . . . . . . . . . . . . . . . . 36
7.2. Informative References . . . . . . . . . . . . . . . . . 37 7.2. Informative References . . . . . . . . . . . . . . . . . 37
Appendix A. Examples . . . . . . . . . . . . . . . . . . . . . . 39 Appendix A. Parsing Expression Grammars (PEG) . . . . . . . . . 39
A.1. RFC 7071 . . . . . . . . . . . . . . . . . . . . . . . . 39 Appendix B. ABNF grammar . . . . . . . . . . . . . . . . . . . . 41
A.2. Examples from JSON Content Rules . . . . . . . . . . . . 43 Appendix C. Matching rules . . . . . . . . . . . . . . . . . . . 43
Appendix B. ABNF grammar . . . . . . . . . . . . . . . . . . . . 45 Appendix D. Standard Prelude . . . . . . . . . . . . . . . . . . 47
Appendix C. Matching rules . . . . . . . . . . . . . . . . . . . 47 Appendix E. Use with JSON . . . . . . . . . . . . . . . . . . . 49
Appendix D. Standard Prelude . . . . . . . . . . . . . . . . . . 51 Appendix F. A CDDL tool . . . . . . . . . . . . . . . . . . . . 51
Appendix E. Use with JSON . . . . . . . . . . . . . . . . . . . 53 Appendix G. Extended Diagnostic Notation . . . . . . . . . . . . 52
Appendix F. A CDDL tool . . . . . . . . . . . . . . . . . . . . 55 G.1. White space in byte string notation . . . . . . . . . . . 52
Appendix G. Extended Diagnostic Notation . . . . . . . . . . . . 56 G.2. Text in byte string notation . . . . . . . . . . . . . . 52
G.1. White space in byte string notation . . . . . . . . . . . 56 G.3. Embedded CBOR and CBOR sequences in byte strings . . . . 53
G.2. Text in byte string notation . . . . . . . . . . . . . . 56 G.4. Concatenated Strings . . . . . . . . . . . . . . . . . . 53
G.3. Embedded CBOR and CBOR sequences in byte strings . . . . 57 G.5. Hexadecimal, octal, and binary numbers . . . . . . . . . 54
G.4. Concatenated Strings . . . . . . . . . . . . . . . . . . 57 G.6. Comments . . . . . . . . . . . . . . . . . . . . . . . . 54
G.5. Hexadecimal, octal, and binary numbers . . . . . . . . . 58 Appendix H. Examples . . . . . . . . . . . . . . . . . . . . . . 55
G.6. Comments . . . . . . . . . . . . . . . . . . . . . . . . 58 H.1. RFC 7071 . . . . . . . . . . . . . . . . . . . . . . . . 55
Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 59 H.2. Examples from JSON Content Rules . . . . . . . . . . . . 58
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 59 Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 59 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 61
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 61
1. Introduction 1. Introduction
In this document, a notational convention to express CBOR [RFC7049] In this document, a notational convention to express CBOR [RFC7049]
data structures is defined. data structures is defined.
The main goal for the convention is to provide a unified notation The main goal for the convention is to provide a unified notation
that can be used when defining protocols that use CBOR. We term the that can be used when defining protocols that use CBOR. We term the
convention "Concise data definition language", or CDDL. convention "Concise data definition language", or CDDL.
skipping to change at page 4, line 17 skipping to change at page 4, line 17
Not an original goal per se, but a convenient side effect of the JSON Not an original goal per se, but a convenient side effect of the JSON
generic data model being a subset of the CBOR generic data model, is generic data model being a subset of the CBOR generic data model, is
the fact that CDDL can also be used for describing JSON data the fact that CDDL can also be used for describing JSON data
structures (see Appendix E). structures (see Appendix E).
This document has the following structure: This document has the following structure:
The syntax of CDDL is defined in Section 3. Examples of CDDL and The syntax of CDDL is defined in Section 3. Examples of CDDL and
related CBOR data items ("instances", which all happen to be in JSON related CBOR data items ("instances", which all happen to be in JSON
form) are given in Appendix A. Section 4 discusses usage of CDDL. form) are given in Appendix H. Section 4 discusses usage of CDDL.
Examples are provided early in the text to better illustrate concept Examples are provided early in the text to better illustrate concept
definitions. A formal definition of CDDL using ABNF grammar is definitions. A formal definition of CDDL using ABNF grammar is
provided in Appendix B. Finally, a _prelude_ of standard CDDL provided in Appendix B. Finally, a _prelude_ of standard CDDL
definitions that is automatically prepended to and thus available in definitions that is automatically prepended to and thus available in
every CBOR specification is listed in Appendix D. every CBOR specification is listed in Appendix D.
1.1. Requirements notation 1.1. Requirements notation
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in "OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here. capitals, as shown here.
1.2. Terminology 1.2. Terminology
New terms are introduced in _cursive_. CDDL text in the running text New terms are introduced in _cursive_, which is rendered in plain
is in "typewriter". text as the new term surrouded by underscores. CDDL text in the
running text is in "typewriter", which is rendered in plain text as
the CDDL text in double quotes (double quotes are also used in the
usual English sense; the reader is expected to disambiguate this by
context).
In this specification, the term "byte" is used in its now customary In this specification, the term "byte" is used in its now customary
sense as a synonym for "octet". sense as a synonym for "octet".
2. The Style of Data Structure Specification 2. The Style of Data Structure Specification
CDDL focuses on styles of specification that are in use in the CDDL focuses on styles of specification that are in use in the
community employing the data model as pioneered by JSON and now community employing the data model as pioneered by JSON and now
refined in CBOR. refined in CBOR.
There are a number of more or less atomic elements of a CBOR data There are a number of more or less atomic elements of a CBOR data
model, such as numbers, simple values (false, true, nil), text and model, such as numbers, simple values (false, true, nil), text and
byte strings; CDDL does not focus on specifying their structure. byte strings; CDDL does not focus on specifying their structure.
CDDL of course also allows adding a CBOR tag to a data item. CDDL of course also allows adding a CBOR tag to a data item.
The more important components of a data structure definition language Beyond those atomic elements, further components of a data structure
are the data types used for composition: arrays and maps in CBOR definition language are the data types used for composition: arrays
(called arrays and objects in JSON). While these are only two and maps in CBOR (called arrays and objects in JSON). While these
representation formats, they are used to specify four loosely are only two representation formats, they are used to specify four
distinguishable styles of composition: loosely distinguishable styles of composition:
o A _vector_, an array of elements that are mostly of the same o A _vector_, an array of elements that are mostly of the same
semantics. The set of signatures associated with a signed data semantics. The set of signatures associated with a signed data
item is a typical application of a vector. item is a typical application of a vector.
o A _record_, an array the elements of which have different, o A _record_, an array the elements of which have different,
positionally defined semantics, as detailed in the data structure positionally defined semantics, as detailed in the data structure
definition. A 2D point, specified as an array of an x coordinate definition. A 2D point, specified as an array of an x coordinate
(which comes first) and a y coordinate (coming second) is an (which comes first) and a y coordinate (coming second) is an
example of a record, as is the pair of exponent (first) and example of a record, as is the pair of exponent (first) and
skipping to change at page 6, line 10 skipping to change at page 6, line 15
acceptable as "instances" for this specification. CDDL acceptable as "instances" for this specification. CDDL
predefines a number of basic types such as "uint" (unsigned predefines a number of basic types such as "uint" (unsigned
integer) or "tstr" (text string), often making use of a simple integer) or "tstr" (text string), often making use of a simple
formal notation for CBOR data items. Each value that can be formal notation for CBOR data items. Each value that can be
expressed as a CBOR data item also is a type in its own right, expressed as a CBOR data item also is a type in its own right,
e.g. "1". A type can be built as a _choice_ of other types, e.g. "1". A type can be built as a _choice_ of other types,
e.g., an "int" is either a "uint" or a "nint" (negative integer). e.g., an "int" is either a "uint" or a "nint" (negative integer).
Finally, a type can be built as an array or a map from a group. Finally, a type can be built as an array or a map from a group.
The rest of this section introduces a number of basic concepts of The rest of this section introduces a number of basic concepts of
CDDL, and section Section 3 defines additional syntax. Appendix C CDDL, and Section 3 defines additional syntax. Appendix C gives a
gives a concise summary of the semantics of CDDL. concise summary of the semantics of CDDL.
2.1. Groups and Composition in CDDL 2.1. Groups and Composition in CDDL
CDDL Groups are lists of group _entries_, each of which can be a CDDL Groups are lists of group _entries_, each of which can be a
name/value pair or a more complex group expression (which then in name/value pair or a more complex group expression (which then in
turn stands for a sequence of name/value pairs). A CDDL group is a turn stands for a sequence of name/value pairs). A CDDL group is a
production in a grammar that matches certain sequences of name/value production in a grammar that matches certain sequences of name/value
pairs but not others. The grammar is based on the concepts of pairs but not others. The grammar is based on the concepts of
Parsing Expression Grammars [PEG]. Parsing Expression Grammars (see Appendix A).
In an array context, only the value of the name/value pair is In an array context, only the value of the name/value pair is
represented; the name is annotation only (and can be left off from represented; the name is annotation only (and can be left off from
the group specification if not needed). In a map context, the names the group specification if not needed). In a map context, the names
become the map keys ("member keys"). become the map keys ("member keys").
In an array context, the actual sequence of elements in the group is In an array context, the actual sequence of elements in the group is
important, as that sequence is the information that allows important, as that sequence is the information that allows
associating actual array elements with entries in the group. In a associating actual array elements with entries in the group. In a
map context, the sequence of entries in a group is not relevant (but map context, the sequence of entries in a group is not relevant (but
skipping to change at page 9, line 7 skipping to change at page 9, line 20
define them in a separate rule and to reference them with their define them in a separate rule and to reference them with their
respective name (possibly more than once). respective name (possibly more than once).
With this, one is allowed to define all small parts of their data With this, one is allowed to define all small parts of their data
structures and compose bigger protocol units with those or to have structures and compose bigger protocol units with those or to have
only one big protocol data unit that has all definitions ad hoc where only one big protocol data unit that has all definitions ad hoc where
needed. needed.
2.1.2. Syntax 2.1.2. Syntax
The composition syntax intends to be concise and easy to read: The composition syntax is intended to be concise and easy to read:
o The start and end of a group can be marked by '(' and ')' o The start and end of a group can be marked by '(' and ')'
o Definitions of entries inside of a group are noted as follows: o Definitions of entries inside of a group are noted as follows:
_keytype => valuetype,_ (read "keytype maps to valuetype"). The _keytype => valuetype,_ (read "keytype maps to valuetype"). The
comma is actually optional (not just in the final entry), but it comma is actually optional (not just in the final entry), but it
is considered good style to set it. The double arrow can be is considered good style to set it. The double arrow can be
replaced by a colon in the common case of directly using a text replaced by a colon in the common case of directly using a text
string or integer literal as a key (see Section 3.5.1; this is string or integer literal as a key (see Section 3.5.1; this is
also the common way of naming elements of an array just for also the common way of naming elements of an array just for
skipping to change at page 10, line 18 skipping to change at page 10, line 26
delimited by a "/" (slash). The entire choice construct can be put delimited by a "/" (slash). The entire choice construct can be put
into parentheses if this is required to make the construction into parentheses if this is required to make the construction
unambiguous (please see Appendix B for the details). unambiguous (please see Appendix B for the details).
Choices of values can be used to express enumerations: Choices of values can be used to express enumerations:
attire = "bow tie" / "necktie" / "Internet attire" attire = "bow tie" / "necktie" / "Internet attire"
protocol = 6 / 17 protocol = 6 / 17
Similarly as for types, CDDL also allows choices between groups, Similarly as for types, CDDL also allows choices between groups,
delimited by a "//" (double slash). Note that the "//" operators delimited by a "//" (double slash). Note that the "//" operator
binds much more weakly than the other CDDL operators, so each line binds much more weakly than the other CDDL operators, so each line
within "delivery" in the following example is its own alternative in within "delivery" in the following example is its own alternative in
the group choice: the group choice:
address = { delivery } address = { delivery }
delivery = ( delivery = (
street: tstr, ? number: uint, city // street: tstr, ? number: uint, city //
po-box: uint, city // po-box: uint, city //
per-pickup: true ) per-pickup: true )
skipping to change at page 13, line 42 skipping to change at page 13, line 47
to be overly formal; refer to Appendix B for the details.) to be overly formal; refer to Appendix B for the details.)
3.1. General conventions 3.1. General conventions
The basic syntax is inspired by ABNF [RFC5234], with The basic syntax is inspired by ABNF [RFC5234], with
o rules, whether they define groups or types, are defined with a o rules, whether they define groups or types, are defined with a
name, followed by an equals sign "=" and the actual definition name, followed by an equals sign "=" and the actual definition
according to the respective syntactic rules of that definition. according to the respective syntactic rules of that definition.
o A name can consist of any of the characters from the set {'A', o A name can consist of any of the characters from the set {'A' to
..., 'Z', 'a', ..., 'z', '0', ..., '9', '_', '-', '@', '.', '$'}, 'Z', 'a' to 'z', '0' to '9', '_', '-', '@', '.', '$'}, starting
starting with an alphabetic character (including '@', '_', '$') with an alphabetic character (including '@', '_', '$') and ending
and ending in one or a digit. in such a character or or a digit.
* Names are case sensitive. * Names are case sensitive.
* It is preferred style to start a name with a lower case letter. * It is preferred style to start a name with a lower case letter.
* The hyphen is preferred over the underscore (except in a * The hyphen is preferred over the underscore (except in a
"bareword" (Section 3.5.1), where the semantics may actually "bareword" (Section 3.5.1), where the semantics may actually
require an underscore). require an underscore).
* The period may be useful for larger specifications, to express * The period may be useful for larger specifications, to express
skipping to change at page 14, line 24 skipping to change at page 14, line 26
in Appendix D. in Appendix D.
* Rule names (types or groups) do not appear in the actual CBOR * Rule names (types or groups) do not appear in the actual CBOR
encoding, but names used as "barewords" in member keys do. encoding, but names used as "barewords" in member keys do.
o Comments are started by a ';' (semicolon) character and finish at o Comments are started by a ';' (semicolon) character and finish at
the end of a line (LF or CRLF). the end of a line (LF or CRLF).
o outside strings, whitespace (spaces, newlines, and comments) is o outside strings, whitespace (spaces, newlines, and comments) is
used to separate syntactic elements for readability (and to used to separate syntactic elements for readability (and to
separate identifiers or numbers that follow each other); it is separate identifiers, range operators, or numbers that follow each
otherwise completely optional. other); it is otherwise completely optional.
o Hexadecimal numbers are preceded by '0x' (without quotes, lower o Hexadecimal numbers are preceded by '0x' (without quotes, lower
case x), and are case insensitive. Similarly, binary numbers are case x), and are case insensitive. Similarly, binary numbers are
preceded by '0b'. preceded by '0b'.
o Text strings are enclosed by double quotation '"' characters. o Text strings are enclosed by double quotation '"' characters.
They follow the conventions for strings as defined in section 7 of They follow the conventions for strings as defined in section 7 of
[RFC8259]. (ABNF users may want to note that there is no support [RFC8259]. (ABNF users may want to note that there is no support
in CDDL for the concept of case insensitivity in text strings; if in CDDL for the concept of case insensitivity in text strings; if
necessary, regular expressions can be used (Section 3.8.3).) necessary, regular expressions can be used (Section 3.8.3).)
o Byte strings are enclosed by single quotation "'" characters and o Byte strings are enclosed by single quotation "'" characters and
may be prefixed by "h" or "b64". If unprefixed, the string is may be prefixed by "h" or "b64". If unprefixed, the string is
interpreted as with a text string, except that single quotes must interpreted as with a text string, except that single quotes must
be escaped and that the UTF-8 bytes resulting are marked as a byte be escaped and that the UTF-8 bytes resulting are marked as a byte
string (major type 2). If prefixed as "h" or "b64", the string is string (major type 2). If prefixed as "h" or "b64", the string is
interpreted as a sequence of pairs of hex digits (base16) or a interpreted as a sequence of pairs of hex digits (base16,
base64(url) string, respectively (as with the diagnostic notation Section 8 of [RFC4648]) or a base64(url) string (Sections 4 or 5
in section 6 of [RFC7049]; cf. Appendix G.2); any white space of [RFC4648]), respectively (as with the diagnostic notation in
present within the string (including comments) is ignored in the section 6 of [RFC7049]; cf. Appendix G.2); any white space present
prefixed case. within the string (including comments) is ignored in the prefixed
case.
o CDDL uses UTF-8 [RFC3629] for its encoding. o CDDL uses UTF-8 [RFC3629] for its encoding.
Example: Example:
; This is a comment ; This is a comment
person = { g } person = { g }
g = ( g = (
"name": tstr, "name": tstr,
skipping to change at page 18, line 36 skipping to change at page 18, line 36
located-samples = { located-samples = {
sample-point: int, sample-point: int,
samples: [+ float], samples: [+ float],
} }
where "located-samples" is the datatype to be used when referring to where "located-samples" is the datatype to be used when referring to
the struct, and "sample-point" and "samples" are the keys to be used. the struct, and "sample-point" and "samples" are the keys to be used.
This is actually a complete example: an identifier that is followed This is actually a complete example: an identifier that is followed
by a colon can be directly used as the text string for a member key by a colon can be directly used as the text string for a member key
(we speak of a "bareword" member key), as can a double-quoted string (we speak of a "bareword" member key), as can a double-quoted string
or a number. (When other types, in particular multi-valued ones, are or a number. (When other types, in particular ones that contain more
used as the types of keys, they are followed by a double arrow, see than one value, are used as the types of keys, they are followed by a
below.) double arrow, see below.)
If a text string key does not match the syntax for an identifier (or If a text string key does not match the syntax for an identifier (or
if the specifier just happens to prefer using double quotes), the if the specifier just happens to prefer using double quotes), the
text string syntax can also be used in the member key position, text string syntax can also be used in the member key position,
followed by a colon. The above example could therefore have been followed by a colon. The above example could therefore have been
written with quoted strings in the member key positions. More written with quoted strings in the member key positions.
generally, all the types defined can be used in a keytype position by
following them with a double arrow -- in particular, the double arrow More generally, types specified in other ways than the cases
is necessary if a type is named by an identifier (which would be described above can be used in a keytype position by following them
interpreted as a string before a colon). A string also is a (single- with a double arrow -- in particular, the double arrow is necessary
valued) type, so another form for this example is: if a type is named by an identifier (which, when followed by a colon,
would be interpreted as a "bareword" and turned into a text string).
A literal text string also gives rise to a type (which contains a
single value only -- the given string), so another form for this
example is:
located-samples = { located-samples = {
"sample-point" => int, "sample-point" => int,
"samples" => [+ float], "samples" => [+ float],
} }
See Section 3.5.4 below for how the colon shortcut described here See Section 3.5.4 below for how the colon shortcut described here
also adds some implied semantics. also adds some implied semantics.
A better way to demonstrate the double-arrow use may be: A better way to demonstrate the double-arrow use may be:
skipping to change at page 20, line 32 skipping to change at page 20, line 32
{"familyName": "agust", "antiforeignism": "pretzel", {"familyName": "agust", "antiforeignism": "pretzel",
"springbuck": "illuminatingly", "exuviae": "ephemeris", "springbuck": "illuminatingly", "exuviae": "ephemeris",
"kilometrage": "frogfish"} "kilometrage": "frogfish"}
(See Section 3.9 for one way to explicitly identify an extension (See Section 3.9 for one way to explicitly identify an extension
point.) point.)
3.5.2. Tables 3.5.2. Tables
A table can be specified by defining a map with entries where the A table can be specified by defining a map with entries where the
keytype is not single-valued, e.g.: keytype allows more than just a single value, e.g.:
square-roots = {* x => y} square-roots = {* x => y}
x = int x = int
y = float y = float
Here, the key in each key/value pair has datatype x (defined as int), Here, the key in each key/value pair has datatype x (defined as int),
and the value has datatype y (defined as float). and the value has datatype y (defined as float).
If the specification does not need to restrict one of x or y (i.e., If the specification does not need to restrict one of x or y (i.e.,
the application is free to choose per entry), it can be replaced by the application is free to choose per entry), it can be replaced by
skipping to change at page 21, line 8 skipping to change at page 21, line 8
As another example, the following could be used as a conversion table As another example, the following could be used as a conversion table
converting from an integer or float to a string: converting from an integer or float to a string:
tostring = {* mynumber => tstr} tostring = {* mynumber => tstr}
mynumber = int / float mynumber = int / float
3.5.3. Non-deterministic order 3.5.3. Non-deterministic order
While the way arrays are matched is fully determined by the Parsing While the way arrays are matched is fully determined by the Parsing
Expression Grammar (PEG) algorithm, matching is more complicated for Expression Grammar (PEG) formalism (see Appendix A), matching is more
maps, as maps do not have an inherent order. For each candidate complicated for maps, as maps do not have an inherent order. For
name/value pair that the PEG algorithm would try, a matching member each candidate name/value pair that the PEG algorithm would try, a
is picked out of the entire map. For certain group expressions, more matching member is picked out of the entire map. For certain group
than one member in the map may match. Most often, this is expressions, more than one member in the map may match. Most often,
inconsequential, as the group expression tends to consume all this is inconsequential, as the group expression tends to consume all
matches: matches:
labeled-values = { labeled-values = {
? fritz: number, ? fritz: number,
* label => value * label => value
} }
label = text label = text
value = number value = number
Here, if any member with the key "fritz" is present, this will be Here, if any member with the key "fritz" is present, this will be
skipping to change at page 25, line 30 skipping to change at page 25, line 30
label = bstr .size (1..63) label = bstr .size (1..63)
Figure 8: Control for size in bytes Figure 8: Control for size in bytes
When applied to an unsigned integer, the ".size" control restricts When applied to an unsigned integer, the ".size" control restricts
the range of that integer by giving a maximum number of bytes that the range of that integer by giving a maximum number of bytes that
should be needed in a computer representation of that unsigned should be needed in a computer representation of that unsigned
integer. In other words, "uint .size N" is equivalent to integer. In other words, "uint .size N" is equivalent to
"0...BYTES_N", where BYTES_N == 256**N. "0...BYTES_N", where BYTES_N == 256**N.
audio_sample = uint .size 3 ; 24-bit, equivalent to 0..16777215 audio_sample = uint .size 3 ; 24-bit, equivalent to 0...16777216
Figure 9: Control for integer size in bytes Figure 9: Control for integer size in bytes
Note that, as with value restrictions in CDDL, this control is not a Note that, as with value restrictions in CDDL, this control is not a
representation constraint; a number that fits into fewer bytes can representation constraint; a number that fits into fewer bytes can
still be represented in that form, and an inefficient implementation still be represented in that form, and an inefficient implementation
could use a longer form (unless that is restricted by some format could use a longer form (unless that is restricted by some format
constraints outside of CDDL, such as the rules in Section 3.9 of constraints outside of CDDL, such as the rules in Section 3.9 of
[RFC7049]). [RFC7049]).
skipping to change at page 29, line 13 skipping to change at page 29, line 13
$message /= [4, noodles: text, sauce: text, parmesan: bool] $message /= [4, noodles: text, sauce: text, parmesan: bool]
For ".within", a tool might flag an error if type1 allows data items For ".within", a tool might flag an error if type1 allows data items
that are not allowed by type2. In contrast, for ".and", there is no that are not allowed by type2. In contrast, for ".and", there is no
expectation that type1 already is a subset of type2. expectation that type1 already is a subset of type2.
3.8.6. Control operators .lt, .le, .gt, .ge, .eq, .ne, and .default 3.8.6. Control operators .lt, .le, .gt, .ge, .eq, .ne, and .default
The controls .lt, .le, .gt, .ge, .eq, .ne specify a constraint on the The controls .lt, .le, .gt, .ge, .eq, .ne specify a constraint on the
left hand side type to be a value less than, less than or equal, left hand side type to be a value less than, less than or equal,
greater than, greater than or equal, equal, or not equal, to a value greater than, greater than or equal, equal, or not equal, to a value
given as a (single-valued) right hand side type. In the present given as a right hand side type (containing just that single value).
specification, the first four controls (.lt, .le, .gt, .ge) are In the present specification, the first four controls (.lt, .le, .gt,
defined only for numeric types, as these have a natural ordering .ge) are defined only for numeric types, as these have a natural
relationship. ordering relationship.
speed = number .ge 0 ; unit: m/s speed = number .ge 0 ; unit: m/s
.ne and .eq are defined both for numeric values and values of other .ne and .eq are defined both for numeric values and values of other
types. If one of the values is not of a numeric type, equality is types. If one of the values is not of a numeric type, equality is
determined as follows: Text strings are equal (satisfy .eq/do not determined as follows: Text strings are equal (satisfy .eq/do not
satisfy .ne) if they are byte-wise identical; the same applies for satisfy .ne) if they are byte-wise identical; the same applies for
byte strings. Arrays are equal if they have the same number of byte strings. Arrays are equal if they have the same number of
elements, all of which are equal pairwise in order between the elements, all of which are equal pairwise in order between the
arrays. Maps are equal if they have the same number of key/value arrays. Maps are equal if they have the same number of key/value
skipping to change at page 30, line 32 skipping to change at page 30, line 32
$$tcp-option //= ( $$tcp-option //= (
sack: [+(left: uint, right: uint)] sack: [+(left: uint, right: uint)]
) )
; and, maybe in another file ; and, maybe in another file
$$tcp-option //= ( $$tcp-option //= (
sack-permitted: true sack-permitted: true
) )
Names that start with a single "$" are "type sockets", names with a Names that start with a single "$" are "type sockets", starting out
double "$$" are "group sockets". It is not an error if there is no as an empty type, and intended to be extended via "/=". Names that
definition for a socket at all; this then means there is no way to start with a double "$$" are "group sockets", starting out as an
satisfy the rule (i.e., the choice is empty). empty group choice, and intended to be extended via "//=". In either
case, it is not an error if there is no definition for a socket at
all; this then means there is no way to satisfy the rule (i.e., the
choice is empty).
As a convention, all definitions (plugs) for socket names must be As a convention, all definitions (plugs) for socket names must be
augmentations, i.e., they must be using "/=" and "//=", respectively. augmentations, i.e., they must be using "/=" and "//=", respectively.
To pick up the example illustrated in Figure 7, the socket/plug To pick up the example illustrated in Figure 7, the socket/plug
mechanism could be used as shown in Figure 12: mechanism could be used as shown in Figure 12:
PersonalData = { PersonalData = {
? displayName: tstr, ? displayName: tstr,
NameComponents, NameComponents,
skipping to change at page 37, line 9 skipping to change at page 37, line 9
[RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC [RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC
Text on Security Considerations", BCP 72, RFC 3552, Text on Security Considerations", BCP 72, RFC 3552,
DOI 10.17487/RFC3552, July 2003, DOI 10.17487/RFC3552, July 2003,
<https://www.rfc-editor.org/info/rfc3552>. <https://www.rfc-editor.org/info/rfc3552>.
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
2003, <https://www.rfc-editor.org/info/rfc3629>. 2003, <https://www.rfc-editor.org/info/rfc3629>.
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
<https://www.rfc-editor.org/info/rfc4648>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234, Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008, DOI 10.17487/RFC5234, January 2008,
<https://www.rfc-editor.org/info/rfc5234>. <https://www.rfc-editor.org/info/rfc5234>.
[RFC7049] Bormann, C. and P. Hoffman, "Concise Binary Object [RFC7049] Bormann, C. and P. Hoffman, "Concise Binary Object
Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049, Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049,
October 2013, <https://www.rfc-editor.org/info/rfc7049>. October 2013, <https://www.rfc-editor.org/info/rfc7049>.
[RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493,
skipping to change at page 38, line 20 skipping to change at page 38, line 25
[PEG] Ford, B., "Parsing expression grammars", Proceedings of [PEG] Ford, B., "Parsing expression grammars", Proceedings of
the 31st ACM SIGPLAN-SIGACT symposium on Principles of the 31st ACM SIGPLAN-SIGACT symposium on Principles of
programming languages - POPL '04, programming languages - POPL '04,
DOI 10.1145/964001.964011, 2004. DOI 10.1145/964001.964011, 2004.
[RELAXNG] ISO/IEC, "Information technology -- Document Schema [RELAXNG] ISO/IEC, "Information technology -- Document Schema
Definition Language (DSDL) -- Part 2: Regular-grammar- Definition Language (DSDL) -- Part 2: Regular-grammar-
based validation -- RELAX NG", ISO/IEC 19757-2, December based validation -- RELAX NG", ISO/IEC 19757-2, December
2008. 2008.
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
<https://www.rfc-editor.org/info/rfc4648>.
[RFC7071] Borenstein, N. and M. Kucherawy, "A Media Type for [RFC7071] Borenstein, N. and M. Kucherawy, "A Media Type for
Reputation Interchange", RFC 7071, DOI 10.17487/RFC7071, Reputation Interchange", RFC 7071, DOI 10.17487/RFC7071,
November 2013, <https://www.rfc-editor.org/info/rfc7071>. November 2013, <https://www.rfc-editor.org/info/rfc7071>.
[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language",
RFC 7950, DOI 10.17487/RFC7950, August 2016, RFC 7950, DOI 10.17487/RFC7950, August 2016,
<https://www.rfc-editor.org/info/rfc7950>. <https://www.rfc-editor.org/info/rfc7950>.
[RFC8007] Murray, R. and B. Niven-Jenkins, "Content Delivery Network [RFC8007] Murray, R. and B. Niven-Jenkins, "Content Delivery Network
Interconnection (CDNI) Control Interface / Triggers", Interconnection (CDNI) Control Interface / Triggers",
skipping to change at page 39, line 5 skipping to change at page 39, line 5
[RFC8428] Jennings, C., Shelby, Z., Arkko, J., Keranen, A., and C. [RFC8428] Jennings, C., Shelby, Z., Arkko, J., Keranen, A., and C.
Bormann, "Sensor Measurement Lists (SenML)", RFC 8428, Bormann, "Sensor Measurement Lists (SenML)", RFC 8428,
DOI 10.17487/RFC8428, August 2018, DOI 10.17487/RFC8428, August 2018,
<https://www.rfc-editor.org/info/rfc8428>. <https://www.rfc-editor.org/info/rfc8428>.
7.3. URIs 7.3. URIs
[1] https://github.com/cabo/cbor-diag [1] https://github.com/cabo/cbor-diag
Appendix A. Examples Appendix A. Parsing Expression Grammars (PEG)
This appendix is for information only.
This section contains a few examples of structures defined using
CDDL.
The theme for the first example is taken from [RFC7071], which
defines certain JSON structures in English. For a similar example,
it may also be of interest to examine Appendix A of [RFC8007], which
contains a CDDL definition for a JSON structure defined in the main
body of the RFC.
The second subsection in this appendix translates examples from
[I-D.newton-json-content-rules] into CDDL.
These examples all happen to describe data that is interchanged in
JSON. Examples for CDDL definitions of data that is interchanged in
CBOR can be found in [RFC8152], [I-D.ietf-anima-grasp], or [RFC8428].
A.1. RFC 7071
[RFC7071] defines the Reputon structure for JSON using somewhat
formalized English text. Here is a (somewhat verbose) equivalent
definition using the same terms, but notated in CDDL:
reputation-object = {
reputation-context,
reputon-list
}
reputation-context = (
application: text
)
reputon-list = (
reputons: reputon-array
)
reputon-array = [* reputon]
reputon = {
rater-value,
assertion-value,
rated-value,
rating-value,
? conf-value,
? normal-value,
? sample-value,
? gen-value,
? expire-value,
* ext-value,
}
rater-value = ( rater: text )
assertion-value = ( assertion: text )
rated-value = ( rated: text )
rating-value = ( rating: float16 )
conf-value = ( confidence: float16 )
normal-value = ( normal-rating: float16 )
sample-value = ( sample-size: uint )
gen-value = ( generated: uint )
expire-value = ( expires: uint )
ext-value = ( text => any )
An equivalent, more compact form of this example would be:
reputation-object = {
application: text
reputons: [* reputon]
}
reputon = {
rater: text
assertion: text
rated: text
rating: float16
? confidence: float16
? normal-rating: float16
? sample-size: uint
? generated: uint
? expires: uint
* text => any
}
Note how this rather clearly delineates the structure somewhat
shrouded by so many words in section 6.2.2. of [RFC7071]. Also, this
definition makes it clear that several ext-values are allowed (by
definition with different member names); RFC 7071 could be read to
forbid the repetition of ext-value ("A specific reputon-element MUST
NOT appear more than once" is ambiguous.)
The CDDL tool reported on in Appendix F (which hasn't quite been
trained for polite conversation) says:
{
"application": "tridentiferous",
"reputons": [
{
"rater": "loamily",
"assertion": "Dasyprocta",
"rated": "uncommensurableness",
"rating": 0.05055809746548934,
"confidence": 0.7484706448605812,
"normal-rating": 0.8677887734049299,
"sample-size": 4059,
"expires": 3969,
"bearer": "nitty",
"faucal": "postulnar",
"naturalism": "sarcotic"
},
{
"rater": "precreed",
"assertion": "xanthosis",
"rated": "balsamy",
"rating": 0.36091333590593955,
"confidence": 0.3700759808403371,
"sample-size": 3904
},
{
"rater": "urinosexual",
"assertion": "malacostracous",
"rated": "arenariae",
"rating": 0.9210673488013762,
"normal-rating": 0.4778762617112776,
"sample-size": 4428,
"generated": 3294,
"backfurrow": "enterable",
"fruitgrower": "flannelflower"
},
{
"rater": "pedologistically",
"assertion": "unmetaphysical",
"rated": "elocutionist",
"rating": 0.42073613384304287,
"misimagine": "retinaculum",
"snobbish": "contradict",
"Bosporanic": "periostotomy",
"dayworker": "intragyral"
}
]
}
A.2. Examples from JSON Content Rules
Although JSON Content Rules [I-D.newton-json-content-rules] seems to
address a more general problem than CDDL, it is still a worthwhile
resource to explore for examples (beyond all the inspiration the
format itself has had for CDDL).
Figure 2 of the JCR I-D looks very similar, if slightly less noisy, This appendix is normative.
in CDDL:
root = [2*2 { Since the 1950s, many grammar notations are based on Backus-Naur Form
precision: text, (BNF), a notation for context-free grammars (CFGs) within Chomsky's
Latitude: float, generative system of grammars. ABNF [RFC5234], the Augmented Backus-
Longitude: float, Naur Form widely used in IETF specifications and also inspiring the
Address: text, syntax of CDDL, is an example of this.
City: text,
State: text,
Zip: text,
Country: text
}]
Figure 13: JCR, Figure 2, in CDDL Generative grammars can express ambiguity well, but this very
property may make them hard to use in recognition systems, spawning a
number of subdialects that pose constraints on generative grammars to
be used with parser generators, which may be hard to manage for the
specification writer.
Apart from the lack of a need to quote the member names, text strings Parsing Expression Grammars [PEG] provide an alternative formal
are called "text" or "tstr" in CDDL ("string" would be ambiguous as foundation for describing grammars that emphasizes recognition over
CBOR also provides byte strings). generation, and resolves what would have been ambiguity in generative
systems by introducing the concept of "prioritized choice".
The CDDL tool reported on in Appendix F creates the below example The notation for Parsing Expression Grammars is quite close to BNF,
instance for this: with the usual "Extended BNF" features such as repetition added.
However, where BNF uses the unordered (symmetrical) choice operator
"|" (incidentally notated as "/" in ABNF), PEG provides a prioritized
choice operator "/". The two alternatives listed are to be tested in
left-to-right order, locking in the first successful match and
disregarding any further potential matches within the choice (but not
disabling alternatives in choices containing this choice, as a "cut"
would - Section 3.5.4}.
[{"precision": "pyrosphere", "Latitude": 0.5399712314350172, For example, the ABNF expressions
"Longitude": 0.5157523963028087, "Address": "resow",
"City": "problemwise", "State": "martyrlike", "Zip": "preprove",
"Country": "Pace"},
{"precision": "unrigging", "Latitude": 0.10422704368372193,
"Longitude": 0.6279808663725834, "Address": "picturedom",
"City": "decipherability", "State": "autometry", "Zip": "pout",
"Country": "wimple"}]
Figure 4 of the JCR I-D in CDDL: A = "a" "b" / "a" (1)
root = { image } and
image = ( A = "a" / "a" "b" (2)
Image: {
size,
Title: text,
thumbnail,
IDs: [* int]
}
)
size = ( are equivalent in ABNF's original generative framework, but very
Width: 0..1280 different in PEG: In (2), the second alternative will never match, as
Height: 0..1024 any input string starting with an "a" will already succeed in the
) first alternative, locking in the match.
thumbnail = ( Similarly, the occurrence indicators ("?", "*", "+") are "greedy" in
Thumbnail: { PEG, i.e., they consume as much input as they match (and, as a
size, consequence, "a* a" in PEG notation or "*a a" in CDDL syntax never
Url: ~uri can match anything as all input matching "a" is already consumed by
} the initial "a*", leaving nothing to match the second "a").
)
This shows how the group concept can be used to keep related elements Incidentally, the grammar of the CDDL language itself, as written in
(here: width, height) together, and to emulate the JCR style of ABNF in Appendix B, can be interpreted both in the generative
specification. (It also shows referencing a type by unwrapping a tag framework on which RFC 5234 is based, and as a PEG. This was made
from the prelude, "uri" - this could be done differently.) The more possible by ordering the choices in the grammar such that a
compact form of Figure 5 of the JCR I-D could be emulated like this: successful match made on the left hand side of a "/" operator is
always the intended match, instead of relying on the power of
symmetrical choices (for example, note the sequence of alternatives
in the rule for "uint", where the lone zero is behind the longer
match alternatives that start with a zero).
root = { The syntax used for expressing the PEG component of CDDL is based on
Image: { ABNF, interpreted in the obvious way with PEG semantics. The ABNF
size, Title: text, convention of notating occurrence indicators before the controlled
Thumbnail: { size, Url: ~uri }, primary, and of allowing numeric values for minimum and maximum
IDs: [* int] occurrence around a "*" sign, is copied. While PEG is only about
} characters, CDDL has a richer set of elements, such as types and
} groups. Specifically, the following constructs map:
size = ( +-------+-------+-------------------------------------------+
Width: 0..1280, | CDDL | PEG | Remark |
Height: 0..1024, +-------+-------+-------------------------------------------+
) | "=" | "<-" | /= and //= are abbreviations |
| "//" | "/" | prioritized choice |
| "/" | "/" | prioritized choice, limited to types only |
| "?" P | P "?" | zero or one |
| "*" P | P "*" | zero or more |
| "+" P | P "+" | one or more |
| A B | A B | sequence |
| A, B | A B | sequence, comma is decoration only |
+-------+-------+-------------------------------------------+
The CDDL tool reported on in Appendix F creates the below example The literal notation and the use of square brackets, curly braces,
instance for this: tildes, ampersands, and hash marks is specific to CDDL and unrelated
to the conventional PEG notation. The DOT (".") is replaced by the
unadorned "#" or its alias "any". Also, CDDL does not provide the
syntactic predicate operators NOT ("!") or AND ("&") from PEG,
reducing expressiveness as well as complexity.
{"Image": {"Width": 566, "Height": 516, "Title": "leisterer", For more details about PEG's theoretical foundation and interesting
"Thumbnail": {"Width": 1111, "Height": 176, "Url": 32("scrog")}, properties of the operators such as associativity and distributivity,
"IDs": []}} the reader is referred to [PEG].
Appendix B. ABNF grammar Appendix B. ABNF grammar
This appendix is normative. This appendix is normative.
The following is a formal definition of the CDDL syntax in Augmented The following is a formal definition of the CDDL syntax in Augmented
Backus-Naur Form (ABNF, [RFC5234]). Backus-Naur Form (ABNF, [RFC5234]). Note that, as is defined in
ABNF, the quote-delimited strings below are case-insensitive (while
cddl = S 1*(rule S) string values and names are case-sensitive in CDDL).
rule = typename [genericparm] S assignt S type
/ groupname [genericparm] S assigng S grpent
typename = id cddl = S 1*(rule S)
groupname = id rule = typename [genericparm] S assignt S type
/ groupname [genericparm] S assigng S grpent
assignt = "=" / "/=" typename = id
assigng = "=" / "//=" groupname = id
genericparm = "<" S id S *("," S id S ) ">" assignt = "=" / "/="
genericarg = "<" S type1 S *("," S type1 S ) ">" assigng = "=" / "//="
type = type1 *(S "/" S type1) genericparm = "<" S id S *("," S id S ) ">"
genericarg = "<" S type1 S *("," S type1 S ) ">"
type1 = type2 [S (rangeop / ctlop) S type2] type = type1 *(S "/" S type1)
type2 = value type1 = type2 [S (rangeop / ctlop) S type2]
/ typename [genericarg] ; space may be needed before the operator if type2 ends in a name
/ "(" S type S ")"
/ "{" S group S "}"
/ "[" S group S "]"
/ "~" S typename [genericarg]
/ "&" S "(" S group S ")"
/ "&" S groupname [genericarg]
/ "#" "6" ["." uint] "(" S type S ")" ; note no space!
/ "#" DIGIT ["." uint] ; major/ai
/ "#" ; any
rangeop = "..." / ".." type2 = value
/ typename [genericarg]
/ "(" S type S ")"
/ "{" S group S "}"
/ "[" S group S "]"
/ "~" S typename [genericarg]
/ "&" S "(" S group S ")"
/ "&" S groupname [genericarg]
/ "#" "6" ["." uint] "(" S type S ")"
/ "#" DIGIT ["." uint] ; major/ai
/ "#" ; any
ctlop = "." id rangeop = "..." / ".."
group = grpchoice *(S "//" S grpchoice) ctlop = "." id
grpchoice = *(grpent optcom) group = grpchoice *(S "//" S grpchoice)
grpent = [occur S] [memberkey S] type grpchoice = *(grpent optcom)
/ [occur S] groupname [genericarg] ; preempted by above
/ [occur S] "(" S group S ")"
memberkey = type1 S ["^" S] "=>" grpent = [occur S] [memberkey S] type
/ bareword S ":" / [occur S] groupname [genericarg] ; preempted by above
/ value S ":" / [occur S] "(" S group S ")"
bareword = id memberkey = type1 S ["^" S] "=>"
/ bareword S ":"
/ value S ":"
optcom = S ["," S] bareword = id
occur = [uint] "*" [uint] optcom = S ["," S]
/ "+"
/ "?"
uint = DIGIT1 *DIGIT occur = [uint] "*" [uint]
/ "0x" 1*HEXDIG / "+"
/ "0b" 1*BINDIG / "?"
/ "0"
value = number uint = DIGIT1 *DIGIT
/ text / "0x" 1*HEXDIG
/ bytes / "0b" 1*BINDIG
/ "0"
int = ["-"] uint value = number
/ text
/ bytes
; This is a float if it has fraction or exponent; int otherwise int = ["-"] uint
number = hexfloat / (int ["." fraction] ["e" exponent ])
hexfloat = "0x" 1*HEXDIG ["." 1*HEXDIG] "p" exponent
fraction = 1*DIGIT
exponent = ["+"/"-"] 1*DIGIT
text = %x22 *SCHAR %x22 ; This is a float if it has fraction or exponent; int otherwise
SCHAR = %x20-21 / %x23-5B / %x5D-10FFFD / SESC number = hexfloat / (int ["." fraction] ["e" exponent ])
SESC = "\" %x20-10FFFD hexfloat = "0x" 1*HEXDIG ["." 1*HEXDIG] "p" exponent
fraction = 1*DIGIT
exponent = ["+"/"-"] 1*DIGIT
bytes = [bsqual] %x27 *BCHAR %x27 text = %x22 *SCHAR %x22
BCHAR = %x20-26 / %x28-5B / %x5D-10FFFD / SESC / CRLF SCHAR = %x20-21 / %x23-5B / %x5D-7E / %x80-10FFFD / SESC
bsqual = "h" / "b64" SESC = "\" (%x20-7E / %x80-10FFFD)
id = EALPHA *(*("-" / ".") (EALPHA / DIGIT)) bytes = [bsqual] %x27 *BCHAR %x27
ALPHA = %x41-5A / %x61-7A BCHAR = %x20-26 / %x28-5B / %x5D-10FFFD / SESC / CRLF
EALPHA = ALPHA / "@" / "_" / "$" bsqual = "h" / "b64"
DIGIT = %x30-39
DIGIT1 = %x31-39
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
BINDIG = %x30-31
S = *WS id = EALPHA *(*("-" / ".") (EALPHA / DIGIT))
WS = SP / NL ALPHA = %x41-5A / %x61-7A
SP = %x20 EALPHA = ALPHA / "@" / "_" / "$"
NL = COMMENT / CRLF DIGIT = %x30-39
COMMENT = ";" *PCHAR CRLF DIGIT1 = %x31-39
PCHAR = %x20-10FFFD HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
CRLF = %x0A / %x0D.0A BINDIG = %x30-31
S = *WS
WS = SP / NL
SP = %x20
NL = COMMENT / CRLF
COMMENT = ";" *PCHAR CRLF
PCHAR = %x20-7E / %x80-10FFFD
CRLF = %x0A / %x0D.0A
Figure 14: CDDL ABNF Figure 13: CDDL ABNF
Note that this ABNF does not attempt to reflect the detailed rules of Note that this ABNF does not attempt to reflect the detailed rules of
what can be in a prefixed byte string. what can be in a prefixed byte string.
Appendix C. Matching rules Appendix C. Matching rules
This appendix is normative. This appendix is normative.
In this appendix, we go through the ABNF syntax rules defined in In this appendix, we go through the ABNF syntax rules defined in
Appendix B and briefly describe the matching semantics of each Appendix B and briefly describe the matching semantics of each
skipping to change at page 47, line 49 skipping to change at page 44, line 4
2. Where a rule contributes to a type or group choice (using "/=" or 2. Where a rule contributes to a type or group choice (using "/=" or
"//="), that choice is populated in the order the rules are "//="), that choice is populated in the order the rules are
given; see below. given; see below.
rule = typename [genericparm] S assignt S type rule = typename [genericparm] S assignt S type
/ groupname [genericparm] S assigng S grpent / groupname [genericparm] S assigng S grpent
typename = id typename = id
groupname = id groupname = id
A rule defines a name for a type expression (production "type") or A rule defines a name for a type expression (production "type") or
for a group expression (production "grpent"), with the intention that for a group expression (production "grpent"), with the intention that
the semantics does not change when the name is replaced by its the semantics does not change when the name is replaced by its
(parenthesized if needed) definition. Note that whether the name (parenthesized if needed) definition. Note that whether the name
defined by a rule stands for a type or a group isn't always defined by a rule stands for a type or a group isn't always
determined by syntax alone: e.g., "a = b" can make "a" a type if "b" determined by syntax alone: e.g., "a = b" can make "a" a type if "b"
is one, or a group if "b" is one. More subtly, in "a = (b)", "a" may is a type, or a group if "b" is a group. More subtly, in "a = (b)",
be used as a type if "b" is a type, or as a group both when "b" is a "a" may be used as a type if "b" is a type, or as a group both when
group and when "b" is a type (a good convention to make the latter "b" is a group and when "b" is a type (a good convention to make the
case stand out to the human reader is to write "a = (b,)"). (Note latter case stand out to the human reader is to write "a = (b,)").
that the same dual meaning of parentheses applies within an (Note that the same dual meaning of parentheses applies within an
expression, but often can be resolved by the context of the expression, but often can be resolved by the context of the
parenthesized expression. On the more general point, it may not be parenthesized expression. On the more general point, it may not be
clear immediately either whether "b" stands for a group or a type -- clear immediately either whether "b" stands for a group or a type --
this semantic processing may need to span several levels of rule this semantic processing may need to span several levels of rule
definitions before a determination can be made.) definitions before a determination can be made.)
assignt = "=" / "/=" assignt = "=" / "/="
assigng = "=" / "//=" assigng = "=" / "//="
A plain equals sign defines the rule name as the equivalent of the A plain equals sign defines the rule name as the equivalent of the
expression to the right. A "/=" or "//=" extends a named type or a expression to the right; it is an error if the name already was
group by additional choices; a number of these could be replaced by defined with a different expression. A "/=" or "//=" extends a named
collecting all the right hand sides and creating a single rule with a type or a group by additional choices; a number of these could be
type choice or a group choice built from the right hand sides in the replaced by collecting all the right hand sides and creating a single
order of the rules given. (It is not an error to extend a rule name rule with a type choice or a group choice built from the right hand
that has not yet been defined; this makes the right hand side the sides in the order of the rules given. (It is not an error to extend
first entry in the choice being created.) a rule name that has not yet been defined; this makes the right hand
side the first entry in the choice being created.)
genericparm = "<" S id S *("," S id S ) ">" genericparm = "<" S id S *("," S id S ) ">"
genericarg = "<" S type1 S *("," S type1 S ) ">" genericarg = "<" S type1 S *("," S type1 S ) ">"
Rule names can have generic parameters, which cause temporary Rule names can have generic parameters, which cause temporary
assignments within the right hand sides to the parameter names from assignments within the right hand sides to the parameter names from
the arguments given when citing the rule name. the arguments given when citing the rule name.
type = type1 *(S "/" S type1) type = type1 *(S "/" S type1)
A type can be given as a choice between one or more types. The A type can be given as a choice between one or more types. The
choice matches a data item if the data item matches any one of the choice matches a data item if the data item matches any one of the
types given in the choice. The choice uses Parsing Expression types given in the choice. The choice uses Parsing Expression
Grammar [PEG] semantics: The first choice that matches wins. (As a Grammar semantics as discussed in Appendix A: The first choice that
result, the order of rules that contribute to a single rule name can matches wins. (As a result, the order of rules that contribute to a
very well matter.) single rule name can very well matter.)
type1 = type2 [S (rangeop / ctlop) S type2] type1 = type2 [S (rangeop / ctlop) S type2]
Two types can be combined with a range operator (which see below) or Two types can be combined with a range operator (which see below) or
a control operator (see Section 3.8). a control operator (see Section 3.8).
type2 = value type2 = value
A type can be just a single value (such as 1 or "icecream" or A type can be just a single value (such as 1 or "icecream" or
h'0815'), which matches only a data item with that specific value (no h'0815'), which matches only a data item with that specific value (no
conversions defined), conversions defined),
/ typename [genericarg] / typename [genericarg]
skipping to change at page 49, line 44 skipping to change at page 45, line 46
an "unwrapped" group (see Section 3.7), which matches the group an "unwrapped" group (see Section 3.7), which matches the group
inside a type defined as a map or an array by wrapping the group, or inside a type defined as a map or an array by wrapping the group, or
/ "&" S "(" S group S ")" / "&" S "(" S group S ")"
/ "&" S groupname [genericarg] / "&" S groupname [genericarg]
an enumeration expression, which matches any a value that is within an enumeration expression, which matches any a value that is within
the set of values that the values of the group given can take, or the set of values that the values of the group given can take, or
/ "#" "6" ["." uint] "(" S type S ")" ; note no space! / "#" "6" ["." uint] "(" S type S ")"
a tagged data item, tagged with the "uint" given and containing the a tagged data item, tagged with the "uint" given and containing the
type given as the tagged value, or type given as the tagged value, or
/ "#" DIGIT ["." uint] ; major/ai / "#" DIGIT ["." uint] ; major/ai
a data item of a major type (given by the DIGIT), optionally a data item of a major type (given by the DIGIT), optionally
constrained to the additional information given by the uint, or constrained to the additional information given by the uint, or
/ "#" ; any / "#" ; any
any data item. any data item.
rangeop = "..." / ".." rangeop = "..." / ".."
A range operator can be used to join two type expressions that stand A range operator can be used to join two type expressions that stand
for either two integer values or two floating point values; it for either two integer values or two floating point values; it
matches any value that is between the two values, where the first matches any value that is between the two values, where the first
value is always included in the matching set and the second value is value is always included in the matching set and the second value is
skipping to change at page 52, line 50 skipping to change at page 48, line 50
float32-64 = float32 / float64 float32-64 = float32 / float64
float = float16-32 / float64 float = float16-32 / float64
false = #7.20 false = #7.20
true = #7.21 true = #7.21
bool = false / true bool = false / true
nil = #7.22 nil = #7.22
null = nil null = nil
undefined = #7.23 undefined = #7.23
Figure 15: CDDL Prelude Figure 14: CDDL Prelude
Note that the prelude is deemed to be fixed. This means, for Note that the prelude is deemed to be fixed. This means, for
instance, that additional tags beyond [RFC7049], as registered, need instance, that additional tags beyond [RFC7049], as registered, need
to be defined in each CDDL file that is using them. to be defined in each CDDL file that is using them.
A common stumbling point is that the prelude does not define a type A common stumbling point is that the prelude does not define a type
"string". CBOR has byte strings ("bytes" in the prelude) and text "string". CBOR has byte strings ("bytes" in the prelude) and text
strings ("text"), so a type that is simply called "string" would be strings ("text"), so a type that is simply called "string" would be
ambiguous. ambiguous.
skipping to change at page 53, line 49 skipping to change at page 49, line 49
float16-32 = float16 / float32 float16-32 = float16 / float32
float32-64 = float32 / float64 float32-64 = float32 / float64
float = float16-32 / float64 float = float16-32 / float64
false = #7.20 false = #7.20
true = #7.21 true = #7.21
bool = false / true bool = false / true
nil = #7.22 nil = #7.22
null = nil null = nil
Figure 16: JSON compatible subset of CDDL Prelude Figure 15: JSON compatible subset of CDDL Prelude
(The major types given here do not have a direct meaning in JSON, but (The major types given here do not have a direct meaning in JSON, but
they can be interpreted as CBOR major types translated through they can be interpreted as CBOR major types translated through
Section 4 of [RFC7049].) Section 4 of [RFC7049].)
There are a few fine points in using CDDL with JSON. First, JSON There are a few fine points in using CDDL with JSON. First, JSON
does not distinguish between integers and floating point numbers; does not distinguish between integers and floating point numbers;
there is only one kind of number (which may happen to be integral). there is only one kind of number (which may happen to be integral).
In this context, specifying a type as "uint", "nint" or "int" then In this context, specifying a type as "uint", "nint" or "int" then
becomes a predicate that the number be integral. As an example, this becomes a predicate that the number be integral. As an example, this
skipping to change at page 54, line 41 skipping to change at page 50, line 41
numbers and decimal fractions and does not have limits to its numbers and decimal fractions and does not have limits to its
precision or range. In practice, JSON numbers are often parsed into precision or range. In practice, JSON numbers are often parsed into
a number type that is called float64 here, creating a number of a number type that is called float64 here, creating a number of
limitations to the generic data model [RFC7493]. In particular, this limitations to the generic data model [RFC7493]. In particular, this
means that integers can only be expressed with interoperable means that integers can only be expressed with interoperable
exactness when they lie in the range [-(2**53)+1, (2**53)-1] -- a exactness when they lie in the range [-(2**53)+1, (2**53)-1] -- a
smaller range than that covered by CDDL "int". smaller range than that covered by CDDL "int".
JSON applications that want to stay compatible with I-JSON JSON applications that want to stay compatible with I-JSON
([RFC7493], "Internet JSON") therefore may want to define integer ([RFC7493], "Internet JSON") therefore may want to define integer
types with more limited ranges, such as in Figure 17. Note that the types with more limited ranges, such as in Figure 16. Note that the
types given here are not part of the prelude; they need to be copied types given here are not part of the prelude; they need to be copied
into the CDDL specification if needed. into the CDDL specification if needed.
ij-uint = 0..9007199254740991 ij-uint = 0..9007199254740991
ij-nint = -9007199254740991..-1 ij-nint = -9007199254740991..-1
ij-int = -9007199254740991..9007199254740991 ij-int = -9007199254740991..9007199254740991
Figure 17: I-JSON types for CDDL (not part of prelude) Figure 16: I-JSON types for CDDL (not part of prelude)
JSON applications that do not need to stay compatible with I-JSON and JSON applications that do not need to stay compatible with I-JSON and
that actually may need to go beyond the 64-bit unsigned and negative that actually may need to go beyond the 64-bit unsigned and negative
integers supported by "int" (= "uint"/"nint") may want to use the integers supported by "int" (= "uint"/"nint") may want to use the
following additional types from the standard prelude, which are following additional types from the standard prelude, which are
expressed in terms of tags but can straightforwardly be mapped into expressed in terms of tags but can straightforwardly be mapped into
JSON (but not I-JSON) numbers: JSON (but not I-JSON) numbers:
biguint = #6.2(bstr) biguint = #6.2(bstr)
bignint = #6.3(bstr) bignint = #6.3(bstr)
skipping to change at page 55, line 39 skipping to change at page 51, line 39
check the syntax, generate one or more instances (expressed in CBOR check the syntax, generate one or more instances (expressed in CBOR
diagnostic notation or in pretty-printed JSON), and validate an diagnostic notation or in pretty-printed JSON), and validate an
existing instance against the specification: existing instance against the specification:
Usage: Usage:
cddl spec.cddl generate [n] cddl spec.cddl generate [n]
cddl spec.cddl json-generate [n] cddl spec.cddl json-generate [n]
cddl spec.cddl validate instance.cbor cddl spec.cddl validate instance.cbor
cddl spec.cddl validate instance.json cddl spec.cddl validate instance.json
Figure 18: CDDL tool usage Figure 17: CDDL tool usage
Install on a system with a modern Ruby via: Install on a system with a modern Ruby via:
gem install cddl gem install cddl
Figure 19: CDDL tool installation Figure 18: CDDL tool installation
The accompanying CBOR diagnostic tools (which are automatically The accompanying CBOR diagnostic tools (which are automatically
installed by the above) are described in https://github.com/cabo/ installed by the above) are described in https://github.com/cabo/
cbor-diag [1]; they can be used to convert between binary CBOR, a cbor-diag [1]; they can be used to convert between binary CBOR, a
pretty-printed form of that, CBOR diagnostic notation, JSON, and pretty-printed form of that, CBOR diagnostic notation, JSON, and
YAML. YAML.
Appendix G. Extended Diagnostic Notation Appendix G. Extended Diagnostic Notation
This appendix is normative. This appendix is normative.
skipping to change at page 59, line 5 skipping to change at page 55, line 5
This can be used to annotate a CBOR structure as in: This can be used to annotate a CBOR structure as in:
/grasp-message/ [/M_DISCOVERY/ 1, /session-id/ 10584416, /grasp-message/ [/M_DISCOVERY/ 1, /session-id/ 10584416,
/objective/ [/objective-name/ "opsonize", /objective/ [/objective-name/ "opsonize",
/D, N, S/ 7, /loop-count/ 105]] /D, N, S/ 7, /loop-count/ 105]]
(There are currently no end-of-line comments. If we want to add (There are currently no end-of-line comments. If we want to add
them, "//" sounds like a reasonable delimiter given that we already them, "//" sounds like a reasonable delimiter given that we already
use slashes for comments, but we also could go e.g. for "#".) use slashes for comments, but we also could go e.g. for "#".)
Appendix H. Examples
This appendix is for information only.
This section contains a few examples of structures defined using
CDDL.
The theme for the first example is taken from [RFC7071], which
defines certain JSON structures in English. For a similar example,
it may also be of interest to examine Appendix A of [RFC8007], which
contains a CDDL definition for a JSON structure defined in the main
body of the RFC.
The second subsection in this appendix translates examples from
[I-D.newton-json-content-rules] into CDDL.
These examples all happen to describe data that is interchanged in
JSON. Examples for CDDL definitions of data that is interchanged in
CBOR can be found in [RFC8152], [I-D.ietf-anima-grasp], or [RFC8428].
H.1. RFC 7071
[RFC7071] defines the Reputon structure for JSON using somewhat
formalized English text. Here is a (somewhat verbose) equivalent
definition using the same terms, but notated in CDDL:
reputation-object = {
reputation-context,
reputon-list
}
reputation-context = (
application: text
)
reputon-list = (
reputons: reputon-array
)
reputon-array = [* reputon]
reputon = {
rater-value,
assertion-value,
rated-value,
rating-value,
? conf-value,
? normal-value,
? sample-value,
? gen-value,
? expire-value,
* ext-value,
}
rater-value = ( rater: text )
assertion-value = ( assertion: text )
rated-value = ( rated: text )
rating-value = ( rating: float16 )
conf-value = ( confidence: float16 )
normal-value = ( normal-rating: float16 )
sample-value = ( sample-size: uint )
gen-value = ( generated: uint )
expire-value = ( expires: uint )
ext-value = ( text => any )
An equivalent, more compact form of this example would be:
reputation-object = {
application: text
reputons: [* reputon]
}
reputon = {
rater: text
assertion: text
rated: text
rating: float16
? confidence: float16
? normal-rating: float16
? sample-size: uint
? generated: uint
? expires: uint
* text => any
}
Note how this rather clearly delineates the structure somewhat
shrouded by so many words in section 6.2.2. of [RFC7071]. Also, this
definition makes it clear that several ext-values are allowed (by
definition with different member names); RFC 7071 could be read to
forbid the repetition of ext-value ("A specific reputon-element MUST
NOT appear more than once" is ambiguous.)
The CDDL tool reported on in Appendix F generates as one example:
{
"application": "conchometry",
"reputons": [
{
"rater": "Ephthianura",
"assertion": "codding",
"rated": "sphaerolitic",
"rating": 0.34133473256800795,
"confidence": 0.9481983064298332,
"expires": 1568,
"unplaster": "grassy"
},
{
"rater": "nonchargeable",
"assertion": "raglan",
"rated": "alienage",
"rating": 0.5724646875815566,
"sample-size": 3514,
"Aldebaran": "unchurched",
"puruloid": "impersonable",
"uninfracted": "pericarpoidal",
"schorl": "Caro"
},
{
"rater": "precollectable",
"assertion": "Merat",
"rated": "thermonatrite",
"rating": 0.19164006323936977,
"confidence": 0.6065252103391268,
"normal-rating": 0.5187773690879303,
"generated": 899,
"speedy": "solidungular",
"noviceship": "medicine",
"checkrow": "epidictic"
}
]
}
H.2. Examples from JSON Content Rules
Although JSON Content Rules [I-D.newton-json-content-rules] seems to
address a more general problem than CDDL, it is still a worthwhile
resource to explore for examples (beyond all the inspiration the
format itself has had for CDDL).
Figure 2 of the JCR I-D looks very similar, if slightly less noisy,
in CDDL:
root = [2*2 {
precision: text,
Latitude: float,
Longitude: float,
Address: text,
City: text,
State: text,
Zip: text,
Country: text
}]
Figure 19: JCR, Figure 2, in CDDL
Apart from the lack of a need to quote the member names, text strings
are called "text" or "tstr" in CDDL ("string" would be ambiguous as
CBOR also provides byte strings).
The CDDL tool reported on in Appendix F creates the below example
instance for this:
[{"precision": "pyrosphere", "Latitude": 0.5399712314350172,
"Longitude": 0.5157523963028087, "Address": "resow",
"City": "problemwise", "State": "martyrlike", "Zip": "preprove",
"Country": "Pace"},
{"precision": "unrigging", "Latitude": 0.10422704368372193,
"Longitude": 0.6279808663725834, "Address": "picturedom",
"City": "decipherability", "State": "autometry", "Zip": "pout",
"Country": "wimple"}]
Figure 4 of the JCR I-D in CDDL:
root = { image }
image = (
Image: {
size,
Title: text,
thumbnail,
IDs: [* int]
}
)
size = (
Width: 0..1280
Height: 0..1024
)
thumbnail = (
Thumbnail: {
size,
Url: ~uri
}
)
This shows how the group concept can be used to keep related elements
(here: width, height) together, and to emulate the JCR style of
specification. (It also shows referencing a type by unwrapping a tag
from the prelude, "uri" - this could be done differently.) The more
compact form of Figure 5 of the JCR I-D could be emulated like this:
root = {
Image: {
size, Title: text,
Thumbnail: { size, Url: ~uri },
IDs: [* int]
}
}
size = (
Width: 0..1280,
Height: 0..1024,
)
The CDDL tool reported on in Appendix F creates the below example
instance for this:
{"Image": {"Width": 566, "Height": 516, "Title": "leisterer",
"Thumbnail": {"Width": 1111, "Height": 176, "Url": 32("scrog")},
"IDs": []}}
Contributors Contributors
CDDL was originally conceived by Bert Greevenbosch, who also wrote CDDL was originally conceived by Bert Greevenbosch, who also wrote
the original five versions of this document. the original five versions of this document.
Acknowledgements Acknowledgements
Inspiration was taken from the C and Pascal languages, MPEG's Inspiration was taken from the C and Pascal languages, MPEG's
conventions for describing structures in the ISO base media file conventions for describing structures in the ISO base media file
format, Relax-NG and its compact syntax [RELAXNG], and in particular format, Relax-NG and its compact syntax [RELAXNG], and in particular
 End of changes. 82 change blocks. 
390 lines changed or deleted 486 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/