<?xml version="1.0" encoding="UTF-8"?>
<metanorma xmlns="https://www.metanorma.org/ns/standoc" type="semantic" version="2.9.1" schema-version="v2.3.0" flavor="ribose">
<bibdata type="standard">
<title language="en" type="main">UnitsML specifications — Asciiunits Content Language</title>
<docidentifier primary="true" type="Ribose">36817(d)</docidentifier><docnumber>36817</docnumber><date type="updated"><on>2026-11-01</on></date><contributor><role type="author"/><organization>
<name>Ribose Asia Limited</name>
<abbreviation>Ribose</abbreviation></organization></contributor><contributor><role type="author"><description>committee</description></role><organization>
<name>Ribose Asia Limited</name>
<subdivision type="Committee" subtype="technical">
<name>CalConnect</name>
</subdivision></organization></contributor><contributor><role type="publisher"/><organization>
<name>Ribose Asia Limited</name>
<abbreviation>Ribose</abbreviation></organization></contributor><edition>1</edition><version>2026-11-01</version><language>en</language><script>Latn</script><status><stage>draft-standard</stage></status><copyright><from>2026</from><owner><organization>
<name>Ribose Asia Limited</name>
<abbreviation>Ribose</abbreviation></organization></owner></copyright><ext><doctype>standard</doctype><flavor>ribose</flavor></ext></bibdata><metanorma-extension><semantic-metadata><stage-published>false</stage-published></semantic-metadata>
<presentation-metadata><toc-heading-levels>2</toc-heading-levels><html-toc-heading-levels>2</html-toc-heading-levels><doc-toc-heading-levels>2</doc-toc-heading-levels><pdf-toc-heading-levels>2</pdf-toc-heading-levels></presentation-metadata></metanorma-extension>
<boilerplate><copyright-statement>

<clause id="_0bf1199e-8f6c-bc16-f9b0-78b3f1efec79" obligation="normative"><p id="_945067f2-795a-1e64-6f2b-25dd57c0f4d3">© Ribose Asia Limited 2026</p>
</clause>
</copyright-statement>

<license-statement>

<clause id="_3179d22c-816d-e694-6037-341f744bc6dc" obligation="normative">
<title id="_5ad8fb30-fcae-1072-87a2-407e6b4939ec">Warning for Drafts</title>
<p id="_a24807ee-0381-7ef8-1167-c3aacbb0fd73">This document is not a Ribose Standard. It is distributed for review and comment, and is subject to change without notice and may not be referred to as a Standard. Recipients of this draft are invited to submit, with their comments, notification of any relevant patent rights of which they are aware and to provide supporting documentation.</p>
</clause>
</license-statement>

<legal-statement>

<clause id="_7e0f3c63-3fc9-65cf-37f7-b94afa0dbc5d" obligation="normative"><p id="_50bbfa02-61c3-8332-bad8-61e7389d1808">All rights reserved. Unless otherwise specified, no part of this publication may be reproduced or utilized otherwise in any form or by any means, electronic or mechanical, including photocopying, or posting on the internet or an intranet, without prior written permission. Permission can be requested from the address below.</p>
</clause>
</legal-statement>

<feedback-statement>

<clause id="_d43a5e83-e752-e9bc-955e-4282a8ebb43a" obligation="normative"><p id="_0145a561-c9cc-a509-4784-ac2a1e6ea922" anchor="boilerplate-name" align="left">Ribose Asia Limited</p>

<p id="_80954cc8-1f49-9d20-5987-829595995a92" anchor="boilerplate-address" align="left">Suite 1, 8/F, New Henry House<br/> 10 Ice House Street<br/> Central<br/> Hong Kong<br/> <br/> <link target="mailto:copyright@ribose.com"/><br/> <link target="https://www.ribose.com">www.ribose.com</link></p>
</clause>
</feedback-statement>
</boilerplate><preface><foreword id="_32acce7c-a15f-4325-e722-afb83e6db4fd" obligation="informative">
<title id="_41c9fad3-d4c1-eecc-4fad-f91704acc026">Foreword</title>
<p id="_5aa9f488-7b2b-0c11-e2bf-bdeaf5b30a1b">The unit expression is the connective tissue of the series: it is the content of <tt>unitsml(...)</tt> in legacy dialects, of the <tt>unit(...)</tt> constructor in pma, and the payload of every dimension decomposition. This part specifies that language as a grammar-only artifact: a PARG grammar compiled to a checksummed artifact, terminals generated from the register, and a corpus frozen as the conformance reference. No runtime code lives beside the grammar; runtimes are separate implementations (Ruby, TypeScript) of the same artifact.</p>
</foreword><introduction id="_a76cd30a-427d-860a-313d-b93ee65db7ea" obligation="informative">
<title id="_2b2e98d1-114a-3da4-8556-01ae0a724280">Introduction</title>
<p id="_bc4d0c90-7e9f-8bac-ffda-fe1fb875bd4e">When the unit vocabulary lived inside a parser, every register edit meant a parser edit, and consumers drifted. Generating the terminals from the register — and shipping the grammar as a checksummed artifact that Ruby, TypeScript and Rust runtimes all load — turned that drift into a build failure. This part specifies the result.</p>
</introduction></preface><sections>

<clause id="_f549c8d1-76e0-8cdc-ff0c-e7eccb474b5f" type="scope" obligation="normative">
<title id="_f70b6ff6-6131-0e24-81e1-850dbe94b63d">Scope</title>
<p id="_746aa5d9-139c-3bdb-2e9f-aa9559d6928e">This document specifies the expression surface; the terminal-generation rule from the register (CalConnect 36814; the registration of multi-term and prefixed symbols; extender rules; and the artifact contract. It does not define the embedding syntax of host languages (asciimath 2 and pma 1 do that) nor any semantics beyond parsing to a formula tree.</p>
</clause>



<terms id="_c032c733-b3d6-ef91-bef7-909840f32781" obligation="normative">
<title id="_dfb2eab2-f980-6365-3c47-81d0eb272962">Terms and definitions</title><p id="_e5876e78-fa42-efa9-f5ba-a93535689e8d">No terms and definitions are listed in this document.</p>
<dl id="_dc138a2b-bde9-6879-3616-9949082fb3db"><dt>terminal</dt>
<dd id="_73ee1230-40d9-31e0-0ffb-c21328c31ad8"><p id="_7eb12a03-3131-054a-cb15-5b692e846fd1">a registered string the grammar matches as one token: a unit symbol, prefix symbol, registered multi-term or prefixed symbol, or a structural keyword.</p>
</dd>
<dt>extender</dt>
<dd id="_26caf850-4efa-bfcf-8207-960953c29b14"><p id="_ee786c93-afc6-682d-8497-f270f8ebfef0">a continuation mark for interrupted unit series; legal only inside an expression.</p>
</dd>
<dt>artifact</dt>
<dd id="_0656aebe-b283-2c45-daf8-8ee38bff9c31"><p id="_345f9a6a-618e-5169-6fe0-a241638afe37">the checksummed <tt>artifacts/unitsml.json</tt> compiled from the grammar; the normative form of this language.</p>
</dd>
<dt>edition</dt>
<dd id="_3281835e-bb23-3f4d-b5b2-b49048f54d82"><p id="_6c24e6c2-d967-3029-7246-4b7aff75d4d2">the recorded grammar revision carried by the artifact.</p>
</dd>
</dl>
</terms>

<clause id="_1b1a15ec-f11c-42dd-5fc5-ae3750f95cb7" obligation="normative">
<title id="_577f0878-cbad-249b-c576-b43a5f664bb6">Conventions</title>
<p id="_ae3be88b-82b4-b017-8f02-99c1b7d7c162">Requirement language per CalConnect 36812. A single space separates juxtaposed factors; no space occurs inside a terminal; multi-term registered symbols match as whole tokens before sub-term decomposition.</p>
</clause>

<clause id="_2973e3bd-f4da-3c0a-9353-36247ecaecc9" obligation="normative">
<title id="_19cb81d9-640f-f307-a47c-4b9cf1b3840f">Expression grammar</title>
<p id="_209bff12-20c6-9bb7-8ff1-c5a3cc95af34">The artifact (<tt>artifacts/unitsml.json</tt>, checksummed) is normative; this clause orients. The surface: products (<tt>kg m</tt>); quotients <tt>/</tt> and <tt>//</tt> with exponent inversion (<tt>m/s^2</tt>); powers <tt>^</tt> (integer and specified-fraction numerators); <tt>sqrt(...)</tt>; parentheses; the dimension symbols <tt>dim_L</tt>, <tt>dim_M</tt>, <tt>dim_I</tt>, <tt>dim_Θ</tt>, <tt>dim_N</tt>, <tt>dim_J</tt>, <tt>dim_Φ</tt>; and the number <tt>1</tt>.</p>

<example id="_6c77cc69-b280-9214-35d4-e56e3b9a4bda"><p id="_1a8ab997-7e4d-e40a-f6d8-7e4f781f9c8c"><strong>Expected outcome.</strong> <tt>kg m/s^2</tt> parses to mass × length × time⁻²; <tt>J/(kg K)</tt> groups the denominator; <tt>sqrt(m^2)</tt> resolves to a length root; <tt>1</tt> is the unity expression.</p>
</example>
</clause>

<clause id="_2a6ebb10-8d45-1cfd-9298-9091aba48736" obligation="normative">
<title id="_6f2565ee-ac47-0740-0111-64269a7f04d4">Terminal generation from the register</title>
<p id="_2259f080-48a1-2c1a-263e-7078071404be">Every unit symbol, prefix symbol and registered multi-term symbol is generated from the UnitsDB 3 release. The grammar never hardcodes vocabulary: a register edit regenerates the terminals.</p>

<example id="_70b6aced-c978-1af9-92bb-ed1018e41ff8"><p id="_1052e17b-da84-c306-7b01-e43757b4f900"><strong>Expected outcome.</strong> Adding a unit to the register lands its symbol as a terminal in the regenerated artifact in the same change; a consumer loading a stale artifact against the new register fails checksum verification rather than silently missing the symbol.</p>
</example>
</clause>

<clause id="_502603dc-de8e-81ce-4394-c6631f4275fa" obligation="normative">
<title id="_32c34f4b-c910-1012-83dc-c59db0f3c06e">Registered and prefixed symbols</title>
<p id="_e41cd05e-a16d-68a2-877c-48ce767c7e3f">Registered prefixed symbols (dB, mbar, kgf, cSt, …) are single terminals, resolved deterministically against prefix+unit decompositions; registration order and precedence are part of the generated tables.</p>

<example id="_a269b3e5-dee0-1eef-5321-4a4ce3c3c564"><p id="_0db02e76-efbc-6488-529c-61fc6ebe32f4"><strong>Expected outcome.</strong> <tt>dB</tt> matches as one token (never d·b); <tt>mbar</tt> precedes <tt>m</tt>-prefixed <tt>bar</tt> in match order; <tt>kgf</tt> never decomposes to kg·f.</p>
</example>
</clause>

<clause id="_cfa7f34d-7b76-dded-4481-32679cabca2b" obligation="normative">
<title id="_609da520-d413-4110-233a-7b760912339e">Extender rules</title>
<p id="_0794a7ef-4762-2c04-9563-92f47e686be8">Extenders continue interrupted series inside an expression; an expression MAY NOT terminate on an extender (grammar v2 trailing-extender rejection).</p>

<example id="_29941f99-baa8-4d2d-aa95-0482496f932f"><p id="_9164b0cb-cf79-6625-18fe-3a48e9b187d8"><strong>Expected outcome.</strong> <tt>m + …</tt> inside a continuation series parses; the bare tail <tt>m ⟶</tt> at the end of an expression is rejected with a parse error.</p>
</example>
</clause>

<clause id="_dd8d37a8-ddc9-527c-5d44-6570a9b8e1f9" obligation="normative">
<title id="_4c78b421-f2e3-7a48-79dc-f65b7121d7f9">The artifact contract</title>
<ul id="_280df277-8b0a-85d0-857c-6384d308b8cb"><li><p id="_f58becdb-01d5-9517-1940-48ff5cf11a74">The artifact carries a checksum set; every consuming runtime verifies checksums before load.</p>
</li>
<li><p id="_dc671fb0-faf6-6851-2dee-7407fd831438">The artifact records its grammar edition; edition 2 carries grammar v2 (registered prefixed symbols, trailing-extender rejection).</p>
</li>
<li><p id="_369dec53-d6e2-36d3-f360-701f2ac3da89">Grammar edits regenerate the artifact AND the corpus in the same change; consumer-runtime CI (dependent-gems against unitsml-ruby) gates the regeneration.</p>
</li>
<li><p id="_cc504723-35f4-88fa-a7ea-4c9dc0b5469f">The corpus: 143 cases covering every terminal class and every production of Clause 5, frozen byte-for-byte.</p>
</li>
</ul>
</clause>

<clause id="_c84068b0-3b2f-b056-fb43-5f925e8e0daa" obligation="normative">
<title id="_e499f69a-c963-37a4-031c-6b4334a863d4">Conformance</title>
<p id="_f3ef98a2-b89a-17bb-2be4-88c735eda850">Conformance class <tt>parse/render</tt> includes this part. The 143-case corpus is replayed by unitsml-ruby, unitsml-ts and asciiunits-ts; the embedding vectors of CalConnect 36819 Annex B cover host-language integration. Additional test-suite examples are given in <xref target="annex-test-suite"/>.</p>
</clause>




</sections><annex id="_39e934e8-17ed-2240-f30e-0f8a484e09cd" anchor="annex-test-suite" obligation="normative">
<title id="_0da4a895-8c0e-9760-d71a-3c5ee3665bb1">Annex A (informative): additional test-suite examples</title>
<example id="_aa245a2a-1208-8bc6-6ef8-b4bd11888954"><p id="_6bde04b5-9e19-a00c-c0c4-58bb1e11a65a"><strong>Checksum gate.</strong> A stale artifact (one edited byte, stale checksums) aborts the load with the typed checksum error in every runtime.</p>
</example>

<example id="_069c880c-3ad6-aacf-5404-3af5929c246f"><p id="_86af5f13-2360-7b28-267f-b6cfce3f5c03"><strong>Trailing-extender rejection.</strong> <tt>m/s ⟶</tt> fails; <tt>m/s ⟶ m</tt> parses as a series continuation.</p>
</example>

<example id="_3f0e40b0-fbb1-c762-4418-511cecd5ee15"><p id="_90a5c74e-8715-d2e1-34a9-4b376627d055"><strong>Longest-match registration.</strong> <tt>mbar</tt> matches as one registered symbol; <tt>dB</tt> never matches d × B; <tt>kgf</tt> never decomposes to kg × f.</p>
</example>
</annex><bibliography><references id="_42589008-b632-f03b-e1fc-ed82e38624b0" normative="true" obligation="informative">
<title id="_270c5ee6-077e-f285-ff95-287984a30140">Normative references</title><p id="_49996d2b-65c1-916b-9bbf-42b933aa0025">The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.</p>
<bibitem anchor="parg" id="_ee59be28-7b6f-c565-5ea1-702c512e5c7f"><formattedref format="application/x-isodoc+xml">(parsanol/docs)</formattedref><docidentifier>PARG grammar language and artifact format</docidentifier><language>en</language><script>Latn</script></bibitem>
<bibitem anchor="cc36810" id="_c839e61b-9c51-8ac8-ab16-0d0a07693239"><formattedref format="application/x-isodoc+xml"><em>AsciiUnits syntax specification</em> (v1 base standard, frozen 2025-03; historical)</formattedref><docidentifier>CalConnect 36810</docidentifier><docnumber>36810</docnumber><language>en</language><script>Latn</script></bibitem>
</references><references id="_f8afe31d-8df4-3e0b-8a42-e16dcf277513" normative="false" obligation="informative">
<title id="_50ceb1e1-516f-2673-d73d-4f0c58b4d023">Bibliography</title><bibitem anchor="parg-b" id="_02fef958-fdbc-8457-c1aa-4fe30a677bf8">
  <formattedref format="application/x-isodoc+xml">(parsanol/docs)</formattedref>
  <docidentifier>parsanol PARG specification and artifact format</docidentifier>
  <language>en</language>
  <script>Latn</script>
</bibitem><bibitem anchor="asciiunits-repo" id="_73591548-89c4-fe2a-3f01-61206d6d5b4e">
  <formattedref format="application/x-isodoc+xml">(grammar source, artifacts, corpus); unitsml/unitsml-ruby#80</formattedref>
  <docidentifier>unitsml/asciiunits</docidentifier>
  <language>en</language>
  <script>Latn</script>
</bibitem>


</references></bibliography>
</metanorma>
