SemanticAdaptation.xtext 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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. GlobalFMU | Connection;
  12. Connection:
  13. src=SpecifiedPort '->' tgt=SpecifiedPort;
  14. GlobalFMU:
  15. AtomicFMU | CompositeFMU | Adaptation;
  16. FMU:
  17. AtomicFMU | InnerFMU | CompositeFMU | Adaptation;
  18. AtomicFMU:
  19. 'fmu' type=FMUType name=ID
  20. //('type' type=ModelType)?
  21. 'at' path=STRING // to be found here
  22. ('input' 'ports' inports+=Port ("," inports+=Port)* )?
  23. ('output' 'ports' outports+=Port ("," outports+=Port)* )?
  24. //('full' 'internal' 'dependencies')? // not needed but extracted from the FMU (at-clause)
  25. ;
  26. InnerFMU: // slightly different syntax
  27. 'inner' 'fmu' type=FMUType name=ID
  28. ('at' path=STRING)? // optional in case of a semantic adaptation, where we still want to specify the ports
  29. ('with' 'input' 'ports' inports+=Port ("," inports+=Port)* )?
  30. ('with' 'output' 'ports' outports+=Port ("," outports+=Port)* )?
  31. ;
  32. CompositeFMU:
  33. 'fmu' type=FMUType name=ID
  34. 'at' path=STRING // to be generated here
  35. 'composed' 'of' instances+=[FMU] (',' instances+=[FMU])*
  36. ('input' 'ports' inports+=Port ("," inports+=Port)*)?
  37. ('output' 'ports' outports+=Port ("," outports+=Port)* )?;
  38. Adaptation:
  39. ({Adaptation} 'semantic' 'adaptation' (reactiveness=ReactiveOrDelayed)? (machine=MooreOrMealy)? type=FMUType (name=ID)? | // this is a type or a name?
  40. {AdaptationWithSpecificMaster} 'semantic' 'adaptation' (reactiveness=ReactiveOrDelayed)? (machine=MooreOrMealy)? type=FMUType (name=ID)? 'without' 'master')
  41. 'at' path=STRING // to be generated here
  42. inner=InnerFMUDeclaration
  43. ('input' 'ports' inports+=Port ("," inports+=Port)*)? // only in case of instance-specific SA
  44. ('output' 'ports' outports+=Port ("," outports+=Port)* )? // only in case of instance-specific SA
  45. (params+=ParamDeclarations)*
  46. // (globalvars+=Declaration)*
  47. // algebraic loop generates an FMU encapsulating the loop
  48. // note that the order of semantic adaptations is prefixed in case of a algebraic loop:
  49. // adaptations on internal signals of the loop are inner most, then the algebraic loop iteration, then adaptations on external signals
  50. (generalrules+=GeneraleRule)*
  51. (control=ControlRuleBlock)?
  52. (in=InRulesBlock)?
  53. (out=OutRulesBlock)?
  54. // ('contains' '{' adaptations+=Adaptation+ '}')? // I prefer no structural information here, this belongs to a graphical model
  55. ;
  56. enum ReactiveOrDelayed:
  57. REACTIVE='reactive' | DELAYED='delayed';
  58. enum MooreOrMealy:
  59. MOORE='moore' | MEALY='mealy';
  60. FMUType:
  61. name=ID; // TODO: maybe better to declare types and
  62. ModelType: DE | UT | CT | DT;
  63. DE: 'DE' | 'de' | 'DiscreteEvent' | 'Discrete' 'Event' | 'discrete' 'event';
  64. UT: 'UT' | 'ut' | 'Untimed' | 'untimed';
  65. CT: 'CT' | 'ct' | 'ContinuousTime' | 'Continuous' 'Time' | 'continuous' 'time';
  66. DT: 'DT' | 'dt' | 'DiscreteTime' | 'Discrete' 'Time' | 'discrete' 'time';
  67. InnerFMUDeclaration:
  68. /*'for' type=ModelType*/ {InnerFMUDeclarationList} 'for' ('fmu' instances+=[FMU] (',' instances+=[FMU])* /*| 'signal' ports+=SpecifiedPort (',' ports+=SpecifiedPort)**/) | // only multiple instances in case of CT because we only have CT master?
  69. {InnerFMUDeclarationFull} ( 'for' fmus+=InnerFMU )+ ('coupled' 'as' connection+=Connection (',' connection+=Connection)* )?
  70. ;
  71. GeneraleRule:
  72. AlgebraicLoopSolution | MultiRate | Derivative;
  73. AlgebraicLoopSolution:
  74. {AlgebraicLoopSolutionFixPointIteration} 'successive' 'substitution' 'starts' 'at' signals+=SpecifiedPort (('and'|',') signals+=SpecifiedPort)? 'with' params+=SettingAssignment ('and' params+=SettingAssignment)* |
  75. {AlgebraicLoopSolutionDelayIntroduction} 'delay' 'at' signals+=SpecifiedPort (('and'|',') signals+=SpecifiedPort)?; // TODO: must be in in or out rule
  76. MultiRate:
  77. 'multiply' 'rate' rate=INT 'times' ('with' interpolation=Interpolation)?; // default first order interpolation
  78. Interpolation:
  79. ({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
  80. {CustomOrderInterpolation} 'interpolation' 'of' 'order' order=INT |
  81. {CustomInterpolation} 'interpolation' function=AnonymousFunction;
  82. Derivative:
  83. {PredefinedDerivative} 'with' (directionalderivative?='directionalderivative'? & timederivative?='timederivative'?) |
  84. {DefinedDerivative} 'extract' (extractdirectionalderivative?='directionalderivative'? & // decide sensitivity
  85. extracttimederivative?='timederivative'? & // decide sensitivity
  86. extractsensitivity+=AnonymousFunction* ); // new sensitivity definitions
  87. InOutRules:
  88. InRulesBlock | OutRulesBlock;
  89. InRulesBlock:
  90. {InRulesBlock} ('in' globalInVars+=Declaration)* 'in' 'rules' ('with' setting+=GeneralSetting (',' setting+=GeneralSetting)*)? '{' iterationvars+=Declaration* rules+=DataRule* '}';
  91. OutRulesBlock:
  92. {OutRulesBlock} ('out' globalOutVars+=Declaration)* 'out' 'rules' ('with' setting+=GeneralSetting (',' setting+=GeneralSetting)*)? '{' iterationvars+=Declaration* rules+=DataRule* '}';
  93. ControlRuleBlock:
  94. ('control' globalCtrlVars+=Declaration)* rule=ControlRule; // TODO: multiple rules or just one?
  95. DataRule: // condition -> state transition --> output function
  96. (((condition=RuleCondition "->" statetransitionfunction=StateTransitionFunction) | ConditionStateTransition | ConditionLessRule) ("-->" outputfunction=OutputFunction)? | AlgebraicLoopSolution) ';';
  97. GeneralSetting:
  98. {GeneralVariableSetting} strategy=RuleStrategy params+=SettingAssignment ('and' params+=SettingAssignment)* |
  99. OutputFunction;
  100. SettingAssignment:
  101. setting=RuleSetting '=' expr=Expression;
  102. RuleCondition:
  103. {RuleCondition} condition=Expression (params+=SettingAssignment ('and' params+=SettingAssignment)*)? |
  104. {CompositeRuleCondition} '{' statements+=Statement* returnstatement=ReturnStatement '}';
  105. RuleSetting:
  106. {AbsoluteTolerance} 'absolute' 'tolerance' | // todo relative/absolute tolerance (look up float equality)
  107. {RelativeTolerance} 'relative' 'tolerance'; // todo relative/absolute tolerance (look up float equality)
  108. // otherwise null
  109. RuleStrategy:
  110. {Crossing} 'crossing';
  111. StateTransitionFunction:
  112. {StateTransitionFunction} expression=Expression |
  113. {StateTransitionFunction} '{' statements+=Statement* '}' |
  114. {StateTransitionFunction} assignment=Assignment;// |
  115. //{StoreNull} ('null' | 'nothing') |
  116. //{StateTransitionFunction} 'todo';
  117. ConditionLessRule:
  118. assignment=Assignment;
  119. ConditionStateTransition:
  120. quantization=Quantize;
  121. Quantize returns ConditionStoreStrategy:
  122. {FiniteQuantize} 'quantize' '(' signal=SpecifiedPort ',' zones+=StringLiteral (',' boundaries+=ArithmeticExpression ',' zones+=StringLiteral)* ')' |
  123. {FunctionQuantize} 'quantize' '(' signal=SpecifiedPort ',' '=' function=ArithmeticExpression ')' |
  124. {LinearQuantize} 'quantize' signal=SpecifiedPort 'every' steps=ArithmeticExpression ('with'? 'offset' offset=ArithmeticExpression)?;
  125. OutputFunction:
  126. {NoHold} 'no' 'hold' |
  127. {ZeroOrderHold} (('zero' 'order' 'hold') | 'ZOH') |
  128. {FirstOrderHold} (('first' 'order' 'hold') | 'FOH') |
  129. {CustomOutputFunction} expr=Expression |
  130. {CompositeOutputFunction} '{' statements+=Statement* (returnstatement=ReturnStatement)? '}';
  131. ControlRule:
  132. {ImpliedControlRule} 'implied' | // the default
  133. {TriggeredControlRule} 'triggered' 'by' condition=Expression |
  134. {PeriodicControlRule} 'periodic' ('at' init_time=REALTYPE)? 'every' period=REALTYPE |
  135. {MultipliedControlRule} 'multiplied' multiplication=INT 'times' |
  136. {CustomControlRule} 'control' 'rules' '{' ControlRulestatements+=Statement* returnstatement=ReturnStatement '}';
  137. AnonymousFunction: // has access to ports
  138. {FunctionExpression} '{=' code=Expression '}'|
  139. {FunctionBody} '{' statements+=Statement* returnstatement=ReturnStatement '}' | // should return something
  140. FunctionDeclaration; // TODO: should return something
  141. SpecifiedPort: // if ports need owners
  142. (owner=[FMU] '.' )? port=[Port];
  143. Port:
  144. // TODO: add initial values to ports (to do 1st, 2nd, ... order stuff)
  145. // TODO: add internal destination/source of port
  146. // Unity conversions: https://pint.readthedocs.io/en/0.7.2/
  147. (type=TypeDefinition)?
  148. name=ID
  149. (':=' initval=LiteralOrArray)?
  150. ( multiplicity=Multiplicity )?
  151. ( '(' unity=Unity ')' )?
  152. (('->' targetdependency=SpecifiedPort)
  153. | ('<-' sourcedependency=SpecifiedPort)
  154. )?;
  155. // TODO: -> output port of wrapped FMU to output port of SA FMU (only used in SA!)
  156. TypeDefinition:
  157. 'Real' | 'Integer' | 'String' | 'Bool'
  158. ;
  159. Multiplicity:
  160. '[' (lower=INT '..')? upper=INT ']';
  161. Unity:
  162. DivideUnity;
  163. DivideUnity returns Unity:
  164. MultiplyUnity (({DivideUnity.left=current} '/') right=MultiplyUnity)*;
  165. MultiplyUnity returns Unity:
  166. AtomicUnity (({MultiplyUnity.left=current} '.') right=AtomicUnity)*;
  167. AtomicUnity:
  168. name=ID ('^' (power=INT | power=INTTYPE))?; // somehow LETTERS as name does not work, so power will never be parsed...
  169. //FunctionBody:
  170. // statements+=Statement* returnstatement=ReturnStatement;
  171. Statement:
  172. NestableStatement | FunctionDeclaration;
  173. NestableStatement:
  174. Declaration | (Assignment ';') | (Procedure ';') | For | If | BreakStatement;
  175. For:
  176. 'for' '(' 'var' iterator=DeclaredParameter 'in' iterable=Range ')' '{' (statements+=NestableStatement)* '}';
  177. If:
  178. 'if' '(' ifcondition=Expression ')' '{' (ifstatements+=NestableStatement)* '}' ('else' '{' (elsestatements+=NestableStatement)* '}')?;
  179. FunctionDeclaration:
  180. 'def' name=ID ('(' args+=DeclaredParameter (',' args+=DeclaredParameter)* ')')?
  181. '{' statements+=Statement* returnstatement=ReturnStatement '}';
  182. Declaration:
  183. // 'var' name=ID (':=' expr=Expression)? ';';
  184. 'var' declarations+=SingleVarDeclaration ("," declarations+=SingleVarDeclaration)* ';'
  185. ;
  186. SingleVarDeclaration:
  187. (type=TypeDefinition)? name=ID (':=' expr=Expression)?
  188. ;
  189. ParamDeclarations:
  190. //'param' name=ID ':=' expr=Expression ';';
  191. 'param' declarations+=SingleParamDeclaration ("," declarations+=SingleParamDeclaration)* ';'
  192. ;
  193. SingleParamDeclaration:
  194. (type=TypeDefinition)? name=ID ':=' expr=Expression
  195. ;
  196. ReturnStatement:
  197. 'return' Expression ';';
  198. BreakStatement:
  199. {BreakStatement} 'break' ';';
  200. DeclaredParameter:
  201. name=ID;
  202. //AbstractDeclaration: // can contain overlapping elements as long as it is only used as reference
  203. // Port | ParamDeclaration | Declaration | DeclaredParameter | FunctionDeclaration;
  204. LValueDeclaration: // can contain overlapping elements as long as it is only used as reference
  205. Port | SingleParamDeclaration | SingleVarDeclaration | DeclaredParameter;
  206. Assignment:
  207. lvalue=Variable ':=' expr=Expression; // TODO: to what can be assigned? only local vars?
  208. Expression:
  209. OrExpression;
  210. OrExpression returns Expression:
  211. AndExpression ({Or.left=current} 'or' right=AndExpression)*;
  212. AndExpression returns Expression:
  213. NotExpression ({And.left=current} 'and' right=NotExpression)*;
  214. NotExpression returns Expression:
  215. {Not} 'not' left=GreaterThanExpression |
  216. GreaterThanExpression;
  217. GreaterThanExpression returns Expression:
  218. LessThanExpression ({GreaterThan.left=current} '>' right=ArithmeticExpression)?;
  219. LessThanExpression returns Expression:
  220. GreaterThanOrEqualsExpression ({LessThan.left=current} '<' right=ArithmeticExpression)?;
  221. GreaterThanOrEqualsExpression returns Expression:
  222. LessThanOrEqualsExpression ({GreaterThanOrEquals.left=current} '>=' right=ArithmeticExpression)?;
  223. LessThanOrEqualsExpression returns Expression:
  224. EqualsExpression ({LessThanOrEquals.left=current} '<=' right=ArithmeticExpression)?;
  225. EqualsExpression returns Expression:
  226. NotEqualsExpression ({Equals.left=current} '==' right=ArithmeticExpression)?;
  227. NotEqualsExpression returns Expression:
  228. CrossesFromBelowExpression ({NotEquals.left=current} '!=' right=ArithmeticExpression)?;
  229. CrossesFromBelowExpression returns Expression:
  230. CrossesFromAboveExpression ({CrossesFromBelow.left=current} '>!' right=ArithmeticExpression)?;
  231. CrossesFromAboveExpression returns Expression:
  232. BooleanFunction ({CrossesFromAbove.left=current} '<!' right=BooleanFunction)?;
  233. BooleanFunction returns Expression:
  234. //{Otherwise} 'otherwise' '(' ref=SpecifiedPort ')' |
  235. //{Otherwise} 'otherwise' ref=SpecifiedPort | // AMBIGUOUS!
  236. {Otherwise} 'otherwise' |
  237. ArithmeticExpression;
  238. ArithmeticExpression returns Expression:
  239. Addition;
  240. Addition returns Expression:
  241. Multiplication (({Plus.left=current} '+' | {Minus.left=current} '-') right=Multiplication)*;
  242. Multiplication returns Expression:
  243. Range (({Multi.left=current} '*' | {Div.left=current} '/') right=Range)*;
  244. Range returns Expression:
  245. UnaryOrPrimaryExpression ({Range.left=current} '..' right=UnaryOrPrimaryExpression)?;
  246. UnaryOrPrimaryExpression returns Expression:
  247. NegationExpression | PrimaryExpression;
  248. NegationExpression returns Expression:
  249. {Neg} '-' right=PrimaryExpression;
  250. PrimaryExpression returns Expression:
  251. '(' Expression ')' | Literal | BuiltinFunction | Var;
  252. LiteralOrArray:
  253. {ArrayLiteral} '[' elements+=Literal (',' elements+=Literal)* ']' |
  254. Literal;
  255. Literal:
  256. IntLiteral | RealLiteral | StringLiteral | BoolLiteral; //| NullLiteral; //| StepLiteral;
  257. IntLiteral:
  258. value=INTTYPE | value=INT;
  259. RealLiteral:
  260. value=REALTYPE;
  261. StringLiteral:
  262. value=STRING;
  263. BoolLiteral:
  264. value=('true'|'false');
  265. //StepLiteral:
  266. // value=('accept'|'discard');
  267. NullLiteral:
  268. value='null';
  269. BuiltinFunction:
  270. {Floor} name='floor' '(' args+=ArithmeticExpression ')' |
  271. {Ceil} name='ceil' '(' args+=ArithmeticExpression ')' |
  272. {Round} name='round' '(' args+=ArithmeticExpression (',' args+=ArithmeticExpression)? ')' |
  273. {Max} name='max' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' |
  274. {Min} name='min' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' |
  275. {Abs} name='abs' '(' args=ArithmeticExpression ')' |
  276. {Close} name='is_close' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ',' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' | // a, b, relative tolerance, absolute tolerance
  277. {IsSet} name='is_set' '(' args=Var ')' |
  278. {DoStepFun} name='do_step' '(' fmu=[FMU] ',' t=ArithmeticExpression ',' h=ArithmeticExpression ')' |
  279. {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
  280. {Elapsed} name='elapsed' '(' fmu=[FMU] ')' |
  281. {LastExecutionTime} name='last_execution_time' '(' fmu=[FMU] ')';
  282. Procedure:
  283. {Rollback} name='rollback' '(' fmu=[FMU] ')' |
  284. {DoStep} name='do_step' '(' fmu=[FMU] ',' t=ArithmeticExpression ',' h=ArithmeticExpression ')' |
  285. {Discard} name='discard' '(' args=Var ')' |
  286. {SaveState} name='save_state' '(' fmu=[FMU] ')';
  287. Var:
  288. {StepSize} name='H' | // available in ctrl
  289. {StepSize} name='h' | // available in mapin/mapout
  290. {CurrentTime} name='t' | // available in ctrl
  291. {PassedTime} name='dt' | // available in mapin/mapout
  292. {ElapsedTime} name='e' | // available in ctrl
  293. {Max} name='MAX' |
  294. {GenericSignal} name='signal' ('[' (
  295. index=NOW |
  296. index=PREV |
  297. index=INTTYPE |
  298. index=INT // TODO: int must be less than -1, TODO: expression
  299. ) ']')? |
  300. Variable |
  301. FunctionCall; // add "directionalderivative"
  302. Variable:
  303. (owner=[FMU] '.' ref=[Port]) |
  304. (ref=[LValueDeclaration])
  305. ;
  306. /*
  307. Variable:
  308. (owner=[FMU] '.' ref=[Port]) |
  309. (ref=[Port]) |
  310. (ref=[SingleParamDeclaration]) |
  311. (ref=[SingleVarDeclaration]) |
  312. (ref=[DeclaredParameter])
  313. ;
  314. Variable:
  315. (owner=[FMU] '.' ref=[Port]) | (ref=[LValueDeclaration]) ('[' (
  316. index=NOW |
  317. index=PREV |
  318. index=INTTYPE |
  319. index=INT // TODO: int must be less than -1, TODO: expression
  320. ) ']')?; // TODO: NO RECURSION (must terminate)
  321. */
  322. FunctionCall:
  323. ref=[FunctionDeclaration] '(' args+=ArithmeticExpression (',' args+=ArithmeticExpression)* ')'; // TODO: NO RECURSION (must terminate)
  324. //SignedInt returns ecore::EInt:
  325. // ('-'|'+')? INT;
  326. //SignedReal returns ecore::EBigDecimal:
  327. // '-'? REAL;
  328. terminal INTTYPE returns ecore::EInt : '-' INT;
  329. terminal REALTYPE returns ecore::EFloat : '-'? ((( INT '.' INT | '.' INT | INT '.') (('e'|'E') ('-'|'+') INT)?) | (INT ('e'|'E') ('-'|'+') INT));
  330. //terminal UNSREALTYPE returns ecore::EFloat : ((( INT '.' INT | '.' INT | INT '.') (('e'|'E') ('-'|'+') INT)?) | (INT ('e'|'E') ('-'|'+') INT));
  331. terminal NOW returns ecore::EInt: 'now';
  332. terminal PREV returns ecore::EInt: 'prev';
  333. //terminal REAL returns ecore::EBigDecimal: INT? '.' INT;
  334. //terminal LETTERS returns ecore::EString: ('a'..'z' | 'A'..'Z')+;