synit-manual/src/protocols/preserves/path.md

109 lines
4.3 KiB
Markdown
Raw Normal View History

2022-06-01 12:47:24 +00:00
# Preserves Path schema
[Preserves Path](https://preserves.dev/preserves-path.html) is a language for selecting and
filtering portions of a Preserves value. It has an associated schema describing the various
kinds of Path expressions as abstract syntax.
The schema source below is taken from
[path/path.prs](https://gitlab.com/preserves/preserves/-/blob/main/path/path.prs) in the
[Preserves source code repository](https://gitlab.com/preserves/preserves).
Preserves Path expressions come in several flavours: selectors, steps (axes and filters), and
predicates. Each is described below along with its abstract syntax definitions.
## Selectors and Steps
*Selectors* are a sequence of *steps*, applied one after the other to the currently-selected
value. Each step transforms an input into zero or more outputs. A step is an *axis* or a
*filter*.
```preserves-schema
Selector = [Step ...] .
Step = Axis / Filter .
```
## Axes: selecting portions of the input
Each *axis* step generally selects some sub-portion or -portions of the current document. An
axis may also have a secondary filtering effect: for example, `label` only applies to Records,
and will yield an empty result set when applied to any other kind of input.
```preserves-schema
Axis =
/ <values> ;; yields the immediate subvalues of the input nonrecursively
/ <descendants> ;; recurses through all descendant subvalues of the input
/ <at @key any> ;; extracts a subvalue named by the given key, if any
/ <label> ;; extracts a Record's label, if any
/ <keys> ;; extracts all keys (for subvalues) of the input, nonrecursively
/ <length> ;; extracts the length/size of the input, if any
/ <annotations> ;; extracts all annotations attached to the input
/ <embedded> ;; moves into the representation of an embedded value, if any
/ <parse @module [symbol ...] @name symbol> ;; parses using Preserves Schema
/ <unparse @module [symbol ...] @name symbol> ;; unparses using Preserves Schema
.
```
The `parse` and `unparse` variants name [Schema](../../guide/preserves.md#schemas) definitions,
to be resolved by the eventual surrounding context in which the expression will be executed. A
`parse` axis parses the input using a Schema definition; if the parse succeeds, the axis moves
into the parse result. Similarly, `unparse` expects an abstract parse result, transforming it
back into a concrete value according to the Schema definition.
## Filters: rejecting inputs
Each *filter* step generally applies some test to the current document as a whole, either
emitting it unchanged (with exceptions, detailed below) or emitting no outputs at all.
```preserves-schema
Filter =
/ <nop> ;; Always emit the input
/ <compare @op Comparison @literal any> ;; Emit iff the comparison holds
/ <regex @regex string> ;; Emit iff input is String and regex matches
/ <test @pred Predicate> ;; Apply complex predicate
/ <real> ;; Emit iff input is Float, Double, or Integer
/ <int> ;; TRUNCATE and emit iff Float, Double or Integer
/ <kind @kind ValueKind> ;; Emit iff input kind matches
.
```
### Complex predicates
The complex predicates in a `test` filter are built up from logical connectives over selectors.
A `Selector` predicate evaluates to true whenever, applied to its input, it results in a
non-empty output set.
```preserves-schema
Predicate =
/ Selector
/ <not @pred Predicate>
/ <or @preds [Predicate ...]>
/ <and @preds [Predicate ...]>
.
```
### Comparison against a literal
Each `compare` filter includes a `Comparison` and a literal value to compare the input against.
For example, `<compare eq 3>` only produces an output if the input is equal (according to the
[Preserves semantic model](https://preserves.dev/preserves.html#starting-with-semantics)) to
`3`.
```preserves-schema
Comparison = =eq / =ne / =lt / =ge / =gt / =le .
```
**NB.** For inequalities (`lt`/`ge`/`gt`/`le`), comparison between values of different kinds is
undefined in the current draft specification.
### Filtering by value kind
Each `kind` filter selects only values from one of the kinds of Preserves value:
```preserves-schema
ValueKind =
/ =Boolean / =Float / =Double / =SignedInteger / =String / =ByteString / =Symbol
/ =Record / =Sequence / =Set / =Dictionary
/ =Embedded
.
```