Foreword
The unit expression is the connective tissue of the series: it is the content of unitsml(...) in legacy dialects, of the unit(...) 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.
Introduction
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.
1 Scope
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.
2 Normative references
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.
PARG grammar language and artifact format, (parsanol/docs)
CalConnect 36810, AsciiUnits syntax specification (v1 base standard, frozen 2025-03; historical)
3 Terms and definitions
No terms and definitions are listed in this document.
terminal
a registered string the grammar matches as one token: a unit symbol, prefix symbol, registered multi-term or prefixed symbol, or a structural keyword.
extender
a continuation mark for interrupted unit series; legal only inside an expression.
artifact
the checksummed artifacts/unitsml.json compiled from the grammar; the normative form of this language.
edition
the recorded grammar revision carried by the artifact.
4 Conventions
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.
5 Expression grammar
The artifact (artifacts/unitsml.json, checksummed) is normative; this clause orients. The surface: products (kg m); quotients / and // with exponent inversion (m/s^2); powers ^ (integer and specified-fraction numerators); sqrt(...); parentheses; the dimension symbols dim_L, dim_M, dim_I, dim_Θ, dim_N, dim_J, dim_Φ; and the number 1.
EXAMPLE
Expected outcome. kg m/s^2 parses to mass × length × time⁻²; J/(kg K) groups the denominator; sqrt(m^2) resolves to a length root; 1 is the unity expression.
6 Terminal generation from the register
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.
EXAMPLE
Expected outcome. 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.
7 Registered and prefixed symbols
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.
EXAMPLE
Expected outcome. dB matches as one token (never d·b); mbar precedes m-prefixed bar in match order; kgf never decomposes to kg·f.
8 Extender rules
Extenders continue interrupted series inside an expression; an expression MAY NOT terminate on an extender (grammar v2 trailing-extender rejection).
EXAMPLE
Expected outcome. m + … inside a continuation series parses; the bare tail m ⟶ at the end of an expression is rejected with a parse error.
9 The artifact contract
The artifact carries a checksum set; every consuming runtime verifies checksums before load.
The artifact records its grammar edition; edition 2 carries grammar v2 (registered prefixed symbols, trailing-extender rejection).
Grammar edits regenerate the artifact AND the corpus in the same change; consumer-runtime CI (dependent-gems against unitsml-ruby) gates the regeneration.
The corpus: 143 cases covering every terminal class and every production of Clause 5, frozen byte-for-byte.
10 Conformance
Conformance class parse/render 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 Annex A.
Annex A
(normative)
Annex A (informative): additional test-suite examples
EXAMPLE 1
Checksum gate. A stale artifact (one edited byte, stale checksums) aborts the load with the typed checksum error in every runtime.
EXAMPLE 2
Trailing-extender rejection. m/s ⟶ fails; m/s ⟶ m parses as a series continuation.
EXAMPLE 3
Longest-match registration. mbar matches as one registered symbol; dB never matches d × B; kgf never decomposes to kg × f.
Bibliography
[1] parsanol PARG specification and artifact format, (parsanol/docs)
[2] unitsml/asciiunits, (grammar source, artifacts, corpus); unitsml/unitsml-ruby#80