From 1fd290eef15df28e9a9dba1961152cf16f7f6c59 Mon Sep 17 00:00:00 2001 From: Colin Date: Thu, 25 Mar 2021 20:25:40 -0400 Subject: [PATCH] Added Target class to represent the kind of transition (external or local). Also added generated antlr classes. I need to figure out exactly what a local transition looks like for test cases. --- makina-compiler/.gitignore | 5 +- .../gen/xyz/colinholzman/makina/makina.interp | 52 ++ .../gen/xyz/colinholzman/makina/makina.tokens | 31 + .../makina/makinaBaseListener.java | 159 ++++ .../makina/makinaBaseVisitor.java | 84 ++ .../colinholzman/makina/makinaLexer.interp | 68 ++ .../xyz/colinholzman/makina/makinaLexer.java | 151 ++++ .../colinholzman/makina/makinaLexer.tokens | 31 + .../colinholzman/makina/makinaListener.java | 120 +++ .../xyz/colinholzman/makina/makinaParser.java | 721 ++++++++++++++++++ .../colinholzman/makina/makinaVisitor.java | 78 ++ makina-compiler/src/makina.g4 | 3 +- .../xyz/colinholzman/makina/CodeGenerator.kt | 4 +- .../src/xyz/colinholzman/makina/Handler.kt | 14 +- .../xyz/colinholzman/makina/HandlerVisitor.kt | 3 +- .../src/xyz/colinholzman/makina/State.kt | 5 + .../colinholzman/makina/StateConfiguration.kt | 5 + .../src/xyz/colinholzman/makina/Target.kt | 8 + .../xyz/colinholzman/makina/TargetVisitor.kt | 13 + .../src/xyz/colinholzman/makina/Transition.kt | 27 +- .../xyz/colinholzman/makina/HandlerTest.kt | 16 +- .../test/xyz/colinholzman/makina/ParseTest.kt | 9 +- 22 files changed, 1579 insertions(+), 28 deletions(-) create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makina.interp create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makina.tokens create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaBaseListener.java create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaBaseVisitor.java create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.interp create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.java create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.tokens create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaListener.java create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaParser.java create mode 100644 makina-compiler/gen/xyz/colinholzman/makina/makinaVisitor.java create mode 100644 makina-compiler/src/xyz/colinholzman/makina/Target.kt create mode 100644 makina-compiler/src/xyz/colinholzman/makina/TargetVisitor.kt diff --git a/makina-compiler/.gitignore b/makina-compiler/.gitignore index 2620c62..b155595 100644 --- a/makina-compiler/.gitignore +++ b/makina-compiler/.gitignore @@ -68,7 +68,4 @@ fabric.properties .idea/httpRequests # Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -# Generated sources -gen \ No newline at end of file +.idea/caches/build_file_checksums.ser \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makina.interp b/makina-compiler/gen/xyz/colinholzman/makina/makina.interp new file mode 100644 index 0000000..266e653 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makina.interp @@ -0,0 +1,52 @@ +token literal names: +null +'machine' +';' +'initial' +'state' +'{' +'}' +'.' +'entry' +'exit' +'on' +'(' +')' +'->' +'>' +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +ID +WHITESPACE +COMMENT + +rule names: +file +state +id +handler +action +guard +target + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 19, 88, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 3, 2, 3, 2, 3, 2, 3, 2, 7, 2, 21, 10, 2, 12, 2, 14, 2, 24, 11, 2, 3, 2, 3, 2, 3, 3, 5, 3, 29, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 36, 10, 3, 12, 3, 14, 3, 39, 11, 3, 3, 3, 3, 3, 3, 4, 5, 4, 44, 10, 4, 3, 4, 3, 4, 3, 4, 7, 4, 49, 10, 4, 12, 4, 14, 4, 52, 11, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 65, 10, 5, 3, 5, 5, 5, 68, 10, 5, 3, 5, 5, 5, 71, 10, 5, 3, 5, 5, 5, 74, 10, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 86, 10, 8, 3, 8, 2, 2, 9, 2, 4, 6, 8, 10, 12, 14, 2, 2, 2, 92, 2, 16, 3, 2, 2, 2, 4, 28, 3, 2, 2, 2, 6, 43, 3, 2, 2, 2, 8, 73, 3, 2, 2, 2, 10, 75, 3, 2, 2, 2, 12, 77, 3, 2, 2, 2, 14, 85, 3, 2, 2, 2, 16, 17, 7, 3, 2, 2, 17, 18, 7, 17, 2, 2, 18, 22, 7, 4, 2, 2, 19, 21, 5, 4, 3, 2, 20, 19, 3, 2, 2, 2, 21, 24, 3, 2, 2, 2, 22, 20, 3, 2, 2, 2, 22, 23, 3, 2, 2, 2, 23, 25, 3, 2, 2, 2, 24, 22, 3, 2, 2, 2, 25, 26, 7, 2, 2, 3, 26, 3, 3, 2, 2, 2, 27, 29, 7, 5, 2, 2, 28, 27, 3, 2, 2, 2, 28, 29, 3, 2, 2, 2, 29, 30, 3, 2, 2, 2, 30, 31, 7, 6, 2, 2, 31, 32, 5, 6, 4, 2, 32, 37, 7, 7, 2, 2, 33, 36, 5, 8, 5, 2, 34, 36, 5, 4, 3, 2, 35, 33, 3, 2, 2, 2, 35, 34, 3, 2, 2, 2, 36, 39, 3, 2, 2, 2, 37, 35, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 40, 3, 2, 2, 2, 39, 37, 3, 2, 2, 2, 40, 41, 7, 8, 2, 2, 41, 5, 3, 2, 2, 2, 42, 44, 7, 9, 2, 2, 43, 42, 3, 2, 2, 2, 43, 44, 3, 2, 2, 2, 44, 45, 3, 2, 2, 2, 45, 50, 7, 17, 2, 2, 46, 47, 7, 9, 2, 2, 47, 49, 7, 17, 2, 2, 48, 46, 3, 2, 2, 2, 49, 52, 3, 2, 2, 2, 50, 48, 3, 2, 2, 2, 50, 51, 3, 2, 2, 2, 51, 7, 3, 2, 2, 2, 52, 50, 3, 2, 2, 2, 53, 54, 7, 10, 2, 2, 54, 55, 5, 10, 6, 2, 55, 56, 7, 4, 2, 2, 56, 74, 3, 2, 2, 2, 57, 58, 7, 11, 2, 2, 58, 59, 5, 10, 6, 2, 59, 60, 7, 4, 2, 2, 60, 74, 3, 2, 2, 2, 61, 62, 7, 12, 2, 2, 62, 64, 7, 17, 2, 2, 63, 65, 5, 12, 7, 2, 64, 63, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 67, 3, 2, 2, 2, 66, 68, 5, 10, 6, 2, 67, 66, 3, 2, 2, 2, 67, 68, 3, 2, 2, 2, 68, 70, 3, 2, 2, 2, 69, 71, 5, 14, 8, 2, 70, 69, 3, 2, 2, 2, 70, 71, 3, 2, 2, 2, 71, 72, 3, 2, 2, 2, 72, 74, 7, 4, 2, 2, 73, 53, 3, 2, 2, 2, 73, 57, 3, 2, 2, 2, 73, 61, 3, 2, 2, 2, 74, 9, 3, 2, 2, 2, 75, 76, 7, 17, 2, 2, 76, 11, 3, 2, 2, 2, 77, 78, 7, 13, 2, 2, 78, 79, 7, 17, 2, 2, 79, 80, 7, 14, 2, 2, 80, 13, 3, 2, 2, 2, 81, 82, 7, 15, 2, 2, 82, 86, 5, 6, 4, 2, 83, 84, 7, 16, 2, 2, 84, 86, 5, 6, 4, 2, 85, 81, 3, 2, 2, 2, 85, 83, 3, 2, 2, 2, 86, 15, 3, 2, 2, 2, 13, 22, 28, 35, 37, 43, 50, 64, 67, 70, 73, 85] \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makina.tokens b/makina-compiler/gen/xyz/colinholzman/makina/makina.tokens new file mode 100644 index 0000000..b53eb61 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makina.tokens @@ -0,0 +1,31 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +ID=15 +WHITESPACE=16 +COMMENT=17 +'machine'=1 +';'=2 +'initial'=3 +'state'=4 +'{'=5 +'}'=6 +'.'=7 +'entry'=8 +'exit'=9 +'on'=10 +'('=11 +')'=12 +'->'=13 +'>'=14 diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaBaseListener.java b/makina-compiler/gen/xyz/colinholzman/makina/makinaBaseListener.java new file mode 100644 index 0000000..2d4a386 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaBaseListener.java @@ -0,0 +1,159 @@ +// Generated from /Users/colinholzman/makina/makina-compiler/src/makina.g4 by ANTLR 4.9.1 +package xyz.colinholzman.makina; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link makinaListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +public class makinaBaseListener implements makinaListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFile(makinaParser.FileContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFile(makinaParser.FileContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterState(makinaParser.StateContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitState(makinaParser.StateContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterId(makinaParser.IdContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitId(makinaParser.IdContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEntryHandler(makinaParser.EntryHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEntryHandler(makinaParser.EntryHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExitHandler(makinaParser.ExitHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExitHandler(makinaParser.ExitHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEventHandler(makinaParser.EventHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEventHandler(makinaParser.EventHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAction(makinaParser.ActionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAction(makinaParser.ActionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterGuard(makinaParser.GuardContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitGuard(makinaParser.GuardContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExternalTransition(makinaParser.ExternalTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExternalTransition(makinaParser.ExternalTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLocalTransition(makinaParser.LocalTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLocalTransition(makinaParser.LocalTransitionContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaBaseVisitor.java b/makina-compiler/gen/xyz/colinholzman/makina/makinaBaseVisitor.java new file mode 100644 index 0000000..d4440e2 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaBaseVisitor.java @@ -0,0 +1,84 @@ +// Generated from /Users/colinholzman/makina/makina-compiler/src/makina.g4 by ANTLR 4.9.1 +package xyz.colinholzman.makina; +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link makinaVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public class makinaBaseVisitor extends AbstractParseTreeVisitor implements makinaVisitor { + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitFile(makinaParser.FileContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitState(makinaParser.StateContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitId(makinaParser.IdContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitEntryHandler(makinaParser.EntryHandlerContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExitHandler(makinaParser.ExitHandlerContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitEventHandler(makinaParser.EventHandlerContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAction(makinaParser.ActionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitGuard(makinaParser.GuardContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExternalTransition(makinaParser.ExternalTransitionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitLocalTransition(makinaParser.LocalTransitionContext ctx) { return visitChildren(ctx); } +} \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.interp b/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.interp new file mode 100644 index 0000000..4ab03b4 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.interp @@ -0,0 +1,68 @@ +token literal names: +null +'machine' +';' +'initial' +'state' +'{' +'}' +'.' +'entry' +'exit' +'on' +'(' +')' +'->' +'>' +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +ID +WHITESPACE +COMMENT + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +T__6 +T__7 +T__8 +T__9 +T__10 +T__11 +T__12 +T__13 +ID +WHITESPACE +COMMENT + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 19, 126, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 7, 16, 93, 10, 16, 12, 16, 14, 16, 96, 11, 16, 3, 16, 3, 16, 6, 16, 100, 10, 16, 13, 16, 14, 16, 101, 3, 16, 5, 16, 105, 10, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 7, 18, 115, 10, 18, 12, 18, 14, 18, 118, 11, 18, 3, 18, 5, 18, 121, 10, 18, 3, 18, 3, 18, 3, 18, 3, 18, 2, 2, 19, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 3, 2, 7, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 98, 98, 5, 2, 11, 12, 14, 15, 34, 34, 4, 2, 12, 12, 15, 15, 2, 130, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 3, 37, 3, 2, 2, 2, 5, 45, 3, 2, 2, 2, 7, 47, 3, 2, 2, 2, 9, 55, 3, 2, 2, 2, 11, 61, 3, 2, 2, 2, 13, 63, 3, 2, 2, 2, 15, 65, 3, 2, 2, 2, 17, 67, 3, 2, 2, 2, 19, 73, 3, 2, 2, 2, 21, 78, 3, 2, 2, 2, 23, 81, 3, 2, 2, 2, 25, 83, 3, 2, 2, 2, 27, 85, 3, 2, 2, 2, 29, 88, 3, 2, 2, 2, 31, 104, 3, 2, 2, 2, 33, 106, 3, 2, 2, 2, 35, 110, 3, 2, 2, 2, 37, 38, 7, 111, 2, 2, 38, 39, 7, 99, 2, 2, 39, 40, 7, 101, 2, 2, 40, 41, 7, 106, 2, 2, 41, 42, 7, 107, 2, 2, 42, 43, 7, 112, 2, 2, 43, 44, 7, 103, 2, 2, 44, 4, 3, 2, 2, 2, 45, 46, 7, 61, 2, 2, 46, 6, 3, 2, 2, 2, 47, 48, 7, 107, 2, 2, 48, 49, 7, 112, 2, 2, 49, 50, 7, 107, 2, 2, 50, 51, 7, 118, 2, 2, 51, 52, 7, 107, 2, 2, 52, 53, 7, 99, 2, 2, 53, 54, 7, 110, 2, 2, 54, 8, 3, 2, 2, 2, 55, 56, 7, 117, 2, 2, 56, 57, 7, 118, 2, 2, 57, 58, 7, 99, 2, 2, 58, 59, 7, 118, 2, 2, 59, 60, 7, 103, 2, 2, 60, 10, 3, 2, 2, 2, 61, 62, 7, 125, 2, 2, 62, 12, 3, 2, 2, 2, 63, 64, 7, 127, 2, 2, 64, 14, 3, 2, 2, 2, 65, 66, 7, 48, 2, 2, 66, 16, 3, 2, 2, 2, 67, 68, 7, 103, 2, 2, 68, 69, 7, 112, 2, 2, 69, 70, 7, 118, 2, 2, 70, 71, 7, 116, 2, 2, 71, 72, 7, 123, 2, 2, 72, 18, 3, 2, 2, 2, 73, 74, 7, 103, 2, 2, 74, 75, 7, 122, 2, 2, 75, 76, 7, 107, 2, 2, 76, 77, 7, 118, 2, 2, 77, 20, 3, 2, 2, 2, 78, 79, 7, 113, 2, 2, 79, 80, 7, 112, 2, 2, 80, 22, 3, 2, 2, 2, 81, 82, 7, 42, 2, 2, 82, 24, 3, 2, 2, 2, 83, 84, 7, 43, 2, 2, 84, 26, 3, 2, 2, 2, 85, 86, 7, 47, 2, 2, 86, 87, 7, 64, 2, 2, 87, 28, 3, 2, 2, 2, 88, 89, 7, 64, 2, 2, 89, 30, 3, 2, 2, 2, 90, 94, 9, 2, 2, 2, 91, 93, 9, 3, 2, 2, 92, 91, 3, 2, 2, 2, 93, 96, 3, 2, 2, 2, 94, 92, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 105, 3, 2, 2, 2, 96, 94, 3, 2, 2, 2, 97, 99, 7, 98, 2, 2, 98, 100, 10, 4, 2, 2, 99, 98, 3, 2, 2, 2, 100, 101, 3, 2, 2, 2, 101, 99, 3, 2, 2, 2, 101, 102, 3, 2, 2, 2, 102, 103, 3, 2, 2, 2, 103, 105, 7, 98, 2, 2, 104, 90, 3, 2, 2, 2, 104, 97, 3, 2, 2, 2, 105, 32, 3, 2, 2, 2, 106, 107, 9, 5, 2, 2, 107, 108, 3, 2, 2, 2, 108, 109, 8, 17, 2, 2, 109, 34, 3, 2, 2, 2, 110, 111, 7, 49, 2, 2, 111, 112, 7, 49, 2, 2, 112, 116, 3, 2, 2, 2, 113, 115, 10, 6, 2, 2, 114, 113, 3, 2, 2, 2, 115, 118, 3, 2, 2, 2, 116, 114, 3, 2, 2, 2, 116, 117, 3, 2, 2, 2, 117, 120, 3, 2, 2, 2, 118, 116, 3, 2, 2, 2, 119, 121, 7, 15, 2, 2, 120, 119, 3, 2, 2, 2, 120, 121, 3, 2, 2, 2, 121, 122, 3, 2, 2, 2, 122, 123, 7, 12, 2, 2, 123, 124, 3, 2, 2, 2, 124, 125, 8, 18, 2, 2, 125, 36, 3, 2, 2, 2, 8, 2, 94, 101, 104, 116, 120, 3, 8, 2, 2] \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.java b/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.java new file mode 100644 index 0000000..779ab18 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.java @@ -0,0 +1,151 @@ +// Generated from /Users/colinholzman/makina/makina-compiler/src/makina.g4 by ANTLR 4.9.1 +package xyz.colinholzman.makina; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class makinaLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, + T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, ID=15, WHITESPACE=16, + COMMENT=17; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", + "T__9", "T__10", "T__11", "T__12", "T__13", "ID", "WHITESPACE", "COMMENT" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'machine'", "';'", "'initial'", "'state'", "'{'", "'}'", "'.'", + "'entry'", "'exit'", "'on'", "'('", "')'", "'->'", "'>'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, "ID", "WHITESPACE", "COMMENT" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public makinaLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "makina.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\23~\b\1\4\2\t\2\4"+ + "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ + "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+ + "\4\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t\3\t"+ + "\3\t\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\16"+ + "\3\17\3\17\3\20\3\20\7\20]\n\20\f\20\16\20`\13\20\3\20\3\20\6\20d\n\20"+ + "\r\20\16\20e\3\20\5\20i\n\20\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\7"+ + "\22s\n\22\f\22\16\22v\13\22\3\22\5\22y\n\22\3\22\3\22\3\22\3\22\2\2\23"+ + "\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20"+ + "\37\21!\22#\23\3\2\7\5\2C\\aac|\6\2\62;C\\aac|\3\2bb\5\2\13\f\16\17\""+ + "\"\4\2\f\f\17\17\2\u0082\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2"+ + "\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25"+ + "\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2"+ + "\2\2\2!\3\2\2\2\2#\3\2\2\2\3%\3\2\2\2\5-\3\2\2\2\7/\3\2\2\2\t\67\3\2\2"+ + "\2\13=\3\2\2\2\r?\3\2\2\2\17A\3\2\2\2\21C\3\2\2\2\23I\3\2\2\2\25N\3\2"+ + "\2\2\27Q\3\2\2\2\31S\3\2\2\2\33U\3\2\2\2\35X\3\2\2\2\37h\3\2\2\2!j\3\2"+ + "\2\2#n\3\2\2\2%&\7o\2\2&\'\7c\2\2\'(\7e\2\2()\7j\2\2)*\7k\2\2*+\7p\2\2"+ + "+,\7g\2\2,\4\3\2\2\2-.\7=\2\2.\6\3\2\2\2/\60\7k\2\2\60\61\7p\2\2\61\62"+ + "\7k\2\2\62\63\7v\2\2\63\64\7k\2\2\64\65\7c\2\2\65\66\7n\2\2\66\b\3\2\2"+ + "\2\678\7u\2\289\7v\2\29:\7c\2\2:;\7v\2\2;<\7g\2\2<\n\3\2\2\2=>\7}\2\2"+ + ">\f\3\2\2\2?@\7\177\2\2@\16\3\2\2\2AB\7\60\2\2B\20\3\2\2\2CD\7g\2\2DE"+ + "\7p\2\2EF\7v\2\2FG\7t\2\2GH\7{\2\2H\22\3\2\2\2IJ\7g\2\2JK\7z\2\2KL\7k"+ + "\2\2LM\7v\2\2M\24\3\2\2\2NO\7q\2\2OP\7p\2\2P\26\3\2\2\2QR\7*\2\2R\30\3"+ + "\2\2\2ST\7+\2\2T\32\3\2\2\2UV\7/\2\2VW\7@\2\2W\34\3\2\2\2XY\7@\2\2Y\36"+ + "\3\2\2\2Z^\t\2\2\2[]\t\3\2\2\\[\3\2\2\2]`\3\2\2\2^\\\3\2\2\2^_\3\2\2\2"+ + "_i\3\2\2\2`^\3\2\2\2ac\7b\2\2bd\n\4\2\2cb\3\2\2\2de\3\2\2\2ec\3\2\2\2"+ + "ef\3\2\2\2fg\3\2\2\2gi\7b\2\2hZ\3\2\2\2ha\3\2\2\2i \3\2\2\2jk\t\5\2\2"+ + "kl\3\2\2\2lm\b\21\2\2m\"\3\2\2\2no\7\61\2\2op\7\61\2\2pt\3\2\2\2qs\n\6"+ + "\2\2rq\3\2\2\2sv\3\2\2\2tr\3\2\2\2tu\3\2\2\2ux\3\2\2\2vt\3\2\2\2wy\7\17"+ + "\2\2xw\3\2\2\2xy\3\2\2\2yz\3\2\2\2z{\7\f\2\2{|\3\2\2\2|}\b\22\2\2}$\3"+ + "\2\2\2\b\2^ehtx\3\b\2\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.tokens b/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.tokens new file mode 100644 index 0000000..b53eb61 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaLexer.tokens @@ -0,0 +1,31 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +ID=15 +WHITESPACE=16 +COMMENT=17 +'machine'=1 +';'=2 +'initial'=3 +'state'=4 +'{'=5 +'}'=6 +'.'=7 +'entry'=8 +'exit'=9 +'on'=10 +'('=11 +')'=12 +'->'=13 +'>'=14 diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaListener.java b/makina-compiler/gen/xyz/colinholzman/makina/makinaListener.java new file mode 100644 index 0000000..cc30b8c --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaListener.java @@ -0,0 +1,120 @@ +// Generated from /Users/colinholzman/makina/makina-compiler/src/makina.g4 by ANTLR 4.9.1 +package xyz.colinholzman.makina; +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link makinaParser}. + */ +public interface makinaListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link makinaParser#file}. + * @param ctx the parse tree + */ + void enterFile(makinaParser.FileContext ctx); + /** + * Exit a parse tree produced by {@link makinaParser#file}. + * @param ctx the parse tree + */ + void exitFile(makinaParser.FileContext ctx); + /** + * Enter a parse tree produced by {@link makinaParser#state}. + * @param ctx the parse tree + */ + void enterState(makinaParser.StateContext ctx); + /** + * Exit a parse tree produced by {@link makinaParser#state}. + * @param ctx the parse tree + */ + void exitState(makinaParser.StateContext ctx); + /** + * Enter a parse tree produced by {@link makinaParser#id}. + * @param ctx the parse tree + */ + void enterId(makinaParser.IdContext ctx); + /** + * Exit a parse tree produced by {@link makinaParser#id}. + * @param ctx the parse tree + */ + void exitId(makinaParser.IdContext ctx); + /** + * Enter a parse tree produced by the {@code entryHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + */ + void enterEntryHandler(makinaParser.EntryHandlerContext ctx); + /** + * Exit a parse tree produced by the {@code entryHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + */ + void exitEntryHandler(makinaParser.EntryHandlerContext ctx); + /** + * Enter a parse tree produced by the {@code exitHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + */ + void enterExitHandler(makinaParser.ExitHandlerContext ctx); + /** + * Exit a parse tree produced by the {@code exitHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + */ + void exitExitHandler(makinaParser.ExitHandlerContext ctx); + /** + * Enter a parse tree produced by the {@code eventHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + */ + void enterEventHandler(makinaParser.EventHandlerContext ctx); + /** + * Exit a parse tree produced by the {@code eventHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + */ + void exitEventHandler(makinaParser.EventHandlerContext ctx); + /** + * Enter a parse tree produced by {@link makinaParser#action}. + * @param ctx the parse tree + */ + void enterAction(makinaParser.ActionContext ctx); + /** + * Exit a parse tree produced by {@link makinaParser#action}. + * @param ctx the parse tree + */ + void exitAction(makinaParser.ActionContext ctx); + /** + * Enter a parse tree produced by {@link makinaParser#guard}. + * @param ctx the parse tree + */ + void enterGuard(makinaParser.GuardContext ctx); + /** + * Exit a parse tree produced by {@link makinaParser#guard}. + * @param ctx the parse tree + */ + void exitGuard(makinaParser.GuardContext ctx); + /** + * Enter a parse tree produced by the {@code externalTransition} + * labeled alternative in {@link makinaParser#target}. + * @param ctx the parse tree + */ + void enterExternalTransition(makinaParser.ExternalTransitionContext ctx); + /** + * Exit a parse tree produced by the {@code externalTransition} + * labeled alternative in {@link makinaParser#target}. + * @param ctx the parse tree + */ + void exitExternalTransition(makinaParser.ExternalTransitionContext ctx); + /** + * Enter a parse tree produced by the {@code localTransition} + * labeled alternative in {@link makinaParser#target}. + * @param ctx the parse tree + */ + void enterLocalTransition(makinaParser.LocalTransitionContext ctx); + /** + * Exit a parse tree produced by the {@code localTransition} + * labeled alternative in {@link makinaParser#target}. + * @param ctx the parse tree + */ + void exitLocalTransition(makinaParser.LocalTransitionContext ctx); +} \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaParser.java b/makina-compiler/gen/xyz/colinholzman/makina/makinaParser.java new file mode 100644 index 0000000..ee7c8f9 --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaParser.java @@ -0,0 +1,721 @@ +// Generated from /Users/colinholzman/makina/makina-compiler/src/makina.g4 by ANTLR 4.9.1 +package xyz.colinholzman.makina; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class makinaParser extends Parser { + static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, + T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, ID=15, WHITESPACE=16, + COMMENT=17; + public static final int + RULE_file = 0, RULE_state = 1, RULE_id = 2, RULE_handler = 3, RULE_action = 4, + RULE_guard = 5, RULE_target = 6; + private static String[] makeRuleNames() { + return new String[] { + "file", "state", "id", "handler", "action", "guard", "target" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'machine'", "';'", "'initial'", "'state'", "'{'", "'}'", "'.'", + "'entry'", "'exit'", "'on'", "'('", "')'", "'->'", "'>'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, "ID", "WHITESPACE", "COMMENT" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "makina.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public makinaParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + public static class FileContext extends ParserRuleContext { + public TerminalNode ID() { return getToken(makinaParser.ID, 0); } + public TerminalNode EOF() { return getToken(makinaParser.EOF, 0); } + public List state() { + return getRuleContexts(StateContext.class); + } + public StateContext state(int i) { + return getRuleContext(StateContext.class,i); + } + public FileContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_file; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterFile(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitFile(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitFile(this); + else return visitor.visitChildren(this); + } + } + + public final FileContext file() throws RecognitionException { + FileContext _localctx = new FileContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_file); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(14); + match(T__0); + setState(15); + match(ID); + setState(16); + match(T__1); + setState(20); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__2 || _la==T__3) { + { + { + setState(17); + state(); + } + } + setState(22); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(23); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StateContext extends ParserRuleContext { + public Token initial; + public IdContext id() { + return getRuleContext(IdContext.class,0); + } + public List handler() { + return getRuleContexts(HandlerContext.class); + } + public HandlerContext handler(int i) { + return getRuleContext(HandlerContext.class,i); + } + public List state() { + return getRuleContexts(StateContext.class); + } + public StateContext state(int i) { + return getRuleContext(StateContext.class,i); + } + public StateContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_state; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterState(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitState(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitState(this); + else return visitor.visitChildren(this); + } + } + + public final StateContext state() throws RecognitionException { + StateContext _localctx = new StateContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_state); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(26); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__2) { + { + setState(25); + ((StateContext)_localctx).initial = match(T__2); + } + } + + setState(28); + match(T__3); + setState(29); + id(); + setState(30); + match(T__4); + setState(35); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__3) | (1L << T__7) | (1L << T__8) | (1L << T__9))) != 0)) { + { + setState(33); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__7: + case T__8: + case T__9: + { + setState(31); + handler(); + } + break; + case T__2: + case T__3: + { + setState(32); + state(); + } + break; + default: + throw new NoViableAltException(this); + } + } + setState(37); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(38); + match(T__5); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IdContext extends ParserRuleContext { + public Token root; + public List ID() { return getTokens(makinaParser.ID); } + public TerminalNode ID(int i) { + return getToken(makinaParser.ID, i); + } + public IdContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_id; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterId(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitId(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitId(this); + else return visitor.visitChildren(this); + } + } + + public final IdContext id() throws RecognitionException { + IdContext _localctx = new IdContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_id); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(41); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__6) { + { + setState(40); + ((IdContext)_localctx).root = match(T__6); + } + } + + setState(43); + match(ID); + setState(48); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__6) { + { + { + setState(44); + match(T__6); + setState(45); + match(ID); + } + } + setState(50); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class HandlerContext extends ParserRuleContext { + public HandlerContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_handler; } + + public HandlerContext() { } + public void copyFrom(HandlerContext ctx) { + super.copyFrom(ctx); + } + } + public static class EntryHandlerContext extends HandlerContext { + public ActionContext action() { + return getRuleContext(ActionContext.class,0); + } + public EntryHandlerContext(HandlerContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterEntryHandler(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitEntryHandler(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitEntryHandler(this); + else return visitor.visitChildren(this); + } + } + public static class ExitHandlerContext extends HandlerContext { + public ActionContext action() { + return getRuleContext(ActionContext.class,0); + } + public ExitHandlerContext(HandlerContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterExitHandler(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitExitHandler(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitExitHandler(this); + else return visitor.visitChildren(this); + } + } + public static class EventHandlerContext extends HandlerContext { + public TerminalNode ID() { return getToken(makinaParser.ID, 0); } + public GuardContext guard() { + return getRuleContext(GuardContext.class,0); + } + public ActionContext action() { + return getRuleContext(ActionContext.class,0); + } + public TargetContext target() { + return getRuleContext(TargetContext.class,0); + } + public EventHandlerContext(HandlerContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterEventHandler(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitEventHandler(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitEventHandler(this); + else return visitor.visitChildren(this); + } + } + + public final HandlerContext handler() throws RecognitionException { + HandlerContext _localctx = new HandlerContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_handler); + int _la; + try { + setState(71); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__7: + _localctx = new EntryHandlerContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(51); + match(T__7); + setState(52); + action(); + setState(53); + match(T__1); + } + break; + case T__8: + _localctx = new ExitHandlerContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(55); + match(T__8); + setState(56); + action(); + setState(57); + match(T__1); + } + break; + case T__9: + _localctx = new EventHandlerContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(59); + match(T__9); + setState(60); + match(ID); + setState(62); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__10) { + { + setState(61); + guard(); + } + } + + setState(65); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ID) { + { + setState(64); + action(); + } + } + + setState(68); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__12 || _la==T__13) { + { + setState(67); + target(); + } + } + + setState(70); + match(T__1); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ActionContext extends ParserRuleContext { + public TerminalNode ID() { return getToken(makinaParser.ID, 0); } + public ActionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_action; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterAction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitAction(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitAction(this); + else return visitor.visitChildren(this); + } + } + + public final ActionContext action() throws RecognitionException { + ActionContext _localctx = new ActionContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_action); + try { + enterOuterAlt(_localctx, 1); + { + setState(73); + match(ID); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class GuardContext extends ParserRuleContext { + public TerminalNode ID() { return getToken(makinaParser.ID, 0); } + public GuardContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_guard; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterGuard(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitGuard(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitGuard(this); + else return visitor.visitChildren(this); + } + } + + public final GuardContext guard() throws RecognitionException { + GuardContext _localctx = new GuardContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_guard); + try { + enterOuterAlt(_localctx, 1); + { + setState(75); + match(T__10); + setState(76); + match(ID); + setState(77); + match(T__11); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TargetContext extends ParserRuleContext { + public TargetContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_target; } + + public TargetContext() { } + public void copyFrom(TargetContext ctx) { + super.copyFrom(ctx); + } + } + public static class ExternalTransitionContext extends TargetContext { + public IdContext id() { + return getRuleContext(IdContext.class,0); + } + public ExternalTransitionContext(TargetContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterExternalTransition(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitExternalTransition(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitExternalTransition(this); + else return visitor.visitChildren(this); + } + } + public static class LocalTransitionContext extends TargetContext { + public IdContext id() { + return getRuleContext(IdContext.class,0); + } + public LocalTransitionContext(TargetContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).enterLocalTransition(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof makinaListener ) ((makinaListener)listener).exitLocalTransition(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof makinaVisitor ) return ((makinaVisitor)visitor).visitLocalTransition(this); + else return visitor.visitChildren(this); + } + } + + public final TargetContext target() throws RecognitionException { + TargetContext _localctx = new TargetContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_target); + try { + setState(83); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__12: + _localctx = new ExternalTransitionContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(79); + match(T__12); + setState(80); + id(); + } + break; + case T__13: + _localctx = new LocalTransitionContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(81); + match(T__13); + setState(82); + id(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\23X\4\2\t\2\4\3\t"+ + "\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\3\2\3\2\3\2\3\2\7\2\25\n\2"+ + "\f\2\16\2\30\13\2\3\2\3\2\3\3\5\3\35\n\3\3\3\3\3\3\3\3\3\3\3\7\3$\n\3"+ + "\f\3\16\3\'\13\3\3\3\3\3\3\4\5\4,\n\4\3\4\3\4\3\4\7\4\61\n\4\f\4\16\4"+ + "\64\13\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5A\n\5\3\5\5\5"+ + "D\n\5\3\5\5\5G\n\5\3\5\5\5J\n\5\3\6\3\6\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3"+ + "\b\5\bV\n\b\3\b\2\2\t\2\4\6\b\n\f\16\2\2\2\\\2\20\3\2\2\2\4\34\3\2\2\2"+ + "\6+\3\2\2\2\bI\3\2\2\2\nK\3\2\2\2\fM\3\2\2\2\16U\3\2\2\2\20\21\7\3\2\2"+ + "\21\22\7\21\2\2\22\26\7\4\2\2\23\25\5\4\3\2\24\23\3\2\2\2\25\30\3\2\2"+ + "\2\26\24\3\2\2\2\26\27\3\2\2\2\27\31\3\2\2\2\30\26\3\2\2\2\31\32\7\2\2"+ + "\3\32\3\3\2\2\2\33\35\7\5\2\2\34\33\3\2\2\2\34\35\3\2\2\2\35\36\3\2\2"+ + "\2\36\37\7\6\2\2\37 \5\6\4\2 %\7\7\2\2!$\5\b\5\2\"$\5\4\3\2#!\3\2\2\2"+ + "#\"\3\2\2\2$\'\3\2\2\2%#\3\2\2\2%&\3\2\2\2&(\3\2\2\2\'%\3\2\2\2()\7\b"+ + "\2\2)\5\3\2\2\2*,\7\t\2\2+*\3\2\2\2+,\3\2\2\2,-\3\2\2\2-\62\7\21\2\2."+ + "/\7\t\2\2/\61\7\21\2\2\60.\3\2\2\2\61\64\3\2\2\2\62\60\3\2\2\2\62\63\3"+ + "\2\2\2\63\7\3\2\2\2\64\62\3\2\2\2\65\66\7\n\2\2\66\67\5\n\6\2\678\7\4"+ + "\2\28J\3\2\2\29:\7\13\2\2:;\5\n\6\2;<\7\4\2\2\7\f\2\2>@\7"+ + "\21\2\2?A\5\f\7\2@?\3\2\2\2@A\3\2\2\2AC\3\2\2\2BD\5\n\6\2CB\3\2\2\2CD"+ + "\3\2\2\2DF\3\2\2\2EG\5\16\b\2FE\3\2\2\2FG\3\2\2\2GH\3\2\2\2HJ\7\4\2\2"+ + "I\65\3\2\2\2I9\3\2\2\2I=\3\2\2\2J\t\3\2\2\2KL\7\21\2\2L\13\3\2\2\2MN\7"+ + "\r\2\2NO\7\21\2\2OP\7\16\2\2P\r\3\2\2\2QR\7\17\2\2RV\5\6\4\2ST\7\20\2"+ + "\2TV\5\6\4\2UQ\3\2\2\2US\3\2\2\2V\17\3\2\2\2\r\26\34#%+\62@CFIU"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/makina-compiler/gen/xyz/colinholzman/makina/makinaVisitor.java b/makina-compiler/gen/xyz/colinholzman/makina/makinaVisitor.java new file mode 100644 index 0000000..e6e438d --- /dev/null +++ b/makina-compiler/gen/xyz/colinholzman/makina/makinaVisitor.java @@ -0,0 +1,78 @@ +// Generated from /Users/colinholzman/makina/makina-compiler/src/makina.g4 by ANTLR 4.9.1 +package xyz.colinholzman.makina; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link makinaParser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface makinaVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link makinaParser#file}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFile(makinaParser.FileContext ctx); + /** + * Visit a parse tree produced by {@link makinaParser#state}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitState(makinaParser.StateContext ctx); + /** + * Visit a parse tree produced by {@link makinaParser#id}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitId(makinaParser.IdContext ctx); + /** + * Visit a parse tree produced by the {@code entryHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEntryHandler(makinaParser.EntryHandlerContext ctx); + /** + * Visit a parse tree produced by the {@code exitHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExitHandler(makinaParser.ExitHandlerContext ctx); + /** + * Visit a parse tree produced by the {@code eventHandler} + * labeled alternative in {@link makinaParser#handler}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEventHandler(makinaParser.EventHandlerContext ctx); + /** + * Visit a parse tree produced by {@link makinaParser#action}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAction(makinaParser.ActionContext ctx); + /** + * Visit a parse tree produced by {@link makinaParser#guard}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGuard(makinaParser.GuardContext ctx); + /** + * Visit a parse tree produced by the {@code externalTransition} + * labeled alternative in {@link makinaParser#target}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternalTransition(makinaParser.ExternalTransitionContext ctx); + /** + * Visit a parse tree produced by the {@code localTransition} + * labeled alternative in {@link makinaParser#target}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLocalTransition(makinaParser.LocalTransitionContext ctx); +} \ No newline at end of file diff --git a/makina-compiler/src/makina.g4 b/makina-compiler/src/makina.g4 index 8eb88fe..b4c6565 100644 --- a/makina-compiler/src/makina.g4 +++ b/makina-compiler/src/makina.g4 @@ -27,7 +27,8 @@ guard ; target - : '->' id + : '->' id #externalTransition + | '>' id #localTransition ; ID : ('_'|'a'..'z'|'A'..'Z') ('_'|'0'..'9'|'a'..'z'|'A'..'Z')* diff --git a/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt b/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt index 49830f9..3a93f40 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt @@ -55,7 +55,7 @@ class CodeGenerator(val machine: Machine, private fun generateExitActions(handler: Handler.Event, sourceState: State, activeLeafState: State, output: PrintWriter) { output.apply { - if (handler.target.isNotEmpty()) { + if (handler.target != null) { val target = handler.getTargetState(sourceState, machine) val transition = Transition(activeLeafState, target) val exitSet = transition.getExitSet() @@ -71,7 +71,7 @@ class CodeGenerator(val machine: Machine, private fun generateEntryActions(handler: Handler.Event, sourceState: State, activeLeafState: State, output: PrintWriter) { output.apply { - if (handler.target.isNotEmpty()) { + if (handler.target != null) { val target = handler.getTargetState(sourceState, machine) val transition = Transition(activeLeafState, target) val entrySet = transition.getEntrySet() + target.getDefaultEntrySet() diff --git a/makina-compiler/src/xyz/colinholzman/makina/Handler.kt b/makina-compiler/src/xyz/colinholzman/makina/Handler.kt index 889da4a..c18a94d 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/Handler.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/Handler.kt @@ -39,15 +39,15 @@ sealed class Handler(location: SourceLocation): Node(location) { } class Event(val id: String, val guard: String? = null, - val action: String? = null, val target: List = emptyList(), + val action: String? = null, val target: Target? = null, location: SourceLocation = SourceLocation.none): Handler(location) { fun getTargetState(source: State, machine: Machine): State { - if (target.isEmpty()) throw RuntimeException("handler doesn't define a transition") + if (target == null) throw RuntimeException("handler doesn't define a transition") //first look in the top level if the target is so specified - if (target.first() == ".") - return machine.states.find { it.getFullyQualifiedId() == target } ?: + if (target.id.first() == ".") + return machine.states.find { it.getFullyQualifiedId() == target.id } ?: throw RuntimeException("target $target not found at $location") //then look for the target among the children of the source state, @@ -57,15 +57,15 @@ sealed class Handler(location: SourceLocation): Node(location) { while (true) { //append the scope's fully qualified name to the target val fullTargetId = - if (scope == null) listOf(".") + target - else scope.getFullyQualifiedId() + target + if (scope == null) listOf(".") + target.id + else scope.getFullyQualifiedId() + target.id //look for the fully qualified target among the states val found = machine.states.find { it.getFullyQualifiedId() == fullTargetId } if (found != null) return found //if scope is null then we have looked everywhere - if (scope == null) throw RuntimeException("target $target not found at $location") + if (scope == null) throw RuntimeException("target ${target.id} not found at $location") else scope = scope.parent } } diff --git a/makina-compiler/src/xyz/colinholzman/makina/HandlerVisitor.kt b/makina-compiler/src/xyz/colinholzman/makina/HandlerVisitor.kt index 2c0327d..1b272f4 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/HandlerVisitor.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/HandlerVisitor.kt @@ -13,8 +13,7 @@ class HandlerVisitor: makinaBaseVisitor() { val event = ctx!!.ID().text val guard = if (ctx.guard() != null) ctx.guard().ID().text else null val action = if (ctx.action() != null) ctx.action().ID().text else null - val target = if (ctx.target() == null) emptyList() - else ctx.target().id().accept(IdVisitor()) + val target = if (ctx.target() == null) null else ctx.target().accept(TargetVisitor()) return Handler.Event(event, guard, action, target, SourceLocation.fromParseContext(ctx)) } } \ No newline at end of file diff --git a/makina-compiler/src/xyz/colinholzman/makina/State.kt b/makina-compiler/src/xyz/colinholzman/makina/State.kt index 58b5a82..96e6678 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/State.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/State.kt @@ -172,6 +172,11 @@ class State(val id: String, } return null } + + //returns true if all states are descendants of the same ancestor + fun List.areRelated(): Boolean { + return map { it.getStateConfiguration().getParentState() }.toSet().size == 1 + } } } \ No newline at end of file diff --git a/makina-compiler/src/xyz/colinholzman/makina/StateConfiguration.kt b/makina-compiler/src/xyz/colinholzman/makina/StateConfiguration.kt index 41478d3..0821436 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/StateConfiguration.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/StateConfiguration.kt @@ -33,6 +33,11 @@ data class StateConfiguration(val states: Set) { return orderedStates.first() } + //Returns the top level state of this configuration + fun getParentState(): State { + return orderedStates.last() + } + companion object { fun List>.groupByIdAndRemoveRedundantHandlers(): Map>> { return groupBy { it.second.id }.mapValues { entry -> diff --git a/makina-compiler/src/xyz/colinholzman/makina/Target.kt b/makina-compiler/src/xyz/colinholzman/makina/Target.kt new file mode 100644 index 0000000..470acd1 --- /dev/null +++ b/makina-compiler/src/xyz/colinholzman/makina/Target.kt @@ -0,0 +1,8 @@ +package xyz.colinholzman.makina + +data class Target(val id: List = emptyList(), val kind: Kind = Kind.EXTERNAL) { + enum class Kind { + EXTERNAL, + LOCAL + } +} \ No newline at end of file diff --git a/makina-compiler/src/xyz/colinholzman/makina/TargetVisitor.kt b/makina-compiler/src/xyz/colinholzman/makina/TargetVisitor.kt new file mode 100644 index 0000000..815c958 --- /dev/null +++ b/makina-compiler/src/xyz/colinholzman/makina/TargetVisitor.kt @@ -0,0 +1,13 @@ +package xyz.colinholzman.makina + +class TargetVisitor: makinaBaseVisitor() { + override fun visitExternalTransition(ctx: makinaParser.ExternalTransitionContext?): Target { + val targetId = ctx!!.id().accept(IdVisitor()) + return Target(targetId, Target.Kind.EXTERNAL) + } + + override fun visitLocalTransition(ctx: makinaParser.LocalTransitionContext?): Target { + val targetId = ctx!!.id().accept(IdVisitor()) + return Target(targetId, Target.Kind.LOCAL) + } +} \ No newline at end of file diff --git a/makina-compiler/src/xyz/colinholzman/makina/Transition.kt b/makina-compiler/src/xyz/colinholzman/makina/Transition.kt index 3ea61c4..a2f3050 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/Transition.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/Transition.kt @@ -1,16 +1,37 @@ package xyz.colinholzman.makina +import xyz.colinholzman.makina.State.Companion.areRelated import xyz.colinholzman.makina.State.Companion.getLCCA -data class Transition(val source: State, val target: State) { +data class Transition(val source: State, val target: State, val kind: Target.Kind = Target.Kind.EXTERNAL) { init { if (!source.isLeafState()) throw RuntimeException("source must be a leaf state") + if (kind == Target.Kind.LOCAL) { + //The UML spec says local transitions can't have the same source and target, + //but I don't see why not, Yet... + //It seems like a useful way to 'restart' a sub state without triggering + //entry and exit actions for all parents + //if (source == target) + // throw RuntimeException("source must not equal target") + if (!listOf(source, target).areRelated()) + throw RuntimeException("source and target must be related") + } } fun getEntrySet(): List { - return (listOf(target) + target.getProperAncestors(listOf(source, target).getLCCA())).reversed() + return when (kind) { + Target.Kind.EXTERNAL -> + (listOf(target) + target.getProperAncestors(listOf(source, target).getLCCA())).reversed() + Target.Kind.LOCAL -> + TODO("same as for external but not including containing state") + } } fun getExitSet(): List { - return listOf(source) + source.getProperAncestors(listOf(source, target).getLCCA()) + return when (kind) { + Target.Kind.EXTERNAL -> + listOf(source) + source.getProperAncestors(listOf(source, target).getLCCA()) + Target.Kind.LOCAL -> + TODO("same as for external but not including containing state") + } } } \ No newline at end of file diff --git a/makina-compiler/test/xyz/colinholzman/makina/HandlerTest.kt b/makina-compiler/test/xyz/colinholzman/makina/HandlerTest.kt index 1bdba0d..6c84241 100644 --- a/makina-compiler/test/xyz/colinholzman/makina/HandlerTest.kt +++ b/makina-compiler/test/xyz/colinholzman/makina/HandlerTest.kt @@ -19,7 +19,7 @@ internal class HandlerTest { val s1 = State("s1") val s11 = State("s11", parentId = listOf(".", "s1")) val s12 = State("s12", parentId = listOf(".", "s1")) - val handler = Handler.Event("foo", target = listOf(".", "s2")) + val handler = Handler.Event("foo", target = Target(listOf(".", "s2"))) val s111 = State("s111", parentId = listOf(".", "s1", "s11"), handlers = listOf(handler)) val s2 = State("s2") val machine = Machine("test", listOf(s1, s11, s12, s111, s2)) @@ -41,25 +41,25 @@ internal class HandlerTest { @Test fun getPartiallySpecifiedTargetState() { - var handler = Handler.Event("foo", target = listOf("s11", "s111")) + var handler = Handler.Event("foo", target = Target(listOf("s11", "s111"))) assertEquals(s111, handler.getTargetState(s12, machine)) - handler = Handler.Event("foo", target = listOf("s121")) + handler = Handler.Event("foo", target = Target(listOf("s121"))) assertEquals(s121, handler.getTargetState(s12, machine)) - handler = Handler.Event("foo", target = listOf("s3", "s12")) + handler = Handler.Event("foo", target = Target(listOf("s3", "s12"))) assertEquals(s3_s12, handler.getTargetState(s1, machine)) - handler = Handler.Event("foo", target = listOf("s12")) + handler = Handler.Event("foo", target = Target(listOf("s12"))) assertEquals(s12, handler.getTargetState(s1, machine)) - handler = Handler.Event("foo", target = listOf(".", "s2")) + handler = Handler.Event("foo", target = Target(listOf(".", "s2"))) assertEquals(s2, handler.getTargetState(s3, machine)) - handler = Handler.Event("foo", target = listOf("s12")) + handler = Handler.Event("foo", target = Target(listOf("s12"))) assertEquals(s12, handler.getTargetState(s11, machine)) - handler = Handler.Event("foo", target = listOf("s1")) + handler = Handler.Event("foo", target = Target(listOf("s1"))) assertEquals(s1, handler.getTargetState(s2, machine)) } } \ No newline at end of file diff --git a/makina-compiler/test/xyz/colinholzman/makina/ParseTest.kt b/makina-compiler/test/xyz/colinholzman/makina/ParseTest.kt index ea27a19..835c762 100644 --- a/makina-compiler/test/xyz/colinholzman/makina/ParseTest.kt +++ b/makina-compiler/test/xyz/colinholzman/makina/ParseTest.kt @@ -60,7 +60,14 @@ internal class ParseTest { @Test fun testParseTransitionEventHandler() { val actual = Parse.handler("on Foo -> bar;") - val expected = Handler.Event("Foo", null, null, listOf("bar")) + val expected = Handler.Event("Foo", null, null, Target(listOf("bar"))) + assertEquals(expected, actual) + } + + @Test + fun testParseLocalTransitionEventHandler() { + val actual = Parse.handler("on Foo > bar;") + val expected = Handler.Event("Foo", null, null, Target(listOf("bar"), Target.Kind.LOCAL)) assertEquals(expected, actual) }