Internet Engineering Task Force (IETF)                       H. Birkholz
Request for Comments: 8610                                Fraunhofer SIT
Category: Standards Track                                      C. Vigano
ISSN: 2070-1721                                      Universitaet Bremen
                                                              C. Bormann
                                                 Universitaet Bremen TZI
                                                               June 2019
        
Internet Engineering Task Force (IETF)                       H. Birkholz
Request for Comments: 8610                                Fraunhofer SIT
Category: Standards Track                                      C. Vigano
ISSN: 2070-1721                                      Universitaet Bremen
                                                              C. Bormann
                                                 Universitaet Bremen TZI
                                                               June 2019
        

Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures

简明数据定义语言(CDDL):一种表示简明二进制对象表示(CBOR)和JSON数据结构的符号约定

Abstract

摘要

This document proposes a notational convention to express Concise Binary Object Representation (CBOR) data structures (RFC 7049). Its main goal is to provide an easy and unambiguous way to express structures for protocol messages and data formats that use CBOR or JSON.

本文档提出了一种表示简明二进制对象表示(CBOR)数据结构的符号约定(RFC 7049)。它的主要目标是提供一种简单明确的方式来表示使用CBOR或JSON的协议消息和数据格式的结构。

Status of This Memo

关于下段备忘

This is an Internet Standards Track document.

这是一份互联网标准跟踪文件。

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 7841.

本文件是互联网工程任务组(IETF)的产品。它代表了IETF社区的共识。它已经接受了公众审查,并已被互联网工程指导小组(IESG)批准出版。有关互联网标准的更多信息,请参见RFC 7841第2节。

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at https://www.rfc-editor.org/info/rfc8610.

有关本文件当前状态、任何勘误表以及如何提供反馈的信息,请访问https://www.rfc-editor.org/info/rfc8610.

Copyright Notice

版权公告

Copyright (c) 2019 IETF Trust and the persons identified as the document authors. All rights reserved.

版权(c)2019 IETF信托基金和被确定为文件作者的人员。版权所有。

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

本文件受BCP 78和IETF信托有关IETF文件的法律规定的约束(https://trustee.ietf.org/license-info)自本文件出版之日起生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。从本文件中提取的代码组件必须包括信托法律条款第4.e节中所述的简化BSD许可证文本,并提供简化BSD许可证中所述的无担保。

Table of Contents

目录

   1. Introduction ....................................................4
      1.1. Requirements Notation ......................................5
      1.2. Terminology ................................................5
   2. The Style of Data Structure Specification .......................5
      2.1. Groups and Composition in CDDL .............................7
           2.1.1. Usage ..............................................10
           2.1.2. Syntax .............................................10
      2.2. Types .....................................................11
           2.2.1. Values .............................................11
           2.2.2. Choices ............................................11
           2.2.3. Representation Types ...............................13
           2.2.4. Root Type ..........................................14
   3. Syntax .........................................................15
      3.1. General Conventions .......................................15
      3.2. Occurrence ................................................16
      3.3. Predefined Names for Types ................................17
      3.4. Arrays ....................................................18
      3.5. Maps ......................................................19
           3.5.1. Structs ............................................19
           3.5.2. Tables .............................................22
           3.5.3. Non-deterministic Order ............................23
           3.5.4. Cuts in Maps .......................................24
      3.6. Tags ......................................................25
      3.7. Unwrapping ................................................26
      3.8. Controls ..................................................27
           3.8.1. Control Operator .size .............................27
           3.8.2. Control Operator .bits .............................28
           3.8.3. Control Operator .regexp ...........................29
        
   1. Introduction ....................................................4
      1.1. Requirements Notation ......................................5
      1.2. Terminology ................................................5
   2. The Style of Data Structure Specification .......................5
      2.1. Groups and Composition in CDDL .............................7
           2.1.1. Usage ..............................................10
           2.1.2. Syntax .............................................10
      2.2. Types .....................................................11
           2.2.1. Values .............................................11
           2.2.2. Choices ............................................11
           2.2.3. Representation Types ...............................13
           2.2.4. Root Type ..........................................14
   3. Syntax .........................................................15
      3.1. General Conventions .......................................15
      3.2. Occurrence ................................................16
      3.3. Predefined Names for Types ................................17
      3.4. Arrays ....................................................18
      3.5. Maps ......................................................19
           3.5.1. Structs ............................................19
           3.5.2. Tables .............................................22
           3.5.3. Non-deterministic Order ............................23
           3.5.4. Cuts in Maps .......................................24
      3.6. Tags ......................................................25
      3.7. Unwrapping ................................................26
      3.8. Controls ..................................................27
           3.8.1. Control Operator .size .............................27
           3.8.2. Control Operator .bits .............................28
           3.8.3. Control Operator .regexp ...........................29
        
           3.8.4. Control Operators .cbor and .cborseq ...............30
           3.8.5. Control Operators .within and .and .................30
           3.8.6. Control Operators .lt, .le, .gt, .ge, .eq,
                  .ne, and .default ..................................31
      3.9. Socket/Plug ...............................................32
      3.10. Generics .................................................33
      3.11. Operator Precedence ......................................34
   4. Making Use of CDDL .............................................36
      4.1. As a Guide for a Human User ...............................36
      4.2. For Automated Checking of CBOR Data Structures ............36
      4.3. For Data Analysis Tools ...................................37
   5. Security Considerations ........................................37
   6. IANA Considerations ............................................38
      6.1. CDDL Control Operators Registry ...........................38
   7. References .....................................................40
      7.1. Normative References ......................................40
      7.2. Informative References ....................................41
   Appendix A. Parsing Expression Grammars (PEGs) ....................43
   Appendix B. ABNF Grammar ..........................................45
   Appendix C. Matching Rules ........................................47
   Appendix D. Standard Prelude ......................................52
   Appendix E. Use with JSON .........................................53
   Appendix F. A CDDL Tool ...........................................56
   Appendix G. Extended Diagnostic Notation ..........................56
     G.1. Whitespace in Byte String Notation .........................57
     G.2. Text in Byte String Notation ...............................57
     G.3. Embedded CBOR and CBOR Sequences in Byte Strings ...........57
     G.4. Concatenated Strings .......................................58
     G.5. Hexadecimal, Octal, and Binary Numbers .....................59
     G.6. Comments ...................................................59
   Appendix H. Examples ..............................................60
   Acknowledgements ..................................................63
   Contributors ......................................................63
   Authors' Addresses ................................................64
        
           3.8.4. Control Operators .cbor and .cborseq ...............30
           3.8.5. Control Operators .within and .and .................30
           3.8.6. Control Operators .lt, .le, .gt, .ge, .eq,
                  .ne, and .default ..................................31
      3.9. Socket/Plug ...............................................32
      3.10. Generics .................................................33
      3.11. Operator Precedence ......................................34
   4. Making Use of CDDL .............................................36
      4.1. As a Guide for a Human User ...............................36
      4.2. For Automated Checking of CBOR Data Structures ............36
      4.3. For Data Analysis Tools ...................................37
   5. Security Considerations ........................................37
   6. IANA Considerations ............................................38
      6.1. CDDL Control Operators Registry ...........................38
   7. References .....................................................40
      7.1. Normative References ......................................40
      7.2. Informative References ....................................41
   Appendix A. Parsing Expression Grammars (PEGs) ....................43
   Appendix B. ABNF Grammar ..........................................45
   Appendix C. Matching Rules ........................................47
   Appendix D. Standard Prelude ......................................52
   Appendix E. Use with JSON .........................................53
   Appendix F. A CDDL Tool ...........................................56
   Appendix G. Extended Diagnostic Notation ..........................56
     G.1. Whitespace in Byte String Notation .........................57
     G.2. Text in Byte String Notation ...............................57
     G.3. Embedded CBOR and CBOR Sequences in Byte Strings ...........57
     G.4. Concatenated Strings .......................................58
     G.5. Hexadecimal, Octal, and Binary Numbers .....................59
     G.6. Comments ...................................................59
   Appendix H. Examples ..............................................60
   Acknowledgements ..................................................63
   Contributors ......................................................63
   Authors' Addresses ................................................64
        
1. Introduction
1. 介绍

In this document, a notational convention to express Concise Binary Object Representation (CBOR) data structures [RFC7049] is defined.

在本文档中,定义了表示简明二进制对象表示(CBOR)数据结构的符号约定[RFC7049]。

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 convention "Concise Data Definition Language", or CDDL.

该公约的主要目标是提供一个统一的符号,在定义使用CBOR的协议时可以使用该符号。我们将该约定称为“简明数据定义语言”或CDDL。

The CBOR notational convention has the following goals:

CBOR符号公约有以下目标:

(G1) Provide an unambiguous description of the overall structure of a CBOR data item.

(G1)明确描述CBOR数据项的总体结构。

(G2) Be flexible in expressing the multiple ways in which data can be represented in the CBOR data format.

(G2)在以CBOR数据格式表示数据时,应灵活表达多种方式。

(G3) Be able to express common CBOR datatypes and structures.

(G3)能够表达通用的CBOR数据类型和结构。

(G4) Provide a single format that is both readable and editable for humans and processable by a machine.

(G4)提供一种可供人阅读和编辑且可由机器处理的单一格式。

(G5) Enable automatic checking of CBOR data items for data format compliance.

(G5)自动检查CBOR数据项是否符合数据格式。

(G6) Enable extraction of specific elements from CBOR data for further processing.

(G6)允许从CBOR数据中提取特定元素以进行进一步处理。

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 the fact that CDDL can also be used for describing JSON data structures (see Appendix E).

JSON通用数据模型作为CBOR通用数据模型的一个子集,其一个方便的副作用是CDDL也可用于描述JSON数据结构(见附录E),这本身并不是最初的目标。

This document has the following structure:

本文件的结构如下:

The syntax of CDDL is defined in Section 3. Examples of CDDL and a related CBOR data item ("instance"), some of which use the JSON form, are described in Appendix H. Section 4 discusses usage of CDDL. Examples are provided throughout the text to better illustrate concept definitions. A formal definition of CDDL using ABNF grammar [RFC5234] is provided in Appendix B. Finally, a _prelude_ of standard CDDL definitions that is automatically prepended to, and thus available in, every CDDL specification is listed in Appendix D.

第3节定义了CDDL的语法。附录H中描述了CDDL和相关CBOR数据项(“实例”)的示例,其中一些使用JSON格式。第4节讨论了CDDL的使用。全文提供了示例,以更好地说明概念定义。附录B中提供了使用ABNF语法[RFC5234]的CDDL的正式定义。最后,附录D中列出了自动添加到每个CDDL规范前的标准CDDL定义的“前奏曲”。

1.1. Requirements Notation
1.1. 需求符号

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

本文件中的关键词“必须”、“不得”、“必需”、“应”、“不应”、“建议”、“不建议”、“可”和“可选”在所有大写字母出现时(如图所示)应按照BCP 14[RFC2119][RFC8174]所述进行解释。

1.2. Terminology
1.2. 术语

New terms are introduced in _cursive_, which is rendered in plain text as the new term surrounded 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).

新术语以_cursive_形式引入,以纯文本形式呈现,新术语由下划线包围。运行文本中的CDDL文本在“打字机”中,以纯文本形式呈现为双引号中的CDDL文本(双引号也在通常的英语意义中使用;读者希望通过上下文消除歧义)。

In this specification, the term "byte" is used in its now-customary sense as a synonym for "octet".

在本规范中,术语“字节”在其现在的习惯意义上用作“八位字节”的同义词。

2. The Style of Data Structure Specification
2. 数据结构规范的风格

CDDL focuses on styles of specification that are in use in the community employing the data model as pioneered by JSON and now refined in CBOR.

CDDL侧重于社区中使用的规范样式,采用JSON率先开发的数据模型,现在在CBOR中进行了改进。

There are a number of more or less atomic elements of a CBOR data model, such as numbers, simple values (false, true, nil), text strings, and byte strings; CDDL does not focus on specifying their structure. CDDL of course also allows adding a CBOR tag to a data item.

CBOR数据模型有许多或多或少的原子元素,例如数字、简单值(false、true、nil)、文本字符串和字节字符串;CDDL并不专注于指定它们的结构。当然,CDDL还允许向数据项添加CBOR标记。

Beyond those atomic elements, further components of a data structure definition language are the datatypes used for composition: arrays and maps in CBOR (called "arrays" and "objects" in JSON). While these are only two representation formats, they are used to specify four loosely distinguishable styles of composition:

除了这些原子元素之外,数据结构定义语言的其他组件还有用于组合的数据类型:CBOR中的数组和映射(JSON中称为“数组”和“对象”)。虽然这只是两种表示格式,但它们用于指定四种可松散区分的构图样式:

o A _vector_: an array of elements that are mostly of the same semantics. The set of signatures associated with a signed data item is a typical application of a vector.

o A _vector:语义基本相同的元素数组。与签名数据项关联的签名集是向量的典型应用。

o A _record_: an array the elements of which have different, positionally defined semantics, as detailed in the data structure definition. A 2D point, specified as an array of an x coordinate (which comes first) and a y coordinate (coming second), is an example of a record, as is the pair of exponent (first) and mantissa (second) in a CBOR decimal fraction.

o A _record_:一个数组,其元素具有不同的位置定义语义,如数据结构定义中所述。指定为x坐标(第一个)和y坐标(第二个)数组的2D点是记录的一个示例,CBOR小数中的指数(第一个)和尾数(第二个)对也是记录的一个示例。

o A _table_: a map from a domain of map keys to a domain of map values, that are mostly of the same semantics. A set of language tags, each mapped to a text string translated to that specific language, is an example of a table. The key domain is usually not limited to a specific set by the specification but is open for the application, e.g., in a table mapping IP addresses to Media Access Control (MAC) addresses, the specification does not attempt to foresee all possible IP addresses. In a language such as JavaScript, a "Map" (as opposed to a plain "Object") would often be employed to achieve the generality of the key domain.

o A _table u:从映射键域映射到映射值域的映射,这些映射值大多具有相同的语义。一组语言标记(每个标记映射到翻译为该特定语言的文本字符串)是表的一个示例。密钥域通常不限于规范规定的特定集合,而是对应用程序开放,例如,在将IP地址映射到媒体访问控制(MAC)地址的表中,规范不试图预见所有可能的IP地址。在JavaScript等语言中,通常会使用“映射”(而不是普通的“对象”)来实现关键域的通用性。

o A _struct_: a map from a domain of map keys as defined by the specification to a domain of map values the semantics of each of which is bound to a specific map key. This is what many people have in mind when they think about JSON objects; CBOR adds the ability to use map keys that are not just text strings. Structs can be used to solve problems similar to those records are used for; the use of explicit map keys facilitates optionality and extensibility.

o A _struct u:从规范定义的映射键域到映射值域的映射,每个映射值的语义都绑定到特定的映射键。这是许多人在考虑JSON对象时的想法;CBOR增加了使用不仅仅是文本字符串的映射键的能力。结构可以用来解决类似于那些记录的问题;显式映射键的使用促进了可选性和可扩展性。

Two important concepts provide the foundation for CDDL:

两个重要概念为CDDL提供了基础:

1. Instead of defining all four types of composition in CDDL separately, or even defining one kind for arrays (vectors and records) and one kind for maps (tables and structs), there is only one kind of composition in CDDL: the _group_ (Section 2.1).

1. CDDL中没有分别定义所有四种类型的组合,甚至没有定义一种数组(向量和记录)和一种映射(表和结构),CDDL中只有一种组合:组(第2.1节)。

2. The other important concept is that of a _type_. The entire CDDL specification defines a type (the one defined by its first _rule_), which formally is the set of CBOR data items that are acceptable as "instances" for this specification. CDDL predefines a number of basic types such as "uint" (unsigned integer) or "tstr" (text string), often making use of a simple formal notation for CBOR data items. Each value that can be expressed as a CBOR data item is also a type in its own right, 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). Finally, a type can be built as an array or a map from a group.

2. 另一个重要的概念是a型。整个CDDL规范定义了一个类型(由其第一个_规则u定义的类型),该类型形式上是可接受为本规范“实例”的CBOR数据项集。CDDL预先定义了许多基本类型,例如“uint”(无符号整数)或“tstr”(文本字符串),通常对CBOR数据项使用简单的形式表示法。可以表示为CBOR数据项的每个值本身也是一种类型,例如“1”。类型可以构建为其他类型的选择,例如,“int”是“uint”或“nint”(负整数)。最后,可以将类型构建为数组或组中的映射。

The rest of this section introduces a number of basic concepts of CDDL, and Section 3 defines additional syntax. Appendix C gives a concise summary of the semantics of CDDL.

本节的其余部分介绍了CDDL的一些基本概念,第3节定义了其他语法。附录C简要总结了CDDL的语义。

2.1. Groups and Composition in CDDL
2.1. CDDL中的群与组成

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 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 pairs but not others. The grammar is based on the concepts of Parsing Expression Grammars (PEGs) (see Appendix A).

CDDL组是组_条目u的列表,每个条目都可以是名称/值对或更复杂的组表达式(然后表示名称/值对序列)。CDDL组是语法中的产物,它匹配某些名称/值对序列,但不匹配其他序列。语法基于解析表达式语法(PEG)的概念(见附录A)。

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 the group specification if not needed). In a map context, the names become the map keys ("member keys").

在数组上下文中,仅表示名称/值对的值;名称仅为注释(如果不需要,可以从组规范中删除)。在映射上下文中,名称成为映射键(“成员键”)。

In an array context, the actual sequence of elements in the group is important, as that sequence is the information that allows associating actual array elements with entries in the group. In a map context, the sequence of entries in a group is not relevant (but there is still a need to write down group entries in a sequence).

在数组上下文中,组中元素的实际顺序很重要,因为该顺序是允许将实际数组元素与组中的条目关联的信息。在映射上下文中,组中的条目序列不相关(但仍需要在序列中写下组条目)。

An array matches a specification given as a group when the group matches a sequence of name/value pairs the value parts of which exactly match the elements of the array in order.

当组匹配名称/值对序列(其值部分按顺序与数组元素完全匹配)时,数组匹配作为组给定的规范。

A map matches a specification given as a group when the group matches a sequence of name/value pairs such that all of these name/value pairs are present in the map and the map has no name/value pair that is not covered by the group.

当组匹配一系列名称/值对时,映射匹配作为组给定的规范,这样所有这些名称/值对都存在于映射中,并且映射没有未包含在组中的名称/值对。

A simple example of using a group directly in a map definition is:

直接在地图定义中使用组的一个简单示例是:

                             person = {
                               age: int,
                               name: tstr,
                               employer: tstr,
                             }
        
                             person = {
                               age: int,
                               name: tstr,
                               employer: tstr,
                             }
        

Figure 1: Using a Group Directly in a Map

图1:直接在地图中使用组

The three entries of the group are written between the curly braces that create the map: here, "age", "name", and "employer" are the names that turn into the map key text strings, and "int" and "tstr" (text string) are the types of the map values under these keys.

组中的三个条目写在创建映射的花括号之间:这里,“年龄”、“姓名”和“雇主”是转换为映射键文本字符串的名称,“int”和“tstr”(文本字符串)是这些键下映射值的类型。

A group by itself (without creating a map around it) can be placed in (round) parentheses and given a name by using it in a rule:

组本身(不在其周围创建地图)可以放在(圆)括号中,并通过在规则中使用它来命名:

                             pii = (
                               age: int,
                               name: tstr,
                               employer: tstr,
                             )
        
                             pii = (
                               age: int,
                               name: tstr,
                               employer: tstr,
                             )
        

Figure 2: A Basic Group

图2:一个基本组

This separate, named group definition allows us to rephrase Figure 1 as:

此单独的命名组定义允许我们将图1重新表述为:

                                person = {
                                  pii
                                }
        
                                person = {
                                  pii
                                }
        

Figure 3: Using a Group by Name

图3:按名称使用组

Note that the (curly) braces signify the creation of a map; the groups themselves are neutral as to whether they will be used in a map or an array.

请注意,(卷曲的)大括号表示地图的创建;对于是否将在地图或数组中使用这些组,这些组本身是中立的。

As shown in Figure 1, the parentheses for groups are optional when there is some other set of brackets present. Note that they can still be used, leading to this not-so-realistic, but perfectly valid, example:

如图1所示,当存在其他一组括号时,组的括号是可选的。请注意,它们仍然可以使用,导致这不太现实,但完全有效,例如:

                             person = {(
                               age: int,
                               name: tstr,
                               employer: tstr,
                             )}
        
                             person = {(
                               age: int,
                               name: tstr,
                               employer: tstr,
                             )}
        

Figure 4: Using a Parenthesized Group in a Map

图4:在地图中使用带括号的组

Groups can be used to factor out common parts of structs, e.g., instead of writing specifications in copy/paste style, such as in Figure 5, one can factor out the common subgroup, choose a name for it, and write only the specific parts into the individual maps (Figure 6).

可以使用组来分解结构的公共部分,例如,不用像图5那样以复制/粘贴方式编写规范,可以分解公共子组,为其选择名称,并只将特定部分写入各个映射(图6)。

                          person = {
                            age: int,
                            name: tstr,
                            employer: tstr,
                          }
        
                          person = {
                            age: int,
                            name: tstr,
                            employer: tstr,
                          }
        
                          dog = {
                            age: int,
                            name: tstr,
                            leash-length: float,
                          }
        
                          dog = {
                            age: int,
                            name: tstr,
                            leash-length: float,
                          }
        

Figure 5: Maps with Copy/Paste

图5:具有复制/粘贴功能的地图

                          person = {
                            identity,
                            employer: tstr,
                          }
        
                          person = {
                            identity,
                            employer: tstr,
                          }
        
                          dog = {
                            identity,
                            leash-length: float,
                          }
        
                          dog = {
                            identity,
                            leash-length: float,
                          }
        
                          identity = (
                            age: int,
                            name: tstr,
                          )
        
                          identity = (
                            age: int,
                            name: tstr,
                          )
        

Figure 6: Using a Group for Factorization

图6:使用组进行因式分解

Note that the lists inside the braces in the above definitions constitute (anonymous) groups, while "identity" is a named group, which can then be included as part of other groups (anonymous as in the example, or themselves named).

请注意,上述定义中大括号内的列表构成(匿名)组,而“identity”是一个命名组,可以将其作为其他组的一部分(如示例中的匿名组或其本身命名组)包含。

2.1.1. Usage
2.1.1. 用法

Groups are the instrument used in composing data structures with CDDL. It is a matter of style in defining those structures whether to define groups (anonymously) right in their contexts or whether to define them in a separate rule and to reference them with their respective name (possibly more than once).

组是使用CDDL组成数据结构的工具。在定义这些结构时,风格是一个问题,是在上下文中定义组(匿名),还是在单独的规则中定义组,并使用各自的名称引用组(可能不止一次)。

With this, one is allowed to define all small parts of their data structures and compose bigger protocol data units with those or to have only one big protocol data unit that has all definitions ad hoc where needed.

这样,就可以定义其数据结构的所有小部分,并用这些小部分组成更大的协议数据单元,或者只有一个大协议数据单元,在需要时具有所有临时定义。

2.1.2. Syntax
2.1.2. 语法

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 组的开始和结束可以用“(“和”)”标记。

o Definitions of entries inside of a group are noted as follows: _keytype => valuetype,_ (read "keytype maps to valuetype"). The comma is actually optional (not just in the final entry), but it 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 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 documentation; see Section 3.4.

o 组内条目的定义如下所示:_keytype=>valuetype,_(读“keytype映射到valuetype”)。逗号实际上是可选的(不仅仅是在最后一个条目中),但是设置它被认为是一种好的样式。在直接使用文本字符串或整数文本作为键的常见情况下,双箭头可以替换为冒号;见第3.5.1节。这也是为文档命名数组元素的常用方法;见第3.4节。

A basic entry consists of a _keytype_ and a _valuetype_, both of which are types (Section 2.2); this entry matches any name/value pair the name of which is in the keytype and the value of which is in the valuetype.

基本条目由一个_keytype_uuu和一个_valuetype_uu组成,这两个类型都是类型(第2.2节);此条目匹配任何名称/值对,其名称在keytype中,其值在valuetype中。

A group defined as a sequence of group entries matches any sequence of name/value pairs that is composed by concatenation in order of what the entries match.

定义为组项序列的组与任何名称/值对序列相匹配,这些名称/值对是按项匹配的顺序串联而成的。

A group definition can also contain choices between groups; see Section 2.2.2.

组定义还可以包含组之间的选择;见第2.2.2节。

2.2. Types
2.2. 类型
2.2.1. Values
2.2.1. 价值观

Values such as numbers and strings can be used in place of a type. (For instance, this is a very common thing to do for a key type, common enough that CDDL provides additional convenience syntax for this.)

可以使用数字和字符串等值代替类型。(例如,对于键类型,这是一种非常常见的操作,非常常见,以至于CDDL为此提供了额外的方便语法。)

The value notation is based on the C language, but does not offer all the syntactic variations (see Appendix B for details). The value notation for numbers inherits from C the distinction between integer values (no fractional part or exponent given -- NR1 [ISO6093]; "NR" stands for "numerical representation") and floating-point values (where a fractional part, an exponent, or both are present -- NR2 or NR3), so the type "1" does not include any floating-point numbers while the types "1e3" and "1.5" are both floating-point numbers and do not include any integer numbers.

值表示法基于C语言,但不提供所有语法变体(详细信息请参见附录B)。数字的值表示法从C继承了整数值(未给出小数部分或指数--NR1[ISO6093];“NR”表示“数字表示”)和浮点值(其中小数部分、指数或两者都存在--NR2或NR3)之间的区别,因此类型“1”不包括任何浮点数,而类型“1e3”和“1.5”都是浮点数,不包括任何整数。

2.2.2. Choices
2.2.2. 选择

Many places that allow a type also allow a choice between types, delimited by a "/" (slash). The entire choice construct can be put into parentheses if this is required to make the construction unambiguous (please see Appendix B for details of the CDDL grammar).

许多允许类型的地方也允许在类型之间进行选择,以“/”(斜杠)分隔。如果需要将整个choice构造放在括号中以使构造明确(请参见附录B了解CDDL语法的详细信息)。

Choices of values can be used to express enumerations:

值的选择可用于表示枚举:

            attire = "bow tie" / "necktie" / "Internet attire"
            protocol = 6 / 17
        
            attire = "bow tie" / "necktie" / "Internet attire"
            protocol = 6 / 17
        

Analogous to types, CDDL also allows choices between groups, delimited by a "//" (double slash). Note that the "//" operator binds much more weakly than the other CDDL operators, so each line within "delivery" in the following example is its own alternative in the group choice:

与类型类似,CDDL还允许在组之间进行选择,以“/”(双斜杠)分隔。请注意“/”运算符的绑定比其他CDDL运算符弱得多,因此下面示例中“delivery”中的每一行在组选择中都是其自己的替代项:

                   address = { delivery }
        
                   address = { delivery }
        
                   delivery = (
                   street: tstr, ? number: uint, city //
                   po-box: uint, city //
                   per-pickup: true )
        
                   delivery = (
                   street: tstr, ? number: uint, city //
                   po-box: uint, city //
                   per-pickup: true )
        
                   city = (
                   name: tstr, zip-code: uint
                   )
        
                   city = (
                   name: tstr, zip-code: uint
                   )
        

A group choice matches the union of the sets of name/value pair sequences that the alternatives in the choice can.

组选项与选项中的备选项可以匹配的名称/值对序列集的并集相匹配。

For both type choices and group choices, additional alternatives can be added to a rule later in separate rules by using "/=" and "//=", respectively, instead of "=":

对于类型选择和组选择,稍后可以分别使用“/=”和“//=”而不是“=”将其他备选方案添加到单独规则中:

attire /= "swimwear"

服装/=“泳装”

                 delivery //= (
                 lat: float, long: float, drone-type: tstr
                 )
        
                 delivery //= (
                 lat: float, long: float, drone-type: tstr
                 )
        

It is not an error if a name is first used with a "/=" or "//=" (there is no need to "create it" with "=").

如果名称第一次与“/=”或“//=”(不需要用“=”来“创建它”)一起使用,则不是错误。

2.2.2.1. Ranges
2.2.2.1. 范围

Instead of naming all the values that make up a choice, CDDL allows building a _range_ out of two values that are in an ordering relationship: a lower bound (first value) and an upper bound (second value). A range can be inclusive of both bounds given (denoted by joining two values by ".."), or it can include the lower bound and exclude the upper bound (denoted by instead using "..."). If the lower bound exceeds the upper bound, the resulting type is the empty set (this behavior can be desirable when generics (Section 3.10) are being used).

CDDL不需要命名组成选项的所有值,而是允许从排序关系中的两个值中构建一个_range uu:下限(第一个值)和上限(第二个值)。一个范围可以包含给定的两个边界(用“.”连接两个值表示),也可以包含下限而排除上限(用“…”表示)。如果下限超过上限,则结果类型为空集(当使用泛型(第3.10节)时,这种行为可能是可取的)。

         device-address = byte
         max-byte = 255
         byte = 0..max-byte ; inclusive range
         first-non-byte = 256
         byte1 = 0...first-non-byte ; byte1 is equivalent to byte
        
         device-address = byte
         max-byte = 255
         byte = 0..max-byte ; inclusive range
         first-non-byte = 256
         byte1 = 0...first-non-byte ; byte1 is equivalent to byte
        

CDDL currently only allows ranges between integers (matching integer values) or between floating-point values (matching floating-point values). If both are needed in a type, a type choice between the two kinds of ranges can be (clumsily) used:

CDDL目前只允许整数之间(匹配整数值)或浮点值之间(匹配浮点值)的范围。如果类型中同时需要这两种类型,则可以(笨拙地)使用两种范围之间的类型选择:

                int-range = 0..10 ; only integers match
                float-range = 0.0..10.0 ; only floats match
                BAD-range1 = 0..10.0 ; NOT DEFINED
                BAD-range2 = 0.0..10 ; NOT DEFINED
                numeric-range = int-range / float-range
        
                int-range = 0..10 ; only integers match
                float-range = 0.0..10.0 ; only floats match
                BAD-range1 = 0..10.0 ; NOT DEFINED
                BAD-range2 = 0.0..10 ; NOT DEFINED
                numeric-range = int-range / float-range
        

(See also the control operators .lt/.ge and .le/.gt in Section 3.8.6.)

(另请参见第3.8.6节中的控制运算符.lt/.ge和.le/.gt。)

Note that the dot is a valid name continuation character in CDDL, so

请注意,点在CDDL中是一个有效的名称延续字符,因此

min..max

最小..最大

is not a range expression but a single name. When using a name as the left-hand side of a range operator, use spacing as in

不是范围表达式,而是单个名称。将名称用作范围运算符的左侧时,请使用间距,如中所示

min .. max

闵。。最大值

to separate off the range operator.

要分离范围运算符。

2.2.2.2. Turning a Group into a Choice
2.2.2.2. 把一个群体变成一种选择

Some choices are built out of large numbers of values, often integers, each of which is best given a semantic name in the specification. Instead of naming each of these integers and then accumulating them into a choice, CDDL allows building a choice from a group by prefixing it with an "&" character:

有些选择是由大量的值(通常是整数)构成的,每个值最好在规范中给出一个语义名称。CDDL不需要命名这些整数中的每一个,然后将它们累加到一个选项中,而是允许通过在组前面加一个“&”字符来构建一个选项:

              terminal-color = &basecolors
              basecolors = (
                black: 0,  red: 1,  green: 2,  yellow: 3,
                blue: 4,  magenta: 5,  cyan: 6,  white: 7,
              )
              extended-color = &(
                basecolors,
                orange: 8,  pink: 9,  purple: 10,  brown: 11,
              )
        
              terminal-color = &basecolors
              basecolors = (
                black: 0,  red: 1,  green: 2,  yellow: 3,
                blue: 4,  magenta: 5,  cyan: 6,  white: 7,
              )
              extended-color = &(
                basecolors,
                orange: 8,  pink: 9,  purple: 10,  brown: 11,
              )
        

As with the use of groups in arrays (Section 3.4), the member names have only documentary value (in particular, they might be used by a tool when displaying integers that are taken from that choice).

与在数组中使用组一样(第3.4节),成员名称只有文档值(特别是,当显示从该选项中获取的整数时,工具可能会使用它们)。

2.2.3. Representation Types
2.2.3. 表示类型

CDDL allows the specification of a data item type by referring to the CBOR representation (specifically, to major types and additional information; see Section 2 of [RFC7049]). How this is used should be evident from the prelude (Appendix D): a hash mark ("#") optionally followed by a number from 0 to 7 identifying the major type, which then can be followed by a dot and a number specifying the additional information. This construction specifies the set of values that can be serialized in CBOR (i.e., "any"), by the given major type if one is given, or by the given major type with the additional information if both are given. Where a major type of 6 (Tag) is used, the type of the tagged item can be specified by appending it in parentheses.

CDDL允许通过引用CBOR表示(特别是主要类型和附加信息;参见[RFC7049]第2节)来指定数据项类型。从序言(附录D)中可以看出这一点的使用方式:一个散列标记(“#”)后跟一个从0到7的数字,标识主要类型,然后可以后跟一个点和一个指定附加信息的数字。这种结构指定了一组值,这些值可以在CBOR(即“任意”)中通过给定的主类型(如果给定了一个)序列化,或者通过给定的主类型(如果两者都给定)序列化。如果使用主要类型6(标记),则可以通过在括号中添加标记项来指定标记项的类型。

Note that although this notation is based on the CBOR serialization, it is about a set of values at the data model level, e.g., "#7.25" specifies the set of values that can be represented as half-precision floats; it does not mandate that these values also do have to be serialized as half-precision floats: CDDL does not provide any language means to restrict the choice of serialization variants. This also enables the use of CDDL with JSON, which uses a fundamentally different way of serializing (some of) the same values.

请注意,尽管此表示法基于CBOR序列化,但它是关于数据模型级别的一组值,例如,“7.25”指定可以表示为半精度浮点的一组值;它并不要求这些值也必须序列化为半精度浮点:CDDL不提供任何语言手段来限制序列化变量的选择。这也支持将CDDL与JSON结合使用,它使用了一种根本不同的方式来序列化(某些)相同的值。

It may be necessary to make use of representation types outside the prelude, e.g., a specification could start by making use of an existing tag in a more specific way or could define a new tag not defined in the prelude:

可能需要使用序曲之外的表示类型,例如,规范可以从以更具体的方式使用现有标记开始,或者可以定义序曲中未定义的新标记:

      my_breakfast = #6.55799(breakfast)   ; cbor-any is too general!
      breakfast = cereal / porridge
      cereal = #6.998(tstr)
      porridge = #6.999([liquid, solid])
      liquid = milk / water
      milk = 0
      water = 1
      solid = tstr
        
      my_breakfast = #6.55799(breakfast)   ; cbor-any is too general!
      breakfast = cereal / porridge
      cereal = #6.998(tstr)
      porridge = #6.999([liquid, solid])
      liquid = milk / water
      milk = 0
      water = 1
      solid = tstr
        
2.2.4. Root Type
2.2.4. 根型

There is no special syntax to identify the root of a CDDL data structure definition: that role is simply taken by the first rule defined in the file.

没有特殊的语法来标识CDDL数据结构定义的根:该角色仅由文件中定义的第一条规则承担。

This is motivated by the usual top-down approach for defining data structures, decomposing a big data structure unit into smaller parts; however, except for the root type, there is no need to strictly follow this sequence.

这是由通常的自上而下的方法来定义数据结构,将大数据结构单元分解为更小的部分;但是,除了根类型之外,没有必要严格遵循此顺序。

(Note that there is no way to use a group as a root -- it must be a type.)

(请注意,无法将组用作根,它必须是类型。)

3. Syntax
3. 语法

In this section, the overall syntax of CDDL is shown, alongside some examples just illustrating syntax. (The definition does not attempt to be overly formal; refer to Appendix B for details.)

在本节中,将展示CDDL的总体语法,以及一些仅说明语法的示例。(该定义并不试图过于正式;有关详细信息,请参阅附录B。)

3.1. General Conventions
3.1. 一般公约

The basic syntax is inspired by ABNF [RFC5234], with the following:

基本语法受ABNF[RFC5234]的启发,如下所示:

o Rules, whether they define groups or types, are defined with a name, followed by an equals sign "=" and the actual definition according to the respective syntactic rules of that definition.

o 规则,无论是定义组还是类型,都是用名称定义的,后面跟一个等号“=”和根据该定义各自的语法规则定义的实际定义。

o A name can consist of any of the characters from the set {"A" to "Z", "a" to "z", "0" to "9", "_", "-", "@", ".", "$"}, starting with an alphabetic character (including "@", "_", "$") and ending in such a character or a digit.

o 名称可以由以下任意字符组成{“A”到“Z”、“A”到“Z”、“0”到“9”、“”、“-”、“@”、“$”},以字母字符(包括“@”、“”、“$”)开头,以这样的字符或数字结尾。

* Names are case sensitive.

* 名称区分大小写。

* It is preferred style to start a name with a lowercase letter.

* 首选的样式是以小写字母开头的名称。

* The hyphen is preferred over the underscore (except in a "bareword" (Section 3.5.1), where the semantics may actually require an underscore).

* 连字符优先于下划线(除了“裸字”(第3.5.1节),其中语义可能实际需要下划线)。

* The period may be useful for larger specifications, to express some module structure (as in "tcp.throughput" vs. "udp.throughput").

* 这段时间对于更大的规范可能有用,以表示某些模块结构(如“tcp.throughts”与“udp.throughts”)。

* A number of names are predefined in the CDDL prelude, as listed in Appendix D.

* CDDL序言中预先定义了许多名称,如附录D所示。

* Rule names (types or groups) do not appear in the actual CBOR encoding, but names used as "barewords" in member keys do.

* 规则名称(类型或组)不会出现在实际的CBOR编码中,但在成员键中用作“裸字”的名称会出现。

o Comments are started by a ";" (semicolon) character and finish at the end of a line (LF or CRLF).

o 注释以“;”(分号)字符开头,在一行(LF或CRLF)末尾结束。

o Except within strings, whitespace (spaces, newlines, and comments) is used to separate syntactic elements for readability (and to separate identifiers, range operators, or numbers that follow each other); it is otherwise completely optional.

o 除了字符串之外,空格(空格、换行符和注释)用于分隔语法元素以提高可读性(以及分隔标识符、范围运算符或后面的数字);否则它是完全可选的。

o Hexadecimal numbers are preceded by "0x" (without quotes) and are case insensitive. Similarly, binary numbers are preceded by "0b".

o 十六进制数前加“0x”(不带引号),不区分大小写。类似地,二进制数前面有“0b”。

o Text strings are enclosed by double quotation '"' characters. They follow the conventions for strings as defined in Section 7 of [RFC8259]. (ABNF users may want to note that there is no support in CDDL for the concept of case insensitivity in text strings; if necessary, regular expressions can be used (Section 3.8.3).)

o 文本字符串由双引号“.”字符括起。它们遵循[RFC8259]第7节中定义的字符串惯例。(ABNF用户可能希望注意,CDDL中不支持文本字符串中不区分大小写的概念;如有必要,可以使用正则表达式(第3.8.3节)。)

o Byte strings are enclosed by single quotation "'" characters and may be prefixed by "h" or "b64". If unprefixed, the string is interpreted as with a text string, except that single quotes must be escaped and that the resulting UTF-8 bytes are marked as a byte string (major type 2). If prefixed as "h" or "b64", the string is interpreted as a sequence of pairs of hex digits (base16; see Section 8 of [RFC4648]) or a base64(url) string (Section 4 or Section 5 of [RFC4648]), respectively (as with the diagnostic notation in Section 6 of [RFC7049]; cf. Appendix G.2); any whitespace present within the string (including comments) is ignored in the prefixed case.

o 字节字符串由单引号“'”字符括起,前缀可以是“h”或“b64”。如果不固定,字符串将被解释为文本字符串,但必须转义单引号,并且生成的UTF-8字节被标记为字节字符串(主类型2)。如果前缀为“h”或“b64”,则该字符串分别被解释为一组十六进制数字(base16;参见[RFC4648]第8节)或base64(url)字符串(参见[RFC4648]第4节或第5节)(与[RFC7049]第6节中的诊断符号相同;参见附录G.2);在带前缀的情况下,字符串中存在的任何空白(包括注释)都将被忽略。

o CDDL uses UTF-8 [RFC3629] for its encoding. Processing of CDDL does not involve Unicode normalization processes.

o CDDL使用UTF-8[RFC3629]进行编码。CDDL的处理不涉及Unicode规范化过程。

Example:

例子:

                    ; This is a comment
                    person = { g }
        
                    ; This is a comment
                    person = { g }
        
                    g = (
                      "name": tstr,
                      age: int,  ; "age" is a bareword
                    )
        
                    g = (
                      "name": tstr,
                      age: int,  ; "age" is a bareword
                    )
        
3.2. Occurrence
3.2. 发生

An optional _occurrence_ indicator can be given in front of a group entry. It is either (1) one of the characters "?" (optional), "*" (zero or more), or "+" (one or more) or (2) of the form n*m, where n and m are optional unsigned integers and n is the lower limit (default 0) and m is the upper limit (default no limit) of occurrences.

可以在组条目前面提供可选的_出现u指示符。它是形式为n*m的(1)个字符“?”(可选)、“*”(零或多个)或“+”(一个或多个)或(2),其中n和m是可选的无符号整数,n是出现次数的下限(默认为0),m是出现次数的上限(默认为无限制)。

If no occurrence indicator is specified, the group entry is to occur exactly once (as if 1*1 were specified). A group entry with an occurrence indicator matches sequences of name/value pairs that are composed by concatenating a number of sequences that the basic group entry matches, where the number needs to be allowed by the occurrence indicator.

如果未指定发生指示符,则组条目将恰好发生一次(如同指定了1*1)。带有引用指示符的组条目匹配名称/值对序列,这些名称/值对由基本组条目匹配的多个序列串联而成,其中引用指示符需要允许该数字。

Note that CDDL, outside any directives/annotations that could possibly be defined, does not make any prescription as to whether arrays or maps use definite-length or indefinite-length encoding. That is, there is no correlation between leaving the size of an array "open" in the spec and the fact that it is then interchanged with definite or indefinite length.

请注意,除了可能定义的任何指令/注释之外,CDDL并没有对数组或映射使用定长编码还是不定长编码做出任何规定。也就是说,在规范中保持数组的大小为“打开”与它随后以确定或不确定的长度交换这一事实之间没有关联。

Please also note that CDDL can describe flexibility that the data model of the target representation does not have. This is rather obvious for JSON but is also relevant for CBOR:

还请注意,CDDL可以描述目标表示的数据模型所不具备的灵活性。这对于JSON来说非常明显,但对于CBOR来说也很重要:

                           apartment = {
                             kitchen: size,
                             * bedroom: size,
                           }
                           size = float ; in m2
        
                           apartment = {
                             kitchen: size,
                             * bedroom: size,
                           }
                           size = float ; in m2
        

The previous specification does not mean that CBOR is changed to allow using the key "bedroom" more than once. In other words, due to the restrictions imposed by the data model, the third line pretty much turns into:

先前的规范并不意味着CBOR被更改为允许多次使用钥匙“卧室”。换句话说,由于数据模型施加的限制,第三行几乎变成:

? bedroom: size,

? 卧室:大小,

(Occurrence indicators beyond one are still useful in maps for groups that allow a variety of keys.)

(对于允许使用多种关键点的组,超过1的出现指示器在地图中仍然很有用。)

3.3. Predefined Names for Types
3.3. 类型的预定义名称

CDDL predefines a number of names. This subsection summarizes these names, but please see Appendix D for the exact definitions.

CDDL预定义了许多名称。本小节总结了这些名称,但具体定义请参见附录D。

The following keywords for primitive datatypes are defined:

定义了基本数据类型的以下关键字:

"bool" Boolean value (major type 7, additional information 20 or 21).

“布尔”布尔值(主要类型7,附加信息20或21)。

"uint" An unsigned integer (major type 0).

“uint”是一个无符号整数(主类型为0)。

"nint" A negative integer (major type 1).

“nint”是一个负整数(主要类型1)。

"int" An unsigned integer or a negative integer.

“int”是无符号整数或负整数。

"float16" A number representable as a half-precision float [IEEE754] (major type 7, additional information 25).

“float16”表示为半精度浮点的数字[IEEE754](主要类型7,附加信息25)。

"float32" A number representable as a single-precision float [IEEE754] (major type 7, additional information 26).

“float32”表示为单精度浮点的数字[IEEE754](主要类型7,附加信息26)。

"float64" A number representable as a double-precision float [IEEE754] (major type 7, additional information 27).

“float64”表示为双精度浮点的数字[IEEE754](主要类型7,附加信息27)。

"float" One of float16, float32, or float64.

“浮点”浮点16、浮点32或浮点64中的一个。

"bstr" or "bytes" A byte string (major type 2).

“bstr”或“bytes”字节字符串(主要类型2)。

"tstr" or "text" Text string (major type 3).

“tstr”或“文本”文本字符串(主要类型3)。

(Note that there are no predefined names for arrays or maps; these are defined with the syntax given below.)

(请注意,数组或映射没有预定义的名称;它们是使用下面给出的语法定义的。)

In addition, a number of types are defined in the prelude that are associated with CBOR tags, such as "tdate", "bigint", "regexp", etc.

此外,前奏曲中定义了许多与CBOR标记相关的类型,如“tdate”、“bigint”、“regexp”等。

3.4. Arrays
3.4. 阵列

Array definitions surround a group with square brackets.

数组定义用方括号括住一个组。

For each entry, an occurrence indicator as specified in Section 3.2 is permitted.

对于每个条目,允许使用第3.2节中规定的事件指示器。

For example:

例如:

                     unlimited-people = [* person]
                     one-or-two-people = [1*2 person]
                     at-least-two-people = [2* person]
                     person = (
                         name: tstr,
                         age: uint,
                     )
        
                     unlimited-people = [* person]
                     one-or-two-people = [1*2 person]
                     at-least-two-people = [2* person]
                     person = (
                         name: tstr,
                         age: uint,
                     )
        

The group "person" is defined in such a way that repeating it in the array each time generates alternating names and ages, so these are four valid values for a data item of type "unlimited-people":

组“person”的定义方式是,每次在数组中重复它都会生成交替的姓名和年龄,因此对于类型为“unlimited people”的数据项,这是四个有效值:

      ["roundlet", 1047, "psychurgy", 2204, "extrarhythmical", 2231]
      []
      ["aluminize", 212, "climograph", 4124]
      ["penintime", 1513, "endocarditis", 4084, "impermeator", 1669,
       "coextension", 865]
        
      ["roundlet", 1047, "psychurgy", 2204, "extrarhythmical", 2231]
      []
      ["aluminize", 212, "climograph", 4124]
      ["penintime", 1513, "endocarditis", 4084, "impermeator", 1669,
       "coextension", 865]
        
3.5. Maps
3.5. 地图

The syntax for specifying maps merits special attention, as well as a number of optimizations and conveniences, as it is likely to be the focal point of many specifications employing CDDL. While the syntax does not strictly distinguish struct and table usage of maps, it caters specifically to each of them.

指定映射的语法值得特别注意,还有许多优化和便利,因为它可能是使用CDDL的许多规范的焦点。虽然语法没有严格区分映射的结构和表用法,但它专门针对它们中的每一个。

But first, let's reiterate a feature of CBOR that it has inherited from JSON: the key/value pairs in CBOR maps have no fixed ordering. (One could imagine situations where fixing the ordering may be of use. For example, a decoder could look for values related with integer keys 1, 3, and 7. If the order were fixed and the decoder encounters the key 4 without having encountered key 3, it could conclude that key 3 is not available without doing more complicated bookkeeping. Unfortunately, neither JSON nor CBOR supports this, so no attempt was made to support this in CDDL either.)

但首先,让我们重申CBOR从JSON继承的一个特性:CBOR映射中的键/值对没有固定的顺序。(人们可以想象,在某些情况下,修复顺序可能很有用。例如,解码器可以查找与整数键1、3和7相关的值。如果顺序是固定的,并且解码器遇到键4而没有遇到键3,则可以得出结论,如果不进行更复杂的簿记,则键3不可用。不可原谅。)实际上,JSON和CBOR都不支持这一点,因此也没有尝试在CDDL中支持这一点。)

3.5.1. Structs
3.5.1. 结构体

The "struct" usage of maps is similar to the way JSON objects are used in many JSON applications.

映射的“struct”用法类似于许多JSON应用程序中使用JSON对象的方式。

A map is defined in the same way as that for defining an array (see Section 3.4), except for using curly braces "{}" instead of square brackets "[]".

除了使用大括号“{}”而不是方括号“[]”之外,映射的定义方式与定义数组的定义方式相同(参见第3.4节)。

An occurrence indicator as specified in Section 3.2 is permitted for each group entry.

第3.2节中规定的事件指示器允许用于每个组条目。

The following is an example of a record with a structure embedded:

以下是嵌入结构的记录示例:

       Geography = [
         city           : tstr,
         gpsCoordinates : GpsCoordinates,
       ]
        
       Geography = [
         city           : tstr,
         gpsCoordinates : GpsCoordinates,
       ]
        
       GpsCoordinates = {
         longitude      : uint,            ; degrees, scaled by 10^7
         latitude       : uint,            ; degrees, scaled by 10^7
       }
        
       GpsCoordinates = {
         longitude      : uint,            ; degrees, scaled by 10^7
         latitude       : uint,            ; degrees, scaled by 10^7
       }
        

When encoding, the Geography record is encoded using a CBOR array with two members (the keys for the group entries are ignored), whereas the GpsCoordinates structure is encoded as a CBOR map with two key/value pairs.

编码时,使用具有两个成员的CBOR数组对地理记录进行编码(忽略组条目的键),而GpsCoordinates结构则编码为具有两个键/值对的CBOR映射。

Types used in a structure can be defined in separate rules or just in place (potentially placed inside parentheses, such as for choices). For example:

结构中使用的类型可以在单独的规则中定义,也可以就地定义(可能放在括号内,例如用于选择)。例如:

                           located-samples = {
                             sample-point: int,
                             samples: [+ float],
                           }
        
                           located-samples = {
                             sample-point: int,
                             samples: [+ float],
                           }
        

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. 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 (we speak of a "bareword" member key), as can a double-quoted string or a number. (When other types -- in particular, types that contain more than one value -- are used as the types of keys, they are followed by a double arrow; see below.)

其中,“located samples”是引用结构时要使用的数据类型,“sample point”和“samples”是要使用的键。这实际上是一个完整的示例:后跟冒号的标识符可以直接用作成员键的文本字符串(我们称之为“裸字”成员键),双引号字符串或数字也可以。(当其他类型(特别是包含多个值的类型)用作键的类型时,它们后面跟着一个双箭头;请参见下文。)

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 text string syntax can also be used in the member key position, followed by a colon. The above example could therefore have been written with quoted strings in the member key positions.

如果文本字符串键与标识符的语法不匹配(或者说明符恰好更喜欢使用双引号),也可以在成员键位置使用文本字符串语法,后跟冒号。因此,上面的示例可以在成员键位置使用带引号的字符串编写。

More generally, types specified in ways other than those listed for the cases described above can be used in a key-type position by following them with a double arrow -- in particular, the double arrow is necessary 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 = {
                           "sample-point" => int,
                           "samples" => [+ float],
                         }
        
                         located-samples = {
                           "sample-point" => int,
                           "samples" => [+ float],
                         }
        

See Section 3.5.4 below for how the colon (":") shortcut described here also adds some implied semantics.

请参阅下面的第3.5.4节,了解此处描述的冒号(“:”)快捷方式如何添加一些隐含语义。

A better way to demonstrate the use of the double arrow may be:

演示双箭头使用的更好方法可能是:

             located-samples = {
               sample-point: int,
               samples: [+ float],
               * equipment-type => equipment-tolerances,
             }
             equipment-type = [name: tstr, manufacturer: tstr]
             equipment-tolerances = [+ [float, float]]
        
             located-samples = {
               sample-point: int,
               samples: [+ float],
               * equipment-type => equipment-tolerances,
             }
             equipment-type = [name: tstr, manufacturer: tstr]
             equipment-tolerances = [+ [float, float]]
        

The example below defines a struct with optional entries: display name (as a text string), the name components first name and family name (as text strings), and age information (as an unsigned integer).

下面的示例定义了一个具有可选项的结构:显示名称(作为文本字符串)、名称组件名和姓氏(作为文本字符串)以及年龄信息(作为无符号整数)。

                          PersonalData = {
                            ? displayName: tstr,
                            NameComponents,
                            ? age: uint,
                          }
        
                          PersonalData = {
                            ? displayName: tstr,
                            NameComponents,
                            ? age: uint,
                          }
        
                          NameComponents = (
                            ? firstName: tstr,
                            ? familyName: tstr,
                          )
        
                          NameComponents = (
                            ? firstName: tstr,
                            ? familyName: tstr,
                          )
        

Note that the group definition for NameComponents does not generate another map; instead, all four keys are directly in the struct built by PersonalData.

请注意,NameComponents的组定义不会生成另一个映射;相反,所有四个键都直接位于PersonalData构建的结构中。

In this example, all key/value pairs are optional from the perspective of CDDL. With no occurrence indicator, an entry is mandatory.

在本例中,从CDDL的角度来看,所有键/值对都是可选的。如果没有发生指示器,则必须输入。

If the addition of more entries not specified by the current specification is desired, one can add this possibility explicitly:

如果需要添加当前规范未指定的更多条目,可以明确添加这种可能性:

                          PersonalData = {
                            ? displayName: tstr,
                            NameComponents,
                            ? age: uint,
                            * tstr => any
                          }
        
                          PersonalData = {
                            ? displayName: tstr,
                            NameComponents,
                            ? age: uint,
                            * tstr => any
                          }
        
                          NameComponents = (
                            ? firstName: tstr,
                            ? familyName: tstr,
                          )
        
                          NameComponents = (
                            ? firstName: tstr,
                            ? familyName: tstr,
                          )
        

Figure 7: Personal Data: Example for Extensibility

图7:个人数据:扩展性示例

The CDDL tool described in Appendix F generated the following as one acceptable instance for this specification:

附录F中描述的CDDL工具生成了以下内容,作为本规范的一个可接受实例:

         {"familyName": "agust", "antiforeignism": "pretzel",
          "springbuck": "illuminatingly", "exuviae": "ephemeris",
          "kilometrage": "frogfish"}
        
         {"familyName": "agust", "antiforeignism": "pretzel",
          "springbuck": "illuminatingly", "exuviae": "ephemeris",
          "kilometrage": "frogfish"}
        

(See Section 3.9 for one way to explicitly identify an extension point.)

(有关明确标识扩展点的方法,请参见第3.9节。)

3.5.2. Tables
3.5.2. 桌子

A table can be specified by defining a map with entries where the key type allows more than just a single value; for example:

表可以通过定义一个映射来指定,其中键类型允许不止一个值;例如:

                         square-roots = {* x => y}
                         x = int
                         y = float
        
                         square-roots = {* x => y}
                         x = int
                         y = float
        

Here, the key in each key/value pair has datatype x (defined as int), and the value has datatype y (defined as float).

这里,每个键/值对中的键具有数据类型x(定义为int),值具有数据类型y(定义为float)。

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 predefined name "any".

如果规范不需要限制x或y中的一个(即,应用程序可以自由选择每个条目),则可以用预定义的名称“any”替换。

As another example, the following could be used as a conversion table converting from an integer or float to a string:

作为另一个示例,以下内容可用作从整数或浮点转换为字符串的转换表:

                      tostring = {* mynumber => tstr}
                      mynumber = int / float
        
                      tostring = {* mynumber => tstr}
                      mynumber = int / float
        
3.5.3. Non-deterministic Order
3.5.3. 非确定序

While the way arrays are matched is fully determined by the PEG formalism (see Appendix A), matching is more complicated for maps, as maps do not have an inherent order. For each candidate name/value pair that the PEG algorithm would try, a matching member is picked out of the entire map. For certain group expressions, more than one member in the map may match. Most often, this is inconsequential, as the group expression tends to consume all matches:

虽然数组的匹配方式完全由PEG形式主义决定(见附录A),但匹配对于贴图来说更为复杂,因为贴图没有固有的顺序。对于PEG算法将尝试的每个候选名称/值对,将从整个映射中选择一个匹配的成员。对于某些组表达式,映射中可能有多个成员匹配。大多数情况下,这是无关紧要的,因为组表达式倾向于使用所有匹配项:

                            labeled-values = {
                              ? fritz: number,
                              * label => value
                            }
                            label = text
                            value = number
        
                            labeled-values = {
                              ? fritz: number,
                              * label => value
                            }
                            label = text
                            value = number
        

Here, if any member with the key "fritz" is present, this will be picked by the first entry of the group; all remaining text/number members will be picked by the second entry (and if anything remains unpicked, the map does not match).

在这里,如果有键为“fritz”的成员出现,则该组的第一个条目将选择该成员;第二个条目将拾取所有剩余的文本/编号成员(如果有任何内容未拾取,则地图不匹配)。

However, it is possible to construct group expressions where what is actually picked is indeterminate, but does matter:

但是,可以在实际拾取的内容不确定的情况下构造组表达式,但这并不重要:

                            do-not-do-this = {
                              int => int,
                              int => 6,
                            }
        
                            do-not-do-this = {
                              int => int,
                              int => 6,
                            }
        

When this expression is matched against "{3: 5, 4: 6}", the first group entry might pick off the "3: 5", leaving "4: 6" for matching the second one. Or it might pick off "4: 6", leaving nothing for the second entry. This pathological non-determinism is caused by specifying "more general" before "more specific" and by having a general rule that only consumes a subset of the map key/value pairs that it is able to match -- both tend not to occur in real-world specifications of maps. At the time of writing, CDDL tools cannot detect such cases automatically, and for the present version of the CDDL specification, the specification writer is simply urged to not write pathologically non-deterministic specifications.

当这个表达式与{3:5,4:6}匹配时,第一个组条目可能会去掉“3:5”,留下“4:6”来匹配第二个组条目。或者它可能会选择“4:6”,第二次输入时不会留下任何内容。这种病态的不确定性是由于在“更具体”之前指定了“更一般”,并且有一个只使用它能够匹配的映射键/值对子集的一般规则造成的——这两种情况在现实世界的映射规范中都不会发生。在编写时,CDDL工具无法自动检测此类情况,对于CDDL规范的当前版本,规范编写者只需敦促不要编写病态的非确定性规范。

(The astute reader will be reminded of what was called "ambiguous content models" in the Standard Generalized Markup Language (SGML) and "non-deterministic content models" in XML. That problem is related to the one described here, but the problem here is specifically caused by the lack of order in maps, something that the XML schema languages do not have to contend with. Note that RELAX NG's "interleave" pattern handles lack of order explicitly on the specification side, while the instances in XML always have determinate order.)

(精明的读者会想起标准通用标记语言(SGML)中所谓的“不明确内容模型”和“非确定性内容模型”在XML中。这个问题与这里描述的问题有关,但这里的问题是由映射中缺少顺序造成的,这是XML模式语言不必解决的问题。请注意RELAXNG的“交错”模式在规范方面显式地处理缺少顺序的问题,而XML中的实例总是具有确定的顺序。)

3.5.4. Cuts in Maps
3.5.4. 地图裁剪

The extensibility idiom discussed above for structs has one problem:

上面讨论的结构的可扩展性习惯用法有一个问题:

                        extensible-map-example = {
                          ? "optional-key" => int,
                          * tstr => any
                        }
        
                        extensible-map-example = {
                          ? "optional-key" => int,
                          * tstr => any
                        }
        

In this example, there is one optional key "optional-key", which, when present, maps to an integer. There is also a wildcard for any future additions.

在本例中,有一个可选键“optional key”,它在出现时映射到一个整数。还有一个通配符用于将来的任何添加。

Unfortunately, the data item

不幸的是,数据项

                      { "optional-key": "nonsense" }
        
                      { "optional-key": "nonsense" }
        

does match this specification: while the first entry of the group does not match, the second one (the wildcard) does. This may very well be desirable (e.g., if a future extension is to be allowed to extend the type of "optional-key"), but in many cases it isn't.

是否匹配此规范:组的第一个条目不匹配,第二个条目(通配符)不匹配。这可能非常理想(例如,如果允许将来的扩展扩展“可选密钥”的类型),但在许多情况下并非如此。

In anticipation of a more general potential feature called "cuts", CDDL allows inserting a cut "^" into the definition of the map entry:

预计将有一个更通用的潜在功能称为“切割”,CDDL允许在地图条目的定义中插入切割“^”:

                       extensible-map-example = {
                         ? "optional-key" ^ => int,
                         * tstr => any
                       }
        
                       extensible-map-example = {
                         ? "optional-key" ^ => int,
                         * tstr => any
                       }
        

A cut in this position means that once the member key matches the name part of an entry that carries a cut, other potential matches for the key of the member that occur in later entries in the group of the map are no longer allowed. In other words, when a group entry would pick a key/value pair based on just a matching key, it "locks in" the pick -- this rule applies, independently of whether the value matches

此位置的剪切意味着,一旦成员键与带有剪切的条目的名称部分匹配,则不再允许在映射组的后续条目中出现该成员键的其他潜在匹配。换句话说,当一个组条目仅基于一个匹配的键来选择一个键/值对时,它会“锁定”选择——这条规则适用,与值是否匹配无关

as well, so when it does not, the entire map fails to match. In summary, the example above no longer matches the specification as modified with the cut.

同样,如果不匹配,则整个地图无法匹配。总之,上面的示例不再与使用切割修改的规范匹配。

Since the desire for this kind of exclusive matching is so frequent, the ":" shortcut is actually defined to include the cut semantics. So, the preceding example (including the cut) can be written more simply as:

由于对这种排他匹配的需求非常频繁,因此“:”快捷方式实际上被定义为包含剪切语义。因此,前面的示例(包括切割)可以更简单地写成:

                        extensible-map-example = {
                          ? "optional-key": int,
                          * tstr => any
                        }
        
                        extensible-map-example = {
                          ? "optional-key": int,
                          * tstr => any
                        }
        

or even shorter, using a bareword for the key:

甚至更短,用一个单词作为关键字:

                        extensible-map-example = {
                          ? optional-key: int,
                          * tstr => any
                        }
        
                        extensible-map-example = {
                          ? optional-key: int,
                          * tstr => any
                        }
        
3.6. Tags
3.6. 标签

A type can make use of a CBOR tag (major type 6) by using the representation type notation, giving #6.nnn(type) where nnn is an unsigned integer giving the tag number and "type" is the type of the data item being tagged.

类型可以通过使用表示类型表示法使用CBOR标记(主要类型6),给出#6.nnn(类型),其中nnn是给出标记号的无符号整数,“type”是被标记的数据项的类型。

For example, the following line from the CDDL prelude (Appendix D) defines "biguint" as a type name for an unsigned bignum N:

例如,CDDL序言(附录D)中的以下行将“biguint”定义为无符号bignum N的类型名:

                           biguint = #6.2(bstr)
        
                           biguint = #6.2(bstr)
        

The tags defined by [RFC7049] are included in the prelude. Additional tags registered since [RFC7049] was written need to be added to a CDDL specification as needed; e.g., a binary Universally Unique Identifier (UUID) tag could be referenced as "buuid" in a specification after defining

[RFC7049]定义的标签包含在序言中。自[RFC7049]编写以来注册的其他标签需要根据需要添加到CDDL规范中;e、 例如,一个二进制通用唯一标识符(UUID)标签在定义后可以在规范中引用为“buuid”

                            buuid = #6.37(bstr)
        
                            buuid = #6.37(bstr)
        

In the following example, usage of tag 32 for URIs is optional:

在以下示例中,URI的标记32的使用是可选的:

                        my_uri = #6.32(tstr) / tstr
        
                        my_uri = #6.32(tstr) / tstr
        
3.7. Unwrapping
3.7. 展开

The group that is used to define a map or an array can often be reused in the definition of another map or array. Similarly, a type defined as a tag carries an internal data item that one would like to refer to. In these cases, it is expedient to simply use the name of the map, array, or tag type as a handle for the group or type defined inside it.

用于定义映射或数组的组通常可以在另一映射或数组的定义中重用。类似地,定义为标记的类型携带希望引用的内部数据项。在这些情况下,只需使用映射、数组或标记类型的名称作为在其中定义的组或类型的句柄,就很方便了。

The "unwrap" operator (written by preceding a name by a tilde character "~") can be used to strip the type defined for a name by one layer, exposing the underlying group (for maps and arrays) or type (for tags).

“展开”操作符(在名称前面加上波浪号“~”)可用于将为名称定义的类型剥离一层,从而公开基础组(用于贴图和数组)或类型(用于标记)。

For example, an application might want to define a basic header and an advanced header. Without unwrapping, this might be done as follows:

例如,应用程序可能需要定义基本标头和高级标头。在不展开的情况下,可以按如下方式进行:

             basic-header-group = (
               field1: int,
               field2: text,
             )
        
             basic-header-group = (
               field1: int,
               field2: text,
             )
        
             basic-header = [ basic-header-group ]
        
             basic-header = [ basic-header-group ]
        
             advanced-header = [
               basic-header-group,
               field3: bytes,
               field4: number, ; as in the tagged type "time"
             ]
        
             advanced-header = [
               basic-header-group,
               field3: bytes,
               field4: number, ; as in the tagged type "time"
             ]
        

Unwrapping simplifies this to:

展开将此简化为:

                            basic-header = [
                              field1: int,
                              field2: text,
                            ]
        
                            basic-header = [
                              field1: int,
                              field2: text,
                            ]
        
                            advanced-header = [
                              ~basic-header,
                              field3: bytes,
                              field4: ~time,
                            ]
        
                            advanced-header = [
                              ~basic-header,
                              field3: bytes,
                              field4: ~time,
                            ]
        

(Note that leaving out the first unwrap operator in the latter example would lead to nesting the basic-header in its own array inside the advanced-header, while, with the unwrapped basic-header, the definition of the group inside basic-header is essentially

(请注意,在后一个示例中,省略第一个展开运算符将导致基本标头嵌套在高级标头内其自己的数组中,而对于展开的基本标头,基本标头内组的定义基本上是

repeated inside advanced-header, leading to a single array. This can be used for various applications often solved by inheritance in programming languages. The effect of unwrapping can also be described as "threading in" the group or type inside the referenced type, which suggested the thread-like "~" character.)

在高级标头内重复,导致单个数组。这可以用于各种应用程序,通常通过编程语言中的继承来解决。展开的效果也可以描述为引用类型内的组或类型中的“threading in”,这表示类似于线程的“~”字符。)

3.8. Controls
3.8. 控制

A _control_ allows relating a _target_ type with a _controller_ type via a _control operator_.

“控制”允许通过“控制运算符”将“目标”类型与“控制器”类型关联起来。

The syntax for a control type is "target .control-operator controller", where control operators are special identifiers prefixed by a dot. (Note that _target_ or _controller_ might need to be parenthesized.)

控件类型的语法是“target.control operator controller”,其中控件运算符是以点为前缀的特殊标识符。(请注意,_target_uuuu或_controller_uuu可能需要加括号。)

A number of control operators are defined at this point. Further control operators may be defined by new versions of this specification or by registering them according to the procedures in Section 6.1.

此时定义了许多控制运算符。可通过本规范的新版本或根据第6.1节中的程序对其进行注册来定义进一步的控制操作员。

3.8.1. Control Operator .size
3.8.1. 控制操作员。大小

A ".size" control controls the size of the target in bytes by the control type. The control is defined for text and byte strings, where it directly controls the number of bytes in the string. It is also defined for unsigned integers (see below). Figure 8 shows example usage for byte strings.

“.size”控件通过控件类型控制目标的大小(以字节为单位)。控件是为文本和字节字符串定义的,它直接控制字符串中的字节数。它也是为无符号整数定义的(见下文)。图8显示了字节字符串的示例用法。

                   full-address = [[+ label], ip4, ip6]
                   ip4 = bstr .size 4
                   ip6 = bstr .size 16
                   label = bstr .size (1..63)
        
                   full-address = [[+ label], ip4, ip6]
                   ip4 = bstr .size 4
                   ip6 = bstr .size 16
                   label = bstr .size (1..63)
        

Figure 8: Control for Size in Bytes

图8:以字节为单位的大小控件

When applied to an unsigned integer, the ".size" control restricts the range of that integer by giving a maximum number of bytes that should be needed in a computer representation of that unsigned integer. In other words, "uint .size N" is equivalent to "0...BYTES_N", where BYTES_N == 256**N.

当应用于无符号整数时,“.size”控件通过提供该无符号整数的计算机表示形式中所需的最大字节数来限制该整数的范围。换句话说,“uint.size N”相当于“0…BYTES\u N”,其中BYTES\u N==256**N。

audio_sample = uint .size 3 ; 24-bit, equivalent to 0...16777216

音频样本=单元尺寸3;24位,相当于0…16777216

Figure 9: Control for Integer Size in Bytes

图9:以字节为单位的整数大小控件

Note that, as with value restrictions in CDDL, this control is not a representation constraint; a number that fits into fewer bytes can still be represented in that form, and an inefficient implementation 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 [RFC7049]).

注意,与CDDL中的值限制一样,该控件不是表示约束;适合更少字节的数字仍然可以用这种形式表示,效率低下的实现可能会使用更长的形式(除非受到CDDL之外的某些格式约束的限制,如[RFC7049]第3.9节中的规则)。

3.8.2. Control Operator .bits
3.8.2. 控制运算符。位

A ".bits" control on a byte string indicates that, in the target, only the bits numbered by a number in the control type are allowed to be set. (Bits are counted the usual way, bit number "n" being set in "str" meaning that "(str[n >> 3] & (1 << (n & 7))) != 0".) Similarly, a ".bits" control on an unsigned integer "i" indicates that for all unsigned integers "n" where "(i & (1 << n)) != 0", "n" must be in the control type.

字节字符串上的“.bits”控件表示,在目标中,只允许设置由控件类型中的数字编号的位。(位按通常方式计数,位号“n”在“str”中设置,意思是“(str[n>>3]&(1<<(n&7))!=0”。)类似地,无符号整数“i”上的“.Bits”控件表示,对于所有无符号整数,“n”其中“(i&(1<<n))!=0,“n”必须为控件类型。

                      tcpflagbytes = bstr .bits flags
                      flags = &(
                        fin: 8,
                        syn: 9,
                        rst: 10,
                        psh: 11,
                        ack: 12,
                        urg: 13,
                        ece: 14,
                        cwr: 15,
                        ns: 0,
                      ) / (4..7) ; data offset bits
        
                      tcpflagbytes = bstr .bits flags
                      flags = &(
                        fin: 8,
                        syn: 9,
                        rst: 10,
                        psh: 11,
                        ack: 12,
                        urg: 13,
                        ece: 14,
                        cwr: 15,
                        ns: 0,
                      ) / (4..7) ; data offset bits
        
                      rwxbits = uint .bits rwx
                      rwx = &(r: 2, w: 1, x: 0)
        
                      rwxbits = uint .bits rwx
                      rwx = &(r: 2, w: 1, x: 0)
        

Figure 10: Control for What Bits Can Be Set

图10:可以设置哪些位的控制

The CDDL tool described in Appendix F generates the following ten example instances for "tcpflagbytes":

附录F中描述的CDDL工具为“tcpflagbytes”生成以下十个示例实例:

h'906d' h'01fc' h'8145' h'01b7' h'013d' h'409f' h'018e' h'c05f' h'01fa' h'01fe'

h'906d'h'01fc'h'8145'h'01b7'h'013d'h'409f'h'018e'h'c05f'h'01fa'h'01fe'

These examples do not illustrate that the above CDDL specification does not explicitly specify a size of two bytes: a valid all-clear instance of flag bytes could be "h''" or "h'00'" or even "h'000000'" as well.

这些示例并没有说明上述CDDL规范没有明确指定两个字节的大小:标志字节的有效全清除实例也可以是“h'”或“h'00'”甚至“h'000000'”。

3.8.3. Control Operator .regexp
3.8.3. 控制运算符.regexp

A ".regexp" control indicates that the text string given as a target needs to match the XML Schema Definition (XSD) regular expression given as a value in the control type. XSD regular expressions are defined in Appendix F of [W3C.REC-xmlschema-2-20041028].

“.regexp”控件表示作为目标提供的文本字符串需要与作为控件类型中的值提供的XML架构定义(XSD)正则表达式匹配。XSD正则表达式在[W3C.REC-xmlschema-2-20041028]的附录F中定义。

     nai = tstr .regexp "[A-Za-z0-9]+@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)+"
        
     nai = tstr .regexp "[A-Za-z0-9]+@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)+"
        

Figure 11: Control with an XSD regexp

图11:带有XSD regexp的控件

An example matching this regular expression:

匹配此正则表达式的示例:

"N1@CH57HF.4Znqe0.dYJRN.igjf"

"N1@CH57HF.4Znqe0.dYJRN.igjf"

3.8.3.1. Usage Considerations
3.8.3.1. 使用注意事项

Note that XSD regular expressions do not support the usual \x or \u escapes for hexadecimal expression of bytes or Unicode code points. However, in CDDL the XSD regular expressions are contained in text strings, the literal notation for which provides \u escapes; this should suffice for most applications that use regular expressions for text strings. (Note that this also means that there is one level of string escaping before the XSD escaping rules are applied.)

请注意,XSD正则表达式不支持字节或Unicode代码点的十六进制表达式的常规\x或\u转义。但是,在CDDL中,XSD正则表达式包含在文本字符串中,文本表示法提供了\u转义;对于大多数将正则表达式用于文本字符串的应用程序来说,这就足够了。(请注意,这也意味着在应用XSD转义规则之前有一个级别的字符串转义。)

XSD regular expressions support character class subtraction, a feature often not found in regular expression libraries; specification writers may want to use this feature sparingly. Similar considerations apply to Unicode character classes; where these are used, the specification that employs CDDL SHOULD identify which Unicode versions are addressed.

XSD正则表达式支持字符类减法,这是正则表达式库中经常找不到的特性;规范编写者可能希望节约使用此功能。类似的考虑也适用于Unicode字符类;在使用这些规范的情况下,使用CDDL的规范应该确定要处理哪些Unicode版本。

Other surprises for infrequent users of XSD regular expressions may include the following:

对于不经常使用XSD正则表达式的用户来说,其他意外情况可能包括:

o No direct support for case insensitivity. While case insensitivity has gone mostly out of fashion in protocol design, it is sometimes needed and then needs to be expressed manually as in "[Cc][Aa][Ss][Ee]".

o 不直接支持案例不敏感。虽然不区分大小写在协议设计中已经过时,但有时需要它,然后需要手动表示为“[Cc][Aa][Ss][Ee]”。

o The support for popular character classes such as \w and \d is based on Unicode character properties; this is often not what is desired in an ASCII-based protocol and thus might lead to surprises. (\s and \S do have their more conventional meanings, and "." matches any character but the line-ending characters \r or \n.)

o 对流行字符类(如\w和\d)的支持基于Unicode字符属性;这通常不是基于ASCII的协议所需要的,因此可能会导致意外。(\s和\s有其更传统的含义,“.”匹配除行尾字符以外的任何字符\r或\n。)

3.8.3.2. Discussion
3.8.3.2. 讨论

There are many flavors of regular expression in use in the programming community. For instance, Perl-Compatible Regular Expressions (PCREs) are widely used and probably are more useful than XSD regular expressions. However, there is no normative reference for PCREs that could be used in the present document. Instead, we opt for XSD regular expressions for now. There is precedent for that choice in the IETF, e.g., in YANG [RFC7950].

在编程社区中使用的正则表达式有很多种。例如,Perl兼容正则表达式(PCRE)被广泛使用,并且可能比XSD正则表达式更有用。然而,本文件中没有可用于PCREs的规范性参考。相反,我们现在选择XSD正则表达式。这种选择在IETF中有先例,例如在YANG[RFC7950]。

Note that CDDL uses controls as its main extension point. This creates the opportunity to add further regular expression formats in addition to the one referenced here, if desired. As an example, a proposal for a ".pcre" control is defined in [CDDL-Freezer].

注意,CDDL使用控件作为其主要扩展点。如果需要的话,这将为在此处引用的正则表达式格式之外添加更多正则表达式格式创造机会。例如,“.pcre”控制方案在[CDDL冷冻柜]中定义。

3.8.4. Control Operators .cbor and .cborseq
3.8.4. 控制运算符.cbor和.cborseq

A ".cbor" control on a byte string indicates that the byte string carries a CBOR-encoded data item. Decoded, the data item matches the type given as the right-hand-side argument (type1 in the following example).

字节字符串上的“.cbor”控件表示该字节字符串包含一个cbor编码的数据项。解码后,数据项与作为右侧参数给出的类型匹配(以下示例中为type1)。

"bytes .cbor type1"

“字节。cbor类型1”

Similarly, a ".cborseq" control on a byte string indicates that the byte string carries a sequence of CBOR-encoded data items. When the data items are taken as an array, the array matches the type given as the right-hand-side argument (type2 in the following example).

类似地,字节字符串上的“.cborseq”控件表示该字节字符串携带一系列CBOR编码的数据项。将数据项作为数组时,数组将匹配作为右侧参数给出的类型(以下示例中的type2)。

"bytes .cborseq type2"

“字节数.cborseq类型2”

(The conversion of the encoded sequence to an array can be effected, for instance, by wrapping the byte string between the two bytes 0x9f and 0xff and decoding the wrapped byte string as a CBOR-encoded data item.)

(例如,通过将字节字符串包装在两个字节0x9f和0xff之间,并将包装后的字节字符串解码为CBOR编码数据项,可以实现编码序列到数组的转换。)

3.8.5. Control Operators .within and .and
3.8.5. 控制操作员。内部和。以及

A ".and" control on a type indicates that the data item matches both the left-hand-side type and the type given as the right-hand side. (Formally, the resulting type is the intersection of the two types given.)

类型上的“.和”控件表示数据项与左侧类型和作为右侧给定的类型都匹配。(在形式上,生成的类型是给定的两种类型的交集。)

"type1 .and type2"

“类型1.和类型2”

A variant of the ".and" control is the ".within" control, which expresses an additional intent: the left-hand-side type is meant to be a subset of the right-hand-side type.

“.”和“control”的一个变体是“control”中的“.”,它表达了另一个意图:左侧类型是右侧类型的子集。

"type1 .within type2"

“类型1.在类型2内”

While both forms have the identical formal semantics (intersection), the intention of the ".within" form is that the right-hand side gives guidance to the types allowed on the left-hand side, which typically is a socket (Section 3.9):

虽然两种形式具有相同的形式语义(交叉点),但“.in”形式的目的是,右侧为左侧允许的类型提供指导,通常为套接字(第3.9节):

        message = $message .within message-structure
        message-structure = [message_type, *message_option]
        message_type = 0..255
        message_option = any
        
        message = $message .within message-structure
        message-structure = [message_type, *message_option]
        message_type = 0..255
        message_option = any
        
        $message /= [3, dough: text, topping: [* text]]
        $message /= [4, noodles: text, sauce: text, parmesan: bool]
        
        $message /= [3, dough: text, topping: [* text]]
        $message /= [4, noodles: text, sauce: text, parmesan: bool]
        

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 expectation that type1 is already a subset of type2.

对于“.within”,如果type1允许type2不允许的数据项,则工具可能会标记错误。相反,对于“.and”,并不期望type1已经是type2的子集。

3.8.6. Control Operators .lt, .le, .gt, .ge, .eq, .ne, and .default
3.8.6. 控制运算符.lt、.le、.gt、.ge、.eq、.ne和.default

The controls .lt, .le, .gt, .ge, .eq, and .ne specify a constraint on the left-hand-side type to be a value less than, less than or equal to, greater than, greater than or equal to, equal to, or not equal to a value given as a right-hand-side type (containing just that single value). In the present specification, the first four controls (.lt, .le, .gt, and .ge) are defined only for numeric types, as these have a natural ordering relationship.

控件.lt、.le、.gt、.ge、.eq和.ne将左侧类型上的约束指定为小于、小于或等于、大于、大于或等于、等于或不等于作为右侧类型给定的值(仅包含该单个值)。在本规范中,前四个控件(.lt、.le、.gt和.ge)仅为数字类型定义,因为它们具有自然的排序关系。

                     speed = number .ge 0  ; unit: m/s
        
                     speed = number .ge 0  ; unit: m/s
        

.ne and .eq are defined for both numeric values and values of other 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 satisfy .ne) if they are bytewise identical; the same applies for byte strings. Arrays are equal if they have the same number of elements, all of which are equal pairwise in order between the arrays. Maps are equal if they have the same number of key/value pairs, and there is pairwise equality between the key/value pairs between the two maps. Tagged values are equal if they both have the same tag and the values are equal. Values of simple types match if they are the same values. Numeric types that occur within arrays,

.ne和.eq是为数值和其他类型的值定义的。如果其中一个值不是数字类型,则相等性的确定如下所示:如果文本字符串按字节相同,则它们相等(满足.eq/不满足.ne);这同样适用于字节字符串。如果数组具有相同数量的元素,则数组是相等的,所有元素在数组之间的顺序是成对的。如果映射具有相同数量的键/值对,并且两个映射之间的键/值对之间存在成对相等,则它们是相等的。如果标记值具有相同的标记且值相等,则标记值相等。如果简单类型的值相同,则它们匹配。数组中出现的数字类型,

maps, or tagged values are equal if their numeric value is equal and they are both integers or both floating-point values. All other cases are not equal (e.g., comparing a text string with a byte string).

如果映射或标记值的数值相等,并且它们都是整数或浮点值,则它们是相等的。所有其他情况都不相同(例如,将文本字符串与字节字符串进行比较)。

A variant of the ".ne" control is the ".default" control, which expresses an additional intent: the value specified by the right-hand-side type is intended as a default value for the left-hand-side type given, and the implied .ne control is there to prevent this value from being sent over the wire. This control is only meaningful when the control type is used in an optional context; otherwise, there would be no way to make use of the default value.

“.ne”控件的一个变体是“.default”控件,它表达了一个额外的意图:由右侧类型指定的值是作为给定左侧类型的默认值,隐含的.ne控件用于防止该值通过线路发送。只有在可选上下文中使用控件类型时,此控件才有意义;否则,将无法使用默认值。

               timer = {
                 time: uint,
                 ? displayed-step: (number .gt 0) .default 1
               }
        
               timer = {
                 time: uint,
                 ? displayed-step: (number .gt 0) .default 1
               }
        
3.9. Socket/Plug
3.9. 插座/插头

For both type choices and group choices, a mechanism is defined that facilitates starting out with empty choices and assembling them later, potentially in separate files that are concatenated to build the full specification.

对于类型选择和组选择,定义了一种机制,该机制有助于从空选择开始,然后将它们组合在单独的文件中,这些文件可能连接起来以构建完整的规范。

Per convention, CDDL extension points are marked with a leading dollar sign (types) or two leading dollar signs (groups). Tools honor that convention by not raising an error if such a type or group is not defined at all; the symbol is then taken to be an empty type choice (group choice), i.e., no choice is available.

按照惯例,CDDL扩展点用一个前导美元符号(类型)或两个前导美元符号(组)进行标记。如果没有定义此类类型或组,则工具不会引发错误,从而遵守该约定;然后,符号被视为空类型选择(组选择),即没有可用的选择。

            tcp-header = {seq: uint, ack: uint, * $$tcp-option}
        
            tcp-header = {seq: uint, ack: uint, * $$tcp-option}
        

; later, in a different file

; 稍后,在另一个文件中

            $$tcp-option //= (
            sack: [+(left: uint, right: uint)]
            )
        
            $$tcp-option //= (
            sack: [+(left: uint, right: uint)]
            )
        

; and, maybe in another file

; 也许在另一个文件里

            $$tcp-option //= (
            sack-permitted: true
            )
        
            $$tcp-option //= (
            sack-permitted: true
            )
        

Names that start with a single "$" are "type sockets", starting out as an empty type, and intended to be extended via "/=". Names that start with a double "$$" are "group sockets", starting out as an

以单个“$”开头的名称是“类型套接字”,以空类型开头,并打算通过“/”扩展。以双“$$”开头的名称是“组套接字”,以

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 augmentations, i.e., they must be using "/=" and "//=", respectively.

按照惯例,套接字名称的所有定义(插头)都必须是扩充,即它们必须分别使用“/”和“//=”。

To pick up the example illustrated in Figure 7, the socket/plug mechanism could be used as shown in Figure 12:

如图7所示,可以使用插座/插头机制,如图12所示:

                     PersonalData = {
                       ? displayName: tstr,
                       NameComponents,
                       ? age: uint,
                       * $$personaldata-extensions
                     }
        
                     PersonalData = {
                       ? displayName: tstr,
                       NameComponents,
                       ? age: uint,
                       * $$personaldata-extensions
                     }
        
                     NameComponents = (
                       ? firstName: tstr,
                       ? familyName: tstr,
                     )
        
                     NameComponents = (
                       ? firstName: tstr,
                       ? familyName: tstr,
                     )
        

; The above already works as is. ; But then, we can add later:

; 以上内容已按原样运行;但是,我们可以在以后添加:

                     $$personaldata-extensions //= (
                       favorite-salsa: tstr,
                     )
        
                     $$personaldata-extensions //= (
                       favorite-salsa: tstr,
                     )
        

; and again, somewhere else:

; 再说一次,在别的地方:

                     $$personaldata-extensions //= (
                       shoesize: uint,
                     )
        
                     $$personaldata-extensions //= (
                       shoesize: uint,
                     )
        
     Figure 12: Personal Data Example: Using Socket/Plug Extensibility
        
     Figure 12: Personal Data Example: Using Socket/Plug Extensibility
        
3.10. Generics
3.10. 仿制药

Using angle brackets, the left-hand side of a rule can add formal parameters after the name being defined, as in:

使用尖括号,规则的左侧可以在定义名称后添加形式参数,如中所示:

      messages = message<"reboot", "now"> / message<"sleep", 1..100>
      message<t, v> = {type: t, value: v}
        
      messages = message<"reboot", "now"> / message<"sleep", 1..100>
      message<t, v> = {type: t, value: v}
        

When using a generic rule, the formal parameters are bound to the actual arguments supplied (also using angle brackets), within the scope of the generic rule (as if there were a rule of the form parameter = argument).

当使用泛型规则时,形式参数将绑定到泛型规则范围内提供的实际参数(也使用尖括号)(就好像有一个形式为parameter=argument的规则一样)。

Generic rules can be used for establishing names for both types and groups.

通用规则可用于建立类型和组的名称。

(At this time, there are some limitations to the nesting of generics in the CDDL tool described in Appendix F.)

(此时,附录F中描述的CDDL工具中的泛型嵌套存在一些限制。)

3.11. Operator Precedence
3.11. 运算符优先级

As with any language that has multiple syntactic features such as prefix and infix operators, CDDL has operators that bind more tightly than others. This is becoming more complicated than, say, in ABNF, as CDDL has both types and groups, with operators that are specific to these concepts. Type operators (such as "/" for type choice) operate on types, while group operators (such as "//" for group choice) operate on groups. Types can simply be used in groups, but groups need to be bracketed (as arrays or maps) to become types. So, type operators naturally bind closer than group operators.

与任何具有多种语法特征(如前缀和中缀运算符)的语言一样,CDDL的运算符绑定得比其他语言更紧密。这比ABNF要复杂得多,因为CDDL既有类型也有组,并且有特定于这些概念的运算符。类型运算符(如“/”用于类型选择)对类型进行操作,而组运算符(如“/”用于组选择)对组进行操作。类型可以简单地在组中使用,但组需要括起来(作为数组或映射)才能成为类型。因此,类型运算符自然比组运算符绑定得更紧密。

For instance, in

例如,在

      t = [group1]
      group1 = (a / b // c / d)
      a = 1 b = 2 c = 3 d = 4
        
      t = [group1]
      group1 = (a / b // c / d)
      a = 1 b = 2 c = 3 d = 4
        

group1 is a group choice between the type choice of a and b and the type choice of c and d. This becomes more relevant once member keys and/or occurrences are added in:

group1是a和b类型选择与c和d类型选择之间的组选择。在以下位置添加成员键和/或引用后,这将变得更加相关:

      t = {group2}
      group2 = (? ab: a / b // cd: c / d)
      a = 1 b = 2 c = 3 d = 4
        
      t = {group2}
      group2 = (? ab: a / b // cd: c / d)
      a = 1 b = 2 c = 3 d = 4
        

is a group choice between the optional member "ab" of type a or b and the member "cd" of type c or d. Note that the optionality is attached to the first choice ("ab"), not to the second choice.

是a或b型可选成员“ab”和c或d型成员“cd”之间的组选择。请注意,可选性附于第一选择(“ab”),而非第二选择。

Similarly, in

同样,在

      t = [group3]
      group3 = (+ a / b / c)
      a = 1 b = 2 c = 3
        
      t = [group3]
      group3 = (+ a / b / c)
      a = 1 b = 2 c = 3
        

group3 is a repetition of a type choice between a, b, and c; if just a is to be repeatable, a group choice is needed to focus the occurrence:

组3是a、b和c之间类型选择的重复;如果要重复某个事件,则需要选择一个组来集中事件:

      t = [group4]
      group4 = (+ a // b / c)
      a = 1 b = 2 c = 3
        
      t = [group4]
      group4 = (+ a // b / c)
      a = 1 b = 2 c = 3
        

group4 is a group choice between a repeatable a and a single b or c.

组4是可重复a和单个b或c之间的组选择。

A comment has been that the semantics of group3 could be counterintuitive. In general, as with many other languages with operator precedence rules, the specification writer is encouraged not to rely on them, but to insert parentheses liberally to guide readers that are not familiar with CDDL precedence rules:

有人评论说,group3的语义可能违反直觉。一般来说,与许多其他具有运算符优先规则的语言一样,鼓励规范编写者不要依赖它们,而是自由地插入括号,以指导不熟悉CDDL优先规则的读者:

      t = [group4a]
      group4a = ((+ a) // (b / c))
      a = 1 b = 2 c = 3
        
      t = [group4a]
      group4a = ((+ a) // (b / c))
      a = 1 b = 2 c = 3
        

The operator precedences, in sequence of loose to tight binding, are defined in Appendix B and summarized in Table 1. (Arities given are 1 for unary prefix operators and 2 for binary infix operators.)

附录B中定义了从松到紧的操作员先例,并在表1中进行了总结。(一元前缀运算符的算术数为1,二元中缀运算符的算术数为2。)

       +----------+-------+---------------------------+------------+
       | Operator | Arity | Operates on               | Precedence |
       +----------+-------+---------------------------+------------+
       |    =     |   2   | name = type, name = group |     1      |
       |    /=    |   2   | name /= type              |     1      |
       |   //=    |   2   | name //= group            |     1      |
       |    //    |   2   | group // group            |     2      |
       |    ,     |   2   | group, group              |     3      |
       |    *     |   1   | * group                   |     4      |
       |   n*m    |   1   | n*m group                 |     4      |
       |    +     |   1   | + group                   |     4      |
       |    ?     |   1   | ? group                   |     4      |
       |    =>    |   2   | type => type              |     5      |
       |    :     |   2   | name: type                |     5      |
       |    /     |   2   | type / type               |     6      |
       |    ..    |   2   | type..type                |     7      |
       |   ...    |   2   | type...type               |     7      |
       |  .ctrl   |   2   | type .ctrl type           |     7      |
       |    &     |   1   | &group                    |     8      |
       |    ~     |   1   | ~type                     |     8      |
       +----------+-------+---------------------------+------------+
        
       +----------+-------+---------------------------+------------+
       | Operator | Arity | Operates on               | Precedence |
       +----------+-------+---------------------------+------------+
       |    =     |   2   | name = type, name = group |     1      |
       |    /=    |   2   | name /= type              |     1      |
       |   //=    |   2   | name //= group            |     1      |
       |    //    |   2   | group // group            |     2      |
       |    ,     |   2   | group, group              |     3      |
       |    *     |   1   | * group                   |     4      |
       |   n*m    |   1   | n*m group                 |     4      |
       |    +     |   1   | + group                   |     4      |
       |    ?     |   1   | ? group                   |     4      |
       |    =>    |   2   | type => type              |     5      |
       |    :     |   2   | name: type                |     5      |
       |    /     |   2   | type / type               |     6      |
       |    ..    |   2   | type..type                |     7      |
       |   ...    |   2   | type...type               |     7      |
       |  .ctrl   |   2   | type .ctrl type           |     7      |
       |    &     |   1   | &group                    |     8      |
       |    ~     |   1   | ~type                     |     8      |
       +----------+-------+---------------------------+------------+
        

Table 1: Summary of Operator Precedences

表1:操作员先例摘要

4. Making Use of CDDL
4. 利用CDDL

In this section, we discuss several potential ways to employ CDDL.

在本节中,我们将讨论几种使用CDDL的潜在方法。

4.1. As a Guide for a Human User
4.1. 作为人类用户的指南

CDDL can be used to efficiently define the layout of CBOR data, such that a human implementer can easily see how data is supposed to be encoded.

CDDL可用于有效地定义CBOR数据的布局,以便人类实现者可以轻松地看到数据应该如何编码。

Since CDDL maps parts of the CBOR data to human-readable names, tools could be built that use CDDL to provide a human-friendly representation of the CBOR data and allow them to edit such data while remaining compliant with its CDDL definition.

由于CDDL将CBOR数据的一部分映射到人类可读的名称,因此可以构建使用CDDL的工具,以提供CBOR数据的人性化表示,并允许他们编辑此类数据,同时保持其CDDL定义的一致性。

4.2. For Automated Checking of CBOR Data Structures
4.2. 用于自动检查CBOR数据结构

CDDL has been specified such that a machine can handle the CDDL definition and related CBOR data (and, thus, also JSON data). For example, a machine could use CDDL to check whether or not CBOR data is compliant with its definition.

CDDL已被指定为机器可以处理CDDL定义和相关的CBOR数据(因此也可以处理JSON数据)。例如,机器可以使用CDDL检查CBOR数据是否符合其定义。

The need for thoroughness of such compliance checking depends on the application. For example, an application may decide not to check the data structure at all and use the CDDL definition solely as a means to indicate the structure of the data to the programmer.

此类合规性检查是否彻底取决于应用程序。例如,应用程序可能决定根本不检查数据结构,而仅将CDDL定义用作向程序员指示数据结构的手段。

On the other hand, the application may also implement a checking mechanism that goes as far as checking that all mandatory map members are available.

另一方面,应用程序还可以实现一种检查机制,检查所有必需的map成员是否可用。

The matter of how far the data description must be enforced by an application is left to the designers and implementers of that application, keeping in mind related security considerations.

应用程序必须在多大程度上强制执行数据描述的问题留给该应用程序的设计人员和实现人员,同时牢记相关的安全注意事项。

In no case is it intended that a CDDL tool would be "writing code" for an implementation.

在任何情况下,CDDL工具都不会为实现“编写代码”。

4.3. For Data Analysis Tools
4.3. 用于数据分析工具

In the long run, it can be expected that more and more data will be stored using the CBOR data format.

从长远来看,可以预期越来越多的数据将使用CBOR数据格式存储。

Where there is data, there is data analysis and the need to process such data automatically. CDDL can be used for such automated data processing, allowing tools to verify data, clean it, and extract particular parts of interest from it.

有数据的地方就有数据分析,需要自动处理这些数据。CDDL可用于此类自动化数据处理,允许工具验证数据、清理数据并从中提取感兴趣的特定部分。

Since CBOR is designed with constrained devices in mind, a likely use of it would be small sensors. An interesting use would thus be automated analysis of sensor data.

由于CBOR在设计时考虑了受约束的设备,因此很可能使用小型传感器。因此,传感器数据的自动分析将是一个有趣的用途。

5. Security Considerations
5. 安全考虑

This document presents a content rules language for expressing CBOR data structures. As such, it does not bring any security issues on itself, although specifications of protocols that use CBOR naturally need security analyses when defined. General guidelines for writing security considerations are defined in [RFC3552] (BCP 72). Specifications using CDDL to define CBOR structures in protocols need to follow those guidelines. Additional topics that could be considered in a security considerations section for a specification that uses CDDL to define CBOR structures include the following:

本文档介绍了一种用于表示CBOR数据结构的内容规则语言。因此,它本身不会带来任何安全问题,尽管使用CBOR的协议的规范在定义时自然需要进行安全分析。[RFC3552](BCP 72)中定义了编写安全注意事项的一般准则。使用CDDL定义协议中CBOR结构的规范需要遵循这些准则。对于使用CDDL定义CBOR结构的规范,安全注意事项部分可以考虑的其他主题包括:

o Where could the language maybe cause confusion in a way that will enable security issues?

o 该语言可能会在哪些方面引起混淆,从而导致安全问题?

o Where a CDDL matcher is part of the implementation of a system, the security of the system ought not depend on the correctness of the CDDL specification or CDDL implementation without any further defenses in place.

o 如果CDDL匹配器是系统实现的一部分,则系统的安全性不应取决于CDDL规范或CDDL实现的正确性,而无任何进一步的防御措施。

o Where the CDDL specification includes extension points, the impact of extensions on the security of the system needs to be carefully considered.

o 当CDDL规范包括扩展点时,需要仔细考虑扩展对系统安全性的影响。

Writers of CDDL specifications are strongly encouraged to value clarity and transparency of the specification over its elegance. Keep it as simple as possible while still expressing the needed data model.

强烈鼓励CDDL规范的编写者重视规范的清晰性和透明度,而不是其优雅性。在表达所需数据模型的同时,尽可能使其简单。

A related observation about formal description techniques in general that is strongly recommended to be kept in mind by writers of CDDL specifications: just because CDDL makes it easier to handle complexity in a specification, that does not make that complexity somehow less bad (except maybe on the level of the humans having to grasp the complex structure while reading the spec).

CDDL规范的编写者强烈建议记住的关于一般形式化描述技术的一个相关观察:仅仅因为CDDL使规范中的复杂性更容易处理,但这并不会使复杂性变得不那么糟糕(除了在阅读说明书时,人类必须掌握复杂结构的层面上)。

6. IANA Considerations
6. IANA考虑
6.1. CDDL Control Operators Registry
6.1. 控制操作员注册表

IANA has created a registry for control operators (Section 3.8). The "CDDL Control Operators" registry has been created within the "Concise Data Definition Language (CDDL)" registry.

IANA为控制操作员创建了一个注册表(第3.8节)。“CDDL控制运算符”注册表已在“简明数据定义语言(CDDL)”注册表中创建。

Each entry in the subregistry must include the name of the control operator (by convention given with the leading dot) and a reference to its documentation. Names must be composed of the leading dot followed by a text string conforming to the production "id" in Appendix B.

子区域中的每个条目必须包括控制操作员的姓名(按照惯例,以前导点给出)及其文件参考。名称必须由前导点和符合附录B中产品“id”的文本字符串组成。

Initial entries in this registry are as follows:

此注册表中的初始条目如下:

                       +----------+---------------+
                       | Name     | Documentation |
                       +----------+---------------+
                       | .size    | RFC 8610      |
                       | .bits    | RFC 8610      |
                       | .regexp  | RFC 8610      |
                       | .cbor    | RFC 8610      |
                       | .cborseq | RFC 8610      |
                       | .within  | RFC 8610      |
                       | .and     | RFC 8610      |
                       | .lt      | RFC 8610      |
                       | .le      | RFC 8610      |
                       | .gt      | RFC 8610      |
                       | .ge      | RFC 8610      |
                       | .eq      | RFC 8610      |
                       | .ne      | RFC 8610      |
                       | .default | RFC 8610      |
                       +----------+---------------+
        
                       +----------+---------------+
                       | Name     | Documentation |
                       +----------+---------------+
                       | .size    | RFC 8610      |
                       | .bits    | RFC 8610      |
                       | .regexp  | RFC 8610      |
                       | .cbor    | RFC 8610      |
                       | .cborseq | RFC 8610      |
                       | .within  | RFC 8610      |
                       | .and     | RFC 8610      |
                       | .lt      | RFC 8610      |
                       | .le      | RFC 8610      |
                       | .gt      | RFC 8610      |
                       | .ge      | RFC 8610      |
                       | .eq      | RFC 8610      |
                       | .ne      | RFC 8610      |
                       | .default | RFC 8610      |
                       +----------+---------------+
        

All other control operator names are Unassigned.

所有其他控制操作员名称均未分配。

The IANA policy for additions to this registry is "Specification Required" as defined in [RFC8126] (which involves an Expert Review) for names that do not include an internal dot and "IETF Review" for names that do include an internal dot. The expert reviewer is specifically instructed that other Standards Development Organizations (SDOs) may want to define control operators that are specific to their fields (e.g., based on a binary syntax already in use at the SDO); the review process should strive to facilitate such an undertaking.

对于不包含内部dot的名称,[RFC8126](涉及专家评审)中定义的IANA添加到此注册表的政策为“需要规范”,对于包含内部dot的名称,为“IETF评审”。专门指示专家评审员,其他标准开发组织(SDO)可能希望定义特定于其领域的控制运算符(例如,基于SDO已经使用的二进制语法);审查进程应努力促进这项工作。

7. References
7. 工具书类
7.1. Normative References
7.1. 规范性引用文件

[ISO6093] ISO, "Information processing -- Representation of numerical values in character strings for information interchange", ISO 6093, 1985.

[ISO6093]ISO,“信息处理——信息交换用字符串中数值的表示”,ISO 6093,1985。

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC2119]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,DOI 10.17487/RFC2119,1997年3月<https://www.rfc-editor.org/info/rfc2119>.

[RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC Text on Security Considerations", BCP 72, RFC 3552, DOI 10.17487/RFC3552, July 2003, <https://www.rfc-editor.org/info/rfc3552>.

[RFC3552]Rescorla,E.和B.Korver,“关于安全考虑的RFC文本编写指南”,BCP 72,RFC 3552,DOI 10.17487/RFC3552,2003年7月<https://www.rfc-editor.org/info/rfc3552>.

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <https://www.rfc-editor.org/info/rfc3629>.

[RFC3629]Yergeau,F.,“UTF-8,ISO 10646的转换格式”,STD 63,RFC 3629,DOI 10.17487/RFC3629,2003年11月<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>.

[RFC4648]Josefsson,S.,“Base16、Base32和Base64数据编码”,RFC 4648,DOI 10.17487/RFC4648,2006年10月<https://www.rfc-editor.org/info/rfc4648>.

[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.

[RFC5234]Crocker,D.,Ed.和P.Overell,“语法规范的扩充BNF:ABNF”,STD 68,RFC 5234,DOI 10.17487/RFC5234,2008年1月<https://www.rfc-editor.org/info/rfc5234>.

[RFC7049] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049, October 2013, <https://www.rfc-editor.org/info/rfc7049>.

[RFC7049]Bormann,C.和P.Hoffman,“简明二进制对象表示法(CBOR)”,RFC 7049,DOI 10.17487/RFC7049,2013年10月<https://www.rfc-editor.org/info/rfc7049>.

[RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, DOI 10.17487/RFC7493, March 2015, <https://www.rfc-editor.org/info/rfc7493>.

[RFC7493]Bray,T.,Ed.,“I-JSON消息格式”,RFC 7493,DOI 10.17487/RFC7493,2015年3月<https://www.rfc-editor.org/info/rfc7493>.

[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.

[RFC8126]Cotton,M.,Leiba,B.,和T.Narten,“在RFC中编写IANA考虑事项部分的指南”,BCP 26,RFC 8126,DOI 10.17487/RFC8126,2017年6月<https://www.rfc-editor.org/info/rfc8126>.

[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8174]Leiba,B.,“RFC 2119关键词中大写与小写的歧义”,BCP 14,RFC 8174,DOI 10.17487/RFC8174,2017年5月<https://www.rfc-editor.org/info/rfc8174>.

[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, <https://www.rfc-editor.org/info/rfc8259>.

[RFC8259]Bray,T.,Ed.“JavaScript对象表示法(JSON)数据交换格式”,STD 90,RFC 8259,DOI 10.17487/RFC8259,2017年12月<https://www.rfc-editor.org/info/rfc8259>.

[W3C.REC-xmlschema-2-20041028] Biron, P. and A. Malhotra, "XML Schema Part 2: Datatypes Second Edition", World Wide Web Consortium Recommendation REC-xmlschema-2-20041028, October 2004, <https://www.w3.org/TR/2004/REC-xmlschema-2-20041028>.

[W3C.REC-xmlschema-2-20041028]Biron,P.和A.Malhotra,“XML模式第2部分:数据类型第二版”,万维网联盟建议REC-xmlschema-2-20041028,2004年10月<https://www.w3.org/TR/2004/REC-xmlschema-2-20041028>.

7.2. Informative References
7.2. 资料性引用

[CDDL-Freezer] Bormann, C., "A feature freezer for the Concise Data Definition Language (CDDL)", Work in Progress, draft-bormann-cbor-cddl-freezer-01, August 2018.

[CDDL冷冻库]Bormann,C.,“简明数据定义语言(CDDL)的功能冷冻库”,正在进行的工作,草稿-Bormann-cbor-CDDL-冷冻库-01,2018年8月。

[GRASP] Bormann, C., Carpenter, B., Ed., and B. Liu, Ed., "A Generic Autonomic Signaling Protocol (GRASP)", Work in Progress, draft-ietf-anima-grasp-15, July 2017.

[GRAP]Bormann,C.,Carpenter,B.,Ed.,和B.Liu,Ed.,“通用自主信号协议(GRAP)”,正在进行的工作,草稿-ietf-anima-GRAP-15,2017年7月。

[IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE Std 754-2008.

[IEEE754]IEEE,“IEEE浮点运算标准”,IEEE标准754-2008。

[JCR] Newton, A. and P. Cordell, "A Language for Rules Describing JSON Content", Work in Progress, draft-newton-json-content-rules-09, September 2017.

[JCR]Newton,A.和P.Cordell,“描述JSON内容的规则语言”,正在进行的工作,草稿-Newton-JSON-Content-Rules-092017年9月。

[PEG] Ford, B., "Parsing expression grammars: a recognition-based syntactic foundation", Proceedings of the 31st ACM SIGPLAN-SIGACT symposium on Principles of programming languages - POPL '04, DOI 10.1145/964001.964011, January 2004.

[PEG]Ford,B.,“解析表达式语法:基于识别的句法基础”,第31届ACM SIGPLAN-SIGACT编程语言原理研讨会论文集,POPL'04,DOI 10.1145/964001.964011,2004年1月。

[RELAXNG] ISO/IEC, "Information technology -- Document Schema Definition Language (DSDL) -- Part 2: Regular-grammar-based validation -- RELAX NG", ISO/IEC 19757-2, December 2008.

[RELAXNG]ISO/IEC,“信息技术——文档模式定义语言(DSDL)——第2部分:基于规则语法的验证——RELAXNG”,ISO/IEC 19757-22008年12月。

[RFC7071] Borenstein, N. and M. Kucherawy, "A Media Type for Reputation Interchange", RFC 7071, DOI 10.17487/RFC7071, November 2013, <https://www.rfc-editor.org/info/rfc7071>.

[RFC7071]Borenstein,N.和M.Kucherawy,“声誉交换的媒体类型”,RFC 7071,DOI 10.17487/RFC7071,2013年11月<https://www.rfc-editor.org/info/rfc7071>.

[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950, DOI 10.17487/RFC7950, August 2016, <https://www.rfc-editor.org/info/rfc7950>.

[RFC7950]Bjorklund,M.,Ed.“YANG 1.1数据建模语言”,RFC 7950,DOI 10.17487/RFC7950,2016年8月<https://www.rfc-editor.org/info/rfc7950>.

[RFC8007] Murray, R. and B. Niven-Jenkins, "Content Delivery Network Interconnection (CDNI) Control Interface / Triggers", RFC 8007, DOI 10.17487/RFC8007, December 2016, <https://www.rfc-editor.org/info/rfc8007>.

[RFC8007]Murray,R.和B.Niven Jenkins,“内容交付网络互连(CDNI)控制接口/触发器”,RFC 8007,DOI 10.17487/RFC8007,2016年12月<https://www.rfc-editor.org/info/rfc8007>.

[RFC8152] Schaad, J., "CBOR Object Signing and Encryption (COSE)", RFC 8152, DOI 10.17487/RFC8152, July 2017, <https://www.rfc-editor.org/info/rfc8152>.

[RFC8152]Schaad,J.,“CBOR对象签名和加密(COSE)”,RFC 8152,DOI 10.17487/RFC8152,2017年7月<https://www.rfc-editor.org/info/rfc8152>.

[RFC8428] Jennings, C., Shelby, Z., Arkko, J., Keranen, A., and C. Bormann, "Sensor Measurement Lists (SenML)", RFC 8428, DOI 10.17487/RFC8428, August 2018, <https://www.rfc-editor.org/info/rfc8428>.

[RFC8428]Jennings,C.,Shelby,Z.,Arkko,J.,Keranen,A.,和C.Bormann,“传感器测量列表(SenML)”,RFC 8428,DOI 10.17487/RFC8428,2018年8月<https://www.rfc-editor.org/info/rfc8428>.

[YAML] Ben-Kiki, O., Evans, C., and I. Net, "YAML Ain't Markup Language (YAML[TM]) Version 1.2", 3rd Edition, October 2009, <https://yaml.org/spec/1.2/spec.html>.

[YAML]Ben Kiki,O.,Evans,C.,和I.Net,“YAML不是标记语言(YAML[TM])版本1.2”,第三版,2009年10月<https://yaml.org/spec/1.2/spec.html>.

Appendix A. Parsing Expression Grammars (PEGs)

附录A.解析表达式语法(PEG)

This appendix is normative.

本附录为规范性附录。

Since the 1950s, many grammar notations are based on Backus-Naur Form (BNF), a notation for context-free grammars (CFGs) within Chomsky's generative system of grammars. The Augmented Backus-Naur Form (ABNF) [RFC5234], widely used in IETF specifications and also inspiring the syntax of CDDL, is an example of this.

自20世纪50年代以来,许多语法符号都基于巴克斯·诺尔形式(BNF),这是乔姆斯基语法生成系统中上下文无关语法(CFG)的一种符号。扩充的巴科斯-诺尔形式(ABNF)[RFC5234],广泛用于IETF规范,也启发了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; this scenario may be hard for the specification writer to manage.

生成语法可以很好地表达歧义,但这一特性可能会使它们难以在识别系统中使用,从而产生许多子标记,这些子标记对生成语法构成约束,以便与解析器生成器一起使用;规范编写者可能很难管理此场景。

PEGs [PEG] provide an alternative formal foundation for describing grammars that emphasizes recognition over generation and resolves what would have been ambiguity in generative systems by introducing the concept of "prioritized choice".

PEGS(PEGs)提供了一个可供选择的形式基础,用于描述强调生成的语法,并通过引入“优先选择”的概念来解决生成系统中的模糊。

The notation for PEGs is quite close to BNF, 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 (Section 3.5.4) would).

PEGs的符号与BNF非常接近,添加了通常的“扩展BNF”特性,例如重复。然而,当BNF使用无序(对称)选择运算符“|”(在ABNF中顺便记为“/”)时,PEG提供了优先选择运算符“/”。列出的两个备选方案将按从左到右的顺序进行测试,锁定第一个成功匹配,并忽略选项中的任何其他潜在匹配(但不禁用包含此选项的选项中的备选方案,如切割(第3.5.4节)所示)。

For example, the ABNF expressions

例如,ABNF表达式

      A = "a" "b" / "a"    (1)
        
      A = "a" "b" / "a"    (1)
        

and

      A = "a" / "a" "b"    (2)
        
      A = "a" / "a" "b"    (2)
        

are equivalent in ABNF's original generative framework but are very different in PEG: in (2), the second alternative will never match, as any input string starting with an "a" will already succeed in the first alternative, locking in the match.

在ABNF最初的生成框架中是等价的,但在PEG中是非常不同的:在(2)中,第二个选项永远不会匹配,因为任何以“a”开头的输入字符串都会在第一个选项中成功,锁定匹配。

Similarly, the occurrence indicators ("?", "*", "+") are "greedy" in PEG, i.e., they consume as much input as they match (and, as a consequence, "a* a" in PEG notation or "*a a" in CDDL syntax never can match anything, as all input matching "a" is already consumed by the initial "a*", leaving nothing to match the second "a").

类似地,出现指示符(“?”、“*”、“+”)在PEG中是“贪婪”的,即它们消耗匹配的输入量(因此,PEG表示法中的“a*a”或CDDL语法中的“*a a”永远无法匹配任何内容,因为匹配“a”的所有输入都已被初始“a*”消耗,没有留下任何内容与第二个“a”匹配)。

Incidentally, the grammar of CDDL itself, as written in ABNF in Appendix B, can be interpreted both (1) in the generative framework on which RFC 5234 is based and (2) as a PEG. This was made possible by ordering the choices in the grammar such that a 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).

顺便提一下,附录B中ABNF中所述的CDDL语法本身可以(1)在RFC 5234所基于的生成框架中解释,也可以(2)作为PEG来解释。通过对语法中的选项进行排序,使得在“/”运算符左侧进行的成功匹配始终是预期的匹配,而不是依赖对称选择的能力(例如,请注意规则中“uint”的选项顺序),其中单独的零位于以零开始的较长匹配备选方案之后)。

The syntax used for expressing the PEG component of CDDL is based on ABNF, interpreted in the obvious way with PEG semantics. The ABNF convention of notating occurrence indicators before the controlled primary, and of allowing numeric values for minimum and maximum 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:

用于表示CDDL的PEG组件的语法基于ABNF,并使用PEG语义以明显的方式进行解释。复制ABNF惯例,即在受控主节点之前标记出现指示器,并允许在“*”符号周围出现最小值和最大值的数值。虽然PEG只涉及字符,但CDDL有更丰富的元素集,如类型和组。具体而言,以下构造映射:

       +-------+-------+-------------------------------------------+
       | CDDL  | PEG   | Remark                                    |
       +-------+-------+-------------------------------------------+
       | "="   | "<-"  | /= 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        |
       +-------+-------+-------------------------------------------+
        
       +-------+-------+-------------------------------------------+
       | CDDL  | PEG   | Remark                                    |
       +-------+-------+-------------------------------------------+
       | "="   | "<-"  | /= 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 literal notation and the use of square brackets, curly braces, tildes, ampersands, and hash marks are specific to CDDL and unrelated to the conventional PEG notation. The DOT (".") from PEG 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.

文字表示法以及方括号、大括号、波浪号、符号和散列标记的使用是CDDL特有的,与传统的PEG表示法无关。PEG中的点(“.”)替换为未加修饰的“#”或其别名“any”。此外,CDDL没有从PEG中提供语法谓词运算符not(“!”)或AND(“&”),从而降低了表达能力和复杂性。

For more details about PEG's theoretical foundation and interesting properties of the operators such as associativity and distributivity, the reader is referred to [PEG].

关于PEG的理论基础和算子的有趣性质,如关联性和分布性,读者可以参考[PEG]。

Appendix B. ABNF Grammar
附录B.ABNF语法

This appendix is normative.

本附录为规范性附录。

The following is a formal definition of the CDDL syntax in ABNF [RFC5234]. Note that, as is defined in ABNF, the quote-delimited strings below are case insensitive (while string values and names are case sensitive in CDDL).

以下是ABNF[RFC5234]中CDDL语法的正式定义。注意,正如ABNF中所定义的,下面以引号分隔的字符串不区分大小写(而字符串值和名称在CDDL中区分大小写)。

cddl = S 1*(rule S) rule = typename [genericparm] S assignt S type / groupname [genericparm] S assigng S grpent

cddl=s1*(规则S)规则=typename[genericparm]S assignt S type/groupname[genericparm]S assigng S grpent

typename = id groupname = id

typename=id groupname=id

     assignt = "=" / "/="
     assigng = "=" / "//="
        
     assignt = "=" / "/="
     assigng = "=" / "//="
        
     genericparm = "<" S id S *("," S id S ) ">"
     genericarg = "<" S type1 S *("," S type1 S ) ">"
        
     genericparm = "<" S id S *("," S id S ) ">"
     genericarg = "<" S type1 S *("," S type1 S ) ">"
        
     type = type1 *(S "/" S type1)
        
     type = type1 *(S "/" S type1)
        

type1 = type2 [S (rangeop / ctlop) S type2] ; space may be needed before the operator if type2 ends in a name

type1=type2[S(rangeop/ctlop)S type2];如果type2以名称结尾,则运算符前面可能需要空格

     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
        
     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
        
     rangeop = "..." / ".."
        
     rangeop = "..." / ".."
        

ctlop = "." id

ctlop=“”id

     group = grpchoice *(S "//" S grpchoice)
        
     group = grpchoice *(S "//" S grpchoice)
        
     grpchoice = *(grpent optcom)
        
     grpchoice = *(grpent optcom)
        
     grpent = [occur S] [memberkey S] type
            / [occur S] groupname [genericarg]  ; preempted by above
            / [occur S] "(" S group S ")"
        
     grpent = [occur S] [memberkey S] type
            / [occur S] groupname [genericarg]  ; preempted by above
            / [occur S] "(" S group S ")"
        
     memberkey = type1 S ["^" S] "=>"
               / bareword S ":"
               / value S ":"
        
     memberkey = type1 S ["^" S] "=>"
               / bareword S ":"
               / value S ":"
        
     bareword = id
        
     bareword = id
        

optcom = S ["," S]

optcom=S[“,”S]

     occur = [uint] "*" [uint]
           / "+"
           / "?"
        
     occur = [uint] "*" [uint]
           / "+"
           / "?"
        
     uint = DIGIT1 *DIGIT
          / "0x" 1*HEXDIG
          / "0b" 1*BINDIG
          / "0"
        
     uint = DIGIT1 *DIGIT
          / "0x" 1*HEXDIG
          / "0b" 1*BINDIG
          / "0"
        

value = number / text / bytes

值=数字/文本/字节

     int = ["-"] uint
        
     int = ["-"] uint
        
     ; This is a float if it has fraction or exponent; int otherwise
     number = hexfloat / (int ["." fraction] ["e" exponent ])
     hexfloat = ["-"] "0x" 1*HEXDIG ["." 1*HEXDIG] "p" exponent
     fraction = 1*DIGIT
     exponent = ["+"/"-"] 1*DIGIT
        
     ; This is a float if it has fraction or exponent; int otherwise
     number = hexfloat / (int ["." fraction] ["e" exponent ])
     hexfloat = ["-"] "0x" 1*HEXDIG ["." 1*HEXDIG] "p" exponent
     fraction = 1*DIGIT
     exponent = ["+"/"-"] 1*DIGIT
        
     text = %x22 *SCHAR %x22
     SCHAR = %x20-21 / %x23-5B / %x5D-7E / %x80-10FFFD / SESC
     SESC = "\" (%x20-7E / %x80-10FFFD)
        
     text = %x22 *SCHAR %x22
     SCHAR = %x20-21 / %x23-5B / %x5D-7E / %x80-10FFFD / SESC
     SESC = "\" (%x20-7E / %x80-10FFFD)
        
     bytes = [bsqual] %x27 *BCHAR %x27
     BCHAR = %x20-26 / %x28-5B / %x5D-10FFFD / SESC / CRLF
     bsqual = "h" / "b64"
        
     bytes = [bsqual] %x27 *BCHAR %x27
     BCHAR = %x20-26 / %x28-5B / %x5D-10FFFD / SESC / CRLF
     bsqual = "h" / "b64"
        
     id = EALPHA *(*("-" / ".") (EALPHA / DIGIT))
     ALPHA = %x41-5A / %x61-7A
     EALPHA = ALPHA / "@" / "_" / "$"
     DIGIT = %x30-39
     DIGIT1 = %x31-39
     HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
     BINDIG = %x30-31
        
     id = EALPHA *(*("-" / ".") (EALPHA / DIGIT))
     ALPHA = %x41-5A / %x61-7A
     EALPHA = ALPHA / "@" / "_" / "$"
     DIGIT = %x30-39
     DIGIT1 = %x31-39
     HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
     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
        
     S = *WS
     WS = SP / NL
     SP = %x20
     NL = COMMENT / CRLF
     COMMENT = ";" *PCHAR CRLF
     PCHAR = %x20-7E / %x80-10FFFD
     CRLF = %x0A / %x0D.0A
        

Figure 13: CDDL ABNF

图13:CDDL ABNF

Note that this ABNF does not attempt to reflect the detailed rules of what can be in a prefixed byte string.

请注意,此ABNF并不试图反映前缀字节字符串中可能包含的内容的详细规则。

Appendix C. Matching Rules
附录C.匹配规则

This appendix is normative.

本附录为规范性附录。

In this appendix, we go through the ABNF syntax rules defined in Appendix B and briefly describe the matching semantics of each syntactic feature. In this context, an instance (data item) "matches" a CDDL specification if it is allowed by the CDDL specification; this is then broken down into parts of specifications (type and group expressions) and parts of instances (data items).

在本附录中,我们将介绍附录B中定义的ABNF语法规则,并简要描述每个语法特征的匹配语义。在此上下文中,如果CDDL规范允许,则实例(数据项)“匹配”CDDL规范;然后将其分解为部分规范(类型和组表达式)和部分实例(数据项)。

cddl = S 1*(rule S)

cddl=s1*(规则S)

A CDDL specification is a sequence of one or more rules. Each rule gives a name to a right-hand-side expression, either a CDDL type or a CDDL group. Rule names can be used in the rule itself and/or other rules (and tools can output warnings if that is not the case). The order of the rules is significant only in two cases:

CDDL规范是一个或多个规则的序列。每个规则为右侧表达式(CDDL类型或CDDL组)提供一个名称。规则名称可以在规则本身和/或其他规则中使用(如果不是这样,工具可以输出警告)。规则的顺序仅在两种情况下重要:

1. The first rule defines the semantics of the entire specification; hence, there is no need to give that root rule a special name or special syntax in the language (as, for example, with "start" in RELAX NG); its name can therefore be chosen to be descriptive. (As with all other rule names, the name of the initial rule may be used in itself or in other rules.)

1. 第一条规则定义了整个规范的语义;因此,不需要在语言中为根规则指定特殊名称或特殊语法(例如,在RELAXNG中使用“start”);因此,其名称可以选择为描述性名称。(与所有其他规则名称一样,初始规则的名称可在其自身或其他规则中使用。)

2. Where a rule contributes to a type or group choice (using "/=" or "//="), that choice is populated in the order the rules are given; see below.

2. 如果规则有助于类型或组选择(使用“/=”或“/=”),则按照规则给出的顺序填充该选择;见下文。

rule = typename [genericparm] S assignt S type / groupname [genericparm] S assigng S grpent

规则=typename[genericparm]S assignt S type/groupname[genericparm]S assigng S grpent

typename = id groupname = id

typename=id groupname=id

   A rule defines a name for a type expression (production "type") or
   for a group expression (production "grpent"), with the intention that
   the semantics does not change when the name is replaced by its
   (parenthesized if needed) definition.  Note that whether the name
   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"
   is a type, or a group if "b" is a group.  More subtly, in "a = (b)",
   "a" may be used as a type if "b" is a type, or as a group both when
   "b" is a group and when "b" is a type (a good convention to make the
   latter case stand out to the human reader is to write "a = (b,)").
   (Note that the same dual meaning of parentheses applies within an
   expression but often can be resolved by the context of the
   parenthesized expression.  On the more general point, it may not be
   clear immediately either whether "b" stands for a group or a type --
   this semantic processing may need to span several levels of rule
   definitions before a determination can be made.)
        
   A rule defines a name for a type expression (production "type") or
   for a group expression (production "grpent"), with the intention that
   the semantics does not change when the name is replaced by its
   (parenthesized if needed) definition.  Note that whether the name
   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"
   is a type, or a group if "b" is a group.  More subtly, in "a = (b)",
   "a" may be used as a type if "b" is a type, or as a group both when
   "b" is a group and when "b" is a type (a good convention to make the
   latter case stand out to the human reader is to write "a = (b,)").
   (Note that the same dual meaning of parentheses applies within an
   expression but often can be resolved by the context of the
   parenthesized expression.  On the more general point, it may not be
   clear immediately either whether "b" stands for a group or a type --
   this semantic processing may need to span several levels of rule
   definitions before a determination can be made.)
        
   assignt = "=" / "/="
   assigng = "=" / "//="
        
   assignt = "=" / "/="
   assigng = "=" / "//="
        

A plain equals sign defines the rule name as the equivalent of the expression to the right; it is an error if the name was already defined with a different expression. A "/=" or "//=" extends a named type or a group by additional choices; a number of these could be replaced by collecting all the right-hand sides and creating a single rule with a type choice or a group choice built from the right-hand sides in the order of the rules given. (It is not an error to extend a rule name that has not yet been defined; this makes the right-hand side the first entry in the choice being created.)

普通等号将规则名称定义为右侧表达式的等价项;如果名称已使用其他表达式定义,则为错误。A“/=”或“/=”通过附加选项扩展命名类型或组;其中一些可以通过收集所有右侧并创建一个单一规则来替代,该规则包含一个类型选择或一个组选择,这些规则是按照给定规则的顺序从右侧构建的。(扩展尚未定义的规则名称不是错误;这将使右侧成为正在创建的选项中的第一个条目。)

   genericparm = "<" S id S *("," S id S ) ">"
   genericarg = "<" S type1 S *("," S type1 S ) ">"
        
   genericparm = "<" S id S *("," S id S ) ">"
   genericarg = "<" S type1 S *("," S type1 S ) ">"
        

Rule names can have generic parameters, which cause temporary assignments within the right-hand sides to the parameter names from 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 choice matches a data item if the data item matches any one of the types given in the choice. The choice uses PEG semantics as discussed in Appendix A: the first choice that matches wins. (As a result, the order of rules that contribute to a single rule name can very well matter.)

类型可以在一个或多个类型之间进行选择。如果数据项与选项中给定的任何一种类型匹配,则该选项与该数据项匹配。该选项使用PEG语义,如附录A所述:匹配的第一个选项获胜。(因此,构成单个规则名称的规则顺序可能非常重要。)

type1 = type2 [S (rangeop / ctlop) S type2]

type1=type2[S(rangeop/ctlop)S type2]

Two types can be combined with a range operator (see below) or a control operator (see Section 3.8).

两种类型可与范围操作员(见下文)或控制操作员(见第3.8节)组合。

   type2 = value
        
   type2 = value
        

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 conversions defined),

一个类型只能是一个值(如1或“icecream”或h'0815'),它只匹配具有该特定值的数据项(未定义转换),

/ typename [genericarg]

/typename[通用标记]

or be defined by a rule giving a meaning to a name (possibly after supplying generic arguments as required by the generic parameters),

或者由赋予名称含义的规则定义(可能在按照通用参数的要求提供通用参数之后),

/ "(" S type S ")"

/“(“S类型S”)”

or be defined in a parenthesized type expression (parentheses may be necessary to override some operator precedence), or

或在带括号的类型表达式中定义(括号可能是重写某些运算符优先级所必需的),或

      / "{" S group S "}"
        
      / "{" S group S "}"
        

a map expression, which matches a valid CBOR map the key/value pairs of which can be ordered in such a way that the resulting sequence matches the group expression, or

映射表达式,与有效的CBOR映射匹配,其键/值对的排序方式可以使生成的序列与组表达式匹配,或

/ "[" S group S "]"

/“[“S组S”]”

an array expression, which matches a CBOR array the elements of which -- when taken as values and complemented by a wildcard (matches anything) key each -- match the group, or

一个数组表达式,它匹配一个CBOR数组,该数组的元素(当作为值并由通配符(匹配任何项)进行补充时)与组匹配,或者

/ "~" S typename [genericarg]

/“~”的类型名[genericarg]

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

“未包装”组(见第3.7节),通过包装组与定义为映射或数组的类型内的组相匹配,或

/ "&" S "(" S group S ")" / "&" S groupname [genericarg]

/“&”S”(“S组S”)“/“&”S组名[genericarg]

an enumeration expression, which matches any value that is within the set of values that the values of the group given can take, or

枚举表达式,该表达式与给定组的值可以采用的值集中的任何值相匹配,或

      / "#" "6" ["." uint] "(" S type S ")"
        
      / "#" "6" ["." uint] "(" S type S ")"
        

a tagged data item, tagged with the "uint" given and containing the type given as the tagged value, or

标记的数据项,用给定的“uint”标记,并包含作为标记值给定的类型,或

      / "#" DIGIT ["." uint]                ; major/ai
        
      / "#" DIGIT ["." uint]                ; major/ai
        

a data item of a major type (given by the DIGIT), optionally constrained to the additional information given by the uint, or

一种主要类型的数据项(由数字给出),可选择地受限于uint给出的附加信息,或

      / "#"                                 ; any
        
      / "#"                                 ; any
        

any data item.

任何数据项。

   rangeop = "..." / ".."
        
   rangeop = "..." / ".."
        

A range operator can be used to join two type expressions that stand for either two integer values or two floating-point values; it 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 included for ".." and excluded for "...".

范围运算符可用于联接表示两个整数值或两个浮点值的两个类型表达式;它匹配两个值之间的任何值,其中第一个值始终包含在匹配集中,第二个值包含在“.”中,排除在“…”中。

ctlop = "." id

ctlop=“”id

A control operator ties a _target_ type to a _controller_ type as defined in Section 3.8. Note that control operators are an extension point for CDDL; additional documents may want to define additional control operators.

控制操作员将第3.8节中定义的_目标uuuuu类型与_控制器uuu类型联系起来。注意,控制操作符是CDDL的扩展点;其他文档可能需要定义其他控制运算符。

   group = grpchoice *(S "//" S grpchoice)
        
   group = grpchoice *(S "//" S grpchoice)
        

A group matches any sequence of key/value pairs that matches any of the choices given (again using PEG semantics).

一个组匹配任何键/值对序列,这些键/值对匹配给定的任何选择(同样使用PEG语义)。

   grpchoice = *(grpent optcom)
        
   grpchoice = *(grpent optcom)
        

Each of the component groups is given as a sequence of group entries. For a match, the sequence of key/value pairs given needs to match the sequence of group entries in the sequence given.

每个组件组都以组条目序列的形式给出。对于匹配,给定的键/值对序列需要与给定序列中的组条目序列匹配。

   grpent = [occur S] [memberkey S] type
        
   grpent = [occur S] [memberkey S] type
        

A group entry can be given by a value type, which needs to be matched by the value part of a single element; and, optionally, a memberkey type, which needs to be matched by the key part of the element, if

组条目可以由值类型给出,该值类型需要与单个元素的值部分匹配;以及可选的memberkey类型,该类型需要与元素的键部分匹配,如果

the memberkey is given. If the memberkey is not given, the entry can only be used for matching arrays, not for maps. (See below for how that is modified by the occurrence indicator.)

memberkey已给定。如果未提供memberkey,则该条目只能用于匹配数组,而不能用于映射。(请参见下文,了解发生指示器是如何修改的。)

/ [occur S] groupname [genericarg] ; preempted by above

/[S]组名[genericarg];先发制人

A group entry can be built from a named group, or

可以从命名组生成组条目,或

/ [occur S] "(" S group S ")"

/ [occur S] "(" S group S ")"translate error, please retry

from a parenthesized group, again with a possible occurrence indicator.

从括号中的组中,再次使用可能出现的指示符。

   memberkey = type1 S ["^" S] "=>"
             / bareword S ":"
             / value S ":"
        
   memberkey = type1 S ["^" S] "=>"
             / bareword S ":"
             / value S ":"
        

Key types can be given by a type expression, a bareword (which stands for a type that just contains a string value created from this bareword), or a value (which stands for a type that just contains this value). A key value matches its key type if the key value is a member of the key type, unless a cut preceding it in the group applies (see Section 3.5.4 for how map matching is influenced by the presence of the cuts denoted by "^" or ":" in previous entries).

键类型可以由类型表达式、裸字(表示仅包含由该裸字创建的字符串值的类型)或值(表示仅包含该值的类型)给出。如果键值是键值类型的一个成员,则键值与其键值类型匹配,除非在组中它前面的剪切适用(参见第3.5.4节,了解在前面的条目中存在以“^”或“:”表示的剪切如何影响映射匹配)。

   bareword = id
        
   bareword = id
        

A bareword is an alternative way to write a type with a single text string value; it can only be used in the syntactic context given above.

裸字是用单个文本字符串值编写类型的另一种方法;它只能在上面给出的语法上下文中使用。

optcom = S ["," S]

optcom=S[“,”S]

(Optional commas do not influence the matching.)

(可选逗号不影响匹配。)

   occur = [uint] "*" [uint]
         / "+"
         / "?"
        
   occur = [uint] "*" [uint]
         / "+"
         / "?"
        

An occurrence indicator modifies the group given to its right by requiring the group to match the sequence to be matched exactly for a certain number of times (see Section 3.2) in sequence, i.e., it acts as a (possibly infinite) group choice that contains choices with the group repeated each of the occurrences times.

发生指示器通过要求组在一定次数(见第3.2节)内按顺序精确匹配要匹配的序列来修改其右侧给定的组,即,它作为(可能无限)组选择,包含组在每次发生时重复的选择。

The rest of the ABNF describes syntax for value notation that should be familiar to readers from programming languages, with the possible exception of h'..' and b64'..' for byte strings, as well as syntactic elements such as comments and line ends.

ABNF的其余部分描述了编程语言读者应该熟悉的值表示法的语法,字节字符串的h'..和b64'..以及注释和行尾等语法元素除外。

Appendix D. Standard Prelude
附录D.标准前奏曲

This appendix is normative.

本附录为规范性附录。

The following prelude is automatically added to each CDDL file. (Note that technically, it is a postlude, as it does not disturb the selection of the first rule as the root of the definition.)

以下序言将自动添加到每个CDDL文件中。(请注意,从技术上讲,它是一个后置规则,因为它不会干扰第一个规则作为定义根的选择。)

                  any = #
        
                  any = #
        
                  uint = #0
                  nint = #1
                  int = uint / nint
        
                  uint = #0
                  nint = #1
                  int = uint / nint
        
                  bstr = #2
                  bytes = bstr
                  tstr = #3
                  text = tstr
        
                  bstr = #2
                  bytes = bstr
                  tstr = #3
                  text = tstr
        
                  tdate = #6.0(tstr)
                  time = #6.1(number)
                  number = int / float
                  biguint = #6.2(bstr)
                  bignint = #6.3(bstr)
                  bigint = biguint / bignint
                  integer = int / bigint
                  unsigned = uint / biguint
                  decfrac = #6.4([e10: int, m: integer])
                  bigfloat = #6.5([e2: int, m: integer])
                  eb64url = #6.21(any)
                  eb64legacy = #6.22(any)
                  eb16 = #6.23(any)
                  encoded-cbor = #6.24(bstr)
                  uri = #6.32(tstr)
                  b64url = #6.33(tstr)
                  b64legacy = #6.34(tstr)
                  regexp = #6.35(tstr)
                  mime-message = #6.36(tstr)
                  cbor-any = #6.55799(any)
        
                  tdate = #6.0(tstr)
                  time = #6.1(number)
                  number = int / float
                  biguint = #6.2(bstr)
                  bignint = #6.3(bstr)
                  bigint = biguint / bignint
                  integer = int / bigint
                  unsigned = uint / biguint
                  decfrac = #6.4([e10: int, m: integer])
                  bigfloat = #6.5([e2: int, m: integer])
                  eb64url = #6.21(any)
                  eb64legacy = #6.22(any)
                  eb16 = #6.23(any)
                  encoded-cbor = #6.24(bstr)
                  uri = #6.32(tstr)
                  b64url = #6.33(tstr)
                  b64legacy = #6.34(tstr)
                  regexp = #6.35(tstr)
                  mime-message = #6.36(tstr)
                  cbor-any = #6.55799(any)
        
                  float16 = #7.25
                  float32 = #7.26
                  float64 = #7.27
                  float16-32 = float16 / float32
                  float32-64 = float32 / float64
                  float = float16-32 / float64
        
                  float16 = #7.25
                  float32 = #7.26
                  float64 = #7.27
                  float16-32 = float16 / float32
                  float32-64 = float32 / float64
                  float = float16-32 / float64
        
                  false = #7.20
                  true = #7.21
                  bool = false / true
                  nil = #7.22
                  null = nil
                  undefined = #7.23
        
                  false = #7.20
                  true = #7.21
                  bool = false / true
                  nil = #7.22
                  null = nil
                  undefined = #7.23
        

Figure 14: CDDL Prelude

图14:CDDL前奏曲

Note that the prelude is deemed to be fixed. This means, for instance, that additional tags beyond those defined in [RFC7049], as registered, need to be defined in each CDDL file that is using them.

请注意,前奏被认为是固定的。这意味着,例如,除了[RFC7049]中定义的标记外,还需要在使用它们的每个CDDL文件中定义注册的其他标记。

A common stumbling point is that the prelude does not define a type "string". CBOR has byte strings ("bytes" in the prelude) and text strings ("text"), so a type that is simply called "string" would be ambiguous.

一个常见的障碍是前奏曲没有定义“字符串”类型。CBOR有字节字符串(“前奏中的字节”)和文本字符串(“文本”),因此简单称为“字符串”的类型是不明确的。

Appendix E. Use with JSON
附录E.与JSON一起使用

This appendix is normative.

本附录为规范性附录。

The JSON generic data model (implicit in [RFC8259]) is a subset of the generic data model of CBOR. So, one can use CDDL with JSON by limiting oneself to what can be represented in JSON. Roughly speaking, this means leaving out byte strings, tags, and simple values other than "false", "true", and "null", leading to the following limited prelude:

JSON通用数据模型(隐含在[RFC8259]中)是CBOR通用数据模型的子集。因此,可以将CDDL与JSON结合使用,只使用JSON中可以表示的内容。粗略地说,这意味着除了“false”、“true”和“null”之外,省略字节字符串、标记和简单值,从而产生以下有限的前奏:

                      any = #
        
                      any = #
        
                      uint = #0
                      nint = #1
                      int = uint / nint
        
                      uint = #0
                      nint = #1
                      int = uint / nint
        
                      tstr = #3
                      text = tstr
        
                      tstr = #3
                      text = tstr
        
                      number = int / float
        
                      number = int / float
        
                      float16 = #7.25
                      float32 = #7.26
                      float64 = #7.27
                      float16-32 = float16 / float32
                      float32-64 = float32 / float64
                      float = float16-32 / float64
        
                      float16 = #7.25
                      float32 = #7.26
                      float64 = #7.27
                      float16-32 = float16 / float32
                      float32-64 = float32 / float64
                      float = float16-32 / float64
        
                      false = #7.20
                      true = #7.21
                      bool = false / true
                      nil = #7.22
                      null = nil
        
                      false = #7.20
                      true = #7.21
                      bool = false / true
                      nil = #7.22
                      null = nil
        

Figure 15: JSON-Compatible Subset of CDDL Prelude

图15:CDDL Prelude的JSON兼容子集

(The major types given here do not have a direct meaning in JSON, but they can be interpreted as CBOR major types translated through Section 4 of [RFC7049].)

(此处给出的主要类型在JSON中没有直接含义,但它们可以解释为CBOR主要类型,通过[RFC7049]第4节进行翻译。)

There are a few fine points in using CDDL with JSON. First, JSON does not distinguish between integers and floating-point numbers; 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 becomes a predicate that the number be integral. As an example, this means that the following JSON numbers are all matching "uint":

将CDDL与JSON结合使用有几个优点。首先,JSON不区分整数和浮点数;只有一种数字(可能恰好是整数)。在这种情况下,将类型指定为“uint”、“nint”或“int”将成为数字为整数的谓词。例如,这意味着以下JSON编号都与“uint”匹配:

10 10.0 1e1 1.0e1 100e-1

10.0 1e1 1.0e1 100e-1

(The fact that these are all integers may be surprising to users accustomed to the long tradition in programming languages of using decimal points or exponents in a number to indicate a floating-point literal.)

(这些都是整数的事实可能会让习惯于编程语言中使用小数点或指数来表示浮点文字的悠久传统的用户感到惊讶。)

CDDL distinguishes the various CBOR number types, but there is only one number type in JSON. The effect of specifying a floating-point precision (float16/float32/float64) is only to restrict the set of

CDDL区分各种CBOR数字类型,但JSON中只有一种数字类型。指定浮点精度(float16/float32/float64)的效果只是限制

permissible values to those expressible with binary16/binary32/ binary64; this is unlikely to be very useful when using CDDL for specifying JSON data structures.

可使用binary16/binary32/binary64表示的允许值;当使用CDDL指定JSON数据结构时,这不太可能非常有用。

Fundamentally, the number system of JSON itself is based on decimal numbers and decimal fractions and does not have limits to its precision or range. In practice, JSON numbers are often parsed into a number type that is called "float64" here, creating a number of limitations to the generic data model [RFC7493]. In particular, this means that integers can only be expressed with interoperable exactness when they lie in the range [-(2**53)+1, (2**53)-1] -- a smaller range than that covered by CDDL "int".

从根本上讲,JSON本身的数字系统是基于十进制数和十进制分数的,对其精度或范围没有限制。实际上,JSON数字通常被解析为一种数字类型,在这里称为“float64”,这对通用数据模型[RFC7493]造成了许多限制。特别是,这意味着只有当整数位于[-(2**53)+1,(2**53)-1]范围内时,才能以可互操作的精确性表示它们——该范围小于CDDL“int”所涵盖的范围。

JSON applications that want to stay compatible with I-JSON ("Internet JSON"; see [RFC7493]) may therefore want to define integer 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 into the CDDL specification if needed.

因此,想要与I-JSON保持兼容的JSON应用程序(“Internet JSON”;参见[RFC7493])可能需要定义范围更有限的整数类型,如图16所示。请注意,这里给出的类型不是前奏曲的一部分;如果需要,需要将它们复制到CDDL规范中。

               ij-uint = 0..9007199254740991
               ij-nint = -9007199254740991..-1
               ij-int = -9007199254740991..9007199254740991
        
               ij-uint = 0..9007199254740991
               ij-nint = -9007199254740991..-1
               ij-int = -9007199254740991..9007199254740991
        

Figure 16: I-JSON Types for CDDL (Not Part of Prelude)

图16:CDDL的I-JSON类型(不是前奏曲的一部分)

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 integers supported by "int" (= "uint"/"nint") may want to use the following additional types from the standard prelude, which are expressed in terms of tags but can straightforwardly be mapped into JSON (but not I-JSON) numbers:

不需要与I-JSON保持兼容并且实际上可能需要超出“int”(=“uint”/“nint”)支持的64位无符号和负整数的JSON应用程序可能需要使用标准prelude中的以下附加类型,这些类型以标记表示,但可以直接映射到JSON(但不是I-JSON)编号:

      biguint = #6.2(bstr)
      bignint = #6.3(bstr)
      bigint = biguint / bignint
      integer = int / bigint
      unsigned = uint / biguint
        
      biguint = #6.2(bstr)
      bignint = #6.3(bstr)
      bigint = biguint / bignint
      integer = int / bigint
      unsigned = uint / biguint
        

CDDL at this point does not have a way to express the unlimited floating-point precision that is theoretically possible with JSON; at the time of writing, this is rarely used in protocols in practice.

CDDL在这一点上无法表达JSON理论上可以实现的无限浮点精度;在撰写本文时,这在实际协议中很少使用。

Note that a data model described in CDDL is always restricted by what can be expressed in the serialization; e.g., floating-point values such as NaN (not a number) and the infinities cannot be represented in JSON even if they are allowed in the CDDL generic data model.

注意,CDDL中描述的数据模型总是受到序列化中可以表达的内容的限制;e、 例如,浮点值如NaN(不是数字)和无穷大不能用JSON表示,即使它们在CDDL通用数据模型中是允许的。

Appendix F. A CDDL Tool
附录F.CDDL工具

This appendix is for information only.

本附录仅供参考。

A rough CDDL tool is available. For CDDL specifications, it can check the syntax, generate one or more instances (expressed in CBOR diagnostic notation or in pretty-printed JSON), and validate an existing instance against the specification:

可以使用粗略的CDDL工具。对于CDDL规范,它可以检查语法,生成一个或多个实例(用CBOR诊断符号或漂亮打印的JSON表示),并根据规范验证现有实例:

Usage: cddl spec.cddl generate [n] cddl spec.cddl json-generate [n] cddl spec.cddl validate instance.cbor cddl spec.cddl validate instance.json

用法:cddl spec.cddl generate[n]cddl spec.cddl json generate[n]cddl spec.cddl validate instance.cbor cddl spec.cddl validate instance.json

Figure 17: CDDL Tool Usage

图17:CDDL工具的使用

Install on a system with a modern Ruby via:

通过以下方式安装在具有现代Ruby的系统上:

gem install cddl

gem安装cddl

Figure 18: CDDL Tool Installation

图18:CDDL工具安装

The accompanying CBOR diagnostic tools (which are automatically installed by the above) are described in <https://github.com/cabo/ cbor-diag>; they can be used to convert between binary CBOR, a pretty-printed hexadecimal form of binary CBOR, CBOR diagnostic notation, JSON, and YAML [YAML].

随附的CBOR诊断工具(由上述人员自动安装)如中所述<https://github.com/cabo/ cbor诊断>;它们可以用于在二进制CBOR(二进制CBOR的一种打印精美的十六进制形式)、CBOR诊断符号、JSON和YAML[YAML]之间进行转换。

Appendix G. Extended Diagnostic Notation

附录G.扩展诊断符号

This appendix is normative.

本附录为规范性附录。

Section 6 of [RFC7049] defines a "diagnostic notation" in order to be able to converse about CBOR data items without having to resort to binary data. Diagnostic notation is based on JSON, with extensions for representing CBOR constructs such as binary data and tags.

[RFC7049]的第6节定义了一种“诊断符号”,以便能够在无需使用二进制数据的情况下转换CBOR数据项。诊断表示法基于JSON,带有表示CBOR结构(如二进制数据和标记)的扩展。

(Standardizing this together with the actual interchange format does not serve to create another interchange format but enables the use of a shared diagnostic notation in tools for and documents about CBOR.)

(将其与实际交换格式一起标准化并不能创建另一种交换格式,但可以在CBOR的工具和文档中使用共享诊断符号。)

This appendix discusses a few extensions to the diagnostic notation that have turned out to be useful since RFC 7049 was written. We refer to the result as Extended Diagnostic Notation (EDN).

本附录讨论了自编写RFC 7049以来对诊断符号的一些扩展,这些扩展被证明是有用的。我们将结果称为扩展诊断符号(EDN)。

G.1. Whitespace in Byte String Notation
G.1. 字节字符串表示法中的空白

Examples often benefit from some whitespace (spaces, line breaks) in byte strings. In EDN, whitespace is ignored in prefixed byte strings; for instance, the following are equivalent:

示例通常受益于字节字符串中的一些空白(空格、换行符)。在EDN中,在前缀字节字符串中忽略空白;例如,以下是等效的:

h'48656c6c6f20776f726c64' h'48 65 6c 6c 6f 20 77 6f 72 6c 64' h'4 86 56c 6c6f 20776 f726c64'

h'48656c6c6f20776f726c64'h'48656C6C6C6F20776F726C664'h'488656C6F20776 f726c64'

G.2. Text in Byte String Notation
G.2. 字节字符串表示法中的文本

Diagnostic notation notates byte strings in one of the base encodings per [RFC4648], enclosed in single quotes, prefixed by >h< for base16, >b32< for base32, >h32< for base32hex, or >b64< for base64 or base64url. Quite often, byte strings carry bytes that are meaningfully interpreted as UTF-8 text. EDN allows the use of single quotes without a prefix to express byte strings with UTF-8 text; for instance, the following are equivalent:

诊断表示法根据[RFC4648]在一个基本编码中表示字节字符串,并用单引号括起来,对于base16,前缀为>h<,对于base32,前缀为>b32<,对于base32hex,前缀为>h32<,对于base64或base64url,前缀为>b64<。通常,字节字符串携带有意义地解释为UTF-8文本的字节。EDN允许使用不带前缀的单引号来表示具有UTF-8文本的字节字符串;例如,以下是等效的:

'hello world' h'68656c6c6f20776f726c64'

'你好世界'h'68656C6F20776F726C64'

The escaping rules of JSON strings are applied equivalently for text-based byte strings, e.g., "\" stands for a single backslash and "'" stands for a single quote. Whitespace is included literally, i.e., the previous section does not apply to text-based byte strings.

JSON字符串的转义规则等效地应用于基于文本的字节字符串,例如,“\”代表单个反斜杠,“'”代表单个引号。空格按字面意思包括在内,即上一节不适用于基于文本的字节字符串。

G.3. Embedded CBOR and CBOR Sequences in Byte Strings
G.3. 字节字符串中的嵌入式CBOR和CBOR序列

Where a byte string is to carry an embedded CBOR-encoded item, or more generally a sequence of zero or more such items, the diagnostic notation for these zero or more CBOR data items, separated by commas, can be enclosed in << and >> to notate the byte string resulting from encoding the data items and concatenating the result. For instance, each pair of columns in the following are equivalent:

如果字节字符串携带嵌入式CBOR编码项,或者更一般地说,携带零个或多个此类项的序列,则这些零个或多个CBOR数据项的诊断符号(用逗号分隔)可以包含在<<和>>中,以表示编码数据项并连接结果所产生的字节字符串。例如,下面的每对列都是等效的:

      <<1>>              h'01'
      <<1, 2>>           h'0102'
      <<"foo", null>>    h'63666F6FF6'
      <<>>               h''
        
      <<1>>              h'01'
      <<1, 2>>           h'0102'
      <<"foo", null>>    h'63666F6FF6'
      <<>>               h''
        
G.4. Concatenated Strings
G.4. 串联字符串

While the ability to include whitespace enables line-breaking of encoded byte strings, a mechanism is needed to be able to include text strings as well as byte strings in direct UTF-8 representation into line-based documents (such as RFCs and source code).

虽然包含空格的功能可以使编码字节字符串分行,但需要一种机制,能够将文本字符串以及直接UTF-8表示的字节字符串包含到基于行的文档(如RFC和源代码)中。

We extend the diagnostic notation by allowing multiple text strings or multiple byte strings to be notated separated by whitespace; these are then concatenated into a single text or byte string, respectively. Text strings and byte strings do not mix within such a concatenation, except that byte string notation can be used inside a sequence of concatenated text string notation to encode characters that may be better represented in an encoded way. The following four values are equivalent:

我们通过允许用空格分隔多个文本字符串或多个字节字符串来扩展诊断表示法;然后将它们分别连接成单个文本或字节字符串。文本字符串和字节字符串不会在这样的串联中混合,除非字节字符串表示法可以在串联文本字符串表示法序列中使用,以编码可能更好地以编码方式表示的字符。以下四个值是等效的:

"Hello world" "Hello " "world" "Hello" h'20' "world" "" h'48656c6c6f20776f726c64' ""

“Hello world”“Hello”“world”“Hello”“h'20”“世界”“h'48656c6c6f20776f726c64”“”

Similarly, the following byte string values are equivalent:

同样,以下字节字符串值是等效的:

'Hello world' 'Hello ' 'world' 'Hello ' h'776f726c64' 'Hello' h'20' 'world' '' h'48656c6c6f20776f726c64' '' b64'' h'4 86 56c 6c6f' h' 20776 f726c64'

“Hello world”“Hello”“world”“Hello”“h'776f726c64”“Hello”“h'20”“world”“h'48656c6c6f20776f726c64”“b64”“h'4886 56c 6c6f”“h'20776 f726c64”

(Note that the approach of separating by whitespace, while familiar from the C language, requires some attention -- a single comma makes a big difference here.)

(注意,用空格分隔的方法虽然与C语言很熟悉,但需要注意——一个逗号在这里会有很大的不同。)

G.5. Hexadecimal, Octal, and Binary Numbers
G.5. 十六进制、八进制和二进制数

In addition to JSON's decimal numbers, EDN provides hexadecimal, octal, and binary numbers in the usual C-language notation (octal with 0o prefix present only).

除了JSON的十进制数之外,EDN还提供了常用C语言表示法中的十六进制数、八进制数和二进制数(八进制数仅包含0o前缀)。

The following are equivalent:

以下是等效的:

4711 0x1267 0o11147 0b1001001100111

4711 0x1267 0o11147 0b1001001100111

As are:

它们是:

1.5 0x1.8p0 0x18p-4

1.5 0x1.8p0 0x18p-4

G.6. Comments
G.6. 评论

Longer pieces of diagnostic notation may benefit from comments. JSON famously does not provide for comments, and basic diagnostic notation per RFC 7049 inherits this property.

较长的诊断符号可能会从注释中受益。众所周知,JSON不提供注释,每个RFC7049的基本诊断符号继承了这个属性。

In EDN, comments can be included, delimited by slashes ("/"). Any text within and including a pair of slashes is considered a comment.

在EDN中,可以包含注释,并用斜杠(“/”)分隔。任何包含一对斜杠的文本都被视为注释。

Comments are considered whitespace. Hence, they are allowed in prefixed byte strings; for instance, the following are equivalent:

注释被视为空白。因此,在前缀字节字符串中允许它们;例如,以下是等效的:

      h'68656c6c6f20776f726c64'
      h'68 65 6c /doubled l!/ 6c 6f /hello/
        20 /space/
        77 6f 72 6c 64' /world/
        
      h'68656c6c6f20776f726c64'
      h'68 65 6c /doubled l!/ 6c 6f /hello/
        20 /space/
        77 6f 72 6c 64' /world/
        

This can be used to annotate a CBOR structure as in:

这可用于注释CBOR结构,如中所示:

      /grasp-message/ [/M_DISCOVERY/ 1, /session-id/ 10584416,
                       /objective/ [/objective-name/ "opsonize",
                                    /D, N, S/ 7, /loop-count/ 105]]
        
      /grasp-message/ [/M_DISCOVERY/ 1, /session-id/ 10584416,
                       /objective/ [/objective-name/ "opsonize",
                                    /D, N, S/ 7, /loop-count/ 105]]
        

(There are currently no end-of-line comments. If we want to add them, "//" sounds like a reasonable delimiter given that we already use slashes for comments, but we could also go, for example, for "#".)

(目前没有行尾注释。如果我们要添加它们,“/”听起来像是一个合理的分隔符,因为我们已经使用斜杠作为注释,但我们也可以使用,例如“#”)

Appendix H. Examples

附录H.示例

This appendix is for information only.

本附录仅供参考。

This appendix contains a few examples of structures defined using CDDL. The theme for the examples 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 that RFC.

本附录包含一些使用CDDL定义的结构示例。示例的主题取自[RFC7071],它用英语定义了某些JSON结构。对于一个类似的例子,还可以查看[RFC8007]的附录a,其中包含RFC主体中定义的JSON结构的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], [GRASP], and [RFC8428].

这些示例都恰巧描述了在JSON中交换的数据。在CBOR中交换的数据的CDDL定义示例可在[RFC8152]、[GRASP]和[RFC8428]中找到。

[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:

[RFC7071]使用某种形式化的英文文本定义JSON的“reputon”结构。以下是使用相同术语的(有些冗长)等效定义,但以CDDL表示:

                 reputation-object = {
                   reputation-context,
                   reputon-list
                 }
        
                 reputation-object = {
                   reputation-context,
                   reputon-list
                 }
        
                 reputation-context = (
                   application: text
                 )
        
                 reputation-context = (
                   application: text
                 )
        
                 reputon-list = (
                   reputons: reputon-array
                 )
        
                 reputon-list = (
                   reputons: reputon-array
                 )
        
                 reputon-array = [* reputon]
        
                 reputon-array = [* reputon]
        
                 reputon = {
                   rater-value,
                   assertion-value,
                   rated-value,
                   rating-value,
                   ? conf-value,
                   ? normal-value,
                   ? sample-value,
                   ? gen-value,
                   ? expire-value,
                   * ext-value,
                 }
        
                 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 )
        
                 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]
                        }
        
                        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
                        }
        
                        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).

请注意,这相当清楚地描述了[RFC7071]第6.2.2节中被如此多的单词所覆盖的结构。此外,该定义明确了允许多个ext值(定义为不同的成员名称);可以读取RFC 7071以禁止重复ext值(“特定reputon元素不能出现多次”是不明确的)。

The CDDL tool described in Appendix F generates as one example:

附录F中描述的CDDL工具作为一个示例生成:

                  {
                    "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"
                      }
                    ]
                  }
        
                  {
                    "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"
                      }
                    ]
                  }
        

Acknowledgements

致谢

Inspiration was taken from the C and Pascal languages, MPEG's conventions for describing structures in the ISO base media file format, RELAX NG and its compact syntax [RELAXNG], and, in particular, Andrew Lee Newton's early proposals on JSON Content Rules (JCR) as found in draft version four (-04) of [JCR].

灵感来源于C和Pascal语言、MPEG描述ISO基本媒体文件格式结构的约定、RELAXNG及其紧凑语法[RELAXNG],特别是安德鲁·李·牛顿(Andrew Lee Newton)在[JCR]第四版(-04)草案中提出的关于JSON内容规则(JCR)的早期建议。

Lots of highly useful feedback came from members of the IETF CBOR WG -- in particular, Ari Keranen, Brian Carpenter, Burt Harris, Jeffrey Yasskin, Jim Hague, Jim Schaad, Joe Hildebrand, Max Pritikin, Michael Richardson, Pete Cordell, Sean Leonard, and Yaron Sheffer. Also, Francesca Palombini and Joe volunteered to chair the WG when it was created, providing the framework for generating and processing this feedback, with Barry Leiba having taken over from Joe since then. Chris Lonvick and Ines Robles provided additional reviews during IESG processing, and Alexey Melnikov steered the process as the responsible Area Director.

IETF CBOR工作组成员提供了大量非常有用的反馈,特别是Ari Keranen、Brian Carpenter、Burt Harris、Jeffrey Yasskin、Jim Hague、Jim Schaad、Joe Hildebrand、Max Pritikin、Michael Richardson、Pete Cordell、Sean Leonard和Yaron Sheffer。此外,Francesca Palombini和Joe在工作组成立时自愿担任工作组主席,为产生和处理反馈提供了框架,Barry Leiba从那时起接替Joe。Chris Lonvick和Ines Robles在IESG处理过程中提供了额外的审查,Alexey Melnikov作为负责的区域主管指导了该过程。

The CDDL tool described in Appendix F was written by Carsten Bormann, building on previous work by Troy Heninger and Tom Lord.

附录F中描述的CDDL工具是由Carsten Bormann在Troy Heninger和Tom Lord之前工作的基础上编写的。

Contributors

贡献者

CDDL was originally conceived by Bert Greevenbosch, who also wrote the original five draft versions of this document.

CDDL最初由Bert Greevenbosch构思,他还编写了本文档的五个原始草案版本。

Authors' Addresses

作者地址

Henk Birkholz Fraunhofer SIT Rheinstrasse 75 Darmstadt 64295 Germany

德国达姆施塔特75号亨克·比克霍尔茨·弗劳恩霍夫莱茵大街64295号

   Email: henk.birkholz@sit.fraunhofer.de
        
   Email: henk.birkholz@sit.fraunhofer.de
        

Christoph Vigano Universitaet Bremen

不来梅维加诺大学

   Email: christoph.vigano@uni-bremen.de
        
   Email: christoph.vigano@uni-bremen.de
        

Carsten Bormann Universitaet Bremen TZI Bibliothekstr. 1 Bremen D-28359 Germany

不来梅卡斯滕·鲍曼大学图书馆。1不来梅D-28359德国

   Phone: +49-421-218-63921
   Email: cabo@tzi.org
        
   Phone: +49-421-218-63921
   Email: cabo@tzi.org