From 5ca38eb3a5cb914feae080b7164b136eb075e5dd Mon Sep 17 00:00:00 2001 From: Yuri Blankenstein Date: Wed, 24 Jun 2026 17:18:36 +0200 Subject: [PATCH 01/27] [#350] WIP: Adding data constraints to the language --- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 6 +- .../nl.esi.comma.behavior.scl.ui/plugin.xml | 8 + .../ConstraintsDiagramTextProvider.xtend | 38 +++ .../plantuml/IXtextDiagramTextProvider.java | 64 +++++ .../scl/ui/quickfix/SclQuickfixProvider.xtend | 4 +- .../META-INF/MANIFEST.MF | 5 +- .../esi/comma/behavior/scl/GenerateScl.mwe2 | 5 +- .../src/nl/esi/comma/behavior/scl/Scl.xtext | 246 +++++++----------- .../generator/ConstraintStateMachine.xtend | 1 + .../ConstraintsStateMachineGenerator.xtend | 72 ++--- .../scl/generator/ScenarioGenerator.xtend | 23 +- .../scl/scoping/SclScopeProvider.xtend | 21 +- .../scl/validation/SclValidator.xtend | 27 +- 14 files changed, 295 insertions(+), 227 deletions(-) create mode 100644 bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/ConstraintsDiagramTextProvider.xtend create mode 100644 bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/IXtextDiagramTextProvider.java diff --git a/bundles/nl.esi.comma.behavior.scl.ide/META-INF/MANIFEST.MF b/bundles/nl.esi.comma.behavior.scl.ide/META-INF/MANIFEST.MF index d9be9a83..a84a0a5f 100644 --- a/bundles/nl.esi.comma.behavior.scl.ide/META-INF/MANIFEST.MF +++ b/bundles/nl.esi.comma.behavior.scl.ide/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Bundle-Version: 4.2.0.qualifier Bundle-SymbolicName: nl.esi.comma.behavior.scl.ide; singleton:=true Bundle-ActivationPolicy: lazy Require-Bundle: nl.esi.comma.behavior.scl;visibility:=reexport, - nl.esi.xtext.actions.ide;visibility:=reexport, + nl.esi.xtext.expressions.ide;visibility:=reexport, org.eclipse.xtext.ide, org.eclipse.xtext.xbase.ide, org.antlr.runtime;bundle-version="[3.2.0,3.2.1)" diff --git a/bundles/nl.esi.comma.behavior.scl.ui/META-INF/MANIFEST.MF b/bundles/nl.esi.comma.behavior.scl.ui/META-INF/MANIFEST.MF index 12a4ca4f..e537d2e1 100644 --- a/bundles/nl.esi.comma.behavior.scl.ui/META-INF/MANIFEST.MF +++ b/bundles/nl.esi.comma.behavior.scl.ui/META-INF/MANIFEST.MF @@ -8,7 +8,7 @@ Bundle-SymbolicName: nl.esi.comma.behavior.scl.ui; singleton:=true Bundle-ActivationPolicy: lazy Require-Bundle: nl.esi.comma.behavior.scl;visibility:=reexport, nl.esi.comma.behavior.scl.ide, - nl.esi.xtext.actions.ui;visibility:=reexport, + nl.esi.xtext.expressions.ui;visibility:=reexport, org.eclipse.xtext.ui, org.eclipse.xtext.ui.shared, org.eclipse.xtext.ui.codetemplates.ui, @@ -18,12 +18,14 @@ Require-Bundle: nl.esi.comma.behavior.scl;visibility:=reexport, org.eclipse.compare, org.eclipse.xtext.builder, org.eclipse.xtext.xbase.lib;bundle-version="2.36.0", - org.eclipse.xtend.lib;bundle-version="2.36.0";resolution:=optional + org.eclipse.xtend.lib;bundle-version="2.36.0";resolution:=optional, + net.sourceforge.plantuml.eclipse Import-Package: org.apache.log4j Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: nl.esi.comma.behavior.scl.ui, nl.esi.comma.behavior.scl.ui.internal, nl.esi.comma.behavior.scl.ui.labeling, nl.esi.comma.behavior.scl.ui.outline, + nl.esi.comma.behavior.scl.ui.plantuml, nl.esi.comma.behavior.scl.ui.quickfix Bundle-Activator: nl.esi.comma.behavior.scl.ui.internal.SclActivator diff --git a/bundles/nl.esi.comma.behavior.scl.ui/plugin.xml b/bundles/nl.esi.comma.behavior.scl.ui/plugin.xml index ca604110..06acbef3 100644 --- a/bundles/nl.esi.comma.behavior.scl.ui/plugin.xml +++ b/bundles/nl.esi.comma.behavior.scl.ui/plugin.xml @@ -445,4 +445,12 @@ type="text"> + + + + diff --git a/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/ConstraintsDiagramTextProvider.xtend b/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/ConstraintsDiagramTextProvider.xtend new file mode 100644 index 00000000..ec92398b --- /dev/null +++ b/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/ConstraintsDiagramTextProvider.xtend @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024, 2025 TNO-ESI + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available + * under the terms of the MIT License which is available at + * https://opensource.org/licenses/MIT + * + * SPDX-License-Identifier: MIT + */ +package nl.esi.comma.behavior.scl.ui.plantuml + +import java.util.Collection +import nl.esi.comma.behavior.scl.generator.ConstraintsStateMachineGenerator +import nl.esi.comma.behavior.scl.scl.Model +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.util.EcoreUtil + +class ConstraintsDiagramTextProvider implements IXtextDiagramTextProvider { + override getDiagramText(Collection selection) { + val constraints = selection.map[EcoreUtil.getRootContainer(it, true)].filter(Model).head + if (constraints === null) { + return null + } +// val mapContraintToAutomata = (new ConstraintsStateMachineGenerator()).generateStateMachine(constraints, 'dummyPath', 'dummyName') +// if (!mapContraintToAutomata.isEmpty) { +// return ''' +// @startdot +// +// «mapContraintToAutomata.values.head.dot» +// +// @enddot +// ''' +// } + } +} diff --git a/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/IXtextDiagramTextProvider.java b/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/IXtextDiagramTextProvider.java new file mode 100644 index 00000000..07b33e6e --- /dev/null +++ b/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/plantuml/IXtextDiagramTextProvider.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024, 2025 TNO-ESI + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available + * under the terms of the MIT License which is available at + * https://opensource.org/licenses/MIT + * + * SPDX-License-Identifier: MIT + */ +package nl.esi.comma.behavior.scl.ui.plantuml; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.xtext.nodemodel.ILeafNode; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.ui.editor.XtextEditor; +import org.eclipse.xtext.ui.editor.model.IXtextDocument; + +import net.sourceforge.plantuml.eclipse.utils.DiagramTextProvider; + +public interface IXtextDiagramTextProvider extends DiagramTextProvider { + @Override + default boolean supportsSelection(ISelection selection) { + return selection instanceof StructuredSelection || selection instanceof TextSelection; + } + + @Override + default boolean supportsEditor(IEditorPart editorPart) { + return editorPart instanceof XtextEditor; + } + + @Override + default String getDiagramText(IEditorPart editorPart, ISelection selection) { + if (editorPart instanceof XtextEditor xtextEditor && selection instanceof TextSelection textSelection) { + IXtextDocument document = xtextEditor.getDocument(); + if (document == null) { + return null; + } + int offset = textSelection.getOffset(); + EObject semanticObject = document.readOnly(resource -> { + ILeafNode node = NodeModelUtils.findLeafNodeAtOffset(resource.getParseResult().getRootNode(), offset); + if (node != null) { + return NodeModelUtils.findActualSemanticObjectFor(node); + } + return null; + }); + if (semanticObject != null) { + return getDiagramText(Collections.singleton(semanticObject)); + } + } + return null; + } + + String getDiagramText(Collection selection); +} diff --git a/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/quickfix/SclQuickfixProvider.xtend b/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/quickfix/SclQuickfixProvider.xtend index de4a97f9..f0386272 100644 --- a/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/quickfix/SclQuickfixProvider.xtend +++ b/bundles/nl.esi.comma.behavior.scl.ui/src/nl/esi/comma/behavior/scl/ui/quickfix/SclQuickfixProvider.xtend @@ -15,14 +15,14 @@ */ package nl.esi.comma.behavior.scl.ui.quickfix -import nl.esi.xtext.actions.ui.quickfix.ActionsQuickfixProvider +import nl.esi.xtext.expressions.ui.quickfix.ExpressionQuickfixProvider /** * Custom quickfixes. * * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#quick-fixes */ -class SclQuickfixProvider extends ActionsQuickfixProvider { +class SclQuickfixProvider extends ExpressionQuickfixProvider { // @Fix(SclValidator.INVALID_NAME) // def capitalizeName(Issue issue, IssueResolutionAcceptor acceptor) { diff --git a/bundles/nl.esi.comma.behavior.scl/META-INF/MANIFEST.MF b/bundles/nl.esi.comma.behavior.scl/META-INF/MANIFEST.MF index d3ce6db8..9c24d178 100644 --- a/bundles/nl.esi.comma.behavior.scl/META-INF/MANIFEST.MF +++ b/bundles/nl.esi.comma.behavior.scl/META-INF/MANIFEST.MF @@ -6,7 +6,7 @@ Bundle-Vendor: TNO-ESI Bundle-Version: 4.2.0.qualifier Bundle-SymbolicName: nl.esi.comma.behavior.scl; singleton:=true Bundle-ActivationPolicy: lazy -Require-Bundle: nl.esi.xtext.actions;visibility:=reexport, +Require-Bundle: nl.esi.xtext.expressions;visibility:=reexport, org.eclipse.xtext, org.eclipse.xtext.xbase, org.eclipse.equinox.common;bundle-version="3.5.0", @@ -17,7 +17,8 @@ Require-Bundle: nl.esi.xtext.actions;visibility:=reexport, org.eclipse.emf.common, org.eclipse.core.resources;bundle-version="3.14.0", nl.esi.comma.automata, - org.eclipse.xtend.lib;bundle-version="2.36.0" + org.eclipse.xtend.lib;bundle-version="2.36.0", + org.eclipse.lsat.common.xtend Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: nl.esi.comma.behavior.scl, nl.esi.comma.behavior.scl.validation, diff --git a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/GenerateScl.mwe2 b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/GenerateScl.mwe2 index 97066a01..db1097bd 100644 --- a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/GenerateScl.mwe2 +++ b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/GenerateScl.mwe2 @@ -39,7 +39,7 @@ Workflow { name = "nl.esi.comma.behavior.scl.Scl" fileExtensions = "scl" - referencedResource = "platform:/resource/nl.esi.xtext.actions/model/generated/Actions.genmodel" + referencedResource = "platform:/resource/nl.esi.xtext.expressions/model/generated/Expression.genmodel" serializer = { generateStub = false @@ -56,6 +56,9 @@ Workflow { junitSupport = { junitVersion = "5" } + parserGenerator = { + debugGrammar = true + } } } } diff --git a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/Scl.xtext b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/Scl.xtext index 5ff0aec8..34122f77 100644 --- a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/Scl.xtext +++ b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/Scl.xtext @@ -10,239 +10,189 @@ * * SPDX-License-Identifier: MIT */ -grammar nl.esi.comma.behavior.scl.Scl with nl.esi.xtext.actions.Actions +grammar nl.esi.comma.behavior.scl.Scl with nl.esi.xtext.expressions.Expression generate scl "http://www.esi.nl/comma/behavior/scl/Scl" - import "http://www.esi.nl/xtext/common/lang/Base" as base +import "http://www.esi.nl/xtext/types/Types" as types +import "http://www.esi.nl/xtext/expressions/Expression" as expr + +Model returns base::ModelContainer: + {Model} + imports+=Import* + types+=TypeDecl* + ('actions' '{' + actions+=Action* + '}')? + ( templates+=Template | + sequences+=Sequence | + compositions+=Composition + )*; -Model returns base::ModelContainer: {Model} - imports += Import* - features += Features* - actions += Actions+ - sequences += SequenceDef* - 'Requirements' - composition += Composition* - ('for-configurations' commonFeatures += [Feature|ID]+)? - templates += Templates* - useLabels?= 'use-provided-labels'? -; +// name is used as reference|ID by templates. In generator this must be changed +Action: + act=ActionType name=ID (label=STRING)? ('consumes' inputs+=Variable*)? ('produces' outputs+=Variable*)?; -Composition: - 'constraint' name = ID 'is-composed-of' '{' templates += [Templates|ID]+ '}' - ('description' descTxt = STRING)? - ('for-configurations' commonFeatures += [Feature|ID]+ ';')? - ('requirement-tags' tagStr += STRING* ';')? -; +enum ActionType: + Observable='Observable' | Trigger='Trigger' | PreCondition='Pre-condition' | Conjunction='And'; -SequenceDef: - 'Sequence-Def' name = ID '{' - actList += ParamAct+ - '}' -; +Sequence: + 'sequence' name=ID '{' + actions+=[Action|ID]* + '}'; -ParamAct: - act = [_Action|ID] ('['idx = INT']')? -; +Composition: + 'constraint' name=ID 'is-composed-of' '{' + templates+=[Template|ID]* + '}'; Ref returns Ref: - RefSequence | RefStep -; + RefAction | RefSequence; -RefStep: - 'act' step = [_Action|ID] ('['idx = INT']')? -; +RefAction: + ('act')? action=[Action|ID] ('with' '(' expression=Expression ')')?; RefSequence: - 'seq' seq = [SequenceDef|ID] -; - -Features: - 'feature-list:' '{' - feature += Feature+ - '}' -; + 'seq' seq=[Sequence|ID] ('with' '(' expression=Expression ')')?; -Feature: - name = ID -; -Actions: - 'action-list:' '{' - ('var' localvars+=Variable+ )? - act += _Action+ - '}' -; +@Override +Expression returns expr::Expression: ExpressionLevel0; -ActionParam: - // 'with' '(' parameters+=Expression (',' parameters+=Expression)* ')' - 'init' initActions+=(AssignmentAction | RecordFieldAssignmentAction)+ -; - -// name is used as reference|ID by templates. In generator this must be changed -_Action: - act = ActionType name = ID label = STRING actParam += ActionParam* -; - -enum ActionType: - Observable = 'Observable' | Trigger = 'Trigger' | PreCondition = 'Pre-condition' | Conjunction = 'And' +ExpressionLevel0 returns expr::Expression: // Left associativity + ExpressionLevel1 ({ExpressionByReference.left=current} "<-" right=ExpressionLevel1)? ; /* - templates can be divided into two main groups: existence templates - and relation templates. The former is a set of unary templates. They can be - expressed as predicates over one variable. The latter comprises rules that are - imposed on target activities, when activation tasks occur. Relation templates - thus correspond to binary predicates over two variables. + * templates can be divided into two main groups: existence templates + * and relation templates. The former is a set of unary templates. They can be + * expressed as predicates over one variable. The latter comprises rules that are + * imposed on target activities, when activation tasks occur. Relation templates + * thus correspond to binary predicates over two variables. */ - -Templates: - // name = ID type += (Existential | Relation | Coupling | Negative | Choice)+ ('for-configurations' features += [Feature|ID]+)? - name = ID type += ( Dependencies | Past | Future | Choice | Existential)+ ('for-configurations' features += [Feature|ID]+)? +Template: + // name = ID type += (Existential | Relation | Coupling | Negative | Choice)+ + 'constraint' name=ID + variables+=Variable* + type+=(Dependencies | Past | Future | Choice | Existential)+ ; Past: - 'P' - type += (Precedence | AlternatePrecedence | ChainPrecedence)+ -; + 'P' + type+=(Precedence | AlternatePrecedence | ChainPrecedence)+; Future: - 'F' - type += (Response | AlternateResponse | ChainResponse)+ -; + 'F' + type+=(Response | AlternateResponse | ChainResponse)+; Dependencies: - 'PF' - type += (Succession | CoExistance |AlternateSuccession | ChainSuccession - | RespondedExistence | NotSuccession | NotCoExistance | NotChainSuccession )+ -; + 'PF' + type+=(Succession | CoExistance | AlternateSuccession | ChainSuccession + | RespondedExistence | NotSuccession | NotCoExistance | NotChainSuccession)+; Choice: - 'C' - type += (SimpleChoice | ExclusiveChoice) + -; + 'C' + type+=(SimpleChoice | ExclusiveChoice)+; Existential: - 'E' - type += (AtLeast | AtMost | Init | End | Exact)+ -; + 'E' + type+=(AtLeast | AtMost | Init | End | Exact)+; // Choice ExclusiveChoice: - eitherA?= 'either'? refA += Ref+ 'or' eitherB?= 'either'? refB += Ref+ 'eventually-occur-but-not-together' -; + '^' eitherA?='either'? refA+=Ref+ 'or' eitherB?='either'? refB+=Ref+ 'eventually-occur-but-not-together'; SimpleChoice: - refA += Ref+ 'eventually-occur' -; + '|' refA+=Ref+ 'eventually-occur'; // NEGATION // // A (or | and C..) occurs if and only if not followed immediately by B (or | and D..) -NotChainSuccession: - '!<>' eitherA?= 'either'? refA += Ref+ ('occurs')? 'if-and-only-if-not-followed-immediately-by' eitherB?= 'either'? refB += Ref+ -; +NotChainSuccession: + '!<>' eitherA?='either'? refA+=Ref+ ('occurs')? 'if-and-only-if-not-followed-immediately-by' eitherB?='either'? + refB+=Ref+; //A and B (and C..) do not occur together (implies exclusive choice) NotCoExistance: - '!-'refA += Ref+ 'do-not-occur-together' -; + '!-' refA+=Ref+ 'do-not-occur-together'; // A (or | and C..) occurs if and only if not followed by B (or | and C..) NotSuccession: - '!<-->' eitherA?= 'either'? refA += Ref+ ('occurs')? - 'if-and-only-if-not-followed-by' eitherB?= 'either'? refB += Ref+ -; + '!<-->' eitherA?='either'? refA+=Ref+ ('occurs')? + 'if-and-only-if-not-followed-by' eitherB?='either'? refB+=Ref+; /// TOGETHER //// // A (or | and C..) occurs if and only if followed immediately by B (or | and D..) ChainSuccession: - '<>' eitherA?= 'either'? refA += Ref+ 'occurs-if-and-only-if-immediately-followed-by' - eitherB?= 'either'? refB += Ref+ ('within' minVal = INT ('-' maxVal = INT)? 'ms')? -; + '<>' eitherA?='either'? refA+=Ref+ 'occurs-if-and-only-if-immediately-followed-by' + eitherB?='either'? refB+=Ref+ ('within' minVal=INT ('-' maxVal=INT)? 'ms')?; // A occurs if and only if followed by B with no A and B (C, D...) in between AlternateSuccession: - '' eitherA?= 'either'? refA += Ref+ ('occurs')? 'if-and-only-if-followed-by' - eitherB?= 'either'? refB += Ref+ 'with' - eitherC?= 'either'? negation?= 'no'? refC += Ref+ 'in-between' -; + '' eitherA?='either'? refA+=Ref+ ('occurs')? 'if-and-only-if-followed-by' + eitherB?='either'? refB+=Ref+ 'with' + eitherC?='either'? negation?='no'? refC+=Ref+ 'in-between'; // A (or | and C..) occurs if and only if followed by B (or | and D..) Succession: - '<-->' eitherA?= 'either'? refA += Ref+ ('occurs')? 'if-and-only-if-followed-by' - eitherB?= 'either'? refB += Ref+ ('within' minVal = INT ('-' maxVal = INT)? 'ms')? -; + '<-->' eitherA?='either'? refA+=Ref+ ('occurs')? 'if-and-only-if-followed-by' + eitherB?='either'? refB+=Ref+ ('within' minVal=INT ('-' maxVal=INT)? 'ms')?; // A and B (and C..) occur together CoExistance: - '-' refA += Ref+ 'occur-together' -; + '-' refA+=Ref+ 'occur-together'; RespondedExistence: - '-|-' 'if' eitherA?= 'either'? refA += Ref+ ('occurs')? 'then' eitherB?= 'either'? refB += Ref+ 'occurs-as-well' -; + '-|-' 'if' eitherA?='either'? refA+=Ref+ ('occurs')? 'then' eitherB?='either'? refB+=Ref+ 'occurs-as-well'; ////// RELATION //////// - // Whenever B (OR|AND D...) occurs then A (OR|AND C..) must (not) immediately precede it ChainPrecedence: - '<' 'whenever' eitherB?= 'either'? refB += Ref+ ('occurs')? - 'then' eitherA?= 'either'? refA += Ref+ 'must' not?= 'not'? - 'have-occurred-immediately-before' ('within' minVal = INT ('-' maxVal = INT)? 'ms')? -; + '<' 'whenever' eitherB?='either'? refB+=Ref+ ('occurs')? + 'then' eitherA?='either'? refA+=Ref+ 'must' not?='not'? + 'have-occurred-immediately-before' ('within' minVal=INT ('-' maxVal=INT)? 'ms')?; // If A (OR|AND C..) occurs then B (OR|AND D...) (does not) immediately follow ChainResponse: - '>' 'if' eitherA?= 'either'? refA += Ref+ ('occurs')? - 'then' eitherB?= 'either'? refB += Ref+ 'must' not?= 'not'? - 'immediately-follow' ('within' minVal = INT ('-' maxVal = INT)? 'ms')? -; + '>' 'if' eitherA?='either'? refA+=Ref+ ('occurs')? + 'then' eitherB?='either'? refB+=Ref+ 'must' not?='not'? + 'immediately-follow' ('within' minVal=INT ('-' maxVal=INT)? 'ms')?; // If A (OR|AND X...) occurs then B (OR|AND Y...) must follow with no (only) A (OR|AND X...) and C (OR|AND Z...) in between AlternateResponse: - '!>' 'if' eitherA?= 'either'? refA += Ref+ ('occurs')? - 'then' eitherB?= 'either'? refB += Ref+ 'must-follow' ('within' minVal = INT ('-' maxVal = INT)? 'ms')? - 'with' not?= 'no'? eitherC?= 'either'? refC += Ref+ 'in-between' -; + '!>' 'if' eitherA?='either'? refA+=Ref+ ('occurs')? + 'then' eitherB?='either'? refB+=Ref+ 'must-follow' ('within' minVal=INT ('-' maxVal=INT)? 'ms')? + 'with' not?='no'? eitherC?='either'? refC+=Ref+ 'in-between'; // Whenever B (OR|AND Y...) occurs then A (OR|AND X...) must have occurred before with no B (OR|AND Y...) and C (OR|AND Z...) in between AlternatePrecedence: - '' 'if' eitherA?= 'either'? refA += Ref+ ('occurs')? - 'then' eitherB?= 'either'? refB += Ref+ 'must' not?= 'not'? - 'eventually-follow' ('within' minVal = INT ('-' maxVal = INT)? 'ms')? -; + '->' 'if' eitherA?='either'? refA+=Ref+ ('occurs')? + 'then' eitherB?='either'? refB+=Ref+ 'must' not?='not'? + 'eventually-follow' ('within' minVal=INT ('-' maxVal=INT)? 'ms')?; // Whenever B (OR|AND D...) occurs then A (OR|AND C...) should (not) have occurred before Precedence: - '<-' 'whenever' eitherB?= 'either'? refB += Ref+ ('occurs')? - 'then' eitherA?= 'either'? refA += Ref+ 'must' not?= 'not'? - 'have-occurred-before' ('within' minVal = INT ('-' maxVal = INT)? 'ms')? -; + '<-' 'whenever' eitherB?='either'? refB+=Ref+ ('occurs')? + 'then' eitherA?='either'? refA+=Ref+ 'must' not?='not'? + 'have-occurred-before' ('within' minVal=INT ('-' maxVal=INT)? 'ms')?; // Existential // End: - ref += Ref+ 'occurs-last' -; + '$' ref+=Ref+ 'occurs-last'; Init: - ref += Ref+ 'occurs-first' -; + '^' ref+=Ref+ 'occurs-first'; AtMost: - ref += Ref+ 'occurs-at-most' num = INT 'times' -; + '<=' ref+=Ref+ 'occurs-at-most' num=INT 'times'; Exact: - ref += Ref+ 'occurs-exactly' num = INT 'times' consecutively?= 'consecutively'? ('with-periodicity-of' minVal = INT ('-' maxVal = INT)? 'ms')? -; - + '=' ref+=Ref+ 'occurs-exactly' num=INT 'times' consecutively?='consecutively'? ('with-periodicity-of' minVal=INT ('-' + maxVal=INT)? 'ms')?; AtLeast: - ref += Ref+ 'occurs-at-least' num = INT 'times' ('with-periodicity-of' minVal = INT ('-' maxVal = INT)? 'ms')? -; + '=>' ref+=Ref+ 'occurs-at-least' num=INT 'times' ('with-periodicity-of' minVal=INT ('-' maxVal=INT)? 'ms')?; diff --git a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintStateMachine.xtend b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintStateMachine.xtend index 6153eefd..feaa63b2 100644 --- a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintStateMachine.xtend +++ b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintStateMachine.xtend @@ -49,6 +49,7 @@ class ConstraintStateMachine { def getAutomataList() { return automataList } def getComputedAutomata() { return fa } + def getDot() { return transformWithLabels(getComputedAutomata().toDot(), true) } def getStepName(char c) { for(k : unicodeMap.keySet) { diff --git a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintsStateMachineGenerator.xtend b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintsStateMachineGenerator.xtend index 89aa623d..3589ae29 100644 --- a/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintsStateMachineGenerator.xtend +++ b/bundles/nl.esi.comma.behavior.scl/src/nl/esi/comma/behavior/scl/generator/ConstraintsStateMachineGenerator.xtend @@ -20,10 +20,8 @@ import java.util.HashSet import java.util.List import java.util.Map import java.util.Set -import nl.esi.xtext.actions.generator.plantuml.ActionsUmlGenerator import nl.esi.comma.automata.RelationType import nl.esi.comma.automata.Semantics -import nl.esi.comma.behavior.scl.scl.Actions import nl.esi.comma.behavior.scl.scl.AlternatePrecedence import nl.esi.comma.behavior.scl.scl.AlternateResponse import nl.esi.comma.behavior.scl.scl.AlternateSuccession @@ -49,12 +47,12 @@ import nl.esi.comma.behavior.scl.scl.Past import nl.esi.comma.behavior.scl.scl.Precedence import nl.esi.comma.behavior.scl.scl.Ref import nl.esi.comma.behavior.scl.scl.RefSequence -import nl.esi.comma.behavior.scl.scl.RefStep import nl.esi.comma.behavior.scl.scl.RespondedExistence import nl.esi.comma.behavior.scl.scl.Response import nl.esi.comma.behavior.scl.scl.SimpleChoice import nl.esi.comma.behavior.scl.scl.Succession -import nl.esi.comma.behavior.scl.scl.Templates +import nl.esi.comma.behavior.scl.scl.Template +import nl.esi.comma.behavior.scl.scl.RefAction class ConstraintsStateMachineGenerator { @@ -65,23 +63,21 @@ class ConstraintsStateMachineGenerator char fs = '0'; var Map mapContraintToAutomata = new HashMap - def computeActionToExpr(List acts) { - for(a : acts) { - for(elm : a.act) { - var ename = elm.name - for(p : elm.actParam) { - for(ia : p.initActions) { - actionToExprMap.put(ename,(new ActionsUmlGenerator().generateAction(ia)).toString) - } - } - } - } - } +// def computeActionToExpr(List acts) { +// for(elm : acts) { +// var ename = elm.name +// for(p : elm.actParam) { +// for(ia : p.initActions) { +// actionToExprMap.put(ename,(new ActionsUmlGenerator().generateAction(ia)).toString) +// } +// } +// } +// } def generateStateMachine(Model model, String path, String name) { - computeActionToExpr(model.actions) - if(model.composition.isNullOrEmpty) { +// computeActionToExpr(model.actions) + if(model.compositions.isNullOrEmpty) { computeStepLabels(model.templates) // generate state machine model for elm.name and save file with that name // precondition: unicodeMap is ready @@ -89,12 +85,12 @@ class ConstraintsStateMachineGenerator mapContraintToAutomata.put(name,constraintSMInst) } else { - for(elm : model.composition) { + for(elm : model.compositions) { symbol = 'a' activityList = new HashSet(); unicodeMap = new HashMap(); fs = '0'; - var templateList = new HashSet + var templateList = new HashSet