SemanticAdaptation.xtext 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. grammar be.uantwerpen.ansymo.semanticadaptation.SemanticAdaptation with org.eclipse.xtext.common.Terminals
  2. import "http://www.eclipse.org/emf/2002/Ecore" as ecore
  3. generate semanticAdaptation "http://www.uantwerpen.be/ansymo/semanticadaptation/SemanticAdaptation"
  4. SemanticAdaptation:
  5. (imports+=Import)*
  6. ('module' name=ID)?
  7. (elements+=Component)*;
  8. Import:
  9. 'import' module=[SemanticAdaptation];
  10. Component:
  11. FMU | Connection;
  12. Connection:
  13. src=[SpecifiedPort] '->' tgt=[SpecifiedPort];
  14. FMU:
  15. AtomicFMU | CompositeFMU | Adaptation;
  16. AtomicFMU:
  17. 'fmu' name=ID
  18. ('type' type=ModelType)?
  19. ('input' 'ports' inports+=Port ("," inports+=Port)*)?
  20. ('output' 'ports' outports+=Port ("," outports+=Port)* )?
  21. ('full' 'internal' 'dependencies')?
  22. ;
  23. CompositeFMU:
  24. 'fmu' name=ID
  25. 'composed' 'of' instances+=[FMU] (',' instances+=[FMU])*
  26. ('input' 'ports' inports+=Port ("," inports+=Port)*)?
  27. ('output' 'ports' outports+=Port ("," outports+=Port)* )?;
  28. Adaptation:
  29. ({Adaptation} 'semantic' 'adaptation' name=ID |
  30. {AdaptationWithSpecificMaster} 'semantic' 'adaptation' name=ID 'without' 'master')
  31. /*'for' type=ModelType*/ ('for' ('fmu' instances+=[FMU] (',' instances+=[FMU])* /*| 'signal' ports+=[SpecifiedPort] (',' ports+=[SpecifiedPort])**/) )? // only multiple instances in case of CT because we only have CT master?
  32. ('input' 'ports' inports+=Port ("," inports+=Port)*)? // only in case of instance-specific SA
  33. ('output' 'ports' outports+=Port ("," outports+=Port)* )? // only in case of instance-specific SA
  34. ('param' params+=ParamDeclaration)*
  35. // (globalvars+=Declaration)*
  36. // algebraic loop generates an FMU encapsulating the loop
  37. // note that the order of semantic adaptations is prefixed in case of a algebraic loop:
  38. // adaptations on internal signals of the loop are inner most, then the algebraic loop iteration, then adaptations on external signals
  39. (generalrules+=GeneraleRule)*
  40. (control=ControlRuleBlock)?
  41. (in=InRulesBlock)?
  42. (out=OutRulesBlock)?
  43. // ('contains' '{' adaptations+=Adaptation+ '}')? // I prefer no structural information here, this belongs to a graphical model
  44. ;
  45. ModelType: DE | UT | CT | DT;
  46. DE: 'DE' | 'de' | 'DiscreteEvent' | 'Discrete' 'Event' | 'discrete' 'event';
  47. UT: 'UT' | 'ut' | 'Untimed' | 'untimed';
  48. CT: 'CT' | 'ct' | 'ContinuousTime' | 'Continuous' 'Time' | 'continuous' 'time';
  49. DT: 'DT' | 'dt' | 'DiscreteTime' | 'Discrete' 'Time' | 'discrete' 'time';
  50. GeneraleRule:
  51. AlgebraicLoopSolution | MultiRate | Derivative;
  52. AlgebraicLoopSolution:
  53. {AlgebraicLoopSolutionFixPointIteration} 'successive' 'substitution' 'starts' 'at' signals+=[SpecifiedPort] (('and'|',') signals+=[SpecifiedPort])? 'with' params+=SettingAssignment ('and' params+=SettingAssignment)* |
  54. {AlgebraicLoopSolutionDelayIntroduction} 'delay' 'at' signals+=[SpecifiedPort] (('and'|',') signals+=[SpecifiedPort])?; // TODO: must be in in or out rule
  55. MultiRate:
  56. 'multiply' 'rate' rate=INT 'times' ('with' interpolation=Interpolation)?; // default first order interpolation
  57. Interpolation:
  58. ({ZeroOrderInterpolation} 'no' | {FirstOrderInterpolation} 'first' 'order' | {SecondOrderInterpolation} 'second' 'order' | {ThirdOrderInterpolation} 'third' 'order' | {FourthOrderInterpolation} 'fourth' 'order') 'interpolation' | // automatically does lower order interpolation in the beginning of simulation when no previous signal values are available
  59. {CustomOrderInterpolation} 'interpolation' 'of' 'order' order=INT |
  60. {CustomInterpolation} 'interpolation' function=AnonymousFunction;
  61. Derivative:
  62. {PredefinedDerivative} 'with' (directionalderivative?='directionalderivative'? & timederivative?='timederivative'?) |
  63. {DefinedDerivative} 'extract' (extractdirectionalderivative?='directionalderivative'? & // decide sensitivity
  64. extracttimederivative?='timederivative'? & // decide sensitivity
  65. extractsensitivity+=AnonymousFunction* ); // new sensitivity definitions
  66. InOutRules:
  67. InRulesBlock | OutRulesBlock;
  68. InRulesBlock:
  69. {InRulesBlock} ('in' globalvars+=Declaration)* 'in' 'rules' ('with' setting+=GeneralSetting (',' setting+=GeneralSetting)*)? '{' iterationvars+=Declaration* rules+=DataRule* '}';
  70. OutRulesBlock:
  71. {OutRulesBlock} ('out' globalvars+=Declaration)* 'out' 'rules' ('with' setting+=GeneralSetting (',' setting+=GeneralSetting)*)? '{' iterationvars+=Declaration* rules+=DataRule* '}';
  72. ControlRuleBlock:
  73. /*('control' globalvars+=Declaration)**/ ControlRule; // TODO: multiple rules or just one?
  74. DataRule: // condition -> state transition --> output function
  75. (((condition=RuleCondition "->" statetransitionfunction=StateTransitionFunction) | ConditionStateTransition | ConditionLessRule) ("-->" outputfunction=OutputFunction)? | AlgebraicLoopSolution) ';';
  76. GeneralSetting:
  77. {GeneralVariableSetting} strategy=RuleStrategy params+=SettingAssignment ('and' params+=SettingAssignment)* |
  78. OutputFunction;
  79. SettingAssignment:
  80. setting=RuleSetting '=' expr=Expression;
  81. RuleCondition:
  82. {RuleCondition} condition=Expression (params+=SettingAssignment ('and' params+=SettingAssignment)*)? |
  83. {CompositeRuleCondition} '{' statements+=Statement* returnstatement=ReturnStatement '}';
  84. RuleSetting:
  85. {AbsoluteTolerance} 'absolute' 'tolerance' | // todo relative/absolute tolerance (look up float equality)
  86. {RelativeTolerance} 'relative' 'tolerance'; // todo relative/absolute tolerance (look up float equality)
  87. // otherwise null
  88. RuleStrategy:
  89. {Crossing} 'crossing';
  90. StateTransitionFunction:
  91. {StateTransitionFunction} expression=Expression |
  92. {StateTransitionFunction} '{' statements+=Statement* '}' |
  93. {StateTransitionFunction} assignment=Assignment;// |
  94. //{StoreNull} ('null' | 'nothing') |
  95. //{StateTransitionFunction} 'todo';
  96. ConditionLessRule:
  97. assignment=Assignment;
  98. ConditionStateTransition:
  99. quantization=Quantize;
  100. Quantize returns ConditionStoreStrategy:
  101. {FiniteQuantize} 'quantize' '(' signal=[SpecifiedPort] ',' zones+=StringLiteral (',' boundaries+=ArithmeticExpression ',' zones+=StringLiteral)* ')' |
  102. {FunctionQuantize} 'quantize' '(' signal=[SpecifiedPort] ',' '=' function=ArithmeticExpression ')' |
  103. {LinearQuantize} 'quantize' signal=[SpecifiedPort] 'every' steps=ArithmeticExpression ('with'? 'offset' offset=ArithmeticExpression)?;
  104. OutputFunction:
  105. {NoHold} 'no' 'hold' |
  106. {ZeroOrderHold} (('zero' 'order' 'hold') | 'ZOH') |
  107. {FirstOrderHold} (('first' 'order' 'hold') | 'FOH') |
  108. {CustomOutputFunction} expr=Expression |
  109. {CompositeOutputFunction} '{' statements+=Statement* (returnstatement=ReturnStatement)? '}';
  110. ControlRule:
  111. {ImpliedControlRule} 'implied' | // the default
  112. {TriggeredControlRule} 'triggered' 'by' condition=Expression |
  113. {PeriodicControlRule} 'periodic' ('at' init_time=REALTYPE)? 'every' period=REALTYPE |
  114. {MultipliedControlRule} 'multiplied' multiplication=INT 'times' |
  115. {CustomControlRule} 'control' '{' ControlRulestatements+=Statement* returnstatement=ReturnStatement '}'; // TODO: how do we know if control is given?
  116. AnonymousFunction: // has access to ports
  117. {FunctionExpression} '{=' code=Expression '}'|
  118. {FunctionBody} '{' statements+=Statement* returnstatement=ReturnStatement '}' | // should return something
  119. FunctionDeclaration; // TODO: should return something
  120. /*[SpecifiedPort]: // if ports need owners
  121. port=[Port] |
  122. {Output[SpecifiedPort]} owner=[FMU] '.' port=[Port] |
  123. {Input[SpecifiedPort]} owner=[FMU] '<-' port=[Port];*/
  124. SpecifiedPort: Port;
  125. Port:
  126. // TODO: add initial values to ports (to do 1st, 2nd, ... order stuff)
  127. // TODO: add internal destination/source of port
  128. // Unity conversions: https://pint.readthedocs.io/en/0.7.2/
  129. name=ID (':=' initval=LiteralOrArray)? ( multiplicity=Multiplicity )? ( '(' unity=Unity ')' )? ('->' target=[SpecifiedPort] | '-->' dependency+=[SpecifiedPort] (dependency+=[SpecifiedPort])*)?;
  130. // TODO: -> output port of wrapped FMU to output port of SA FMU (only used in SA!)
  131. Multiplicity:
  132. '[' (lower=INT '..')? upper=INT ']';
  133. Unity:
  134. DivideUnity;
  135. DivideUnity returns Unity:
  136. MultiplyUnity (({DivideUnity.left=current} '/') right=MultiplyUnity)*;
  137. MultiplyUnity returns Unity:
  138. AtomicUnity (({MultiplyUnity.left=current} '.') right=AtomicUnity)*;
  139. AtomicUnity:
  140. name=ID ('^' (power=INT | power=INTTYPE))?; // somehow LETTERS as name does not work, so power will never be parsed...
  141. //FunctionBody:
  142. // statements+=Statement* returnstatement=ReturnStatement;
  143. Statement:
  144. NestableStatement | FunctionDeclaration;
  145. NestableStatement:
  146. Declaration | (Assignment ';') | (Procedure ';') | For | If | BreakStatement;
  147. For:
  148. 'for' '(' 'var' iterator=DeclaredParameter 'in' iterable=Range ')' '{' (statements+=NestableStatement)* '}';
  149. If:
  150. 'if' '(' ifcondition=Expression ')' '{' (ifstatements+=NestableStatement)* '}' ('else' '{' (elsestatements+=NestableStatement)* '}')?;
  151. FunctionDeclaration:
  152. 'def' name=ID ('(' args+=DeclaredParameter (',' args+=DeclaredParameter)* ')')?
  153. '{' statements+=Statement* returnstatement=ReturnStatement '}';
  154. Declaration:
  155. 'var' name=ID (':=' expr=Expression)? ';';
  156. ParamDeclaration:
  157. name=ID '=' expr=Expression ';';
  158. ReturnStatement:
  159. 'return' Expression ';';
  160. BreakStatement:
  161. {BreakStatement} 'break' ';';
  162. DeclaredParameter:
  163. name=ID;
  164. AbstractDeclaration: // can contain overlapping elements as long as it is only used as reference
  165. Port | ParamDeclaration | Declaration | DeclaredParameter | FunctionDeclaration;
  166. LValueDeclaration: // can contain overlapping elements as long as it is only used as reference
  167. Port | ParamDeclaration | Declaration | DeclaredParameter; // TODO: fmu.port
  168. Assignment:
  169. lvalue=Variable ':=' expr=Expression; // TODO: to what can be assigned? only local vars?
  170. Expression:
  171. OrExpression;
  172. OrExpression returns Expression:
  173. AndExpression ({Or.left=current} 'or' right=AndExpression)*;
  174. AndExpression returns Expression:
  175. NotExpression ({And.left=current} 'and' right=NotExpression)*;
  176. NotExpression returns Expression:
  177. {Not} 'not' left=GreaterThanExpression |
  178. GreaterThanExpression;
  179. GreaterThanExpression returns Expression:
  180. LessThanExpression ({GreaterThan.left=current} '>' right=ArithmeticExpression)?;
  181. LessThanExpression returns Expression:
  182. GreaterThanOrEqualsExpression ({LessThan.left=current} '<' right=ArithmeticExpression)?;
  183. GreaterThanOrEqualsExpression returns Expression:
  184. LessThanOrEqualsExpression ({GreaterThanOrEquals.left=current} '>=' right=ArithmeticExpression)?;
  185. LessThanOrEqualsExpression returns Expression:
  186. EqualsExpression ({LessThanOrEquals.left=current} '<=' right=ArithmeticExpression)?;
  187. EqualsExpression returns Expression:
  188. NotEqualsExpression ({Equals.left=current} '==' right=ArithmeticExpression)?;
  189. NotEqualsExpression returns Expression:
  190. CrossesFromBelowExpression ({NotEquals.left=current} '!=' right=ArithmeticExpression)?;
  191. CrossesFromBelowExpression returns Expression:
  192. CrossesFromAboveExpression ({CrossesFromBelow.left=current} '>!' right=ArithmeticExpression)?;
  193. CrossesFromAboveExpression returns Expression:
  194. BooleanFunction ({CrossesFromAbove.left=current} '<!' right=BooleanFunction)?;
  195. BooleanFunction returns Expression:
  196. {Otherwise} 'otherwise' '(' ref=[SpecifiedPort] ')' |
  197. {Otherwise} 'otherwise' ref=[SpecifiedPort] |
  198. ArithmeticExpression;
  199. ArithmeticExpression returns Expression:
  200. Addition;
  201. Addition returns Expression:
  202. Multiplication (({Plus.left=current} '+' | {Minus.left=current} '-') right=Multiplication)*;
  203. Multiplication returns Expression:
  204. Range (({Multi.left=current} '*' | {Div.left=current} '/') right=Range)*;
  205. Range returns Expression:
  206. UnaryOrPrimaryExpression ({Range.left=current} '..' right=UnaryOrPrimaryExpression)?;
  207. UnaryOrPrimaryExpression returns Expression:
  208. NegationExpression | PrimaryExpression;
  209. NegationExpression returns Expression:
  210. {Neg} '-' right=PrimaryExpression;
  211. PrimaryExpression returns Expression:
  212. '(' Expression ')' | Literal | BuiltinFunction | Var;
  213. LiteralOrArray:
  214. {ArrayLiteral} '[' elements+=Literal (',' elements+=Literal)* ']' |
  215. Literal;
  216. Literal:
  217. IntLiteral | RealLiteral | StringLiteral | BoolLiteral | NullLiteral; //| StepLiteral;
  218. IntLiteral:
  219. value=INTTYPE | value=INT;
  220. RealLiteral:
  221. value=REALTYPE;
  222. StringLiteral:
  223. value=STRING;
  224. BoolLiteral:
  225. value=('true'|'false');
  226. //StepLiteral:
  227. // value=('accept'|'discard');
  228. NullLiteral:
  229. value='null';
  230. BuiltinFunction:
  231. {Floor} name='floor' '(' args+=ArithmeticExpression ')' |
  232. {Ceil} name='ceil' '(' args+=ArithmeticExpression ')' |
  233. {Round} name='round' '(' args+=ArithmeticExpression (',' args+=ArithmeticExpression)? ')' |
  234. {Max} name='max' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' |
  235. {Min} name='min' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' |
  236. {Abs} name='abs' '(' args=ArithmeticExpression ')' |
  237. {Close} name='is_close' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ',' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' | // a, b, relative tolerance, absolute tolerance
  238. {IsSet} name='is_set' '(' args=Variable ')' |
  239. {DoStepFun} name='do_step' '(' fmu=[FMU] ',' H=ArithmeticExpression ')' |
  240. {GetState} name='get_state' '(' fmu=[FMU] ')' |
  241. {GetNextInternalTimeStep} name='get_next_time_step' '(' fmu=[FMU] ')' | // is actually the time step returned by do_step(fmu), preceded by get_state and succeeded by set_state
  242. {Elapsed} name='elapsed' '(' fmu=[FMU] ')';
  243. Procedure:
  244. {Reject} name='reject' |
  245. {Step} name='local_step' '(' fmu=[FMU] ')' |
  246. {Discard} name='discard' '(' args=Variable ')' |
  247. {DoStep} name='do_step' '(' fmu=[FMU] ',' H=ArithmeticExpression ')' |
  248. {SetState} name='set_state' '(' fmu=[FMU] ',' state=Var ')'; // arg: new proposed step size
  249. Var:
  250. {StepSize} name='H' |
  251. {CurrentTime} name='t' |
  252. {ElapsedTime} name='e' | // min (elapsed(fmu1), elapsed(fmu2), ...)
  253. {Max} name='MAX' |
  254. {GenericSignal} name='signal' ('[' (
  255. index=NOW |
  256. index=PREV |
  257. index=INTTYPE |
  258. index=INT // TODO: int must be less than -1, TODO: expression
  259. ) ']')? |
  260. Variable |
  261. FunctionCall; // add "directionalderivative"
  262. Variable:
  263. ref=[LValueDeclaration] ('[' (
  264. index=NOW |
  265. index=PREV |
  266. index=INTTYPE |
  267. index=INT // TODO: int must be less than -1, TODO: expression
  268. ) ']')?; // TODO: NO RECURSION (must terminate)
  269. FunctionCall:
  270. ref=[FunctionDeclaration] '(' args+=ArithmeticExpression (',' args+=ArithmeticExpression)* ')'; // TODO: NO RECURSION (must terminate)
  271. //SignedInt returns ecore::EInt:
  272. // ('-'|'+')? INT;
  273. //SignedReal returns ecore::EBigDecimal:
  274. // '-'? REAL;
  275. terminal INTTYPE returns ecore::EInt : '-' INT;
  276. terminal REALTYPE returns ecore::EFloat : '-'? ((( INT '.' INT | '.' INT | INT '.') (('e'|'E') ('-'|'+') INT)?) | (INT ('e'|'E') ('-'|'+') INT));
  277. //terminal UNSREALTYPE returns ecore::EFloat : ((( INT '.' INT | '.' INT | INT '.') (('e'|'E') ('-'|'+') INT)?) | (INT ('e'|'E') ('-'|'+') INT));
  278. terminal NOW returns ecore::EInt: 'now';
  279. terminal PREV returns ecore::EInt: 'prev';
  280. //terminal REAL returns ecore::EBigDecimal: INT? '.' INT;
  281. //terminal LETTERS returns ecore::EString: ('a'..'z' | 'A'..'Z')+;