diff --git a/src/main/java/avatartranslator/AvatarError.java b/src/main/java/avatartranslator/AvatarError.java index 3313eec7f2f7cb7604d4279aec1b5666a94f53b0..55ec62c9119b258afe14e0968497a6ff776a5985 100644 --- a/src/main/java/avatartranslator/AvatarError.java +++ b/src/main/java/avatartranslator/AvatarError.java @@ -59,7 +59,9 @@ public class AvatarError { "State machine must terminate with a (stop) state", "ASM operator has not next operator", "Empty state machine", - "Unused elements in state machine" + "Unused elements in state machine", + "The name should start with an upper case letter", + "The name should start with a lower case letter" }; diff --git a/src/main/java/avatartranslator/AvatarSyntaxChecker.java b/src/main/java/avatartranslator/AvatarSyntaxChecker.java index 4679df4fe2372b941084b76a292b39f68785dede..646946bbb5f51f21fb0c1449419a6d535c2361a7 100644 --- a/src/main/java/avatartranslator/AvatarSyntaxChecker.java +++ b/src/main/java/avatartranslator/AvatarSyntaxChecker.java @@ -1,26 +1,26 @@ /* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille - * + * * ludovic.apvrille AT enst.fr - * + * * This software is a computer program whose purpose is to allow the * edition of TURTLE analysis, design and deployment diagrams, to * allow the generation of RT-LOTOS or Java code from this diagram, * and at last to allow the analysis of formal validation traces * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP * from INRIA Rhone-Alpes. - * + * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". - * + * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. - * + * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, @@ -31,38 +31,39 @@ * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. - * + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. */ package avatartranslator; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - import compiler.tmlparser.ParseException; import compiler.tmlparser.SimpleNode; import compiler.tmlparser.TMLExprParser; import compiler.tmlparser.TokenMgrError; -import myutil.BoolExpressionEvaluator; import myutil.Conversion; -import myutil.IntExpressionEvaluator; import myutil.TraceManager; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; /** * Class AvatarSyntaxChecker * Creation: 21/05/2010 - * @version 1.0 21/05/2010 + * * @author Ludovic APVRILLE + * @version 1.0 21/05/2010 */ -public class AvatarSyntaxChecker { +public class AvatarSyntaxChecker { + + // Errors are defined in AvatarError private final static int UNUSED_ELEMENT = 10; + private final static int FIRST_UPPER_CASE = 11; + private final static int FIRST_LOWER_CASE = 12; public AvatarSyntaxChecker() { } @@ -82,6 +83,8 @@ public class AvatarSyntaxChecker { ArrayList<AvatarError> warnings = new ArrayList<>(); warnings.addAll(checkIsolatedElements(avspec)); + warnings.addAll(checkNames(avspec)); + return warnings; } @@ -89,13 +92,14 @@ public class AvatarSyntaxChecker { public static ArrayList<AvatarError> checkIsolatedElements(AvatarSpecification avspec) { ArrayList<AvatarError> warnings = new ArrayList<>(); - for(AvatarBlock ab: avspec.getListOfBlocks()) { + for (AvatarBlock ab : avspec.getListOfBlocks()) { warnings.addAll(checkIsolatedElements(avspec, ab)); } return warnings; } + public static ArrayList<AvatarError> checkIsolatedElements(AvatarSpecification avspec, AvatarBlock ab) { ArrayList<AvatarError> warnings = new ArrayList<>(); @@ -106,7 +110,7 @@ public class AvatarSyntaxChecker { List<AvatarStateMachineElement> unused = asm.getUnusedElements(); if (unused != null) { - for(AvatarStateMachineElement asme: unused) { + for (AvatarStateMachineElement asme : unused) { AvatarError warning = new AvatarError(avspec); warning.firstAvatarElement = asme; warning.secondAvatarElement = ab; @@ -119,10 +123,50 @@ public class AvatarSyntaxChecker { } + public static ArrayList<AvatarError> checkNames(AvatarSpecification avspec) { + ArrayList<AvatarError> warnings = new ArrayList<>(); + + for (AvatarBlock ab : avspec.getListOfBlocks()) { + warnings.addAll(checkNames(avspec, ab)); + } + + return warnings; + } + + public static ArrayList<AvatarError> checkNames(AvatarSpecification avspec, AvatarBlock ab) { + ArrayList<AvatarError> warnings = new ArrayList<>(); + + // Checking block name + if (Conversion.startsWithLowerCase(ab.getName())) { + newError(avspec, warnings, ab, null, FIRST_UPPER_CASE); + } + + // Checking attribute, methods and signal names + for (AvatarAttribute aa: ab.getAttributes()) { + if (!Conversion.startsWithLowerCase(aa.getName())) { + newError(avspec, warnings, ab, aa, FIRST_LOWER_CASE); + } + } + for (AvatarMethod am: ab.getMethods()) { + if (!Conversion.startsWithLowerCase(am.getName())) { + newError(avspec, warnings, ab, am, FIRST_LOWER_CASE); + } + } + for (AvatarSignal as: ab.getSignals()) { + if (!Conversion.startsWithLowerCase(as.getName())) { + newError(avspec, warnings, ab, as, FIRST_LOWER_CASE); + } + } + + + return warnings; + } + + public static ArrayList<AvatarError> checkNextASMSpec(AvatarSpecification avspec) { ArrayList<AvatarError> errors = new ArrayList<>(); - for(AvatarBlock ab: avspec.getListOfBlocks()) { + for (AvatarBlock ab : avspec.getListOfBlocks()) { errors.addAll(checkNextASMBlock(avspec, ab)); } @@ -140,8 +184,8 @@ public class AvatarSyntaxChecker { error.error = 9; errors.add(error); } else { - for(AvatarStateMachineElement asme: asm.getListOfElements()) { - if (! ((asme instanceof AvatarState) || (asme instanceof AvatarStopState) || (asme instanceof AvatarStartState))) { + for (AvatarStateMachineElement asme : asm.getListOfElements()) { + if (!((asme instanceof AvatarState) || (asme instanceof AvatarStopState) || (asme instanceof AvatarStartState))) { if (asme.nexts.isEmpty()) { AvatarError error = new AvatarError(avspec); error.firstAvatarElement = asme; @@ -156,11 +200,10 @@ public class AvatarSyntaxChecker { } - public static ArrayList<AvatarError> checkASMLibraryFunctions(AvatarSpecification avspec) { ArrayList<AvatarError> errors = new ArrayList<>(); - for(AvatarLibraryFunction alf: avspec.getListOfLibraryFunctions()) { + for (AvatarLibraryFunction alf : avspec.getListOfLibraryFunctions()) { errors.addAll(checkASMLibraryFunction(avspec, alf)); } @@ -171,8 +214,8 @@ public class AvatarSyntaxChecker { ArrayList<AvatarError> errors = new ArrayList<>(); AvatarStateMachine asm = alf.getStateMachine(); - for(AvatarStateMachineElement elt: asm.getListOfElements()) { - if ( ! (elt instanceof AvatarStopState) ) { + for (AvatarStateMachineElement elt : asm.getListOfElements()) { + if (!(elt instanceof AvatarStopState)) { if (elt.getNexts().size() == 0) { AvatarError error = new AvatarError(avspec); error.firstAvatarElement = alf; @@ -221,7 +264,7 @@ public class AvatarSyntaxChecker { } else { // Compare signals characteristics AvatarSignal sig1, sig2; - for(int i=0; i<signals1.size(); i++) { + for (int i = 0; i < signals1.size(); i++) { sig1 = signals1.get(i); sig2 = signals2.get(i); @@ -287,7 +330,6 @@ public class AvatarSyntaxChecker { } - public static int isAValidGuard(AvatarSpecification _as, AvatarStateMachineOwner _ab, String _guard) { //TraceManager.addDev("Evaluating (non modified) guard:" + _guard); @@ -302,7 +344,7 @@ public class AvatarSyntaxChecker { String act = tmp; - for(AvatarAttribute aa: _ab.getAttributes()) { + for (AvatarAttribute aa : _ab.getAttributes()) { if (aa.getType() != AvatarType.TIMER) { act = Conversion.putVariableValueInString(AvatarSpecification.ops, act, aa.getName(), aa.getDefaultInitialValue()); } @@ -358,7 +400,7 @@ public class AvatarSyntaxChecker { String tmp = _expr.replaceAll(" ", "").trim(); String act = tmp; - for(AvatarAttribute aa: _ab.getAttributes()) { + for (AvatarAttribute aa : _ab.getAttributes()) { act = Conversion.putVariableValueInString(AvatarSpecification.ops, act, aa.getName(), aa.getDefaultInitialValue()); } @@ -402,7 +444,7 @@ public class AvatarSyntaxChecker { return -1; } - if ((prob <0) || (prob > 1000)) { + if ((prob < 0) || (prob > 1000)) { return -1; } @@ -418,7 +460,7 @@ public class AvatarSyntaxChecker { String tmp = _expr.replaceAll(" ", "").trim(); String act = tmp; - for(AvatarAttribute aa: _ab.getAttributes()) { + for (AvatarAttribute aa : _ab.getAttributes()) { act = Conversion.putVariableValueInString(AvatarSpecification.ops, act, aa.getName(), aa.getDefaultInitialValueTF()); } @@ -442,7 +484,7 @@ public class AvatarSyntaxChecker { //TraceManager.addDev("1. IsValidBoolExpr Evaluating bool:" + act); - for(AvatarAttribute aa: _ab.getAttributes()) { + for (AvatarAttribute aa : _ab.getAttributes()) { act = Conversion.putVariableValueInString(AvatarSpecification.ops, act, aa.getName(), aa.getDefaultInitialValue()); } @@ -465,7 +507,7 @@ public class AvatarSyntaxChecker { //TraceManager.addDev("3. Now with avatar expression solver:" + _expr); AvatarExpressionSolver aee = new AvatarExpressionSolver(act); - if ( !(aee.buildExpression())) { + if (!(aee.buildExpression())) { TraceManager.addDev("4. Error with avatar expression solver:" + act); return -1; } @@ -488,7 +530,7 @@ public class AvatarSyntaxChecker { return -1; } - String action = _expr.substring(index0 + 1, _expr.length()).trim(); + String action = _expr.substring(index0 + 1, _expr.length()).trim(); if (aa.isInt()) { //TraceManager.addDev("Testing action+" + action); @@ -497,7 +539,7 @@ public class AvatarSyntaxChecker { } else if (aa.isBool()) { return isAValidBoolExpr(_as, _ab, action); //return parse(_as, _ab, "actionbool", action); - } + } return -1; } @@ -506,13 +548,14 @@ public class AvatarSyntaxChecker { * 1. Parsing the expression with no variable checking * 2. Parsing the expression with variables values to see whether variables are well-placed or not * The second parsing is performed iff the first one succeeds + * * @param _as : Unused * @param _ab : Avatar block * @param _parseCmd : Parse Command * @param _action : Action * @return : return -1 in case of error in first pass - * return -2 in case of error in second pass - * return -3 in case a variable has not been declared + * return -2 in case of error in second pass + * return -3 in case a variable has not been declared */ public static int parse(AvatarSpecification _as, AvatarStateMachineOwner _ab, String _parseCmd, String _action) { TMLExprParser parser; @@ -533,19 +576,19 @@ public class AvatarSyntaxChecker { } catch (TokenMgrError tke) { TraceManager.addDev("Avatar TokenMgrError --------> Parse error in :" + _parseCmd + " " + _action); return -1; - } + } // Second parsing // We only replace variables values after the "=" sign int index = _action.indexOf('='); String modif = _action; - if (_parseCmd.startsWith("ass")) { + if (_parseCmd.startsWith("ass")) { if (index != -1) { - modif = _action.substring(index+1, _action.length()); + modif = _action.substring(index + 1, _action.length()); } - _parseCmd = "action" + _parseCmd.substring(3, _parseCmd.length()); + _parseCmd = "action" + _parseCmd.substring(3, _parseCmd.length()); } /*for(i=0; i<_ab.attributeNb(); i++) { @@ -563,18 +606,18 @@ public class AvatarSyntaxChecker { TraceManager.addDev("\n(Original parsing :" + _parseCmd + " " + _action + ")"); TraceManager.addDev("ParseException --------> Parse error in :" + _parseCmd + " " + _action); return -2; - } catch (TokenMgrError tke ) { + } catch (TokenMgrError tke) { TraceManager.addDev("\nnAvatar Parsing :" + _parseCmd + " " + modif); TraceManager.addDev("TokenMgrError --------> Parse error in :" + _parseCmd + " " + _action); return -2; - } + } // Tree analysis: if the tree contains a variable, then, this variable has not been declared List<String> vars = root.getVariables(); - for(String s: vars) { + for (String s : vars) { // is that string a variable? if ((s.compareTo("true") != 0) && (s.compareTo("false") != 0) && (s.compareTo("nil") != 0)) { - TraceManager.addDev("Variable not declared: " +s); + TraceManager.addDev("Variable not declared: " + s); return -3; } } @@ -589,7 +632,7 @@ public class AvatarSyntaxChecker { public static ArrayList<AvatarElement> useOfInvalidUPPAALNumericalValues(AvatarSpecification _as, int maxV) { ArrayList<AvatarElement> invalids = new ArrayList<AvatarElement>(); - for(AvatarBlock ab: _as.getListOfBlocks()) { + for (AvatarBlock ab : _as.getListOfBlocks()) { // Check for attribute initial value invalids.addAll(ab.getAttributesOverMax(maxV)); @@ -601,4 +644,13 @@ public class AvatarSyntaxChecker { return invalids; } + private static void newError(AvatarSpecification _spec, ArrayList<AvatarError> _errors, + AvatarElement _first, AvatarElement _second, int _errorIndex) { + AvatarError error = new AvatarError(_spec); + error.firstAvatarElement = _first; + error.secondAvatarElement = _second; + error.error = _errorIndex; + _errors.add(error); + } + } diff --git a/src/main/java/myutil/Conversion.java b/src/main/java/myutil/Conversion.java index e274d08d732867ec50f8a2e1e474dc979004a2ba..8b9997e105a976a490fd8159e87970a2a44d41fc 100644 --- a/src/main/java/myutil/Conversion.java +++ b/src/main/java/myutil/Conversion.java @@ -80,6 +80,10 @@ public class Conversion { return cpt; } + public static boolean startsWithLowerCase(String _s) { + return Character.isLowerCase(_s.charAt(0)); + } + public static String replaceChar(String s, char c, String snew) { int index = s.indexOf(c); if (index > -1) { diff --git a/src/main/java/ui/AvatarDesignPanelTranslator.java b/src/main/java/ui/AvatarDesignPanelTranslator.java index 872755335e272e9fa8e9c5b3e66a3c9df0499dbe..5b5df66e409b7addc0b45e9e78715cd4a498e549 100644 --- a/src/main/java/ui/AvatarDesignPanelTranslator.java +++ b/src/main/java/ui/AvatarDesignPanelTranslator.java @@ -153,7 +153,20 @@ public class AvatarDesignPanelTranslator { ArrayList<AvatarError> listW = AvatarSyntaxChecker.checkSyntaxWarnings(as); for (AvatarError ar : listW) { - UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, AvatarError.errorStrings[ar.error]); + UICheckingError ce; + if (ar.firstAvatarElement != null) { + if (ar.secondAvatarElement == null) { + ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, + AvatarError.errorStrings[ar.error] + ": " + ar.firstAvatarElement.getName()); + } else { + ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, + AvatarError.errorStrings[ar.error] + ": " + + ar.firstAvatarElement.getName() + " / " + ar.secondAvatarElement.getName()); + } + } else { + ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, + AvatarError.errorStrings[ar.error]); + } ce.setTDiagramPanel(adp.getAvatarBDPanel()); Object o = ar.firstAvatarElement.getReferenceObject(); if (o instanceof TGComponent) {