Newer
Older
/* 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,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* 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 ui;
import avatartranslator.*;
import myutil.Conversion;
import myutil.TraceManager;
import translator.CheckingError;
import ui.avatarbd.*;
import ui.avatarsmd.*;
import java.util.*;
* Class AvatarDesignPanelTranslator
* Creation: 18/05/2010
* @author Ludovic APVRILLE
public class AvatarDesignPanelTranslator {
private final AvatarDesignPanel adp;
private final List<CheckingError> checkingErrors, warnings;
private final CorrespondanceTGElement listE; // usual list
//protected CorrespondanceTGElement listB; // list for particular element -> first element of group of blocks
//protected List <TDiagramPanel> panels;
private Map<String, List<TAttribute>> typeAttributesMap;
private Map<String, String> nameTypeMap;
public AvatarDesignPanelTranslator(AvatarDesignPanel _adp) {
adp = _adp;
// reinit();
// }
//public void reinit() {
checkingErrors = new LinkedList<CheckingError>();
warnings = new LinkedList<CheckingError>();
listE = new CorrespondanceTGElement();
}
public List<CheckingError> getErrors() {
return checkingErrors;
}
public List<CheckingError> getWarnings() {
return warnings;
}
public CorrespondanceTGElement getCorrespondanceTGElement() {
return listE;
}
public AvatarSpecification generateAvatarSpecification(List<AvatarBDStateMachineOwner> _blocks) {
List<AvatarBDBlock> blocks = new LinkedList<AvatarBDBlock>();
// List<AvatarBDInterface> interfaces = new LinkedList<AvatarBDInterface>();
List<AvatarBDLibraryFunction> libraryFunctions = new LinkedList<AvatarBDLibraryFunction>();
for (AvatarBDStateMachineOwner owner : _blocks)
if (owner instanceof AvatarBDBlock)
blocks.add((AvatarBDBlock) owner);
// else if (owner instanceof AvatarBDInterface)
// interfaces.add((AvatarBDInterface) owner);
else
libraryFunctions.add((AvatarBDLibraryFunction) owner);
AvatarSpecification as = new AvatarSpecification("avatarspecification", adp);
if (adp != null) {
AvatarBDPanel abdp = adp.getAvatarBDPanel();
if (abdp != null) {
as.addApplicationCode(abdp.getMainCode());
}
}
typeAttributesMap = new HashMap<String, List<TAttribute>>();
nameTypeMap = new HashMap<String, String>();
createLibraryFunctions(as, libraryFunctions);
createBlocks(as, blocks);
//createInterfaces(as, interfaces);
createRelationsBetweenBlocks(as, blocks);
//createRelationsBetweenBlocksAndInterfaces(as, blocks, interfaces);
makeBlockStateMachines(as);
createPragmas(as, blocks);
//TraceManager.addDev("Removing else guards");
as.removeElseGuards();
// Checking integer values
ArrayList<AvatarElement> listOfBadInt = AvatarSyntaxChecker.useOfInvalidUPPAALNumericalValues(as, AvatarSpecification.UPPAAL_MAX_INT);
// Adding warnings for each element
for(AvatarElement ae: listOfBadInt) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Integer expression outside UPPAAL range: " +
ae.toString() +
"-> UPPAAL verification may fail");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
if (ae.getReferenceObject() instanceof TGComponent) {
ce.setTGComponent((TGComponent)ae.getReferenceObject());
}
addWarning(ce);
}
//TraceManager.addDev("Removing else guards ... done");
adp.abdp.repaint();
return as;
}
public class ErrorAccumulator extends avatartranslator.ErrorAccumulator {
private TGComponent tgc;
private TDiagramPanel tdp;
// private AvatarBlock ab;
// public ErrorAccumulator (TGComponent tgc, TDiagramPanel tdp, AvatarBlock ab) {
// this.tgc = tgc;
// this.tdp = tdp;
// this.ab = ab;
// }
public ErrorAccumulator(TGComponent tgc, TDiagramPanel tdp) {
this.tgc = tgc;
this.tdp = tdp;
}
UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, msg);
ce.setTGComponent(this.tgc);
ce.setTDiagramPanel(this.tdp);
return ce;
}
public void addWarning(CheckingError ce) {
AvatarDesignPanelTranslator.this.addWarning(ce);
}
public void addWarning(String msg) {
this.addWarning(this.createError(msg));
}
public void addError(CheckingError ce) {
AvatarDesignPanelTranslator.this.addCheckingError(ce);
}
public void addError(String msg) {
this.addError(this.createError(msg));
}
}
private void createPragmas(AvatarSpecification _as, List<AvatarBDBlock> _blocks) {
Iterator<TGComponent> iterator = adp.getAvatarBDPanel().getComponentList().listIterator();
TGComponent tgc;
AvatarBDPragma tgcn;
AvatarBDSafetyPragma tgsp;
String values[];
String tmp;
List<AvatarPragma> pragmaList;
while (iterator.hasNext()) {
tgc = iterator.next();
if (tgc instanceof AvatarBDPragma) {
ErrorAccumulator errorAcc = new ErrorAccumulator(tgc, adp.getAvatarBDPanel());
tgcn = (AvatarBDPragma) tgc;
tgcn.syntaxErrors.clear();
values = tgcn.getValues();
for (int i = 0; i < values.length; i++) {
tmp = values[i].trim();
if ((tmp.startsWith("#") && (tmp.length() > 1))) {
tmp = tmp.substring(1, tmp.length()).trim();
//TraceManager.addDev("Reworking pragma =" + tmp);
pragmaList = AvatarPragma.createFromString(tmp, tgc, _as.getListOfBlocks(), typeAttributesMap, nameTypeMap, errorAcc);
//TraceManager.addDev("Reworked pragma =" + tmp);
for (AvatarPragma tmpPragma : pragmaList) {
if (tmpPragma instanceof AvatarPragmaConstant) {
AvatarPragmaConstant apg = (AvatarPragmaConstant) tmpPragma;
for (AvatarConstant ac : apg.getConstants()) {
_as.addConstant(ac);
}
}
_as.addPragma(tmpPragma);
//TraceManager.addDev("Adding pragma:" + tmp);
}
} else {
tgcn.syntaxErrors.add(values[i]);
}
}
if (tgc instanceof AvatarBDSafetyPragma) {
tgsp = (AvatarBDSafetyPragma) tgc;
values = tgsp.getValues();
for (String s : values) {
if (checkSafetyPragma(s, _blocks, _as, tgc)) {
_as.addSafetyPragma(s);
} else {
tgsp.syntaxErrors.add(s);
}
}
}
if (tgc instanceof AvatarBDPerformancePragma) {
tgpp = (AvatarBDPerformancePragma) tgc;
for (String s : values) {
AvatarPragmaLatency pragma = checkPerformancePragma(s, _blocks, _as, tgc);
if (pragma != null) {
_as.addLatencyPragma(pragma);
} else {
tgpp.syntaxErrors.add(s);
}
}
}
}
}
public AvatarPragmaLatency checkPerformancePragma(String _pragma, List<AvatarBDBlock> _blocks, AvatarSpecification as, TGComponent tgc) {
if (_pragma.contains("=") || (!_pragma.contains(">") && !_pragma.contains("<") && !_pragma.contains("?")) || !_pragma.contains("Latency(")) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "No latency expression found in pragma " + _pragma);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("No latency expression found in pragma " + _pragma);
return null;
}
String pragma = _pragma.trim();
pragma = pragma.split("Latency\\(")[1];
//Find first block.state
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
String p1 = pragma.split(",")[0];
//Throw error if lack of '.' in block.signal
if (!p1.contains(".")) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Invalid block.signal format in pragma " + _pragma);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Invalid block.signal format in pragma " + _pragma);
return null;
}
String block1 = p1.split("\\.")[0];
String state1 = p1.split("\\.", -1)[1];
AvatarBlock bl1;
AvatarStateMachineElement st1 = null;
List<String> id1 = new ArrayList<String>();
bl1 = as.getBlockWithName(block1);
if (bl1 == null) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Block " + block1 + " in pragma does not exist");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Block " + block1 + " in pragma does not exist");
return null;
}
AvatarStateMachine asm = bl1.getStateMachine();
for (AvatarActionOnSignal aaos : asm.getAllAOSWithName(state1)) {
if (aaos.getCheckLatency()) {
id1.add((aaos.getSignal().isIn() ? "Receive signal" : "Send signal") + "-" + aaos.getSignal().getName() + ":" + aaos.getID());
st1 = aaos;
}
}
AvatarState astate1 = asm.getStateWithName(state1);
if (astate1 != null) {
if (astate1.getCheckLatency()) {
id1.add("State-" + state1 + ":" + astate1.getID());
st1 = astate1;
}
}
if (id1.size() == 0) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Cannot find checkable state " + block1 + "." + state1 + " in pragma");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Cannot find checkable state " + block1 + "." + state1 + " in pragma");
return null;
}
//Find second block.signal
//Throw error if lack of '.'
String p2 = pragma.split(",")[1].split("\\)")[0];
if (!p2.contains(".")) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Invalid block.signal format in pragma " + _pragma);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Invalid block.signal format");
return null;
}
String block2 = p2.split("\\.")[0];
String state2 = p2.split("\\.", -1)[1];
AvatarBlock bl2;
AvatarStateMachineElement st2 = null;
bl2 = as.getBlockWithName(block2);
if (bl2 == null) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Block " + block2 + " in pragma does not exist");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Block " + block2 + " in pragma does not exist");
return null;
}
asm = bl2.getStateMachine();
List<String> id2 = new ArrayList<String>();
for (AvatarActionOnSignal aaos : asm.getAllAOSWithName(state2)) {
if (aaos.getCheckLatency()) {
id2.add((aaos.getSignal().isIn() ? "Receive signal" : "Send signal") + "-" + aaos.getSignal().getName() + ":" + aaos.getID());
st2 = aaos;
}
}
AvatarState astate2 = asm.getStateWithName(state2);
if (astate2 != null) {
if (astate2.getCheckLatency()) {
id2.add("State-" + state2 + ":" + astate2.getID());
st2 = astate2;
}
}
if (id2.size() == 0) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Cannot find checkable state " + block2 + "." + state2 + " in pragma");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Cannot find checkable state " + block2 + "." + state2 + " in pragma");
return null;
}
String equation = pragma.split("\\)")[1];
equation = equation.replaceAll(" ", "");
int symbolType = 0;
int time = 0;
if (equation.substring(0, 1).equals("<")) {
symbolType = AvatarPragmaLatency.lessThan;
try {
time = Integer.valueOf(equation.split("<")[1]);
} catch (Exception e) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Invalid number format in " + _pragma);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Invalid number format");
return null;
}
} else if (equation.substring(0, 1).equals(">")) {
symbolType = AvatarPragmaLatency.greaterThan;
try {
time = Integer.valueOf(equation.split(">")[1]);
} catch (Exception e) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Invalid number format in " + _pragma);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Invalid number format");
return null;
}
} else if (equation.substring(0, 1).equals("?")) {
symbolType = AvatarPragmaLatency.query;
} else {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "no latency expression found in " + _pragma);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("No latency expression found");
return null;
}
return new AvatarPragmaLatency(_pragma, tgc, bl1, st1, bl2, st2, symbolType, time, id1, id2, _pragma);
}
private boolean checkSafetyPragma(String _pragma, List<AvatarBDBlock> _blocks, AvatarSpecification as, TGComponent tgc) {
//Todo: check types
//Todo: handle complex types
_pragma = _pragma.trim();
if (_pragma.compareTo("") == 0) {
// empty pragma
return false;
}
//remove expected result letter from the start if present
if (_pragma.matches("^[TtFf]\\s.*")) {
_pragma = _pragma.substring(2).trim();
}
if (_pragma.contains("=") && !(_pragma.contains("==") || _pragma.contains("<=") || _pragma.contains(">=") || _pragma.contains("!="))) {
//not a query
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Pragma " + _pragma + " cannot be parsed");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " cannot be parsed");
return false;
}
int indexOfWrongLeadsTo = _pragma.indexOf("->");
if (indexOfWrongLeadsTo > 0) {
if (_pragma.charAt(indexOfWrongLeadsTo - 1) != '-') {
//not a query
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Pragma " + _pragma + " uses an invalid operator(->). Maybe you wanted to use \"-->\" instead?");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " cannot be parsed");
return false;
}
}
String header = _pragma.split(" ")[0];
if (_pragma.contains("-->")) {
//will be implies
_pragma = _pragma.replaceAll(" ", "");
String state1 = _pragma.split("-->")[0];
String state2 = _pragma.split("-->")[1];
// System.out.println("checking... " + state1 + " " + state2);
// if (!state1.contains(".") || !state2.contains(".")) {
// TraceManager.addDev("Safety Pragma " + _pragma + " cannot be parsed: missing '.'");
// return false;
// }
if (!statementParser(state1, as, _pragma, tgc)) {
return false;
}
//check the second half of implies
if (!statementParser(state2, as, _pragma, tgc)) {
return false;
}
} else if (header.equals("E[]") || header.equals("E<>") || header.equals("A[]") || header.equals("A<>")) {
String state = _pragma.replace("E[]", "").replace("A[]", "").replace("E<>", "").replace("A<>", "").replaceAll(" ", "");
state = state.trim();
// if (!state.contains("||") && !state.contains("&&")){
if (!statementParser(state, as, _pragma, tgc)) {
return false;
}
} else {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Pragma " + _pragma + " cannot be parsed: wrong or missing CTL header");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " cannot be parsed");
return false;
}
return true;
}
private boolean statementParser(String state, AvatarSpecification as, String _pragma, TGComponent tgc) {
//check the syntax of a single statement
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Safety Pragma " + _pragma + " cannot be parsed");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("UPPAAL Pragma " + _pragma + " cannot be parsed");
return false;
}
state = replaceOperators(state);
int returnVal = statementParserRec(state, as, _pragma, tgc);
if (returnVal == 1) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Safety Pragma " + _pragma + " has invalid return type");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("UPPAAL Pragma " + _pragma + " improperly formatted");
return false;
} else if (returnVal == -1) {
return false;
} else {
return true;
//Divide into simple statements
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
// String[] split = state.split("[|&]+");
// // System.out.println("split " + split[0]);
// if (split.length > 1) {
// boolean validity = true;
// for (String fragment : split) {
// if (fragment.length() > 2) {
// validity = validity && statementParser(fragment, as, _pragma, tgc);
// }
// }
// return validity;
// }
// String number = "[0-9]+";
// String bo = "(?i)true|false";
// if (state.contains("=") || state.contains("<") || state.contains(">")) {
// String state1 = state.split("==|>(=)?|!=|<(=)?")[0];
// String state2 = state.split("==|>(=)?|!=|<(=)?")[1];
// if (!state1.contains(".")) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Pragma " + _pragma + " cannot be parsed: missing '.'");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
//
// TraceManager.addDev("Safety Pragma " + _pragma + " cannot be parsed: missing '.'");
// return false;
// }
//
// String block1 = state1.split("\\.", 2)[0];
// String attr1 = state1.split("\\.", 2)[1];
// if (attr1.contains(".")) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Complex UPPAAL Pragma attribute " + attr1 + " must contain __ and not .");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
//
// TraceManager.addDev("Complex Safety Pragma attribute " + attr1 + " must contain __ and not .");
// return false;
// }
//
// attr1 = attr1.replace(".", "__");
// AvatarType p1Type = AvatarType.UNDEFINED;
// AvatarBlock bl1 = as.getBlockWithName(block1);
// if (bl1 != null) {
// //AvatarStateMachine asm = bl1.getStateMachine();
// if (bl1.getIndexOfAvatarAttributeWithName(attr1) == -1) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " contains invalid attribute name " + attr1);
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid attribute name " + attr1);
// return false;
// } else {
// int ind = bl1.getIndexOfAvatarAttributeWithName(attr1);
// AvatarAttribute attr = bl1.getAttribute(ind);
// p1Type = attr.getType();
// }
// } else {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " contains invalid block name " + block1);
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid block name " + block1);
// return false;
// }
//
//
// if (state2.contains(".")) {
// String block2 = state2.split("\\.", 2)[0];
// String attr2 = state2.split("\\.", 2)[1];
// if (attr2.contains(".")) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Complex UPPAAL Pragma attribute " + attr2 + " must contain __ and not .");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Complex Safety Pragma attribute " + attr2 + " must contain __ and not .");
// return false;
// }
//
// AvatarBlock bl2 = as.getBlockWithName(block2);
// if (bl2 != null) {
// if (bl2.getIndexOfAvatarAttributeWithName(attr2) == -1) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " contains invalid attribute name " + attr2);
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid attribute name " + attr2);
// return false;
// }
// int ind = bl2.getIndexOfAvatarAttributeWithName(attr2);
// AvatarAttribute attr = bl2.getAttribute(ind);
// p1Type = attr.getType();
//
// } else {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Safety Pragma " + _pragma + " contains invalid block name " + block2);
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid block name " + block2);
// return false;
// }
// } else {
// if (state2.matches(number)) {
// if (p1Type != AvatarType.INTEGER) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " has incompatible types");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " has incompatible types");
// return false;
// }
// } else if (state2.matches(bo)) {
// if (p1Type != AvatarType.BOOLEAN) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " has incompatible types");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " has incompatible types");
// return false;
// }
// } else {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " cannot be parsed");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " cannot be parsed");
// return false;
// }
// }
// } else {
// if (!state.contains(".")) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Safety Pragma " + _pragma + " cannot be parsed: missing '.'");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("UPPAAL Pragma " + _pragma + " improperly formatted");
// return false;
// }
// String block1 = state.split("\\.", 2)[0];
// String attr1 = state.split("\\.", 2)[1];
// if (attr1.contains(".")) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Complex Safety Pragma attribute " + attr1 + " must contain __ and not .");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Complex Safety Pragma attribute " + attr1 + " must contain __ and not .");
// return false;
// }
// AvatarBlock bl1 = as.getBlockWithName(block1);
// if (bl1 != null) {
// AvatarStateMachine asm = bl1.getStateMachine();
// if (bl1.getIndexOfAvatarAttributeWithName(attr1) == -1 && asm.getStateWithName(attr1) == null) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " contains invalid attribute or state name " + attr1);
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
//
// TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid attribute or state name " + attr1);
// return false;
// }
//
// int ind = bl1.getIndexOfAvatarAttributeWithName(attr1);
// if (ind != -1) {
// AvatarAttribute attr = bl1.getAttribute(ind);
// if (attr.getType() != AvatarType.BOOLEAN) {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " performs query on non-boolean attribute");
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " performs query on non-boolean attribute");
// return false;
// }
// }
// } else {
// UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " contains invalid block name " + block1);
// ce.setTDiagramPanel(adp.getAvatarBDPanel());
// ce.setTGComponent(tgc);
// addWarning(ce);
// TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid block name " + block1);
// return false;
// }
// }
// return true;
}
private int statementParserRec(String state, AvatarSpecification as, String _pragma, TGComponent tgc) {
//returns -1 for errors, 0 for boolean result type, and 1 for int result type
boolean isNot = false;
boolean isNegated = false;
state = removeExternalBrackets(state);
if (state.startsWith("not(") || state.startsWith("!(")) {
state = removeNot(state);
isNot = true;
}
if (state.startsWith("-(")) {
state = removeNegated(state);
isNegated = true;
}
if (!state.matches("^.+[\\+\\-<>=:;\\$&\\|\\*/].*$")) {
// attribute
if (state.startsWith("-") && isNegated != true) {
state = removeNegated2(state);
isNegated = true;
if (state.equals("true") || state.equals("false")) {
if (isNegated) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Safety Pragma " + _pragma + " negation of a boolean value");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("UPPAAL Pragma " + _pragma + " improperly formatted");
return -1;
}
return 0;
} else if (state.matches("-?\\d+")) {
if (isNot) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Safety Pragma " + _pragma + " not of an integer value");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("UPPAAL Pragma " + _pragma + " improperly formatted");
return -1;
}
return 1;
} else {
if (!state.contains(".")) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Safety Pragma " + _pragma + " cannot be parsed: missing '.'");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("UPPAAL Pragma " + _pragma + " improperly formatted");
return -1;
String block = state.split("\\.", 2)[0];
String attr = state.split("\\.", 2)[1];
if (attr.contains(".")) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Complex Safety Pragma attribute " + attr + " must contain __ and not .");
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Complex Safety Pragma attribute " + attr + " must contain __ and not .");
return -1;
}
AvatarBlock bl = as.getBlockWithName(block);
if (bl != null) {
AvatarStateMachine asm = bl.getStateMachine();
if (bl.getIndexOfAvatarAttributeWithName(attr) == -1 && asm.getStateWithName(attr) == null) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " contains invalid attribute or state name " + attr);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid attribute or state name " + attr);
return -1;
}
int ind = bl.getIndexOfAvatarAttributeWithName(attr);
if (ind != -1) {
AvatarAttribute aa = bl.getAttribute(ind);
if (aa.getType() == AvatarType.BOOLEAN) {
return 0;
} else {
return 1;
}
} else {
//state as boolean condition
return 0;
}
} else {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " contains invalid block name " + block);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " contains invalid block name " + block);
return -1;
}
}
}
int index = getOperatorIndex(state);
if (index == -1) {
UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " cannot parse " + state);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " cannot parse " + state);
return -1;
}
char operator = state.charAt(index);
//split and recur
String leftState = state.substring(0, index).trim();
String rightState = state.substring(index + 1, state.length()).trim();
int optype = getType(operator);
int optypel = statementParserRec(leftState, as, _pragma, tgc);
int optyper = statementParserRec(rightState, as, _pragma, tgc);
if (optypel == -1 || optyper == -1) {
return -1;
}
UICheckingError ce;
switch(optype) {
case -1:
ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " unrecognized " + operator);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " unrecognized operator " + operator);
return -1;
case 1:
if (!(optypel == 1 && optyper == 1)) {
ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " expected integer attributes around " + operator);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " expected integer attributes around " + operator);
return -1;
}
break;
case 0:
if (!(optypel == 0 && optyper == 0)) {
ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " expected boolean attributes around " + operator);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " expected boolean attributes around " + operator);
return -1;
break;
case 3:
if (optypel != optyper) {
ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "UPPAAL Pragma " + _pragma + " has incompatible types around " + operator);
ce.setTDiagramPanel(adp.getAvatarBDPanel());
ce.setTGComponent(tgc);
addWarning(ce);
TraceManager.addDev("Safety Pragma " + _pragma + " has incompatible types around " + operator);
return -1;
}
}
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
private String removeNot(String expression) {
if (expression.startsWith("not(")) {
//not bracket must be closed in the last char
int closingIndex = getClosingBracket(expression, 4);
if (closingIndex == -1) {
return expression;
}
if (closingIndex == expression.length() - 1) {
//not(expression)
return expression.substring(4, expression.length() - 1).trim();
}
} else if (expression.startsWith("!(")) {
int closingIndex = getClosingBracket(expression, 2);
if (closingIndex == -1) {
return expression;
}
if (closingIndex == expression.length() - 1) {
//not(expression)
return expression.substring(2, expression.length() - 1).trim();
}
}
return expression;
}
private String removeNegated(String expression) {
if (expression.startsWith("-(")) {
//not bracket must be closed in the last char
int closingIndex = getClosingBracket(expression, 2);
if (closingIndex == -1) {
return expression;
}
if (closingIndex == expression.length() - 1) {
//-(expression)
return expression.substring(2, expression.length() - 1).trim();
}
}
return expression;
}
private String removeNegated2(String expression) {
if (expression.startsWith("-")) {
return expression.substring(1, expression.length()).trim();
}
return expression;
}
private String removeExternalBrackets(String expression) {
while (expression.startsWith("(") && expression.endsWith(")")) {
if (getClosingBracket(expression, 1) == expression.length() - 1) {
expression = expression.substring(1, expression.length() - 1).trim();
} else {
break;
}
}
return expression;
}
private int getClosingBracket(String expression, int startChar) {
int level = 0;
char a;
for (int i = startChar; i < expression.length(); i++) {
a = expression.charAt(i);
if (a == ')') {
if (level == 0) {
return i;
} else {
level--;
}
} else if (a == '(') {
level++;
}
}
return -1;
}
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
private boolean checkSymbols(String expression) {
if (expression.matches(".*\\b\\|\\b.*") || expression.matches(".*\\b&\\b.*") || expression.contains("\\$") ||
expression.contains(":") || expression.contains(";")) {
return false;
} else {
return true;
}
}
private String replaceOperators(String expression) {
expression = expression.replaceAll("\\|\\|", "\\|").trim();
expression = expression.replaceAll("&&", "&").trim();
expression = expression.replaceAll("==", "=").trim();
expression = expression.replaceAll("!=", "\\$").trim();
expression = expression.replaceAll(">=", ":").trim();
expression = expression.replaceAll("<=", ";").trim();
expression = expression.replaceAll("\\bor\\b", "\\|").trim();
expression = expression.replaceAll("\\band\\b", "&").trim();
return expression;
}
private int getOperatorIndex(String expression) {
int index;
// find the last executed operator
int i, level, priority;
boolean subVar = true; //when a subtraction is only one one variable
char a;
level = 0;
priority = 0;
for (i = 0, index = -1; i < expression.length(); i++) {
a = expression.charAt(i);
switch (a) {
case '|':