Skip to content

Instantly share code, notes, and snippets.

@mdproctor
Last active October 28, 2021 11:57
Show Gist options
  • Save mdproctor/66c7b880415dd9fb11594c946ac9a7d6 to your computer and use it in GitHub Desktop.
Save mdproctor/66c7b880415dd9fb11594c946ac9a7d6 to your computer and use it in GitHub Desktop.
EBNF
/* extracted from https://www.bottlecaps.de/rr/ui on Wed Oct 20, 2021, 23:49 (UTC+01)
*/
DRLJ ::= Rule*
Rule
::= SimpleRule | WithParamsAndCustomisedTypeRule | CustomReturnTypeRule | NoReturnTypeRule
/**
* An underlying Pojo is generated for the rule, with properties for the variables. This provides type safe results for queries.
* Implicitly it has a return type of the generaed class, so it's not added to the rule definition.
*/
SimpleRule
::= 'rule' Name '{' RuleBody '}'
/**
* Extends and Implements can specified and are added to the generated Pojo's class.
*/
WithParamsAndCustomisedTypeRule
::= 'rule' Name ('(' Params')')? ('extends' Type)? ('implements' Type ((',' Type)*)?)? '{' RuleBody '}'
/**
* No Pojo class is generated, instead an instance is returned of the type specied in the rule head.
*/
CustomReturnTypeRule ::= 'rule' Type Name ('(' Params')')? '{' RuleBody 'return' JavaExpr ';' '}'
/**
* the use of "void" means there will be no underlying generated rule
*/
NoReturnTypeRule ::= 'rule' 'void' Name ('(' Params')')? '{' RuleBody '}'
RuleBody
::= Body
RuleElement
::= OOPath | Java | Edge | Group | Assign | Acc | GroupBy
Acc
::= SimpleAcc | Acc2Arg | Acc4Or5Arg
GroupBy
::= GroupBy2Arg | GroupBy4Or5Arg
Java
::= JavaStatement | JavaBlock
Group
::= NotExists | AndOr
AndOr
::= ('and' | 'or') '(' GroupBody ')'
NotExists
::= ('not' | 'exists') ( RuleElement | '(' GroupBody ')')
GroupBody
::= Body
Body
::= (RuleElement ( ',' RuleElement)*)?
OOPath
::= Binding? OOPathSeg+ ('.' PropertyName)?
OOPathSeg
::= '/'JavaExpr ('#'Type)? ('(' PositionalArgs ')')? (('[ 'Constraints ']') |
(('[ 'Constraints ']')'[' WatchParams ']'))?
Binding
::= (Type Var (':' || '='))
Assign
::= (Type Var '=') JavaExpr
WatchParams
::= ('!' | '*')? |
((('!' | '*') ',')
(('!'? PropertyName) (',' ('!'? PropertyName))*)?) |
((('!'? PropertyName) (',' ('!'? PropertyName))*)?)
/**
* Need to make sure OOPath resolve to a valid expected type.
* Embedded OOPath can probably only work in single argument functions
*/
SimpleAcc
::= Binding AccumulateFuncName '('(Args | OOPath)')'
/**
* Accumulates now only return a single value (as per old drools acc).
* If multiple results are needed, an anonymous type must be used and each one assigned to a property.
* A Pojo (or Record) is generated underneath with the property type inferred.
* For now C# notation is used for anonymous types, and us also used for the return element of the 4Or5Arg accumulate.
* Note there is an "exception" behaviour, that means this syntax may need a rethink. In 2Arg form you specify the
* function as they value, in the anon type, but its actually the result of the function which is assigned (this is 'exception'
* rule behaviour which is not desirable), where as the 4Or5Arg version has the result value as the value.
*/
Acc2Arg
::= Binding 'acc' '(' RuleElement','
( AccFunction |
('new {' (PropertyName '=>' AccFunction ((',' PropertyName '=>' AccFunction)*)?)? '}')
)
')'
/** As per Acc2Arg this can only return a single instance. An anonymous type must be used to return 2..n results.
* Declared variables in init, are visible to all the ohter elements.
*/
Acc4Or5Arg
::= Binding 'acc' '(' RuleElement','
Java ',' // init
Java ',' // action
Java ',' // result
Java? //reverse
')'
/**
* Group by works the same as accumulate, except it has the extra eleemnt of the grouper expression.
* Note that groupBy always binds to "GroupBy" class which has group and it's resulting value as properties.
* So there will be a GroupBy instance for each resolved group, based on the grouper expr.
*/
Group2Arg
::= Binding 'acc' '(' RuleElement','
JavaExpr ',' // grouper expr
( AccFunction |
('new {' (PropertyName '=>' AccFunction ((',' PropertyName '=>' AccFunction)*)?)? '}')
)
')'
GroupBy4Or5Arg
::= Binding 'groupBy' '(' RuleElement','
JavaExpr ',' // grouper expr
Java ',' // init
Java ',' // action
Java ',' // result
Java? //reverse
')'
AccFunction
::= AccumulateFuncName '(' Args ')'
Params
::= ((Type Var) ( ',' (Type Var))*)?
Args
::= ( (Var | JavaExpr) ( ',' (Var | JavaExpr))*)?
PositionalArgs
::= ( Binding? (Var | JavaExpr) ( ',' Binding? (Var | JavaExpr))*)?
Constraints
::= ((BoolJavaExpr) ( ',' (BoolJavaExpr))*)?
Edge
::= 'edge' (
( ('onAdd' | 'onUpdate' | 'onRemove') Java)
|
( '(' (
( ('onAdd' Java) (',' 'onUpdate' Java)? (',' 'onRemove' Java)?) |
( ('onUpdate' Java)? (',' 'onRemove' Java)?) |
( ('onRemove' Java)?)
)
')'
)
)
JavaBlock
::= '{' (JavaStatement ( ';' JavaStatement)*)? '}'
JavaStatement
::=
JavaExpr
::=
VoidExpr
::=
BoolExpr
::=
Type
::= 'var' | Name
Var
::=
Name
::=
AccumulateFuncName
::=
PropertyName
::=
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment