Last active
October 28, 2021 11:57
-
-
Save mdproctor/66c7b880415dd9fb11594c946ac9a7d6 to your computer and use it in GitHub Desktop.
EBNF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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