Skip to content

Grammar (EBNF)

This document defines the formal grammar for the Capture Declaration Language (CDL).

NotationMeaning
=Definition
;End of rule
{ ... }Zero or more
[ ... ]Optional
(...)Grouping
|Alternative
"..."Literal token
Document = { Capture } ;
Capture = "capture", Path, NL,
[ INDENT,
{ Directive },
DEDENT ] ;
Directive = SourceBlock
| KeyDirective
| MapBlock
| AppendBlock
| NestedBlock
| ChildrenBlock ;
SourceBlock = "source", SourceType, NL,
INDENT,
{ SourceProperty },
DEDENT ;
SourceType = "api" | "webhook" | "message" ;
SourceProperty = ("api" | "route" | "poll" | "path" | "topic"), LineValue, NL ;
KeyDirective = "key", LineValue, NL ;
MapBlock = "map", NL,
INDENT,
{ MapOperation },
DEDENT ;
MapOperation = SplitOperation
| RenameOrTemplateOrTranslate ;
RenameOrTemplateOrTranslate
= Identifier, "=", LineValue, [ "translate", NL,
INDENT,
{ TranslateEntry },
DEDENT
], NL ;
TranslateEntry = SimpleValue, "=>", SimpleValue, NL ;
SplitOperation = "split", Path, "by", StringLiteral, NL,
INDENT,
{ Path, NL },
DEDENT ;
AppendBlock = "append", Path, NL,
INDENT,
"when", WhenExpression, NL,
{ Assignment },
DEDENT ;
WhenExpression = "added"
| "removed"
| TemplateLiteral
| Path, [ "from", SimpleValue, "to", SimpleValue
| { "or", Path }
| { "and", Path } ] ;
Assignment = Identifier, "=", LineValue, NL ;
NestedBlock = "nested", Path, NL,
INDENT,
[ MapBlock ],
{ AppendBlock },
DEDENT ;
ChildrenBlock = "children", Path, "identified", "by", Path, NL,
INDENT,
[ MapBlock ],
{ AppendBlock },
DEDENT ;
Path = Identifier, { ".", Identifier } ;
LineValue = { TokenExceptNewline } ;
SimpleValue = StringLiteral | NumberLiteral | "true" | "false" | "null" | Identifier ;
Identifier = Letter, { Letter | Digit | "_" } ;

The parser grammar is complemented by compiler validation rules:

  • Exactly one source block is required
  • Exactly one key directive is required
  • At most one root map block is allowed
  • Every append block must contain one when clause