Skip to content

14. Processing model

Contents of FBL 0.9

14.1 Loading an FBL document

  1. Parse the JSON; reject duplicate keys.
  2. Check the version: fbl major version supported.
  3. Validate against fbl.schema.json#/$defs/Document.
  4. Resolve names: rule names unique within each binding; every rule named in parent, cascade, reference.to, within and files exists; every reference's by is an attribute every rule in to binds, or id when every rule in to stores its id with id.from; every type names a type of the specification that uses the binding (checked when the tool type's specification is loaded with it, DISL §14.1).
  5. Compile every regular expression in the common subset (section 2.5) and every CEL expression in its context (section 2.4).
  6. Check the rules: every writable attribute has exactly one slot (section 3.3); no fixed DISL attribute is bound; a shared claim has a marker or is registrationOnly; at most one reading is bare; a declared binding has a family and rules; a plugin reader's plugin is declared by the specification; (FBL 0.8) an insert's constant stands only in a binding whose body's family is yaml or json, and never beside emit, and none of its keys is the key of a {key} slot without child that the same rule writes: a writable attribute binding (one that is not readOnly, whose rule is not readOnly, and that is not a value or capture slot), id.from, or a relation rule's source or target. A read-only attribute binding MAY read a constant's key. (FBL 0.9) A body of the grammar family has grammar and no other family has it; the grammar, its file and the files it imports are read from beside the document, are in ATD grammar notation (ATD section 4.1) with terminals in its regular expression subset (ATD section 3.5), and build from start as an LALR(1) automaton with no shift/reduce or reduce/reduce conflict and no two terminals a state accepts matching the same text, and a binding whose grammar does not is refused with a problem that names the conflict: its kind, the terminal and the rules; recover.unit is a rule of the grammar and the start rule's one expansion is unit*, and every entry of recover.sync names a terminal of the grammar or is the text of one of its anonymous string terminals; every segment of a rule's at and of a {node} slot names a rule, an alias or a terminal of the grammar, or is *, ** or, in a slot, .; a rule of the family has at and no line; and no slot of the family is {key}, {attribute}, {text}, {group}, {continuation} or {capture}, nor a {node} slot of another family.

A validator reports every problem with the JSON Pointer of its location, a severity and a message, as DISL §14.1 does.

14.2 Opening a document

  1. Route the file (section 12.3), or read the registration (section 8.1) and find the body (section 8.2).
  2. Open the body: reuse the open body for this path and binding if there is one (section 9.1); otherwise read it through the binding's reader (sections 4, 5, 11), giving the model, the source spans and the findings.
  3. Build the reading: DISL loads the model as it loads a definition (DISL §14.2), derives what it derives, evaluates constraints.
  4. Apply view data from the registration's layout (section 8.3), reporting stale entries.

14.3 Editing

Each committed DISL transaction is planned as one edit (section 6.4), applied to the open body, recorded in its history, and shown in every reading. A view change (a placement) is an edit of the registration.

14.4 Saving and closing

Saving writes each changed file atomically (section 6.6). Closing the last reading of an open body releases it; its history goes with it.

Referenced from