Open popematt opened 3 years ago
A less invasive change (and perhaps a more intuitive syntax) would be to just allow nesting of ordered elements constructs using a subgroup
annotated struct, like this:
type::{
name: disjunction,
type: document,
ordered_elements: [
{ type: conjunction },
subgroup::{
occurs: range::[0, max],
ordered_elements: [
{ type: { valid_values: [ v ] } },
{ type: conjunction },
]
}
]
}
Upon further thought, if accepted, this feature would need to be designed very carefully to ensure it can be implemented in a way that is not vulnerable to catastrophic backtracking the way some Regex implementations are.
The Problem
ISL has very limited support for validating any sort of relationships between elements in a collection. To illustrate, here is an example. Right now it is impossible to define the grammar of Disjunctive Normal Form (DNF) using ISL.
Here is a grammar for DNF:
And here are some examples of valid DNF:
The reason ISL can't express a grammar like this is because it has no way to specify that:
~
must always immediately precede a variableThis is not necessarily a strong use case for subsequence assertions (because we could use a prefix grammar instead of an infix grammar to express the same thing), but it does help to illustrate some of the things that ISL cannot do right now.
Possible Solutions
It is possible that we could decide this is out of scope for ISL. However, if it is something that would be good for ISL, these are are a few (unrefined) ideas that could be used as a starting point.
Allow some sort of lookahead/behind for
elements
and/orordered_elements
For example:
Define a new syntax for collection members
This might need to be a new constraint altogether because it is significantly different from any of the existing constraints. In this example, I've used
members
, though I think it to be a slightly awkward name.The argument to the
members
constraint is not a list of type references, but a list ofmember definitions
. Amember definition
has anoccurs
(defaults torequired
), and either atype
(with a usual type reference) or amembers
field (with nested member definitions).