Grammar overview
Here is the SPL grammar syntax, with references to the sections that contain the semantics.
For more information, see Lexical syntax and Grammar notation.
The compilation unit is the start symbol of the SPL grammar.
compilationUnit ::= namespace? useDirective* # Compile-time entities ( compositeDef | functionDef | standAloneTypeDef )* namespace ::= ‘namespace' ID+. ‘;' useDirective ::= ‘use' ID+. ‘::' ( ‘*' | ID ) ‘;apos;
Composite operators are defined at the top level in a
namespace.
compositeDef ::= compositeHead compositeBody # Composite operators compositeHead ::= ‘public'? ‘composite' ID ( ‘(' compositeInOut+; ‘)' )? compositeInOut ::= ( ‘input' | ‘output' ) ( streamType? ID )+, streamType ::= ‘stream' ‘<' tupleBody ‘>' compositeBody ::= ‘{' ( ‘param' compositeFormal+ )? ( ‘type' compositeTypeDef+ )? ( ‘graph' opInvoke+ )? ( ‘config' configuration+ )? ‘}' compositeFormal ::= expressionMode ID ( ‘:' opActual )? ‘; # Operator parameter modes opInvokeActual ::= ID ‘:' opActual ‘;' opActual ::= type | expr+, configuration ::= ID ‘:' expr+, ‘;' # Config clause, Config clause
Streams are defined in a composite operator's graph
clause.
opInvoke ::= opInvokeHead opInvokeBody # Operator invocations opInvokeHead ::= opOutputs ( ‘as' ID )? ‘=' ID opInputs # Operator invocation head opOutputs ::= opOutput | ‘(' opOutput*; ‘)' opOutput ::= streamType ID ( ‘as' ID )? opInputs ::= ‘(' portInputs*; ‘)' portInputs ::= streamType? ID+, ( ‘as' ID )? opInvokeBody ::= ‘{' # Operator invocations ( ‘logic' opInvokeLogic+ )? ( ‘window' opInvokeWindow+ )? ( ‘param' opInvokeActual+ )? ( ‘output' opInvokeOutput+ )? ( ‘config' configuration+ )? ‘}' opInvokeLogic ::= opInvokeCode | opInvokeState # Logic clause opInvokeCode ::= 'onProcess' ':' stmt | ( 'onTuple' | 'onPunct' ) ID ':' stmt opInvokeState ::= ‘state' ‘:' ( varDef | ‘{' varDef+ ‘}' ) opInvokeWindow ::= ID ‘:' expr+, ‘;' # Window clause opInvokeOutput ::= ID ‘:' ( ID ‘=' expr )+, ‘;' # Output clause
SPL functions are defined at the top level in a
namespace.
functionDef ::= functionHead blockStmt # SPL functions functionHead ::= functionModifier* type ID ‘(' functionFormal*, ‘)' functionModifier ::= ‘public' | ‘stateful' functionFormal ::= ‘mutable'? type ID
Native function prototype declarations come from XML files, not regular SPL
files.
functionPrototype ::= genericFormals functionModifier* # Native functions type ID ‘(' protoFormal*, ‘)' genericFormals ::= ( ‘<' typeFormal+, ‘>' )? ( ‘[' boundsFormal+, ‘]' )? typeFormal ::= typeFormalConstraint ID typeFormalConstraint ::= ‘any' | ‘collection' | ‘complex' | ‘composite' | ‘decimal' | ‘enum' | ‘float' | ‘floatingpoint' | ‘integral' | ‘list' | ‘map' | ‘numeric' | ‘optional' | ‘ordered' | ‘primitive' | ‘set' | ‘string' | ‘tuple' boundsFormal ::= ID protoFormal ::= formalModifier* type ID?
Imperative statements can appear in function bodies or the logic clause of an operator
invocation.
stmt ::= varDef | blockStmt | exprStmt # Statements | ifStmt | forStmt | whileStmt | breakStmt | continueStmt | returnStmt varDef ::= ‘mutable'? type ( ID ( ‘=' expr )? )+, ‘;' blockStmt ::= ‘{' ( stmt | standAloneTypeDef )* ‘}' exprStmt ::= expr ‘;' ifStmt ::= ‘if' ‘(' expr ‘)' stmt ( ‘else' stmt )? forStmt ::= ‘for' ‘(' type ID ‘in' expr ‘)' stmt whileStmt ::= ‘while' ‘(' expr ‘)' stmt breakStmt ::= ‘break' ‘;' continueStmt ::= ‘continue' ‘;' returnStmt ::= ‘return' expr? ‘;'
Expressions can appear in many places in the grammar. For precedence and associativity, see Expression operators.
expr ::= prefixExpr | infixExpr | postfixExpr
| conditionalExpr | ‘(' expr ‘)' | ID
| literal # Expression language
prefixExpr ::= prefixOp expr
prefixOp ::= ‘!' | ‘-' | ‘~' | ‘++' | ‘--'
infixExpr ::= expr ( infixOp | mappedOp | assignOp ) expr
infixOp ::= ‘+' | ‘-' | ‘*' | ‘/' | ‘%' | ‘<<' | ‘>>' | ‘&' | ‘ˆ' | ‘|'
| ‘&&' | ‘||' | ‘in' | ‘<' | ‘<=' | ‘>' | ‘>=' | ‘!=' | ‘==' | ‘?:'
mappedOp ::= ‘.+' | ‘.-' | ‘.*' | ‘./' | ‘.%' | ‘.<<' | ‘.>>' | ‘.&'
| ‘.^' | ‘.|' | ‘.<' | ‘.<=' | ‘.>' | ‘.>=' | ‘.!=' | ‘.=='
assignOp ::= ‘=' | ‘+=' | ‘-=' | ‘*=' | ‘/=' | ‘%=' | ‘<<=' | ‘>>='
| ‘&=' | ‘^=' | ‘|='
postfixExpr ::= ID ‘(' expr*, ‘)'
| type ‘(' expr ‘)'
| expr ‘[' subscript ‘]'
| expr ‘.' ID
| expr postfixOp
subscript ::= expr | ( expr? ‘:' expr? )
postfixOp ::= ‘++' | ‘--' | ‘??' | ‘!'
conditionalExpr ::= expr ‘?' expr ‘:' exprLiterals are the highest-precedence expressions that denote
values.
literal ::= primitiveLiteral | listLiteral | setLiteral | mapLiteral
| nullLiteral | tupleLiteral # Expression language
listLiteral ::= ‘[' expr*, ‘]' # Collections
setLiteral ::= ‘{' expr*, ‘}'
mapLiteral ::= ‘{' ( expr ‘:' expr )*, ‘}'
nullLiteral ::= ‘null' # Optional types
tupleLiteral ::= ‘{' ( ID ‘=' expr)*, ‘}' # Tuples
primitiveLiteral ::= ‘true' | ‘false' | STRING | FLOAT | INT # Primitive types;Types are defined in a composite operator's type clause, or in a block, or at the top
level.
standAloneTypeDef ::= ‘type' ID ‘=' ( type | tupleBody ) ‘;' compositeTypeDef ::= ‘static'? ID ‘=' ( type | tupleBody ) ‘;' # Type definitions expressionMode ::= ‘attribute' | ‘expression' typeArgs? # Operator parameter modes | ‘function' | ‘operator' | ‘type' type ::= ID | ‘void' | primitiveType | compositeType # Types typeArgs ::= ‘<' type+, ‘>' typeDims ::= ‘[' expr ‘]'
Primitive types are types without other types as
arguments.
primitiveType ::= ‘boolean' # Primitive types | ‘enum' ‘{' ID*, ‘}' | ‘int8' | ‘int16' | ‘int32' | ‘int64' | ‘int128' | ‘uint8' | ‘uint16' | ‘uint3'| ‘uint64' | ‘uint128' | ‘float32' | ‘float64' | ‘decimal32' | ‘decimal64' | ‘decimal128' | ‘complex32' | ‘complex64' | ‘timestamp' | ‘blob' | ‘rstring' typeDims? | ‘ustring' | ‘xml' ('<' "schemaURI" '>')?
Composite types are type constructors for composing new types out of other
types.
compositeType ::= tupleType # Composite types | ‘list' typeArgs typeDims? | ‘map' typeArgs typeDims? | ‘set' typeArgs typeDims? | ‘optional' typeArgs tupleType ::= ‘tuple' ‘<' tupleBody ‘>' # Tuples tupleBody ::= attributeDecl+, | ( ID | tupleType )+, attributeDecl ::= type ID