Grammar of TQL and EBNF-Notation

The Tosca Query Language (TQL) is a formal language, which means that search queries must use a formal grammar so that the system is able to understand them.

The structure includes so-called non-terminals and terminals. Non-terminals are expressions that can be replaced by other expressions (non-terminals or terminals).

Terminals represent atomic elements and cannot be replaced by other expressions. A correct query that is understood by TQL must consist of a series of terminals. To be able to create a valid search expression, all non-terminals are gradually replaced, such that in the end the desired query consists only of terminals.

The EBNF notation is used to be able to describe the TQL grammar (see chapter "EBNF-Notation").

EBNF-Notation

EBNF Notation

|

logical OR
Example:

a | b = a or b

[...]

Square brackets represent an option.

The expression can be used n-times: n = 0, 1

(...)

Parentheses are used for grouping expressions.
The content must be used exactly once.

Example:

(a | b) c = a and c or b and c

in contrast to

a | b c = a or b and c

{...}

Curly brackets represent an iteration

The expression can be used n-times: n = 0, 1, 2, 3, ...

Example:

a {b} = a or a and b or a and b and b...

'...'

Marks a text which must be taken word-by-word (terminals).

Example:

'SUBPARTS'

In this regard it is helpful that non-terminals in TQL always begin with a lower case letter. Terminals are either special characters (e.g.: "]" , ")", ":" ), or they begin with an upper case letter.

Grammar of TQL

A grammar consists of so-called productions. These are rules with which non-terminals can be replaced by other non-terminals and terminals. A query must consist of a sequence of terminals. To create a valid query, all non-terminals must be replaced by terminals.

query: = {arrowOperator [returnToken] searchExpression}

The above mentioned production consists of non-terminals query, arrowOperator, returnToken and searchExpression (Note: they all start with a lower case letter). Thanks to the curly brackets arrowOperator [returnToken]searchExpression can be lined up as often as desired and returnToken is optional.

A grammar consists of a sum of productions which are handled top down. The starting point is the start symbol consisting of a non-terminal and this is replaced until a search query consisting of terminals is left.

Complete TQL-Grammar

Startsymbol : query

query

::= { arrowOperator [ returnToken ] searchExpression }

 

searchExpression

::= ( assocName | aggregation | specialAssocName | setOperation | subsetOperation | sortOperation | objectsSelector ) [ colonToken type ] [ leftSquareBracket logicalExpression rightSpareBracket ]

 

logicalExpression

::= ( notToken logicalExpression ) | leftParenthesis logicalExpression rightParenthesis | comparisionExpression { logicalOperator logicalExpression } 

 

comparisonExpression

::= expression compOperator expression

 

expression

::= term {addOperator term}

This term may be replaced by a stringLiteral, intLiteral, an attribute or a value

term

::= factor {mulOperator factor}

 

factor

::= leftParenthesis expression rightParenthesis | functionStatement | value

 

functionStatement

::= functionName leftParenthesis [ expression { comma expression } ] rightParenthesis

 

value

::= stringLiteral| intLiteral| attribute

 

attribute

::= {assocName pointToken} identifier

 

assocName

::= identifier

The assocName is replaced by an identifier

type

::= identifier

By entering the type you specify which object should be searched in the respective query.

stringLiteral

::= doublequote TEXT doublequote

TEXT represents a place holder for freely definable strings. Special characters require the use of a backslash as escape character. Several special characters in the text can be transferred by using inverted commas [’] as delimiters in the string.

intLiteral

::= [ "+" | "-" ] DIGITS

 

uintLiteral

::= DIGITS

 

identifier

::= (LETTER | "_") {LETTER | DIGIT | "_"} | quote TEXT quote

 

aggregation

::= "SUBPARTS" | "SUPERPART" | "SELF" | "PROJECT"

 

specialAssocName

::= "AllReferences" | "OwningObject"

 

setOperation

::= setFunction leftParenthesis search {comma search}] rightParenthesis

 

setFunction

::= "COMPLEMENT" | "UNION" | "INTERSECTION"

 

sortOperation

::= sortFunction leftParenthesis search {comma stringLiteral}] rightParenthesis

 

sortFunction

::= "SORT"

 

objectsSelector

::= "OBJECTS" leftParenthesis uniqueIdOrNodePath {comma uniqueIdOrNodePath}] rightParenthesis

 

uniqueIdOrNodePath

::= uniqueIdString | nodePathString

 

uniqueIdString

::= stringLiteral

 

nodePathString

::= stringLiteral

 

subsetOperation

::= "SUBSET" leftParenthesis intLiteral [comma uintLiteral]] rightParenthesis

 

arrowOperator

:= "=>" | "->"

 

compOperator

::= "==" | "!=" | "=i=" | "!i=" | ">" | "<" | ">=" | "<=" | "=?" | "=i?" | "!?" | "!i?" | // LIKE "=*" // LIKE (old version) "=~" | "=i~" // REGEX

compOperators are used to link two expressions and to determine a logical value (true, false)

logicalOperator

::= "AND" | "OR"

conjunction, disjunction

addOperator

::= "+" | "-"

 

mulOperator

::= "*" | "/"

 

returnToken

::= "RETURN"

 

notToken

::= "NOT"

with the notToken it is possible to negate a logical expression

pointToken

::= "."

 

colonToken

::= ":"

 

leftSquareBracket

::= "["

represents a left square bracket

rightSquareBracket

::= "]"

represents a right square bracket

leftParenthesis

::= "("

represents a left parenthesis

rightParenthesis

::= ")"

represents a right parenthesis

comma

::= ","

 

quota

::= "'"

 

doublethink

::= "“"

 

quantifierOperator

::= '<ANY>'

returns all objects in which the specified value occurs.