Korml v0 Grammar¶
This page defines the v0 grammar at the token level. v0 is the unversioned, YAML-compatible, single-document language. The node grammar is the same as v1; the stream/document-boundary wrapper is not present.
Status
Korml v0 is intended as the YAML-compatible minimal source format: one document, no version header, and no support for multiple documents.
Notation¶
| Form | Meaning |
|---|---|
A ::= B |
A is defined as B. |
A? |
zero or one occurrence of A. |
A* |
zero or more occurrences of A. |
A+ |
one or more occurrences of A. |
A \| B |
either A or B. |
TOKEN |
a lexer token. |
Whitespace, comments, and blank lines are trivia from the point of view of the semantic document model. They are nevertheless retained by the concrete syntax tree.
Token classes¶
The v0 parser is defined over these token classes:
WHITESPACE
COMMENT
NEWLINE
EOF
INDENT
DEDENT
DASH_ITEM
COLON
FLOW_SEQUENCE_START
FLOW_SEQUENCE_END
FLOW_MAPPING_START
FLOW_MAPPING_END
FLOW_SEPARATOR
SQ_SCALAR
DQ_SCALAR
PLAIN_SCALAR
LITERAL_BLOCK_SCALAR
FOLDED_BLOCK_SCALAR
INDENT and DEDENT are abstract layout tokens.
An implementation may either emit them explicitly or derive the same structure from retained whitespace tokens.
v0 does not use VERSION_DIRECTIVE, DOC_START, or DOC_END tokens.
A source containing a version directive or document boundary marker is not a valid v0 source.
Source¶
A v0 source text represents exactly one implicit document. The document may be empty.
There is no version directive and no explicit document start marker. The version is implicit: a source parsed as v0 is a Korml v0 document.
Examples of complete v0 sources:
Nodes¶
Node ::= BlockNode
| FlowNode
| Scalar
BlockNode ::= BlockMapping
| BlockSequence
FlowNode ::= FlowMapping
| FlowSequence
A node is the syntactic form that represents a document-model value. The document model has only mappings, sequences, scalars, and the empty document. An empty document is a source with no node at all. There is no empty node anywhere else: every mapping entry, sequence entry and flow entry has a value.
Block mappings¶
BlockMapping ::= MappingEntry+
MappingEntry ::= SimpleKey COLON MappingValue
SimpleKey ::= Scalar
MappingValue ::= InlineValue
| NestedBlockValue
InlineValue ::= Trivia* (FlowNode | Scalar)
NestedBlockValue ::= Trivia* NEWLINE INDENT BlockNode DEDENT
Only simple scalar keys are part of Korml v0. Complex keys are intentionally excluded.
Every mapping entry has a value: a key followed by nothing, as in key:, is not valid.
An empty string is written "", an empty sequence [] and an empty mapping {}.
Example:
Block sequences¶
BlockSequence ::= SequenceEntry+
SequenceEntry ::= DASH_ITEM SequenceValue
SequenceValue ::= InlineValue
| NestedBlockValue
Every sequence entry has a value: a dash followed by nothing is not valid.
Examples:
Flow mappings¶
FlowMapping ::= FLOW_MAPPING_START Trivia* FlowMappingEntries? Trivia* FLOW_MAPPING_END
FlowMappingEntries ::= FlowMappingEntry (Trivia* FLOW_SEPARATOR Trivia* FlowMappingEntry)*
FlowMappingEntry ::= SimpleKey Trivia* COLON Trivia* FlowValue
Example:
Flow sequences¶
FlowSequence ::= FLOW_SEQUENCE_START Trivia* FlowSequenceEntries? Trivia* FLOW_SEQUENCE_END
FlowSequenceEntries ::= FlowValue (Trivia* FLOW_SEPARATOR Trivia* FlowValue)*
Example:
Flow values¶
FlowValue ::= FlowMapping
| FlowSequence
| FlowScalar
FlowScalar ::= SQ_SCALAR
| DQ_SCALAR
| PLAIN_SCALAR
Block scalars are block constructs and are not flow scalar forms.
Every flow entry has a value, so { key: }, [alpha, , gamma] and a trailing separator as in [alpha, beta, ] are not valid.
The empty collections [] and {} are values and remain valid.
Scalars¶
Korml has no block-scalar chomping indicators: |-, |+, >- and >+ are not valid.
How a block scalar's final line breaks belong to its value is fixed by the lexical structure.
At the language level, scalar values are text. Boolean, integer, floating-point, date, and application-specific interpretation belong to a schema or decoding layer, not to the core grammar.
Trivia¶
Trivia does not create document-model values. It is part of the concrete syntax and must be retained by round-trip preserving implementations.