From 6913cc5e39e5dd8140dcea43e23394262b788e42 Mon Sep 17 00:00:00 2001 From: miettinen Date: Tue, 4 Feb 2014 13:16:32 +0000 Subject: [PATCH] Unit validation for Sysdyn functions: unit "1" in inputs to not correspond to any anymore (refs #4320). Bug fixes to unit validator (refs #4692). git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28770 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../representation/utils/UnitUtils.java | 82 ++++++++++--------- .../unitParser/UnitCheckingNodeFactory.java | 2 + .../nodes/ComponentReferenceFull.java | 6 +- .../sysdyn/unitParser/nodes/FunctionCall.java | 5 ++ .../nodes/ParenthesisExpression.java | 39 +++++++++ .../sysdyn/unitParser/nodes/Term.java | 7 +- .../org/simantics/sysdyn/utils/Function.java | 7 +- 7 files changed, 100 insertions(+), 48 deletions(-) create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ParenthesisExpression.java diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java index 04369f79..d74b5934 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java @@ -60,9 +60,8 @@ public class UnitUtils { } catch (DatabaseException e) { e.printStackTrace(); } - } catch (ParseException e) { - e.printStackTrace(); + return "Cannot validate units: Syntax error in expression."; } return null; } @@ -94,38 +93,40 @@ public class UnitUtils { public static String matchUnits(ReadGraph graph, SysdynModel model, Configuration configuration, String unit, String expression) { if(unit == null) return "Unit not defined"; + try { - StringReader rightReader = new StringReader(expression); UnitParser rightParser = new UnitParser(rightReader); UnitCheckingNode right = (UnitCheckingNode) rightParser.expr(); rightReader.close(); Set components = findComponents(right); HashMap units = findUnits(graph, model, configuration, components); - - StringReader leftReader = new StringReader(unit); - UnitParser leftParser = new UnitParser(leftReader); - UnitCheckingNode left = (UnitCheckingNode) leftParser.expr(); - leftReader.close(); - + try { - ArrayList functions = Function.getAllBuiltInFunctions(graph); - boolean allowEquivalents = allowEquivalents(graph, model); - UnitResult rightUnits = right.getUnits(units, functions, allowEquivalents); - UnitResult leftUnits = left.getUnits(null, functions, allowEquivalents); - - if(!rightUnits.equals(leftUnits)) - return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); - } catch (UnitCheckingException e) { - return e.getMessage(); - } catch (DatabaseException e) { - e.printStackTrace(); - } - + StringReader leftReader = new StringReader(unit); + UnitParser leftParser = new UnitParser(leftReader); + UnitCheckingNode left = (UnitCheckingNode) leftParser.expr(); + leftReader.close(); + + try { + ArrayList functions = Function.getAllBuiltInFunctions(graph); + boolean allowEquivalents = allowEquivalents(graph, model); + UnitResult rightUnits = right.getUnits(units, functions, allowEquivalents); + UnitResult leftUnits = left.getUnits(null, functions, allowEquivalents); + + if(!rightUnits.equals(leftUnits)) + return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); + } catch (UnitCheckingException e) { + return e.getMessage(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } catch (ParseException e) { + return "Syntax error in defined unit."; + } } catch (ParseException e) { - e.printStackTrace(); + return "Cannot validate units: Syntax error in expression."; } - return null; } @@ -221,29 +222,30 @@ public class UnitUtils { return "No unit defined"; try { - StringReader leftReader = new StringReader(left); UnitParser leftParser = new UnitParser(leftReader); UnitCheckingNode leftNode = (UnitCheckingNode) leftParser.expr(); leftReader.close(); - - StringReader rightReader = new StringReader(right); - UnitParser rightParser = new UnitParser(rightReader); - UnitCheckingNode rightNode = (UnitCheckingNode) rightParser.expr(); - rightReader.close(); - try { - UnitResult leftUnits = leftNode.getUnits(null, functions, allowEquivalents); - UnitResult rightUnits = rightNode.getUnits(null, functions, allowEquivalents); - - if(!rightUnits.equals(leftUnits)) - return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); - } catch (UnitCheckingException e) { - return e.getMessage(); + StringReader rightReader = new StringReader(right); + UnitParser rightParser = new UnitParser(rightReader); + UnitCheckingNode rightNode = (UnitCheckingNode) rightParser.expr(); + rightReader.close(); + + try { + UnitResult leftUnits = leftNode.getUnits(null, functions, allowEquivalents); + UnitResult rightUnits = rightNode.getUnits(null, functions, allowEquivalents); + + if(!rightUnits.equals(leftUnits)) + return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); + } catch (UnitCheckingException e) { + return e.getMessage(); + } + } catch (ParseException e) { + return "Cannot validate units: Syntax error in expression."; } - } catch (ParseException e) { - e.printStackTrace(); + return "Syntax error in defined unit."; } return null; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java index 798659e5..35f22dfb 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java @@ -30,6 +30,7 @@ import org.simantics.sysdyn.unitParser.nodes.FunctionCall; import org.simantics.sysdyn.unitParser.nodes.IfThenElse; import org.simantics.sysdyn.unitParser.nodes.Multiplication; import org.simantics.sysdyn.unitParser.nodes.NamedArguments; +import org.simantics.sysdyn.unitParser.nodes.ParenthesisExpression; import org.simantics.sysdyn.unitParser.nodes.Power; import org.simantics.sysdyn.unitParser.nodes.RelOp; import org.simantics.sysdyn.unitParser.nodes.Relation; @@ -64,6 +65,7 @@ public class UnitCheckingNodeFactory { constructors.put("component_identity", ComponentIdentity.class); constructors.put("condition", Condition.class); constructors.put("for_index", ForIndex.class); + constructors.put("parenthesis_expression", ParenthesisExpression.class); constructors.put("function_call", FunctionCall.class); constructors.put("function_arguments", FunctionArguments.class); constructors.put("named_arguments", NamedArguments.class); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java index 21b01648..fa8e959b 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java @@ -35,16 +35,16 @@ public class ComponentReferenceFull extends UnitCheckingNode { super(id); } - protected UnitResult parseUnits(String units, ArrayList functions, boolean allowEquivalents) { + protected UnitResult parseUnits(String units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { StringReader sr = new StringReader(units); UnitParser parser = new UnitParser(sr); try { UnitCheckingNode node = (UnitCheckingNode) parser.expr(); return node.getUnits(null, functions, allowEquivalents); - } catch (ParseException e) { - e.printStackTrace(); } catch (UnitCheckingException e) { e.printStackTrace(); + } catch (ParseException e) { + throw new UnitCheckingException("Cannot validate units: Syntax error in expression."); } return null; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java index eb07940d..0832b0df 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java @@ -104,6 +104,11 @@ public class FunctionCall extends UnitCheckingNode { private static void addPossibleCorrespondence(HashMap correspondences, Input input, UnitResult argumentUnit) { + if (correspondences.containsKey(input.unit) + && argumentUnit.getUnitType() == UnitType.SCALAR) { + // Don't overwrite if the correspondence already exists and the new argument is scalar. + return; + } if (input.unit.matches("'[a-zA-Z]")) { String fullUnit = argumentUnit.getCleanFullUnit(); if ("".equals(fullUnit)) diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ParenthesisExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ParenthesisExpression.java new file mode 100644 index 00000000..93d28726 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ParenthesisExpression.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Tuomas Miettinen + * + */ +public class ParenthesisExpression extends UnitCheckingNode { + + public ParenthesisExpression(int id) { + super(id); + } + + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException{ + UnitResult result = new UnitResult(allowEquivalents); + // Get the Expression between the parenthesis. + result.appendResult(((UnitCheckingNode)jjtGetChild(1)).getUnits(units, functions, allowEquivalents)); + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java index dfdcc54e..baa4a1ce 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java @@ -69,11 +69,12 @@ public class Term extends UnitCheckingNode { result.addAllDividents(currentUnits.getDividers()); result.addAllDividers(currentUnits.getDividents()); UnitType unitType = currentUnits.getUnitType(); - result.setUnitType(unitType); - if(unitType == UnitType.SCALAR || unitType == UnitType.DMNL) + if(unitType == UnitType.SCALAR || unitType == UnitType.DMNL) { result.append("1"); - else + } else { result.append(currentUnits.getFullUnit()); + result.setUnitType(unitType); + } } } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java index 8fb00e5a..bedd3247 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java @@ -73,10 +73,10 @@ public class Function implements Comparable{ outputReader.close(); result.appendResult(output.getUnits(null, functions, allowEquivalents)); result.setUnitType(UnitType.NORMAL); - } catch (ParseException e) { - e.printStackTrace(); } catch (UnitCheckingException e) { e.printStackTrace(); + } catch (ParseException e) { + throw new UnitCheckingException("Cannot validate units: Syntax error in expression."); } } @@ -541,6 +541,9 @@ public class Function implements Comparable{ } else { // Match input unit to argument unit UnitResult inputUnit = inputList.get(i).getUnitResult(units, this, functions, allowEquivalents, correspondences); + if (inputUnit.getUnitType() == UnitType.SCALAR + && !(argumentUnits.get(i).first.getUnitType() == UnitType.SCALAR)) + return false; // Here we don't accept a "1" replaced with a NORMAL expression, there's "ANY" for that. if (!inputUnit.equals(argumentUnits.get(i).first)) return false; inputMatches.set(i, Boolean.TRUE); -- 2.47.1