diff --git a/generator/src/generator/Generator.java b/generator/src/generator/Generator.java index 8028706..4e9e793 100644 --- a/generator/src/generator/Generator.java +++ b/generator/src/generator/Generator.java @@ -10,65 +10,69 @@ public class Generator { public static void main(String[] args) throws Exception { - if (args.length != 2) { - System.err.println("Usage: java -jar StatemachineGenerator.jar "); - return; - } - - var filename = args[0]; - var out_path = new File(args[1]).toURI().toString(); - - var loader = ClassLoader.getSystemClassLoader(); - - var factory = new EglFileGeneratingTemplateFactory(); - factory.setTemplateRoot(loader.getResource("generator/").toString()); - factory.setOutputRoot(out_path); - factory.setDefaultFormatter(new JavaFormatter()); - - if (filename.endsWith(".uml") || filename.endsWith(".xmi")) { - var uml_module = new EgxModule(factory); - uml_module.parse(loader.getResource("generator/XmiProgram.egx")); - if (!uml_module.getParseProblems().isEmpty()) { - System.err.println("Syntax errors found. Exiting."); - for (var prob : uml_module.getParseProblems()) { - System.err.println(prob.toString()); - } + try { + if (args.length != 2) { + System.err.println("Usage: java -jar StatemachineGenerator.jar "); return; } - var uml = new UmlModel(); - uml.setModelFile(filename); - uml.setName("UML"); - uml.load(); - uml_module.getContext().getModelRepository().addModel(uml); - uml_module.getContext().setUserInput(new UserInput()); + var filename = args[0]; + var out_path = new File(args[1]).toURI().toString(); - System.out.println("Generating XMI/UML model " + filename + " to " + out_path); + var loader = ClassLoader.getSystemClassLoader(); - uml_module.execute(); - } + var factory = new EglFileGeneratingTemplateFactory(); + factory.setTemplateRoot(loader.getResource("generator/").toString()); + factory.setOutputRoot(out_path); + factory.setDefaultFormatter(new JavaFormatter()); - if (filename.endsWith(".scxml")) { - var scxml_module = new EgxModule(factory); - scxml_module.parse(loader.getResource("generator/ScxmlProgram.egx")); - if (!scxml_module.getParseProblems().isEmpty()) { - System.err.println("Syntax errors found. Exiting."); - for (var prob : scxml_module.getParseProblems()) { - System.err.println(prob.toString()); + if (filename.endsWith(".uml") || filename.endsWith(".xmi")) { + var uml_module = new EgxModule(factory); + uml_module.parse(loader.getResource("generator/XmiProgram.egx")); + if (!uml_module.getParseProblems().isEmpty()) { + System.err.println("Syntax errors found. Exiting."); + for (var prob : uml_module.getParseProblems()) { + System.err.println(prob.toString()); + } + return; } - return; + + var uml = new UmlModel(); + uml.setModelFile(filename); + uml.setName("UML"); + uml.load(); + uml_module.getContext().getModelRepository().addModel(uml); + uml_module.getContext().setUserInput(new UserInput()); + + System.out.println("Generating XMI/UML model " + filename + " to " + out_path); + + uml_module.execute(); } - var scxml = new PlainXmlModel(); - scxml.setFile(new File(filename)); - scxml.setName("SCXML"); - scxml.load(); - scxml_module.getContext().getModelRepository().addModel(scxml); - scxml_module.getContext().setUserInput(new UserInput()); - - System.out.println("Generating SCXML model " + filename + " to " + out_path); + if (filename.endsWith(".scxml")) { + var scxml_module = new EgxModule(factory); + scxml_module.parse(loader.getResource("generator/ScxmlProgram.egx")); + if (!scxml_module.getParseProblems().isEmpty()) { + System.err.println("Syntax errors found. Exiting."); + for (var prob : scxml_module.getParseProblems()) { + System.err.println(prob.toString()); + } + return; + } + + var scxml = new PlainXmlModel(); + scxml.setFile(new File(filename)); + scxml.setName("SCXML"); + scxml.load(); + scxml_module.getContext().getModelRepository().addModel(scxml); + scxml_module.getContext().setUserInput(new UserInput()); + + System.out.println("Generating SCXML model " + filename + " to " + out_path); - scxml_module.execute(); + scxml_module.execute(); + } + } catch (Exception ex) { + ex.printStackTrace(); } } } diff --git a/generator/src/generator/ScxmlModel.egl b/generator/src/generator/ScxmlModel.egl index da04a7c..321c9f9 100644 --- a/generator/src/generator/ScxmlModel.egl +++ b/generator/src/generator/ScxmlModel.egl @@ -22,6 +22,7 @@ operation t_state getModel() : Tuple { var result = new Tuple(); result.name = self.a_id; result.id = self.a_id; + result.region = null; if (self.e_onentry.isDefined() and self.e_onentry.e_script.isDefined()) { result.entry = self.e_onentry.e_script.a_src; diff --git a/generator/src/generator/Transformations.egl b/generator/src/generator/Transformations.egl index 808de3d..6b523b9 100644 --- a/generator/src/generator/Transformations.egl +++ b/generator/src/generator/Transformations.egl @@ -50,6 +50,10 @@ operation Tuple transformRegionTransitions(statemachine : Tuple, parent_state : } operation Tuple transformState(statemachine : Tuple, region : Tuple, parent_state : Tuple) { + if ((self.region == null) and self.transitions.isEmpty()) { + (statemachine.name + ": No outgoing transitions for state " + self.name).println(); + } + statemachine.all_states.put(self.id, self); if (parent_state.isDefined()) { diff --git a/generator/src/generator/XmiModel.egl b/generator/src/generator/XmiModel.egl index 5f400b7..ffc3f86 100644 --- a/generator/src/generator/XmiModel.egl +++ b/generator/src/generator/XmiModel.egl @@ -12,6 +12,11 @@ operation Region getModel(sm : Tuple) : Tuple { var result = new Tuple(); var initial = self.subvertices.select(s | s.isKindOf(Pseudostate) and ((s.kind = PseudostateKind#initial) or (s.kind = PseudostateKind#shallowHistory))).first; + if ((initial == null) or (initial.outgoing.first == null)) { + if (self.state != null) { + (sm.name + ": Missing initial state in composite state " + self.state.name).println(); + } + } result.initial_id = initial.outgoing.first.target.id; result.initial_history = (initial.kind = PseudostateKind#shallowHistory); @@ -23,21 +28,30 @@ operation Region getModel(sm : Tuple) : Tuple { return result; } +operation Behavior getBody() : String { + if (self.isKindOf(OpaqueBehavior) and (self.bodies.first != null) and (self.bodies.first != "")) { + return self.bodies.first; + } else { + return self.name; + } +} + operation State getModel(sm : Tuple) : Tuple { var result = new Tuple(); result.name = self.name; result.id = self.id; + result.region = null; if (self.container.state != null) { result.parent_state_id = self.container.state.id; } if (self.entry != null) { - result.entry = self.entry.name; + result.entry = self.entry.getBody(); } if (self.exit != null) { - result.exit = self.exit.name; + result.exit = self.exit.getBody(); } if (not self.regions.isEmpty()) { @@ -56,11 +70,11 @@ operation Transition getModel(sm : Tuple, state : Tuple, transitions : List) : T var result = new Tuple(); result.start = state.name; result.internal = (self.kind != TransitionKind#external); - var trigger = self.trigger.first.event - if (trigger.isKindOf(SignalEvent)) { - result.trigger = trigger.signal.name; + var trigger = self.trigger.first.event; + if (trigger.isKindOf(SignalEvent) and (trigger.signal != null)) { + result.trigger = trigger.signal.name; } else { - result.trigger = trigger.name; + result.trigger = trigger.name; } result.actions = new List(); result.guards = new List(); @@ -69,24 +83,25 @@ operation Transition getModel(sm : Tuple, state : Tuple, transitions : List) : T return result; } +operation Constraint getGuard() : String { + var guard = "else"; + if ((self.specification != null) and self.specification.isKindOf(OpaqueExpression)) { + guard = self.specification.bodies.first; + } else { + guard = self.name; + } + return guard; +} + operation Transition getTarget(sm : Tuple, transition : Tuple, transitions : List) { if (self.effect != null) { - if (self.effect.isKindOf(OpaqueBehavior)) { - transition.actions.add(self.effect.bodies.first); - } else { - transition.actions.add(self.effect.name); - } + transition.actions.add(self.effect.getBody()); } if (self.guard != null) { - var guard = "else" - if ((self.guard.specification != null) and self.guard.specification.isKindOf(OpaqueExpression)) { - guard = self.guard.specification.bodies.first - } else { - guard = self.guard.name - } - if (guard != "else") { - transition.guards.add(guard); - } + var guard = self.guard.getGuard(); + if (guard != "else") { + transition.guards.add(guard); + } } if (self.target.isKindOf(State)) { @@ -108,9 +123,14 @@ operation Transition getTarget(sm : Tuple, transition : Tuple, transitions : Lis } operation Transition getSortKey() : String { - if ((self.guard = null) or (self.guard.name = "else")) { + if (self.guard = null) { return "999999-"; } - return "0" + self.guard.name; + + var guard = self.guard.getGuard(); + if (guard != "else") { + return "0" + guard; + } + return "999999-else"; } %] \ No newline at end of file