Skip to content

11. Bindings

Contents of ATD 0.1

A binding (grammar/binding.lark) is an FBL 0.16 binding written as text (FBL §3 to §13): every property of FBL's Binding has its ATD form in Appendix C. Its meaning, reading and writing are FBL's, unchanged.

11.1 The binding

binding <name> [family <family> | family capability <name>] { … }:

  • family <family> is the family of a declared file body (FBL §4): yaml, json, xml, lines, blocks, bullets or grammar (section 11.9);
  • family capability <name> reads and writes the body through a capability of the reader extension point, under FBL §11's persistence plugin contract (FBL's reader as a PluginReader); its arguments are the binding's setting args;
  • a binding without family has a folder body (FBL §10), described by body { kind: folder … };
  • label is FBL's title.

A description MAY have several bindings, one per format family, as DESL's persistence.bindings lists them.

11.2 Claims, body, text and header

claims { … } (FBL's Claims), or claims files "<glob>", … for its names; body { … } (FBL's Body), text { … } (FBL's TextDefaults), header { … } (FBL's Header), and settings of FBL's Binding (comment, unmatched, readOnly).

11.3 Rules, slots and attribute bindings

element <Type> [as <name>] [at "<selector>" | line "<regex>"] { … } is an element rule (FBL §5.1), relation <Type> [as <name>] […] { … } a relation rule (FBL §5.4). The name after as is FBL's rule name, written as FBL writes it, hyphens and dots included (as unreadable-requirement, section 3.6); without it the rule's name is its type's. The same holds for every name a binding declares or names: the binding's own, a block's, a section's, and those parent, within, files and references name. Members:

  • id from <slot> [{ … }] or id { … } (FBL §5.3);
  • attribute <name> [from <slot>] [{ … }]: an attribute binding (FBL §5.2), its options as settings (empty, absent, default, number, time, style, map, override, content, create, readOnly, read, quoted, fallback, (FBL 0.10) secondary and refusals, (FBL 0.11) escape and gather, (FBL 0.12) items and separator, (FBL 0.13) split, (FBL 0.15) or, expand, ordinal and name), and references <rules> by <name> for FBL's reference (by id for a reference by stored id, FBL §5.7);
  • parent <rules> [slot <name>] (FBL §5.5), within <names>, when <CEL>, files <names>;
  • insert { … } and remove { … } (section 11.5);
  • in a relation rule, source from <slot> and target from <slot>;
  • settings of FBL's ElementRule (caseInsensitive, opens, undo, readOnly, (FBL 0.10) origins, a list of the origins the rule is read for, FBL §5.1, (FBL 0.11) selectedView, §11.9), which a relation rule takes as well.

A slot is <kind> [<argument>]: key "<key>", attribute "<name>", text, group "<name>", continuation, parent "<attribute>", capture "<name>" or value (<CEL>), with the slot's other properties (child, word, flag) in the block that follows it.

11.4 Blocks and sections

block <name> [line "<regex>"] { … } is a block rule of the blocks family (FBL §4.7), (FBL 0.11) and block <name> { … } with at one of the grammar family (section 11.9), section <name> "<heading>" { … } a section of the bullets family (FBL §4.8).

11.5 Inserting and removing

insert { … } and remove { … } are FBL's Insert and Remove (FBL §6.2), as settings: place, container, emit, keys, create, skeleton, constant, (FBL 0.10) refusals (when, container, (FBL 0.14) key, duplicate), cascade. (FBL 0.14) In the yaml and json families, the insert of a rule whose at ends in a capture adds a member to a mapping under the key the add gives the attribute bound to that capture (FBL §6.2); ATD writes it with no setting of its own. (FBL 0.16) In the grammar family, insert takes continues: { at: "<selector>", same: { <attribute>: <slot> }, separator: "<text>", emit: "<text>" } and remove takes parts: [{ item: "<selector>", separator: "<text>" }, …] and whole: "<selector>" (FBL §6.2, §6.3).

11.6 Registration and template

registration { … } is FBL's RegistrationSettings (FBL §8: blocks, createOnFirstPlacement, headers, resource, its settings map holding capture or (FBL 0.10) byOrigin, a capture per reading's origin, legacyLayout, legacyIdentities, (FBL 0.12) read as the JSON array of {id, kind, key} the Wardley map's tool writes, FBL §8.7), with the blocks layout, identities and those a binding declares. (FBL 0.12) A rule's id { sidecar: { key: "<cel>", kind: <name>, ordinal: "<text>" } } keeps its ids in the identities by kind and natural key, ordinal, holding {n} once, keying each later holder of one key (FBL §5.3, §8.6). template <value> is the bytes of a new body (FBL §13): a string, or a settings map of FBL's Template (byOrigin).

11.7 A capability as the family

A binding whose family is a capability has no rules: what it reads is what the capability's reader returns (FBL §11.2), and every edit is a splice the capability plans. The capability is required with requires capability (section 13.2).

11.8 Guarantees

FBL's guarantees hold for every binding in ATD (FBL §1.4, §6, §7): reading never fails on content, unmapped text is kept byte for byte, every edit is a minimal splice with an exact undo.

11.9 The grammar family

family grammar is FBL 0.9's grammar family, with what FBL 0.11 and 0.12 add to it (FBL §4.9): the binding carries an LALR(1) grammar in ATD grammar notation (section 4) and maps the nodes of the tree it reads to elements and relations.

  • grammar { … } carries the grammar inline: everything between the braces is the grammar's text, read under grammar/notation.lark (the rule grammar_text), and is FBL's body.grammar as a string. grammar from "<file>.lark" names a file beside the description that holds it, FBL's body.grammar as {file}. A binding of the family has exactly one of the two, and a binding of another family has neither.
  • The grammar is in the subset of section 4.1, its terminals in the subset of section 3.5; its %imports name the binding's own files beside the description, never the modules of ATD's grammar. It is built as section 4.4 says, from the start rule that the setting start of body names (FBL's body.start, default start), with the lexing rule of section 3.6.
  • body { … } takes the family's settings: start, and recover: { unit: <rule>, sync: [<terminals>] }, which reads a body that does not parse in part (FBL §4.9); (FBL 0.15) and prefixes, ordinals and order, settings maps as FBL states them (FBL §3.2, §4.9).
  • (FBL 0.11) recover also takes nested: { open: <terminal>, close: <terminal> }, the tokens that open and close a block, so that a body is read in part inside blocks too, and unclosed: { <terminal>: "<text>" }, the ignored terminals whose token must end with that text and may run to the end of the body (FBL §4.9, Reading in part): recover: { unit: unit, sync: [_NL], nested: { open: "{", close: "}" }, unclosed: { BLOCK_COMMENT: "*/" } }.
  • (FBL 0.11) A slot's setting escape: { with: "\\", quote: "\"" }, written in the slot's block or in its attribute's, reads and writes a quoted value's escapes (FBL §4.9, Escapes, §5.2).
  • (FBL 0.11) An attribute binding's create takes, in this family, { emit: "<text>", after: [<attributes>], pad: true }: the text of an absent part, the attributes whose parts precede it, nearest first, and whether the parts before it are written empty (FBL §4.9, Writing); and gather: [<slots>], further slots of a read-only many attribute whose items follow the first slot's (FBL §5.2).
  • (FBL 0.11) A rule's opens is, in this family, a settings map, opens: { open: " {", close: "}" }, the text of a block written around a first child (FBL §4.9); and selectedView: true reads the rule for the selected view only (FBL §4.9, Views, §9.3).
  • (FBL 0.12) An attribute binding's slot takes, in this family, items: { <attribute>: <slot>, … }, a slot per item attribute relative to each node the slot reaches, and separator: "<text>", so that a many attribute is a list of structured values (FBL §5.2, §6.3): attribute positions from node "positions/position" { items: { visibility: { node: "visibility" }, maturity: { node: "maturity" } }, separator: "," }.
  • (FBL 0.15) A slot's selector may reach up and across with .. and +; an attribute binding takes or: [<slots>], further slots of which the first present is the value; and a slot takes expand: true or expand: { keywords: { … } }, ordinal: <numbering> and name: true, and its escape takes sequences, unicode, writes and requote (FBL §4.9, §5.2, §6.3). A value is read in Turtle's terms with them, as w3c-turtle.lark shows.
  • (FBL 0.16) An insert's continues writes a new entry into the last statement of the same subject, replacing its last token (replace-separator), and a remove's parts and whole take a part of a list with its separator and the whole statement when it is the last (FBL §4.9, §6.2, §6.3, section 11.5): insert { place: end-of-document, emit: "\n{s} {p} {o} .", continues: { at: "/triples_statement", same: { s: { node: "triples/subject/iri", expand: true } }, separator: ";", emit: "{p} {o} ." } } and remove { parts: [{ item: ".", separator: "," }, { item: "../..", separator: ";" }], whole: "../../../../.." }.
  • (FBL 0.13) An attribute binding's slot takes, in this family, split: "<text>", the text at which the value of each node it reaches is cut into the items of a many attribute, each without the white space around it, and a set of them is written into the node by splices (FBL §4.9, §5.2, §6.3): attribute tags from node "tags" { split: ",", readOnly: true } reads "Extra, More" as the two tags Extra and More.
  • (FBL 0.11) A block rule of this family is block <name> { … } with the settings at, the selector of the view's node, view, its key from a slot, origins, the readings that show it, and insert, how a view block is added (FBL §5.1, §4.9, Views); it has no line.
  • A rule's at "<selector>" selects nodes of the tree by their names (at "/triples_statement"), and a slot node "<selector>" reads the text of the node or token its relative selector reaches, with the setting match when only part of the text is the value (attribute name from node "PNAME_NS" { match: r"(?<value>[^:]*):" }); FBL §4.9 and §5.2 define both.
  • The checker builds the grammar with the desktop host's table builder, on etalii-lark (research R9): a grammar that is not LALR(1), or in which two terminals a state accepts match the same text, is refused with ATD8001, placed at the head of the definition of the rule whose reduction is in conflict (of two such rules, the one defined first), and naming the kind of conflict, the terminal and the rules. A grammar the checker cannot read as notation is ATD1001 at the place it stops, as for any syntax error; a file named by grammar from that is not there is ATD2009.
  • atd-grammar.py --tables writes the normalized tables (section 4.7) of every grammar a binding example carries, inline or from a file, to grammar/tables/<example>.<binding>.tables.json, and those of every grammar an FBL example names to grammar/tables/<fbl example>.<binding>.tables.json, so that the desktop host's builder is cross-checked against Lark's for binding grammars too.

FBL §4.9 says what the family reads, how it writes, and how it reads a body in part; its guarantees are FBL's (section 11.8). In phase 1 no host but the desktop host is required to read the family (FR-081): the family's round-trip fixtures, specifications/fbl/fixtures/w3c-turtle-grammar*/, grammar-*/, (FBL 0.11) structurizr-*/ and (FBL 0.12) wardley-*/, carry the guarantee to every host that implements it later.

The example binding-grammar.atd carries Turtle's grammar inline.

Referenced from