Skip to content
Snippets Groups Projects
Commit d14634fe authored by dgelessus's avatar dgelessus
Browse files

Combine scope checking into type checking

The type checker needs to look up the VTs anyway, so it makes more sense
to put the error check there as well.
parent 095f69f1
No related branches found
No related tags found
No related merge requests found
...@@ -16,13 +16,10 @@ public class VOParser { ...@@ -16,13 +16,10 @@ public class VOParser {
private final Map<String, VTType> tasks; private final Map<String, VTType> tasks;
private final VOScopeChecker scopeChecker;
private final VOTypeChecker typeChecker; private final VOTypeChecker typeChecker;
public VOParser() { public VOParser() {
this.tasks = new HashMap<>(); this.tasks = new HashMap<>();
this.scopeChecker = new VOScopeChecker(this);
this.typeChecker = new VOTypeChecker(this); this.typeChecker = new VOTypeChecker(this);
} }
...@@ -56,21 +53,10 @@ public class VOParser { ...@@ -56,21 +53,10 @@ public class VOParser {
tasks.remove(id); tasks.remove(id);
} }
public void semanticCheck(Start ast) { public void typeCheck(Start ast) {
scopeChecker.scopeCheck(ast);
typeChecker.typeCheck(ast); typeChecker.typeCheck(ast);
} }
public void semanticCheck(String formula) {
scopeCheck(formula);
typeCheck(formula);
}
public void scopeCheck(String formula) {
Start start = parseFormula(formula);
scopeChecker.scopeCheck(start);
}
public void typeCheck(String formula) { public void typeCheck(String formula) {
Start start = parseFormula(formula); Start start = parseFormula(formula);
typeChecker.typeCheck(start); typeChecker.typeCheck(start);
......
package de.prob.voparser;
public class VOScopeCheckException extends VOException {
private static final long serialVersionUID = 1L;
public VOScopeCheckException(final String message, final Throwable cause) {
super(message, cause);
}
public VOScopeCheckException(final String message) {
this(message, null);
}
public VOScopeCheckException(final Throwable cause) {
this(cause == null ? null : cause.toString(), cause);
}
}
package de.prob.voparser;
import de.prob.voparser.analysis.DepthFirstAdapter;
import de.prob.voparser.node.AIdentifierVo;
import de.prob.voparser.node.Start;
public class VOScopeChecker extends DepthFirstAdapter {
private final VOParser voParser;
public VOScopeChecker(VOParser voParser) {
this.voParser = voParser;
}
public void scopeCheck(Start start) {
start.apply(this);
}
@Override
public void caseAIdentifierVo(AIdentifierVo node) {
if (!voParser.getTasks().containsKey(node.getIdentifierLiteral().getText())) {
throw new VOScopeCheckException("Scope error in VO");
}
}
}
...@@ -92,7 +92,11 @@ public class VOTypeChecker extends DepthFirstAdapter { ...@@ -92,7 +92,11 @@ public class VOTypeChecker extends DepthFirstAdapter {
private PersistentHashSet<AnimatorState> visitIdentifierNode(AIdentifierVo node, PersistentHashSet<AnimatorState> animatorState) { private PersistentHashSet<AnimatorState> visitIdentifierNode(AIdentifierVo node, PersistentHashSet<AnimatorState> animatorState) {
VTType type = voParser.getTasks().get(node.getIdentifierLiteral().getText()); final String id = node.getIdentifierLiteral().getText();
if (!voParser.getTasks().containsKey(id)) {
throw new VOTypeCheckException("Scope error in VO");
}
VTType type = voParser.getTasks().get(id);
PersistentHashSet<AnimatorState> newAnimatorState = animatorState; PersistentHashSet<AnimatorState> newAnimatorState = animatorState;
boolean valid = true; boolean valid = true;
switch (type) { switch (type) {
......
package de.prob.voparser;
/**
* (c) 2022 Lehrstuhl fuer Softwaretechnik und Programmiersprachen,
* Heinrich Heine Universitaet Duesseldorf
* This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html)
* */
import org.junit.Test;
public class VOScopingTest {
@Test
public void testAtomic() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1", VTType.EXPLORE);
voParser.scopeCheck("MC1");
}
@Test
public void testSequential() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1", VTType.TRACE);
voParser.registerTask("TR1", VTType.TRACE);
voParser.scopeCheck("MC1;TR1");
}
@Test(expected = VOScopeCheckException.class)
public void testSequentialError() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1", VTType.TRACE);
voParser.scopeCheck("MC1;TR1");
}
@Test
public void testAnd() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1", VTType.TRACE);
voParser.registerTask("TR1", VTType.TRACE);
voParser.scopeCheck("MC1 & TR1");
}
@Test
public void testAnd2() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1.1", VTType.TRACE);
voParser.registerTask("TR1.1", VTType.TRACE);
voParser.registerTask("MC2.1", VTType.TRACE);
voParser.registerTask("TR2.1", VTType.TRACE);
voParser.scopeCheck("(MC1.1; TR1.1) & (MC2.1; TR2.1)");
}
@Test
public void testOr() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1", VTType.TRACE);
voParser.registerTask("TR1", VTType.TRACE);
voParser.scopeCheck("MC1 or TR1");
}
@Test
public void testDot() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1.1", VTType.EXPLORE);
voParser.scopeCheck("MC1.1");
}
@Test(expected = VOScopeCheckException.class)
public void testScopingError() {
VOParser voParser = new VOParser();
voParser.scopeCheck("MC1");
}
}
...@@ -25,6 +25,13 @@ public class VOTypeCheckingTest { ...@@ -25,6 +25,13 @@ public class VOTypeCheckingTest {
voParser.typeCheck("MC1;MC2"); voParser.typeCheck("MC1;MC2");
} }
@Test(expected = VOTypeCheckException.class)
public void testSequentialError() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1", VTType.TRACE);
voParser.typeCheck("MC1;TR1");
}
@Test(expected = VOTypeCheckException.class) @Test(expected = VOTypeCheckException.class)
public void testSequential2() { public void testSequential2() {
VOParser voParser = new VOParser(); VOParser voParser = new VOParser();
...@@ -42,6 +49,16 @@ public class VOTypeCheckingTest { ...@@ -42,6 +49,16 @@ public class VOTypeCheckingTest {
voParser.typeCheck("MC1 & TR1"); voParser.typeCheck("MC1 & TR1");
} }
@Test
public void testAnd2() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1.1", VTType.TRACE);
voParser.registerTask("TR1.1", VTType.TRACE);
voParser.registerTask("MC2.1", VTType.TRACE);
voParser.registerTask("TR2.1", VTType.TRACE);
voParser.typeCheck("(MC1.1; TR1.1) & (MC2.1; TR2.1)");
}
@Test @Test
public void testOr() { public void testOr() {
VOParser voParser = new VOParser(); VOParser voParser = new VOParser();
...@@ -50,4 +67,17 @@ public class VOTypeCheckingTest { ...@@ -50,4 +67,17 @@ public class VOTypeCheckingTest {
voParser.typeCheck("MC1 or TR1"); voParser.typeCheck("MC1 or TR1");
} }
@Test
public void testDot() {
VOParser voParser = new VOParser();
voParser.registerTask("MC1.1", VTType.EXPLORE);
voParser.typeCheck("MC1.1");
}
@Test(expected = VOTypeCheckException.class)
public void testScopingError() {
VOParser voParser = new VOParser();
voParser.typeCheck("MC1");
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment