Skip to main content

Wolf DSL Grammar Reference

This page provides a complete grammar reference for Wolf DSL, derived directly from the Xtext grammar specification. Each section shows the grammar rule along with practical examples.

Grammar Source

This reference is generated from Flow.xtext and stays synchronized with the actual parser implementation.

Top-Level Model Structure

Model

The root grammar rule that defines a complete Wolf DSL file:

Model:
query+=QueryDefinition*
type+=TypeSystemDefinition*
node+=Node*;

Example:

// GraphQL queries (optional)
query GetUser {
user(id: $userId) {
name
email
}
}

// Type definitions (optional - usually inherited from GraphQL)
type User {
id: ID!
name: String
email: String
}

// Wolf DSL nodes (main content)
Schema UserSchema {
string name
string email
}

Flow userFlow {
// ... flow definition
}

Node Types

Node Definition

All executable nodes inherit from this base definition:

Node returns graphql::ObjectTypeDefinition:
State | Schema;

State:
Flow | Service | Mapping | SchemaAssignment |
Rulebase | GraphQLService;

Schema Definitions

Schema

Defines data structure for type safety:

Schema:    
'Schema' id=AllowedKeyword '{'
schema=(Data)
'}';

Data:
entity+=Entity+;

Entity:
(annotation=Annotation)? name=AllowedKeyword op='{'
entity+=Entity*
'}'
|
(annotation=Annotation)? name=AllowedKeyword op='['
entity+=Entity+
']'
|
(annotation=Annotation)? name=AllowedKeyword op='->' schema=[graphql::ObjectTypeDefinition]
|
(annotation=Annotation)? (type=DataType|schema=[graphql::ObjectTypeDefinition]) (op="[]")? name=AllowedKeyword;

Examples:

Schema User {
string name
string email
boolean isActive
}

Data Types

Built-in primitive types:

DataType:
'string' | 'boolean' | 'number';

Value Assignments

Schema Assignment (Value)

Creates data instances conforming to schemas:

SchemaAssignment:
'value' id=AllowedKeyword '->' schema=[Schema]
value = (ObjectValue | ArrayValue);

Examples:

value userProfile -> User {
name: "John Doe"
email: "john@example.com"
isActive: true
}

Service Definitions

REST Service

HTTP service calls with full configuration:

Service:
(sync='synchronous')? (verbose='verbose')? 'Service' type=ID 'as' id=ID
'method' method=ServiceType ('foreach' iterator=SchemaVariable 'as' iteratoralias=AllowedKeyword)?
('input' inputModel=[graphql::ObjectTypeDefinition])?
('output' (outputModel=OutputOrAlias))? '{'

(('Url ->' url=Property)? | ('Url ->' '${'url=Expression'}')?)
('UrlEncoding ->' urlEncoding=EncodingMode)?
('Path ->' '${'path=Expression'}')?
('ProxyHost ->' '${'proxyhost=Expression'}')?
('ProxyPort ->' '${'proxyport=Expression'}')?
('Timeout ->' '${'timeout=Expression'}')?
('Retry ->' '${'retryCount=Expression'}')?
(arguments+=ServiceArguments)*
(requestArguments+=RequestArgument)*
'}';

ServiceType:
'GET' | 'POST' | 'PUT' | 'DELETE';

Examples:

Service userService method GET as getUserById
input UserRequest output User {
Url -> @Config("api.base.url")
Path -> ${"/users/" + UserRequest.id}
Timeout -> ${5000}
Retry -> ${3}
@Header Authorization -> ${"Bearer " + @Config("api.token")}
@Header Accept -> ${"application/json"}
}

GraphQL Service

GraphQL query execution:

GraphQLService:
(sync='synchronous')? (verbose='verbose')? 'GraphQLService' id=ID 'graphqlQuery' query=QueryModel '{'
('Url ->' '${'url=Expression'}')
('Path ->' '${'path=Expression'}')?
('Timeout ->' '${'timeout=Expression'}')?
('Retry ->' '${'retryCount=Expression'}')?
(variables+=GraphQLVariable)*
(headerOrQueryOrPathParam+=HeaderORQueryOrPathParam)*
'}';

Example:

GraphQLService userGraphQL graphqlQuery GetUserQuery as fetchUserData {
Url -> @Config("graphql.endpoint")
Path -> ${"/graphql"}
Timeout -> ${5000}
@Variable userId -> ${userRequest.id}
@Header Authorization -> ${"Bearer " + @Config("graphql.token")}
}

Mapping (Data Transformation)

Mapping Definition

Transform data between schemas:

Mapping:
'Mapping' id=ID
('input' inputModel+=(InPutModel)
(',' inputModel+=(InPutModel))*
'output' outputModel=OutPutModel)
'{'
statement+=Statement*
'}';

Examples:

Mapping userTransform input RawUser output User {
User.name = RawUser.firstName + " " + RawUser.lastName
User.email = lowerCase(RawUser.emailAddress)
User.isActive = RawUser.status == "active"
}

Flow Control

Flow Definition

Orchestrates execution path through nodes:

Flow:
'Flow' id=ID '{'
startState = StartState
transitionStates += TransitionState*
'}';

StartState:
'Start' start=[State] '{'
('transition' '{'
transition=Transition
'}')?
'}';

TransitionState:
state=[State] '{'
('transition' '{'
transition=Transition
'}')?
'}';

Transition Logic

Controls flow between states:

Transition:
expression=Expression '?' trueState=Transition ':' falseState=Transition |
('when' caseExpressions+=Expression 'then' caseStates+=[TransitionState])+ ('otherwise' 'do' defaultState=[TransitionState]) |
transition=[TransitionState];

Examples:

Flow userProcessingFlow {
Start userInput {
transition {
validateUser
}
}

validateUser {
transition {
transformUser
}
}

transformUser {}
}

Expression System

Expression Hierarchy

Wolf DSL supports rich expressions with proper operator precedence:

Expression:
BooleanExpression;

BooleanExpression returns Expression:
Comparison
(({BooleanExpression.left=current} op=("||"|"&&"|"and"|"or")) right=Comparison)*;

Comparison returns Expression:
Membership
(({Comparison.left=current} op=("<" | ">" | "<=" | ">=")) right=Membership)*;

Membership returns Expression:
Equals
(({Membership.left=current} op=("in" | "not_in")) "[" right+=Expression(',' right+=Expression)* "]")*;

Equals returns Expression:
Addition
(({Equals.left=current} op=("==" | "!=" | "=~" | "!~" | "is") ) right=Addition)*;

Addition returns Expression:
Multiplication
(({Plus.left=current} '+' | {Minus.left=current} SIGN)
right=Multiplication)*;

Multiplication returns Expression:
Prefixed (({MultiOrDivOrModPow.left=current} op=("*"|"/"|"%"|"^")) right=Prefixed)*;

Examples:

// Basic arithmetic
total = price * quantity + tax
discount = price * 0.1
finalPrice = price - discount
average = sum / count

Built-in Functions

Collection Functions

Functions for array/list manipulation:

CollectionFunction:
function=CollectionFunctionCall ('[' refexp=Expression ']')?('.'resultKey+=Key)*;

CollectionFunctionCall:
RemoveFunc | FindFirstFunc | FilterFunc | MapFunc | Split | Json |
ConcatFunc | SortFunc | DedupFunc | LastFunc | ParentFunc |
LowerFunc | UpperFunc | UUIDFunc;

Examples:

// Filter collections
activeUsers = filter(users, user -> user.isActive == true)
premiumUsers = filter(users, user -> user.type == "premium")
recentOrders = filter(orders, order -> order.date >= "2023-01-01")

// Find operations
firstAdmin = findFirst(users, user -> user.role == "admin")
lastOrder = last(orders)

String Functions

Text manipulation functions:

Split:
'split('exp=Expression','regex=STRING')';

Contains:
'contains('input=Expression','search=Expression')';

Replace:
'replace('text=Expression','searchString=Expression','replacement=Expression')';

Date Functions

Date and time operations:

DateFormat:
'dateFormat' '(' from=('\"MM/dd/yyyy\"' | '\"yyyyMMdd\"' | '\"yyyy-MM-dd\"' | '\"ms\"' | STRING)
',' to=('\"MM/dd/yyyy\"' | '\"yyyyMMdd\"' | '\"yyyy-MM-dd\"' | '\"ms\"' | STRING)
',' exp=Expression (',' fromTimeZone=(Expression) ',' toTimeZone=(Expression) )? ')';

CurrentDate:
'currentDate('format=('\"MM/dd/yyyy\"' | '\"yyyyMMdd\"' | '\"yyyy-MM-dd\"' | '\"ms\"' | STRING)?')';

DayDifference:
'dayDifference('from=Expression','to=Expression',' formatter=('\"MM/dd/yyyy\"' | '\"yyyyMMdd\"' | '\"yyyy-MM-dd\"') ')';

Advanced Features

Rulebase (Business Rules Engine)

Define conditional rule sets:

Rulebase:
'Rulebase' (async?='asynchronous')? id=UID '{'
rules+=NewRule+
'}';

NewRule:
'Rule' id=UID ('with [' modifiers+=UID(','modifiers+=UID)*']')?
'using' (inputModel+=InPutModel)(',' inputModel+=InPutModel)*
'inject' injectedTopicId=UID ('withValue' outputModel=InPutModel)?
'when' condition=BooleanExpression;

Example:

Rulebase pricingRules {
Rule applyPremiumDiscount using Order, Customer
inject discountAmount withValue DiscountValue
when Customer.type == "premium" && Order.total > 1000

Rule applyBulkDiscount using Order
inject discountPercent withValue DiscountPercent
when length(Order.items) > 5
}

Custom Functions

User-defined function calls:

CustomFunction:
'custom('id=STRING (','arguments+=CustomFunctionArguments)* ')';

CustomFunctionArguments:
value=Expression 'as' key=ID;

Example:

result = custom("calculateTax", orderTotal as amount, "CA" as state, true as includeFees)

Comments and Documentation

Wolf DSL supports standard comment syntax:

// Single line comment
/* Multi-line comment
continues here */

Schema User {
string name // Field comment
/* Complex field with
detailed explanation */
string email
}

Validation Rules

The grammar enforces several validation rules:

  1. Schema References: All data must reference valid schemas
  2. Type Safety: Expressions must be type-compatible
  3. Flow Completeness: All transition targets must exist
  4. Variable Scoping: Variables must be in scope when referenced
  5. Service Configuration: Required service parameters must be provided

Grammar Evolution

This grammar reference is maintained alongside the Xtext specification. For the most current grammar rules, always refer to the source Flow.xtext file.


The grammar specification enables rich IDE support, syntax validation, and code generation while maintaining the declarative simplicity that makes Wolf DSL powerful and easy to use.