From 76bed9258ee72f417bcc88a575796b16d69482ef Mon Sep 17 00:00:00 2001 From: Ludovic Apvrille <ludovic.apvrille@telecom-paristech.fr> Date: Mon, 9 May 2011 14:01:49 +0000 Subject: [PATCH] AVATAR design: new syntax checker, and support of else guards --- executablecode/Makefile.src | 2 +- src/avatartranslator/AvatarBlock.java | 71 +++++++++++++++++++ src/avatartranslator/AvatarSpecification.java | 23 ++++++ src/avatartranslator/AvatarSyntaxChecker.java | 52 ++++++++++++-- src/avatartranslator/AvatarTransition.java | 19 +++++ .../toexecutable/AVATAR2CPOSIX.java | 7 +- src/myutil/BoolExpressionEvaluator.java | 8 +-- src/ui/AvatarDesignPanelTranslator.java | 65 ++++------------- src/ui/GTMLModeling.java | 4 +- 9 files changed, 183 insertions(+), 68 deletions(-) diff --git a/executablecode/Makefile.src b/executablecode/Makefile.src index bf52322a40..da5a5db63a 100755 --- a/executablecode/Makefile.src +++ b/executablecode/Makefile.src @@ -1 +1 @@ -SRCS = generated_src/main.c generated_src/Wallet.c generated_src/CoffeeMachine.c generated_src/CoffeeButton.c generated_src/TeaButton.c \ No newline at end of file +SRCS = generated_src/main.c generated_src/Generator.c generated_src/TestBlock.c \ No newline at end of file diff --git a/src/avatartranslator/AvatarBlock.java b/src/avatartranslator/AvatarBlock.java index e31ce9682c..7f67c3960b 100644 --- a/src/avatartranslator/AvatarBlock.java +++ b/src/avatartranslator/AvatarBlock.java @@ -470,6 +470,77 @@ public class AvatarBlock extends AvatarElement { return cpt; } + public AvatarState removeElseGuards() { + if (asm == null) { + return null; + } + + AvatarStateMachineElement asme0; + AvatarTransition at = null, at0; + int nbOfElse; + String guard, g; + int i; + + for(AvatarStateMachineElement asme :asm.getListOfElements()) { + if (asme instanceof AvatarState) { + // Has only one "else" transition? + if (asme.nbOfNexts() > 0) { + // Search for several "else" + nbOfElse = 0; + for(i=0; i<asme.nbOfNexts(); i++) { + asme0 = asme.getNext(i); + if (asme0 instanceof AvatarTransition) { + if (((AvatarTransition)asme0).hasElseGuard()) { + nbOfElse ++; + at = (AvatarTransition)asme0; + } + } + } + + if ((asme.nbOfNexts() == 1) && (nbOfElse == 1)) { + return (AvatarState)asme; + } + + if (nbOfElse > 2) { + return (AvatarState)asme; + } + + if (nbOfElse == 1) { + // Must compute the new guard + guard = ""; + for(i=0; i<asme.nbOfNexts(); i++) { + asme0 = asme.getNext(i); + if ((asme0 instanceof AvatarTransition) && (asme0 != at)) { + at0 = (AvatarTransition)asme0; + g = at0.getGuard(); + if (g != null) { + if (at0.hasNonDeterministicGuard()) { + guard = "false"; + break; + } else { + if (guard.length() == 0) { + guard = "not(" + at0.getGuard() + ")"; + } else { + guard = guard + " and not(" + at0.getGuard() + ")"; + } + } + } + } + } + guard = Conversion.replaceAllChar(guard, '[', "("); + guard = Conversion.replaceAllChar(guard, ']', ")"); + guard = "[" + guard + "]"; + at.setGuard(guard); + TraceManager.addDev("[ else ] replaced with :" + guard); + } + } + } + } + + return null; + + } + } \ No newline at end of file diff --git a/src/avatartranslator/AvatarSpecification.java b/src/avatartranslator/AvatarSpecification.java index 6405f8816f..0f3dca3249 100644 --- a/src/avatartranslator/AvatarSpecification.java +++ b/src/avatartranslator/AvatarSpecification.java @@ -345,4 +345,27 @@ public class AvatarSpecification extends AvatarElement { return null; } + public AvatarState removeElseGuards() { + AvatarState state; + + for(AvatarBlock block: blocks) { + state = block.removeElseGuards(); + if (state != null) { + return state; + } + } + + return null; + } + + public static boolean isElseGuard(String _guard) { + if (_guard == null) { + return false; + } + + String guard = Conversion.replaceAllChar(_guard, ' ', "").trim(); + + return guard.compareTo("[else]") == 0; + } + } \ No newline at end of file diff --git a/src/avatartranslator/AvatarSyntaxChecker.java b/src/avatartranslator/AvatarSyntaxChecker.java index 57b00f0856..f7651da2c3 100644 --- a/src/avatartranslator/AvatarSyntaxChecker.java +++ b/src/avatartranslator/AvatarSyntaxChecker.java @@ -76,10 +76,10 @@ public class AvatarSyntaxChecker { BoolExpressionEvaluator bee = new BoolExpressionEvaluator(); - TraceManager.addDev("Evaluating:" + act); + //TraceManager.addDev("Evaluating guard:" + act); boolean result = bee.getResultOf(act); if (bee.getError() != null) { - TraceManager.addDev("Error: " + bee.getError()); + //TraceManager.addDev("Error: " + bee.getError()); return -1; } @@ -93,14 +93,52 @@ public class AvatarSyntaxChecker { if (_expr.trim().length() == 0) { return 0; } - return parse(_as, _ab, "actionnat", _expr); + + String tmp = _expr.replaceAll(" ", "").trim(); + String act = tmp; + + for(AvatarAttribute aa: _ab.getAttributes()) { + act = Conversion.putVariableValueInString(AvatarSpecification.ops, act, aa.getName(), aa.getDefaultInitialValue()); + } + + IntExpressionEvaluator iee = new IntExpressionEvaluator(); + + //TraceManager.addDev("Evaluating int:" + act); + double result = iee.getResultOf(act); + if (iee.getError() != null) { + //TraceManager.addDev("Error: " + iee.getError()); + return -1; + } + + return 0; + // OLD return parse(_as, _ab, "actionnat", _expr);*/ + + } public static int isAValidBoolExpr(AvatarSpecification _as, AvatarBlock _ab, String _expr) { if (_expr.trim().length() == 0) { return 0; } - return parse(_as, _ab, "actionbool", _expr); + + String tmp = _expr.replaceAll(" ", "").trim(); + String act = tmp; + + for(AvatarAttribute aa: _ab.getAttributes()) { + act = Conversion.putVariableValueInString(AvatarSpecification.ops, act, aa.getName(), aa.getDefaultInitialValue()); + } + + BoolExpressionEvaluator bee = new BoolExpressionEvaluator(); + + //TraceManager.addDev("Evaluating bool:" + act); + boolean result = bee.getResultOf(act); + if (bee.getError() != null) { + //TraceManager.addDev("Error: " + bee.getError()); + return -1; + } + + return 0; + // OLD return parse(_as, _ab, "actionbool", _expr); } public static int isAValidVariableExpr(AvatarSpecification _as, AvatarBlock _ab, String _expr) { @@ -118,9 +156,11 @@ public class AvatarSyntaxChecker { String action = _expr.substring(index0 + 1, _expr.length()).trim(); if (aa.isInt()) { - return parse(_as, _ab, "actionnat", action); + return isAValidIntExpr(_as, _ab, action); + //return parse(_as, _ab, "actionnat", action); } else if (aa.isBool()) { - return parse(_as, _ab, "actionbool", action); + return isAValidBoolExpr(_as, _ab, action); + //return parse(_as, _ab, "actionbool", action); } return -1; } diff --git a/src/avatartranslator/AvatarTransition.java b/src/avatartranslator/AvatarTransition.java index 41eee5438b..d308b00d92 100644 --- a/src/avatartranslator/AvatarTransition.java +++ b/src/avatartranslator/AvatarTransition.java @@ -117,6 +117,25 @@ public class AvatarTransition extends AvatarStateMachineElement { } return maxCompute; } + + public boolean hasElseGuard() { + if (guard == null) { + return false; + } + + return AvatarSpecification.isElseGuard(guard); + } + + public boolean hasNonDeterministicGuard() { + if (guard == null) { + return false; + } + + String tmp = Conversion.replaceAllChar(guard, ' ', "").trim(); + + return tmp.compareTo("[]") == 0; + + } public AvatarTransition cloneMe() { diff --git a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java index 20b7be3290..5153e1ccd8 100755 --- a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java +++ b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java @@ -459,7 +459,12 @@ public class AVATAR2CPOSIX { if (at.hasActions()) { ret += " if (__returnRequest == &__req" + i + ") {" + CR; for(int j=0; j<at.getNbOfAction(); j++) { - ret += at.getAction(j) + ";" + CR; + if (at.isAMethodCall(at.getAction(j))) { + ret += modifyMethodName(_block, at.getAction(j)) + ";" + CR; + } else { + ret += at.getAction(j) + ";" + CR; + } + } ret += makeBehaviourFromElement(_block, at.getNext(0), false) + CR + "}"; } else { diff --git a/src/myutil/BoolExpressionEvaluator.java b/src/myutil/BoolExpressionEvaluator.java index 09c464f21c..5a07cdcc3c 100755 --- a/src/myutil/BoolExpressionEvaluator.java +++ b/src/myutil/BoolExpressionEvaluator.java @@ -74,8 +74,6 @@ public class BoolExpressionEvaluator { private int currentValue; - - public BoolExpressionEvaluator() { } @@ -102,7 +100,7 @@ public class BoolExpressionEvaluator { //TraceManager.addDev("Computing:" + _expr); - tokens = new java.util.StringTokenizer(_expr," \t\n\r+-*/()!=&|<>",true); + tokens = new java.util.StringTokenizer(_expr," \t\n\r+-*/()!=&|<>:;",true); computeNextToken(); int result = (int)(parseExpression()); @@ -117,8 +115,6 @@ public class BoolExpressionEvaluator { errorMessage = "Not a boolean expression: " + _expr; - - return false; } @@ -494,7 +490,7 @@ public class BoolExpressionEvaluator { return; } - if (s.compareTo("<") == 0) { + if (s.compareTo(";") == 0) { currentValue = 0; currentType = LTEQ_TOKEN; //TraceManager.addDev("equal token!"); diff --git a/src/ui/AvatarDesignPanelTranslator.java b/src/ui/AvatarDesignPanelTranslator.java index 25bb4bd99c..d254f20266 100644 --- a/src/ui/AvatarDesignPanelTranslator.java +++ b/src/ui/AvatarDesignPanelTranslator.java @@ -100,6 +100,9 @@ public class AvatarDesignPanelTranslator { createRelationsBetweenBlocks(as, blocks); makeBlockStateMachines(as); createPragmas(as, blocks); + TraceManager.addDev("Removing else guards"); + as.removeElseGuards(); + TraceManager.addDev("Removing else guards ... done"); return as; } @@ -1003,11 +1006,16 @@ public class AvatarDesignPanelTranslator { // Guard tmp = modifyString(asmdco.getGuard()); - error = AvatarSyntaxChecker.isAValidGuard(_as, _ab, tmp); - if (error < 0) { - makeError(error, tdp, _ab, tgc, "transition guard", tmp); - } else { + + if (AvatarSpecification.isElseGuard(tmp)) { at.setGuard(tmp); + } else { + error = AvatarSyntaxChecker.isAValidGuard(_as, _ab, tmp); + if (error < 0) { + makeError(error, tdp, _ab, tgc, "transition guard", tmp); + } else { + at.setGuard(tmp); + } } // Delays @@ -1308,53 +1316,6 @@ public class AvatarDesignPanelTranslator { return !(TAttribute.isAValidId(tmp, false, false)); } - /*private String makeTIFActionOnParam(String _s) { - String ret = _s.trim(); - int index0 = ret.indexOf("="); - if (index0 == -1) { - return ret; - } - - return ret.substring(index0+1, ret.length()).trim(); - - } - - private String makeTIFAction(String _s, String _replace) { - String ret = _s.trim(); - int index0 = ret.indexOf("("); - if (index0 == -1) { - return ""; - } - - int index1 = ret.indexOf(")"); - if (index1 == -1) { - return ""; - } - - ret = ret.substring(index0, index1); - - ret = Conversion.replaceAllString(ret, "(", _replace); - ret = Conversion.replaceAllString(ret, ",", _replace); - ret = Conversion.replaceAllString(ret, " ", ""); - - return ret; - } - - // Checks whether all states with internal state machines have at most one start state - private TGComponent checkForStartStateOfCompositeStates(AvatarSMDPanel _panel) { - TGComponent tgc; - ListIterator iterator = _panel.getComponentList().listIterator(); - while(iterator.hasNext()) { - tgc = (TGComponent)(iterator.next()); - if (tgc instanceof AvatarSMDState) { - tgc = (((AvatarSMDState)(tgc)).checkForStartStateOfCompositeStates()); - if (tgc != null) { - return tgc; - } - } - } - return null; - }*/ - + } diff --git a/src/ui/GTMLModeling.java b/src/ui/GTMLModeling.java index 91eee97346..0901f0b8ff 100755 --- a/src/ui/GTMLModeling.java +++ b/src/ui/GTMLModeling.java @@ -2047,7 +2047,7 @@ public class GTMLModeling { if (task != null) { tmp.add(task); } else { - CheckingError ce = new CheckingError(CheckingError.STRUCTURE_ERROR, "Task " + artifact.getTaskName() + " referenced by artifact " + artifact.getValue() + "is unknown"); + CheckingError ce = new CheckingError(CheckingError.STRUCTURE_ERROR, "Task " + artifact.getTaskName() + " referenced by artifact " + artifact.getValue() + " is unknown"); //ce.setTMLTask(tmltask); ce.setTDiagramPanel(tmlap.tmlap); ce.setTGComponent(tgc); @@ -2072,7 +2072,7 @@ public class GTMLModeling { tmp.add(pc); allcomp.add(pc); } else { - CheckingError ce = new CheckingError(CheckingError.STRUCTURE_ERROR, "Component " + artifact.getTaskName() + " referenced by artifact " + artifact.getValue() + "is unknown"); + CheckingError ce = new CheckingError(CheckingError.STRUCTURE_ERROR, "Component " + artifact.getTaskName() + " referenced by artifact " + artifact.getValue() + " is unknown"); //ce.setTMLTask(tmltask); ce.setTDiagramPanel(tmlap.tmlap); ce.setTGComponent(tgc); -- GitLab