SBD-JPath Data Model, Entry #1

In this series of entries, this entry being the first, I will specify the SBD-JPath data model. All the resolved values of expressions of this language are within the value-space of the types described in this data model.

This document specifies a grammar for SBD-JPath, using the same basic EBNF notation used in XML 1.0, 5th edition. White space is not significant in expressions. Grammar productions are introduced together with the features that they describe.

All data types in this model are captured by this class hierarchy diagram. Each line describes a type who is directly descendant from the most previous line with one less indentation.

The item type

The item type is an abstract type. An item is the basic building block of SBD-JPath, and is any thing but a sequence. Items can be j-values, functions, maps, tuples or atomic values. All items are immutable.

The sequence type

A sequence is an ordered list of items. Sequences are immutable. A sequence cannot contain a sequence. The empty sequence is identical to an absence of normal value. A sequence with a cardinality of 1 is identical to it’s one member. Sequences are not bags, an item can appear more than once in a sequence. The origin for indexing sequences is 1 (Sorry javascript developers! I chose 1 to be closer to XPath, and for other pragmatic reasons related to sequence predicates). Some core properties/functions of sequences (this is not exhaustive) include:

  1. last(): integer

Last returns the cardinality of the sequence. Equivalently, in the case of non-empty sequences, this is equal to the index of the last item.

Some core operators properties of sequences (this is not exhaustive) include:

  1. left-operand , right-operand
  2. left-operand < < right-operand
  3. left-operand >> right-operand
  4. left-operand is right-operand
  5. left-operand union right-operand
  6. left-operand except right-operand
  7. 1 to 10

A specification for these operands will be defined in a future post. They are equivalent to the ones of the same symbol in XPath 3.1 .

All empty sequences are identical to all other empty sequences. A sequence is identical to another sequence if and only if they have the same cardinality and each member in order, is identical.

An empty sequence can be constructed thus:

The j-value type

The j-value type is an abstract type. It descends from item. It is identical to the type described as “value” in the JSON specification. j-values should be seen as reference data, as opposed to value data, for the purposes of identity. For example, consider the following JSON datum.

The value of the colour property of this json object is a node whose string value is “red”. The type of the node is j-string, which inherits from j-value. Similarly, the value of the flag property is a node whose string value is also “red”. The type of the node is j-string, which inherits from j-value. The two aforementioned instances of j-value are NOT equal nor identical. The string ‘red’ is identical to ‘red’, because string is a value kind of datum. In contrast the two j-values, even though they may have identical property values, are not identical. This is because j-value is a reference kind of datum.

Descendant types are j-string, j-number, j-boolean, j-null, j-object, j-array.

All j-values have two properties:

  1. parent: j-value?
  2. root: j-value

The parent of an array member is the containing array. The parent of a json object’s values are the containing json object. Otherwise the parent is the empty sequence. The root is the ultimate parent or the j-value itself, starting from the given j-value and running up the ancestral path.

The j-string type

The j-string type is a concrete type. It descends from j-value and is sealed. It is identical to the type described as “string” in the JSON specification.

A literal j-string instance without a parent, can be constructed thus:

:"red"

[ebnf title=”j-stringy diagram”]
“j-string” {
j-stringy = string-delimiter { literal-char } string-delimiter.
literal-j-string = “:” j-stringy.
string-delimiter = “”””.
}
[/ebnf]

The model value for such constructed strings are as per JSON specification.

The j-number type

The j-number type is a concrete type. It descends from j-value and is sealed. It is identical to the type described as “number” in the JSON specification.

A literal j-number instance without a parent, can be constructed thus:

The model value for such constructed numbers are as per JSON specification.

The j-object type

The j-object type is a concrete type. It descends from j-value and is sealed. It is identical to the type described as “object” in the JSON specification.

A literal j-object instance without a parent, can be constructed thus:

:{"menu": ["fish", "poultry"]}
[7] j-objecty  ::= "{" (j-stringy ":" j-valuey ("," j-stringy ":" j-valuey)*)? "}"
[8] literal-j-object  ::= ":" j-objecty
[9] j-valuey ::= j-objecty | j-arrayy | j-numbery | j-stringy | j-booleany | y-nully

The model value for such constructed objects are as per JSON specification.

The j-array type

The j-array type is a concrete type. It descends from j-value and is sealed. It is identical to the type described as “array” in the JSON specification.

A literal j-array instance without a parent, can be constructed thus:

:["fish", "poultry"]
[10] j-arrayy ::= "[" (j-valuey ("," j-valuey)*)?] "]"
[11] j-array ::= ":" j-arrayy

The model value for such constructed arrays are as per JSON specification.

The j-boolean type

The j-boolean type is a concrete type. It descends from j-value and is sealed. It is identical to the union of the types described as “true” and “false” in the JSON specification.

A literal j-boolean instance without a parent, can be constructed thus:

:true
[10] j-booleany ::= "true" | "false" 
[11] j-boolean ::= ":" j-booleany

The model value for such constructed booleans are as per JSON specification, with rendered “true” representing logical true, and rendered “false” representing logical false.

The j-null type

The j-null type is a concrete type. It descends from j-value and is sealed. It is identical to the type described as “null” in the JSON specification.

A literal j-null instance without a parent, can be constructed thus:

:null
[12] j-nully ::= "null" 
[14] j-null ::= ":" j-nully

The model value for such constructed nulls are as per JSON specification.

The function type

The function type is a concrete type. It descends from item and is sealed. Functions can be anonymous or named.

A literal anonymous function which doubles a number, can be constructed thus:

function( $x number) as number { 2 * $x }
[15] literalFunction ::= "function" "(" (param ("," param)*)? ")" ("as" sequenceType)? enclosedExpr	
[16] param ::= "$" name ("as" sequenceType)?	
[17] enclosedExpr ::= "{" expr? "}"

expr will be defined later. It is basically an expression.
name will be defined later. It is basically a programmatic identifier, with a grammar common to most language grammars for variable identifiers.
sequenceType is a type specification. Parameters and function returns can be so typed.

Defining our productions further …

sequenceType

[18] SequenceType ::= ("empty-sequence" "(" ")") | (itemType occurrenceIndicator?)	

A sequence type is a test for a parameter type. If the actual value of the parameter does not pass the test, it will be a static error, if this error can be syntactically detected, and a run-time error if not. The empty-sequence() passes if and only if the actual value is an empty sequence.

sequenceType

[19] itemType ::= kindTest | ("item" "(" ")") | functionTest | mapTest | tupleTest | atomic
[20] occurrenceIndicator ::= "?" | "*" | "+"

An item type is a test for a parameter type. If the occuranceIndicator is ?, the count of items must be 0 or 1. If the occuranceIndicator is *, the count of items can be any number. If the occuranceIndicator is +, the count of items must be at least 1. If there is no occuranceIndicator, then the count of items must be precisely 1.

sequenceType

[21] kindTest ::= j-stringTest | j-numberTest | j-booleanTest | j-nullTest | j-arrayTest | j-objectTest | j-anyTest

A kind test is a test for a parameter type. The parameter value must be one of the standard json data types (j-string, j-number, j-object etc.)

j-stringTest

[22] j-stringTest ::= ("text" "(" ")") | ("text-or-null" "(" ")") | ("nonempty-text" "(" ")") 

A j-string test is a test for a parameter type. The parameter value must be a j-string value, or in the case of text-or-null(), either a j-string value or a j-null value. In the case of nonempty-text(), the j-string string value must be a non-empty string.

j-numberTest

[23] j-numberTest ::= ("number" "(" number-constraint* ")") | ("number-or-null" "(" number-constraint* ")")
[24] number-constraint ::= ("min" S number) | ("max" S number) | ("grain" S number) 

A j-number test is a test for a parameter type. The parameter value must be a j-number value, or in the case of number-or-null(), either a j-number value or a j-null value. Each number-constraint kind (min, max or grain), can only occur once, but in any order. If min is present, and the value is not j-null, the test fails if the numerical actual value of the parameter is less than the specified min number. Similarly for max. It is a static error, if the max value is less than the min value. The grain number must be specified with exponent, and be a positive number. If the grain constraint is specified, and the value is not j-null, and the remainder of the parameter actual value after division by the grain number (granularity) is non-zero, then the test fails.

j-booleanTest

[25] j-booleanTest ::= ("boolean" "(" ")") | ("boolean-or-null" "(" ")")

A j-boolean test is a test for a parameter type. The parameter value must be a j-boolean value, or in the case of boolean-or-null(), either a j-boolean value or a j-null value.

j-nullTest

[26] j-nullTest ::= "null" "(" ")"

A j-null test is a test for a parameter type. The parameter value must be a j-null.

j-arrayTest

[27] j-arrayTest ::= ("array" | "array-or-null") "(" arrayTypeConstraint* ")"
[28] arrayTypeConstraint ::= ("base" S (kindTest - j-anyTest)) | ("min" S number) | ("max" S number)

A j-array test is a test for a parameter type. The parameter value must be a j-array, or either j-array or j-null, in the case of array-or-null(). If constraints are present, the constraints must be met. The can be at most only one base constraint, one min constraint and one max constraint, but they can be in any order. If the base constraint is present, each member of the parameter value array, if the value is not j-null, must pass the specified kindTest. The numbers for the min and max, must be non-negative integers and not be rendered with the characters “+”, “-“, “.”, “e” and “E”. It is a static error for the max number to be less than the min number. It is an error if the cardinality of the array is less than the min (if specified) or greater than the max (if specified).

j-objectTest

[29] j-objectTest ::= ("object" | "object-or-null") "(" ")"

A j-object test is a test for a parameter type. The parameter value must be a j-object, or either j-object or j-null, in the case of object-or-null(). In future versions of SBD-JPath, we may allow extensions to the test, which will constrain the objects to a given JSON schema. It is envisaged that SBD-JPath compliant implementations of SBD-JPath processors will each have a convenient mechanism for which to register schemas. These schemas could then be leveraged in j-object tests.

j-anyTest

[30] j-anyTest ::= "node" "(" ")"

A j-any test is a test for a parameter type. The parameter value must be a json datum, namely j-value. This includes j-null.

atomic

[31] atomic  ::= "string" | "number" | "boolean" | "date"

An atomic test is a test for a parameter type. The parameter value must be one of the fundamental non-node types of SBD-JPath, to wit: string, number, boolean or date. None of these types include a null value in their value-space. Dates do not include a time component, nor time-zone. The test passes if the parameter type is a string (in the case of “string”), etc.

functionTest

A function-test is a test for any function. The test passes if the parameter is a function of any signature.

mapTest

A map-test is a test for any map. The test passes if the parameter is a map.

tupleTest

(Content to be developed)

The map type

(Content to be developed)

The tuple type

(Content to be developed)

The atomic-value type

(Content to be developed)
(Content should follow structure:
* basic description
* position in the type hierarchy
* value-space
* properties
* constructor grammar
* some core operators and functions
)

The string type

(Content to be developed)

The number type

(Content to be developed)

The boolean type

(Content to be developed)

The date type

(Content to be developed)


This entry was posted in SBD-JPath. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

Comments Protected by WP-SpamShield Spam Plugin