From a546d257f35408c90f7b5f5f4d6fca8d7a372b33 Mon Sep 17 00:00:00 2001 From: Johan Maasing Date: Sat, 19 Apr 2025 07:08:06 +0200 Subject: [PATCH] Grammar for states and transitions --- .../nu/zoom/dsl/ast/ParseTreeTransformer.java | 14 ----- .../dsl/ast/StatesVisitorTransformer.java | 56 ++++++++++++++++++- .../java/nu/zoom/dsl/cli/EndpointsCLI.java | 5 +- states-templates/nodes.md.ftl | 29 ++++++++++ test01.states | 4 ++ 5 files changed, 88 insertions(+), 20 deletions(-) delete mode 100644 parser/src/main/java/nu/zoom/dsl/ast/ParseTreeTransformer.java create mode 100644 states-templates/nodes.md.ftl create mode 100644 test01.states diff --git a/parser/src/main/java/nu/zoom/dsl/ast/ParseTreeTransformer.java b/parser/src/main/java/nu/zoom/dsl/ast/ParseTreeTransformer.java deleted file mode 100644 index d9ef9f9..0000000 --- a/parser/src/main/java/nu/zoom/dsl/ast/ParseTreeTransformer.java +++ /dev/null @@ -1,14 +0,0 @@ -package nu.zoom.dsl.ast; - -import java.util.List; -import java.util.Map; - -public interface ParseTreeTransformer { - - List getEndpoints(); - - Map getConfig(); - - List getDataTypes(); - -} diff --git a/parser/src/main/java/nu/zoom/dsl/ast/StatesVisitorTransformer.java b/parser/src/main/java/nu/zoom/dsl/ast/StatesVisitorTransformer.java index 4fd3c97..e1360a7 100644 --- a/parser/src/main/java/nu/zoom/dsl/ast/StatesVisitorTransformer.java +++ b/parser/src/main/java/nu/zoom/dsl/ast/StatesVisitorTransformer.java @@ -2,8 +2,10 @@ package nu.zoom.dsl.ast; import nu.zoom.dsl.parser.StatesBaseVisitor; import nu.zoom.dsl.parser.StatesParser; +import org.antlr.v4.runtime.tree.TerminalNode; import java.util.*; +import java.util.stream.Stream; public class StatesVisitorTransformer extends StatesBaseVisitor { private final HashMap config = new HashMap<>(); @@ -29,9 +31,30 @@ public class StatesVisitorTransformer extends StatesBaseVisitor fields = extractFields(ctx.typeDeclaration()) ; + this.messageTypes.add(new TypeNode(messageName, fields)); + return super.visitMessage(ctx); + } + + @Override + public StatesParser.DocumentContext visitConfigitem(StatesParser.ConfigitemContext ctx) { + String configKey = ctx.configkey().IDENTIFIER().getText(); + String configValue = getText(ctx.configvalue().IDENTIFIER(), ctx.configvalue().VALUE()); + this.config.put(configKey, configValue); + return super.visitConfigitem(ctx); + } + public Set getStates() { - // TODO: Calculate state nodes from this.transitions - return Set.of(); + HashSet states = new HashSet<>(); + this.transitions.forEach((state,v)->{ + HashSet transitionNodes = new HashSet<>(); + v.forEach((to, message) -> transitionNodes.add(new TransitionNode(message, to))); + states.add(new StateNode(state, "", transitionNodes)) ; + }) ; + return states ; } public Map getConfig() { @@ -40,10 +63,28 @@ public class StatesVisitorTransformer extends StatesBaseVisitor getTypes() { // TODO calculate data types from NodeTypes and MessageTypes with duplicate check. - return Set.of() ; + HashMap typeNodes = new HashMap<>(); + this.nodeTypes.forEach(typeNode -> { + if (typeNodes.containsKey(typeNode.name())) { + throw new RuntimeException("Duplicate type name: " + typeNode.name()); + } else { + typeNodes.put(typeNode.name(), typeNode); + } + }) ; + this.messageTypes.forEach(typeNode -> { + if (typeNodes.containsKey(typeNode.name())) { + throw new RuntimeException("Duplicate type name: " + typeNode.name()); + } else { + typeNodes.put(typeNode.name(), typeNode); + } + }) ; + return Set.of(typeNodes.values().toArray(new TypeNode[0])) ; } private List extractFields(StatesParser.TypeDeclarationContext declaration) { + if (declaration == null) { + return Collections.emptyList(); + } return declaration .typeField() .stream() @@ -53,4 +94,13 @@ public class StatesVisitorTransformer extends StatesBaseVisitor { - public static enum ParserType { + public enum ParserType { Endpoints, States } @@ -71,7 +70,7 @@ public class EndpointsCLI implements Callable { validateOutputDirectory(); verbose("Parsing: " + file.toAbsolutePath()); if (parser == null) { - if (file.getFileName().endsWith(".states")) { + if (file.getFileName().toString().endsWith(".states")) { parser = ParserType.States; } } diff --git a/states-templates/nodes.md.ftl b/states-templates/nodes.md.ftl new file mode 100644 index 0000000..89a5603 --- /dev/null +++ b/states-templates/nodes.md.ftl @@ -0,0 +1,29 @@ +``` +Copyright 2025 "Johan Maasing" + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +``` + +# The nodes + +```mermaid +--- +title: ${config.title} +--- +stateDiagram-v2 +<#list states as state> + <#list state.transitions as transition> + ${state.name} --> ${transition.toState} : ${transition.message} + + +``` \ No newline at end of file diff --git a/test01.states b/test01.states new file mode 100644 index 0000000..d1f78a9 --- /dev/null +++ b/test01.states @@ -0,0 +1,4 @@ +{ title: SomeNodes } +start(s:S) -> middle: message(foo:bar), +middle -> middle: selfmessage, +middle -> end: endmessage(bar:baz) \ No newline at end of file