Status: Draft official v1 companion reference

Available formats: HTML, Markdown

AEON v1 Structure Syntax Reference

Status: official v1 companion reference Scope: key syntax, attributes, separator specs, list/tuple separators, and newline behavior.

1. Binding Shape

Canonical binding surface:

Transport form may omit attributes and datatype:

Strict form requires datatype presence, but not generic arguments:

Core grammar summary:

Nuances:

  • canonical order is key@{...}:type = value;
  • reversed order such as key:type@{...} = value is not Core v1 canonical syntax;
  • attributes may appear without datatype;
  • datatype may appear without attributes.
  • TypedValue is valid only in anonymous value-element contexts: list elements, tuple elements, and node children.
  • TypedValue is not a binding head and MUST NOT appear where Binding or AttributeEntry is expected.
  • the datatype on TypedValue annotates only the immediate following Value; nested :type = :type = value forms are invalid.
  • *...* is reserved for out-of-band preprocessing and templating conventions, but it is not part of Core v1 syntax.
  • Core parsers must continue to fail closed if a *...* placeholder reaches AEON parsing unchanged.
  • A preprocessor may replace *...* spans before AEON parsing, but that substitution occurs outside the Core language contract.

Informative parser-context illustrations are available in appendices/appendix-grammar-flow.md.

2. Keys

2.1 Supported Key Forms

Valid key forms in all key positions:

Unsupported as core keys:

Key grammar:

Nuances:

  • bare keys are best used when the key is identifier-safe;
  • quoted keys are required for spaces, dots-as-data, and other non-bare characters;
  • single and double quotes are both valid key delimiters;
  • quoted keys must not be empty;
  • backtick-quoted keys are not part of AEON Core v1 key syntax.
  • asterisk-delimited placeholder forms such as *secret-key* are reserved for preprocessors and remain invalid as Core keys or Core values until replaced before parsing.

Canonical notes:

  • canonical paths render non-bare keys using bracketed double-quoted form, for example $.["a.b"];
  • 'a.b' and "a.b" are the same key identity when parsed as keys.

AES notes:

  • key form is structural and does not create a distinct value kind;
  • canonical path identity uses member and index segments only.

3. Attributes

Attributes attach opaque metadata to a binding or node head:

Grammar:

Nuances:

  • attribute entries are key/value pairs;
  • attribute entry heads may themselves carry attributes;
  • attribute entry datatypes are allowed;
  • attribute containers may be empty: @{};
  • attribute entry separators may be commas or newlines;
  • trailing attribute separator is accepted by current parser behavior.
  • binding-attached attributes are valid on any binding head, including bindings whose values are objects, lists, tuples, or other literals;
  • postfix literal attributes are not part of Core v1 syntax: a = [0]@{b=2} is invalid and fails closed;
  • nested bindings inside container values may carry their own attributes, for example a = [{x@{b=0}=1}].
  • nested attribute heads are part of Core v1 and count against max_attribute_depth.
  • duplicate keys inside one attribute block are invalid and fail closed;
  • repeated nested attribute heads on the same attribute entry are invalid; use one nested attribute block with multiple entries instead.

Reference/addressing forms:

Canonical notes:

  • attributes are selectors in addressing expressions, not canonical path identity segments;
  • data namespace and attribute namespace remain distinct.
  • quoted bracket member segments may follow ordinary member or attribute traversal using .[\"...\"].
  • quoted attribute selectors may be followed by ordinary member, quoted member, or index traversal.
  • empty quoted member segments, empty quoted attribute selectors, and incomplete forms such as ~a@ or ~$.a@[ are invalid.

Examples:

Rejected examples:

Namespace note:

  • AEON Core v1 has no dedicated namespace syntax for ordinary keys;
  • # has no intrinsic namespace meaning in core key syntax;
  • when a consumer or ecosystem convention needs namespace labeling, the recommended metadata convention is @{ns="..."} as defined by aeon.gp.convention.v1:

Policy notes:

  • implementations expose max_attribute_depth;
  • default lock is 1;
  • capability floor is at least 8.

4. Separator Specs

Separator specs decorate datatypes:

Grammar:

Generic-depth notes:

  • generic depth counts nested type annotations that appear inside generic arguments;
  • tuple<n, n> has generic depth 0;
  • tuple<tuple<n, n>, tuple<n, n>> has generic depth 1;
  • tuple<tuple<tuple<n, n>, n>, n> has generic depth 2;
  • implementations expose max_generic_depth;
  • default runtime lock is 1;
  • capability floor is at least 8.

Current official v1 rules:

  • exactly one character from A-Za-z0-9!#$%&*+-.:;=?@^_|~<>;
  • horizontal whitespace and newlines may appear around the separator character inside brackets, but the payload itself must remain contiguous;
  • separator depth is the number of [...] segments.
  • only ASCII space, tab, carriage return, and newline act as layout whitespace in Core v1 grammar positions unless another rule says otherwise;
  • non-structural Unicode separators and joiners such as U+2060 WORD JOINER, U+2028 LINE SEPARATOR, and U+2029 PARAGRAPH SEPARATOR are not document, object, list, tuple, or attribute separators.

Nuances:

  • size:sep[x] has separator depth 1;
  • triple:set[x][y][z] has separator depth 3;
  • sep[x], sep[ x ], and sep[\nx\n] are legal;
  • sep[xy] and any form that splits the payload into more than one character are invalid;
  • repeated separator specs are legal and preserved structurally, including duplicate chars;
  • unparameterized sep and set datatypes may still bind separator literals;
  • separator payloads are compact tokens introduced by ^;
  • outside quoted string segments, raw separator payload characters are limited to A-Za-z0-9!#$%&*+-.:;=?@^_|~<>;
  • quoted segments use ordinary single-quoted or double-quoted AEON string lexical rules;
  • backtick segments and raw separator escapes are not part of separator-literal syntax;
  • outside quoted segments, whitespace, \\, /, ,, newline, or a closing container boundary end or invalidate the token depending on surrounding grammar;
  • U+2060, U+2028, and U+2029 do not act as interchangeable layout whitespace or newline tokens in those positions and therefore fail closed when inserted there;
  • default runtime lock is 1;
  • capability floor is at least 8.

Canonical notes:

  • separator specs remain attached to the datatype surface;
  • AEON Core parses separator specs but does not impose splitting semantics on payloads.

5. Assignment and Element Separators

5.1 Top-Level and Object Bindings

At document and object level, bindings may be separated by newline or comma:

Core v1 rules:

  • newline and comma are structural binding separators at document and object level;
  • plain spaces alone are never structural separators;
  • ; is not a structural separator.

5.2 Lists

List examples:

Grammar summary:

Nuances:

  • list elements may be separated by commas or newlines;
  • mixed comma/newline list formatting is accepted by parser behavior;
  • indexed elements are addressable as [0], [1], and so on.
  • anonymous typed elements use :type = value and do not introduce keys or reorder elements.

5.3 Tuples

Tuple examples:

Grammar summary:

Nuances:

  • tuple elements follow the same separator surface as lists;
  • tuple semantics differ from list semantics, but the element separator grammar is the same.
  • anonymous typed tuple elements use :type = value; the annotation is local to that element.

5.4 Node Children

Node child separators follow the same broad rule:

Grammar summary:

Node = "<" Identifier Attribute? TypeAnnotation? ( ">" "(" (NodeChild NodeSep?)* ")" ">" ) ;
NodeChild = Value TypedValue ;
NodeSep = "," Newline ;

Nuances:

  • node children accept comma and newline separators;
  • anonymous typed node children use :type = value; the annotation is local to the immediate child value;
  • empty-node shorthand uses > immediately after the tag metadata and is equivalent to an empty child list;
  • child-bearing nodes require a closing > after the closing );
  • canonical printed form uses the closing > and prefers <tag> over <tag()> for empty nodes;
  • node heads MAY carry an inline datatype syntactically, but strict mode limits this form to :node;
  • transport/custom forms MAY use other inline node-head datatypes, for example <tag:pair("x", "y")>;
  • trailing child separator acceptance is implementation-supported and documented in node appendices.

6. Newline Rules

Newlines are structural in AEON, but only in specific places.

Between structural tokens, a newline is otherwise treated the same as ordinary inter-token whitespace. A newline becomes special only when the surrounding grammar consumes it as a separator, or when inserting it would split a compact token that must remain contiguous.

6.1 Newline as Separator

Newline can separate:

  • bindings in documents and objects;
  • list elements;
  • tuple elements;
  • attribute entries;
  • node children.

6.2 Newline Forbidden in Compact Tokens

Newline is not allowed inside:

  • bare identifiers;
  • single-quoted or double-quoted keys;
  • single-quoted or double-quoted strings;
  • separator specs ([x]);
  • numbers;
  • hex, radix, encoding, date, datetime, and separator literal tokens.

Notes:

  • backtick strings may span newlines as string values, but backtick keys are not valid core keys;
  • trimticks are multiline string values introduced by a contiguous > through >>>> marker immediately before a backtick string opener;
  • trimticks trim the first empty line, trailing empty lines, and common left indentation according to the marker's tab policy;
  • separator literals are compact tokens; outside quoted string segments they terminate at the first character that is not valid raw separator payload or at an enclosing grammar boundary.
  • for worked boundary examples, see appendices/appendix-whitespace-boundaries.md.

6.3 Comments and Newlines

Comments do not become separators by themselves.

Implications:

  • a structured or plain comment may appear between bindings or elements;
  • comment binding rules determine attachment, but comments do not redefine the surrounding grammar;
  • line comments end at newline;
  • block comments may span newlines.

7. Addressing Interaction

Key and attribute syntax affects addressing and references:

Nuances:

  • ~a.b means traversal through two member segments;
  • ~"a.b" and ~["a.b"] are equivalent initial quoted-member forms;
  • ~["a.b"] means one quoted member segment;
  • @key and @["key"] both address attribute namespace segments.

8. Minimum Conformance Reminders

Implementations targeting Core v1 must at minimum:

  • accept bare, single-quoted, and double-quoted keys;
  • reject backtick keys;
  • expose max_attribute_depth and max_separator_depth;
  • support capability floor >=8 for both depth knobs;
  • enforce the official separator-char exclusions;
  • handle newline/comma binding separation deterministically;
  • reject space-only and semicolon binding separation deterministically.