# `parser` ## Purpose CDDL parser per RFC 8610 §3 grammar. Consumes the token stream from the `tokenize` function and produces a typed AST (`CddlAst`) that the validator walks. Supports the working subset of CDDL needed by real consumers (CWT, COSE_Sign1, WebAuthn attestation, vault manifests, drive templates). ## Features - Rule definitions: `name = T`, `name = ...` (generic params). - Type expressions: primitive prelude, named references, generic instantiation. - Type composition: choice (`/`), inclusive (`..`) + exclusive (`...`) ranges, parenthesised grouping. - Group composition: arrays (`[ ... ]`), maps (`{ ... }`), occurrence indicators (`?`, `*`, `+`, `*N`, `M*N`, `M*`), group choice (`//`). - Map keys: identifier-`:`-T (text key), `"quoted":` T (text key with quoted syntax), ` => T` (numeric key), `"quoted" => T`. - Tagged items: `#6.(T)` produces `{ kind: "tagged", tag, inner }`. - Literal values: text strings, byte strings (`h'…'`), integers (positive and negative), `true`/`false`, `null`/`nil`, `undefined`. - Control operators applied to types: `tstr .size 1..32`, `tstr .regexp "pattern"`, `bstr .cbor T`. Both literal and range right-hand sides supported on `.size`. ## Usage: Basic Example ```ts import { parseCddl } from "@suaveplan/cbor/cddl"; const ast = parseCddl(` cwt = { iss: tstr, ? exp: int } `); ``` ## Usage: Advanced Example ```ts import { parseCddl } from "@suaveplan/cbor/cddl"; const ast = parseCddl(` attested-key = #6.18(cose-sign1) cose-sign1 = [ protected: bstr, unprotected: { * any => any }, payload: bstr / nil, signature: bstr ] protected = bstr .size 0..1024 pair = [ K, V ] `); ``` ## API Reference - `parseCddl(source: string): CddlAst` Throws `CborError(CDDL_PARSE_FAILED)` with `{ line, col }` for: empty source (no rules), missing `=`, unexpected token, non-integer range bound, `#N` with N != 6. ## Implementation Notes The parser is a hand-written recursive descent. Operator precedence mirrors RFC 8610 §3: - `type` (top): handles `/` choice - `type1`: handles `..` / `...` ranges and control operators (`.size`, `.regexp`, etc.); the `.size` case can take a range right-hand side - `type2` (atom): primitives, references, literals, parenthesised groups, arrays, maps, tagged items Group choice (`//`) is implemented at the `[`/`{` body level — when the parser encounters `//` between two sets of entries, it returns a `{ kind: "choice", alternatives: [arrayA, arrayB] }` so the validator can short-circuit on the first matching alternative.