<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.4 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-cbor-cddl-modules-01" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.19.0 -->
  <front>
    <title abbrev="CDDL Module Structure">CDDL Module Structure</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-cbor-cddl-modules-01"/>
    <author initials="C." surname="Bormann" fullname="Carsten Bormann">
      <organization>Universität Bremen TZI</organization>
      <address>
        <postal>
          <street>Postfach 330440</street>
          <city>Bremen</city>
          <code>D-28359</code>
          <country>Germany</country>
        </postal>
        <phone>+49-421-218-63921</phone>
        <email>cabo@tzi.org</email>
      </address>
    </author>
    <date year="2023" month="December" day="19"/>
    <area>Applications and Real-Time</area>
    <workgroup>CBOR Maintenance and Extensions</workgroup>
    <keyword>Concise Data Definition Language</keyword>
    <abstract>
      <?line 52?>

<t>At the time of writing,
the Concise Data Definition Language (CDDL) is defined by
RFC 8610 and RFC 9165.
The latter has used the extension point provided in RFC 8610,
the <em>control operator</em>.</t>
      <t>As CDDL is being used in larger projects, the need for corrections
and additional features has become known that cannot be easily
mapped into this single extension point.
Hence, there is a need for evolution of the base CDDL
specification itself.</t>
      <t>The present document defines a backward- and forward-compatible
way to add a module structure to CDDL.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://cbor-wg.github.io/cddl-modules/draft-ietf-cbor-cddl-modules.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ietf-cbor-cddl-modules/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        CBOR Maintenance and Extensions Working Group mailing list (<eref target="mailto:cbor@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/cbor/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/cbor/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/cbor-wg/cddl-modules"/>.</t>
    </note>
  </front>
  <middle>
    <?line 72?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>At the time of writing,
the Concise Data Definition Language (CDDL) is defined by
RFC 8610 and RFC 9165.
The latter has used the extension point provided in RFC 8610,
the <em>control operator</em>.</t>
      <t>As CDDL is being used in larger projects, the need for corrections
and additional features has become known that cannot be easily
mapped into this single extension point.
Hence, there is a need for evolution of the base CDDL
specification itself.</t>
      <t>The present document defines a backward- and forward-compatible
way to add a module structure to CDDL.</t>
      <t>The present document is intended to be the specification
base of what has colloquially been called CDDL 2.0, a term that is now
focusing on module structure (other documents make up what is now sometimes
called CDDL 1.1).
Additional documents describe further work on CDDL.</t>
      <section anchor="conventions-and-definitions">
        <name>Conventions and Definitions</name>
        <t>The Terminology from <xref target="RFC8610"/> applies.</t>
        <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
        <?line -18?>

</section>
    </section>
    <section anchor="module-superstructure">
      <name>Module superstructure</name>
      <dl>
        <dt><em>Compatibility</em>:</dt>
        <dd>
          <t>bidirectional (both backward and forward)</t>
        </dd>
      </dl>
      <t>Originally, CDDL was used for small data models that could be
expressed in a few lines.  As the size of data models that need to be
expressed in CDDL has increased, the need to modularize and re-use
components is increasing.</t>
      <t>CDDL as documented in <xref target="RFC8610"/> (<em>basic CDDL</em>) has been designed with a crude form of composition:
Concatenating a number of CDDL snippets creates a valid CDDL data
model unless there is a name collision (identical redefinition is
allowed to facilitate this approach).
With larger models, managing the name space to avoid collisions
becomes more pressing.</t>
      <t>In CDDL's original composition model,
the knowledge which CDDL snippets need to be concatenated in order to
obtain the desired data model lives entirely outside the CDDL snippets.
With the module structure defined in the present document, rules are
packaged as modules and referenced from other
modules, providing methods for control of namespace pollution.</t>
      <t>Further work may be expended on
unambiguous referencing into evolving specifications ("versioning")
and selection of alternatives (as was emulated with snippets in
<xref section="11" sectionFormat="of" target="RFC8428"/>.  Note that one approach for expressing
variants is demonstrated in <xref target="useful"/> based on <xref section="4" sectionFormat="of" target="RFC9165"/>).
Potential further work is outlined in Sections <xref target="I-D.bormann-cbor-cddl-2-draft" section="4" sectionFormat="bare"/> and <xref target="I-D.bormann-cbor-cddl-2-draft" section="A.2" sectionFormat="bare"/> of <xref target="I-D.bormann-cbor-cddl-2-draft"/>.</t>
      <section anchor="compatibility">
        <name>Compatibility</name>
        <t>To achieve the module structure in a way that is friendly to
existing environments that operate with CDDL and basic CDDL
implementations, we add a super-syntax (similar to the way pragmas
are often added to a language), by carrying them in what is
parsed as comments in basic CDDL.</t>
        <t>This enables each module source file to be basic CDDL on its own (possibly
needing to add some rule definitions imported from other
source files).</t>
      </section>
      <section anchor="namespacing">
        <name>Namespacing</name>
        <t>When importing rules from other modules, there is the potential for
name collisions.  This is exacerbated when the modules evolve, which
may lead to the introduction of a name into an imported module that is
also used (likely in a different way) in the importing module.</t>
        <t>To be able to manage names in such a way that collisions can be
avoided, we introduce means to prepend a prefix to the names of rules
being imported: the "as" clause.</t>
      </section>
      <section anchor="directives-the-module">
        <name>"Directives", the "module"</name>
        <t>This specification introduces <em>directives</em> into CDDL.
A single CDDL file becomes a <em>module</em> by processing the (zero or more)
directives in it.</t>
        <t>The semantics of the module are independent of the module(s) using it,
however, importing a module may involve transforming its rule names
into a new namespace (<xref target="namespacing"/>).</t>
        <t>Directives look like comments in basic CDDL, so they do not interfere
with forward compatibility.</t>
        <t>In the CDDL module structure, lines starting with the prefix <tt>;#</tt> are
parsed as directives.</t>
      </section>
      <section anchor="naming-and-finding-modules">
        <name>Naming and Finding Modules</name>
        <t>We assume that module names are filenames taken from one of several
source directories available to the CDDL module structure processor via the
environment.
This avoids the need to nail down brittle pathnames or (partial?) URIs
into the CDDL files.</t>
        <t>The exact way how these source directories and possibly a precedence
between them are established is intentionally not fully defined in
this specification; it is expected that this will be specified in the
context of the models just as the way they are intended to be used
will be.  (A more formal structure may follow later.)</t>
        <t>In the module structure implementation that is part of the CDDL Tool
described in <xref target="cddlc-tool"/>, the set of sources is
determined from an environment variable, <tt>CDDL_INCLUDE_PATH</tt>, which is
modeled after usual command-line search paths.
It is a colon-separated list of pathnames to directories, with one
special feature: an empty element points to the tool's own collection.
This collection contains fragments of extracted CDDL from published
RFCs, using names such as <tt>rfc9052</tt>.</t>
        <t>(Future versions might augment this with Web extractors and/or ways to
extract CDDL modules from github and from Internet-Drafts; see
<xref section="A.2" sectionFormat="of" target="I-D.bormann-cbor-cddl-2-draft"/> for some design considerations.)</t>
        <t>The default <tt>CDDL_INCLUDE_PATH</tt> is:</t>
        <artwork><![CDATA[
.:
]]></artwork>
        <t>That is: files are found in the current directory (<tt>.</tt>) and, if not
found there, cddlc’s collection.</t>
        <t>In the examples following, a cddlc command line will be shown
(starting with an isolated <tt>$</tt> sign) with the module-structured CDDL input; the
resulting basic CDDL will be shown separately.</t>
      </section>
      <section anchor="directives">
        <name>Basic Set of Directives</name>
        <t>Two groups of directives are defined at this point:</t>
        <ul spacing="normal">
          <li>
            <t><tt>include</tt>, which includes all the rules from a module (which
includes the ones imported/included there, transitively), or
specific explicitly selected rules (clause ending in "from");</t>
          </li>
          <li>
            <t><tt>import</tt>, which includes only those rules from the module that are
 referenced, implicitly or explicitly (clause ending in "from"), including the
 rules that are referenced from these rules, transitively.</t>
          </li>
        </ul>
        <t>The <tt>include</tt> function is more useful for composing a single model
from parts controlled by one author, while the <tt>import</tt> function is
more about treating a module as a library:</t>
        <t>The way an <tt>import</tt> works is shown by this simple example:</t>
        <artwork><![CDATA[
$ cddlc -2tcddl -
start = COSE_Key
;# import rfc9052

]]></artwork>
        <t>This results in the following CDDL 1.0 specification:</t>
        <sourcecode type="cddl"><![CDATA[
start = COSE_Key
COSE_Key = {
  1 => tstr / int,
  ? 2 => bstr,
  ? 3 => tstr / int,
  ? 4 => [+ tstr / int],
  ? 5 => bstr,
  * label => values,
}
label = int / tstr
values = any

]]></sourcecode>
        <t>This is appropriate for using libraries that are well known to the
importing specification.
However, if it is not acceptable that the library can pollute the
namespace of the importing module, the import directive can specify a
namespace prefix ("as" clause):</t>
        <artwork><![CDATA[
$ cddlc -2tcddl -
start = cose.COSE_Key
;# import rfc9052 as cose

]]></artwork>
        <t>This results in the following CDDL 1.0 specification:</t>
        <sourcecode type="cddl"><![CDATA[
start = cose.COSE_Key
cose.COSE_Key = {
  1 => tstr / int,
  ? 2 => bstr,
  ? 3 => tstr / int,
  ? 4 => [+ tstr / int],
  ? 5 => bstr,
  * cose.label => cose.values,
}
cose.label = int / tstr
cose.values = any

]]></sourcecode>
        <t>Note how the imported names are prefixed with <tt>cose.</tt> as specified in
the import directive, but CDDL prelude (<xref section="D" sectionFormat="of" target="RFC8610"/>) names
such as <tt>tstr</tt> and <tt>any</tt> are not.</t>
      </section>
      <section anchor="explicit-selection-of-names">
        <name>Explicit selection of names</name>
        <t>Both <tt>import</tt> and <tt>include</tt> directives can be augmented by an explicit
mentioning of rule names (clause ending in "from").</t>
        <section numbered="false" anchor="include">
          <name><tt>include</tt></name>
          <t>Starting with <tt>include</tt>:</t>
          <artwork><![CDATA[
$ cddlc -2tcddl -
mydata = {* label => values}
;# include label, values from rfc9052

]]></artwork>
          <t>With <tt>include</tt>,
only exactly the rules mentioned are included:</t>
          <sourcecode type="cddl"><![CDATA[
mydata = {* label => values}
label = int / tstr
values = any

]]></sourcecode>
          <t>The module from which rules are explicitly imported can be namespaced:</t>
          <artwork><![CDATA[
$ cddlc -2tcddl -
mydata = {* label => values}
;# include cose.label, cose.values from rfc9052 as cose

]]></artwork>
          <t>Again, only exactly the rules mentioned are included:</t>
          <sourcecode type="cddl"><![CDATA[
mydata = {* label => values}
cose.label = int / tstr
cose.values = any

]]></sourcecode>
        </section>
        <section numbered="false" anchor="import">
          <name><tt>import</tt></name>
          <t>Both examples would work exactly the same with <tt>import</tt>, as the
included rules do not reference anything else from the included
module.</t>
          <t>An import however also draws in the transitive closure of the rules
referenced:</t>
          <artwork><![CDATA[
$ cddlc -2tcddl -
mydata = {Fritz: cose.empty_or_serialized_map}
;# import cose.empty_or_serialized_map from rfc9052 as cose

]]></artwork>
          <t>The transitive closure of the rules mentioned is included:</t>
          <sourcecode type="cddl"><![CDATA[
mydata = {"Fritz" => cose.empty_or_serialized_map}
cose.empty_or_serialized_map = bstr .cbor cose.header_map / bstr .size 0
cose.header_map = {
  cose.Generic_Headers,
  * cose.label => cose.values,
}
cose.Generic_Headers = (
  ? 1 => int / tstr,
  ? 2 => [+ cose.label],
  ? 3 => tstr / int,
  ? 4 => bstr,
  ? (5 => bstr // 6 => bstr),
  )
cose.label = int / tstr
cose.values = any

]]></sourcecode>
          <t>The <tt>import</tt> statement can also request an alias for an imported name:</t>
          <artwork><![CDATA[
$ cddlc -2tcddl -
mydata = {Fritz: cose.empty_or_serialized_map}
;# import empty_or_serialized_map from rfc9052 as cose

]]></artwork>
          <t>Note how an additional rule provides an alias for
<tt>empty_or_serialized_map</tt> that does not have the namespace prefix:</t>
          <sourcecode type="cddl"><![CDATA[
mydata = {"Fritz" => cose.empty_or_serialized_map}
empty_or_serialized_map = cose.empty_or_serialized_map
cose.empty_or_serialized_map = bstr .cbor cose.header_map / bstr .size 0
cose.header_map = {
  cose.Generic_Headers,
  * cose.label => cose.values,
}
cose.Generic_Headers = (
  ? 1 => int / tstr,
  ? 2 => [+ cose.label],
  ? 3 => tstr / int,
  ? 4 => bstr,
  ? (5 => bstr // 6 => bstr),
  )
cose.label = int / tstr
cose.values = any

]]></sourcecode>
        </section>
      </section>
      <section anchor="tool-support-for-command-line-control">
        <name>Tool Support for Command-Line Control</name>
        <t>Tools may provide a convenient way to initiate the processing of
directives from the command line.</t>
        <t>A tool may provide a way to root the module tree from the command line:</t>
        <artwork><![CDATA[
$ cddlc -2tcddl -icose=rfc9052 -scose.COSE_Key

]]></artwork>
        <t>The command line argument <tt>-icose=rfc9052</tt> is a shortcut for</t>
        <artwork><![CDATA[
;# import rfc9052 as cose
]]></artwork>
        <t>Together with the start rule name, <tt>cose.COSE_Key</tt>, this results in the following CDDL 1.0 specification:</t>
        <sourcecode type="cddl"><![CDATA[
$.start.$ = cose.COSE_Key
cose.COSE_Key = {
  1 => tstr / int,
  ? 2 => bstr,
  ? 3 => tstr / int,
  ? 4 => [+ tstr / int],
  ? 5 => bstr,
  * cose.label => cose.values,
}
cose.label = int / tstr
cose.values = any

]]></sourcecode>
        <t>In other words, the module synthesized from the command line had an
empty CDDL file, which therefore was not provided (no <tt>–</tt> on the
command line).</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The module structure specified in this document is not believed to
create additional security considerations beyond the general security
considerations in <xref section="5" sectionFormat="of" target="RFC8610"/>.</t>
      <t>Implementations that employ the module structure defined in this
document need to ascertain the provenance of the modules they combine
into the CDDL models they employ operationally.
This specification does not define how the source directories accessed
via the CDDL_INCLUDE_PATH are populated; this process needs to undergo
the same care and scrutiny as any other introduction of source code
into a build environment.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC8610">
          <front>
            <title>Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures</title>
            <author fullname="H. Birkholz" initials="H." surname="Birkholz"/>
            <author fullname="C. Vigano" initials="C." surname="Vigano"/>
            <author fullname="C. Bormann" initials="C." surname="Bormann"/>
            <date month="June" year="2019"/>
            <abstract>
              <t>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.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8610"/>
          <seriesInfo name="DOI" value="10.17487/RFC8610"/>
        </reference>
        <reference anchor="RFC9165">
          <front>
            <title>Additional Control Operators for the Concise Data Definition Language (CDDL)</title>
            <author fullname="C. Bormann" initials="C." surname="Bormann"/>
            <date month="December" year="2021"/>
            <abstract>
              <t>The Concise Data Definition Language (CDDL), standardized in RFC 8610, provides "control operators" as its main language extension point.</t>
              <t>The present document defines a number of control operators that were not yet ready at the time RFC 8610 was completed:,, and for the construction of constants; / for including ABNF (RFC 5234 and RFC 7405) in CDDL specifications; and for indicating the use of a non-basic feature in an instance.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9165"/>
          <seriesInfo name="DOI" value="10.17487/RFC9165"/>
        </reference>
        <referencegroup anchor="STD68">
          <reference anchor="RFC5234" target="https://www.rfc-editor.org/info/rfc5234">
            <front>
              <title>Augmented BNF for Syntax Specifications: ABNF</title>
              <author fullname="D. Crocker" initials="D." role="editor" surname="Crocker"/>
              <author fullname="P. Overell" initials="P." surname="Overell"/>
              <date month="January" year="2008"/>
              <abstract>
                <t>Internet technical specifications often need to define a formal syntax. Over the years, a modified version of Backus-Naur Form (BNF), called Augmented BNF (ABNF), has been popular among many Internet specifications. The current specification documents ABNF. It balances compactness and simplicity with reasonable representational power. The differences between standard BNF and ABNF involve naming rules, repetition, alternatives, order-independence, and value ranges. This specification also supplies additional rule definitions and encoding for a core lexical analyzer of the type common to several Internet specifications. [STANDARDS-TRACK]</t>
              </abstract>
            </front>
            <seriesInfo name="STD" value="68"/>
            <seriesInfo name="RFC" value="5234"/>
            <seriesInfo name="DOI" value="10.17487/RFC5234"/>
          </reference>
        </referencegroup>
        <reference anchor="RFC7405">
          <front>
            <title>Case-Sensitive String Support in ABNF</title>
            <author fullname="P. Kyzivat" initials="P." surname="Kyzivat"/>
            <date month="December" year="2014"/>
            <abstract>
              <t>This document extends the base definition of ABNF (Augmented Backus-Naur Form) to include a way to specify US-ASCII string literals that are matched in a case-sensitive manner.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7405"/>
          <seriesInfo name="DOI" value="10.17487/RFC7405"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="I-D.bormann-cbor-cddl-2-draft">
          <front>
            <title>CDDL 2.0 -- a draft plan</title>
            <author fullname="Carsten Bormann" initials="C." surname="Bormann">
              <organization>Universität Bremen TZI</organization>
            </author>
            <date day="27" month="August" year="2023"/>
            <abstract>
              <t>   The Concise Data Definition Language (CDDL) today is defined by
   RFC 8610 and RFC 9165.  The latter (as well as some more application
   specific specifications such as RFC 9090) have used the extension
   point provided in RFC 8610, the control operator.

   As CDDL is used in larger projects, feature requirements become known
   that cannot be easily mapped into this single extension point.
   Hence, there is a need for evolution of the base CDDL specification
   itself.

   The present document provides a roadmap towards a "CDDL 2.0".  It is
   based on draft-bormann-cbor-cddl-freezer, but is more selective in
   what potential features it takes up and more detailed in their
   discussion.  It is intended to serve as a basis for prototypical
   implementations of CDDL 2.0.  What specific documents spawn from the
   present one or whether this document is evolved into a single
   CDDL 2.0 specification.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-bormann-cbor-cddl-2-draft-03"/>
        </reference>
        <reference anchor="useful" target="https://github.com/cbor-wg/cddl/wiki/Useful-CDDL">
          <front>
            <title>Useful CDDL</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="cddlc" target="https://github.com/cabo/cddlc">
          <front>
            <title>CDDL conversion utilities</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="RFC8428">
          <front>
            <title>Sensor Measurement Lists (SenML)</title>
            <author fullname="C. Jennings" initials="C." surname="Jennings"/>
            <author fullname="Z. Shelby" initials="Z." surname="Shelby"/>
            <author fullname="J. Arkko" initials="J." surname="Arkko"/>
            <author fullname="A. Keranen" initials="A." surname="Keranen"/>
            <author fullname="C. Bormann" initials="C." surname="Bormann"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This specification defines a format for representing simple sensor measurements and device parameters in Sensor Measurement Lists (SenML). Representations are defined in JavaScript Object Notation (JSON), Concise Binary Object Representation (CBOR), Extensible Markup Language (XML), and Efficient XML Interchange (EXI), which share the common SenML data model. A simple sensor, such as a temperature sensor, could use one of these media types in protocols such as HTTP or the Constrained Application Protocol (CoAP) to transport the measurements of the sensor or to be configured.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8428"/>
          <seriesInfo name="DOI" value="10.17487/RFC8428"/>
        </reference>
      </references>
    </references>
    <?line 486?>

<section anchor="abnf-specification">
      <name>ABNF Specification</name>
      <t>This section specifies the grammar employed by the module structure
directives using the ABNF language defined in <xref target="STD68"/> and
<xref target="RFC7405"/>.</t>
      <sourcecode type="abnf"><![CDATA[
directive = ";#" RS (%s"import" / %s"include") RS [from-clause]
                    filename [as-clause] CRLF
from-clause = 1*(id [","] RS) %s"from" RS
as-clause = RS %s"as" RS id
filename = 1*("-" / "." / %x30-39 / %x41-5a / "_" / %x61-7a)
id = ("$" / %x40-5a / "_" / %x61-7a)
     *("$" / %x30-39 / %x40-5a / "_" / %x61-7a)
RS = 1*WS
WS = SP
SP = %x20
CRLF = %x0A / %x0D.0A
]]></sourcecode>
    </section>
    <section anchor="cddlc-tool">
      <name>A CDDL Tool that Implements CDDL Module Structure</name>
      <t>This appendix is for information only.</t>
      <t>A rough CDDL tool is available <xref target="cddlc"/>.  It can process
module-structured CDDL models into basic CDDL models that can then be
processed by the original CDDL
tool described in <xref section="F" sectionFormat="of" target="RFC8610"/>.</t>
      <t>A typical command line involving both tools might be:</t>
      <artwork><![CDATA[
cddlc -2 -tcddl mytestfile.cddl | cddl - gp 10
]]></artwork>
      <t>Install on a system with a modern Ruby (Ruby version ≥ 3.0) via:</t>
      <artwork><![CDATA[
gem install cddlc
]]></artwork>
      <t>The present document assumes the use of <tt>cddlc</tt> of at least version 0.1.8.</t>
    </section>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+1b3XIby3G+n6eYgHIZkLEgQVE6EmQdmSIli2X9RaRK5agU
YrAYgGstduGdXUIQw1O+zXWucueL5EWcNzlPkq+7Z/9AUkfOsXORiqrO4e7O
X09P99dfzwyCIFDnI31HqTzKYzvSnYPDwxf6ZTotYquP86wI8yKzHWUmk8ye
31yupmmYmAV6mGZmlgeRzWdBOEmzIJxO42DBDVwQm9y6XLk8s2Yx0kdPT56p
LV0sp/R9pO/fG+7gnd5GKjT5SLt8qsI0cTZxBSpgQKsMGkOS/eUyjlApQrE2
yVS/tSYOTqIFxFml2ad5lhZLkvjJ67f6pYmS3CYmCS3XffoZb46adtQnu0b9
6UjpQB+kSRg5qw9NbvShnUVJRAPoFyaZF2Zu1blNCgin9Td3r/XCRDFqkjp+
Q4oZpNmcvs+j/KyY+JJgNd9u6ooqiLpQ4SzPl260ve0rDqTlIEpbTba/pvvB
Wb6IsVCmyM/SjGYQ4D+tZdUOTOYgsn6SZguTJFwCKUf6XRKd28xF+X/9R66f
ZHaBSif/dMQVaBktxHuTunxmwjN9587O3t4Ol4VRvh75BvIhnWKcw2D3/p27
D/yXIskz1PqtpUHX/HF5liao96u9B8He7jDYHd4P7t15sDvkQiuaDM0k/U3+
JSI9KqUSkjmHmDSpt88OyIpQCXOX9wfDe3fxnmKwNKaOjk8O790faTNJZnqL
atzdvbMndb/b27krJUFonFUqSmZ191taHwWHA1HzRFTV0PQM6vhis5H2D0qq
X624G3AXImT5htqFs7MiHvFcc5PNSbnl0vslD9PFdtNctlfRp2j7HTcMyDml
sXizfNb+M1UPR81ydmYohlcYVl7kUQx7t+4nJcAK8PAh9B8EATQGYzBhrtSH
f8bzMPhYP8mQ+7nOzyxGXlidzvQqw0DJvC8joeCnPE93SdqejpyeUqmd6omY
DJbtL3+mRRcUoDda8gEXnqBruFFuM31mHGl4ysPZ0kP1MoXv6mWWnkdTFEZJ
3WEt3ak3H50ubWbyNDsdKJmWEy1CrInFhGQEdBKT9jLq9w82zF2fu0ksCmFQ
UHqW4TMhBHdDkpvplKdsYj2zhnDVscwTC5Vb/SlJVwl6MTkcIEnSHAXaGhfF
ooaFWS556DxFLcjjIE58ZaailucWUMUyZZZkN7Vo9jyNC1Y9lomEnsARdGVa
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
dNV91YH6b2gjplL4NwAA

-->

</rfc>
