]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Sysdyn unit parser to understand ^ (refs #4547) and bugfix to division (refs #4549).
authormiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 13 Jan 2014 08:14:16 +0000 (08:14 +0000)
committermiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 13 Jan 2014 08:14:16 +0000 (08:14 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28621 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java
org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jjt
org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java

index e3db8e8f4bfceb137489c1076093831a58ae99aa..2526d473669081371463927bd9aa806c4663e49c 100644 (file)
@@ -23,11 +23,13 @@ import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull;
 import org.simantics.sysdyn.unitParser.nodes.Condition;\r
 import org.simantics.sysdyn.unitParser.nodes.Divide;\r
 import org.simantics.sysdyn.unitParser.nodes.Expression;\r
+import org.simantics.sysdyn.unitParser.nodes.Factor;\r
 import org.simantics.sysdyn.unitParser.nodes.ForIndex;\r
 import org.simantics.sysdyn.unitParser.nodes.FunctionArguments;\r
 import org.simantics.sysdyn.unitParser.nodes.FunctionCall;\r
 import org.simantics.sysdyn.unitParser.nodes.IfThenElse;\r
 import org.simantics.sysdyn.unitParser.nodes.Multiplication;\r
+import org.simantics.sysdyn.unitParser.nodes.Power;\r
 import org.simantics.sysdyn.unitParser.nodes.RelOp;\r
 import org.simantics.sysdyn.unitParser.nodes.Relation;\r
 import org.simantics.sysdyn.unitParser.nodes.Term;\r
@@ -40,6 +42,7 @@ public class UnitCheckingNodeFactory {
     static {\r
         constructors.put("relation", Relation.class);\r
         constructors.put("term", Term.class);\r
+        constructors.put("factor", Factor.class);\r
         constructors.put("arithmetic_expression", Arithmetic.class);\r
         constructors.put("ifthenelse", IfThenElse.class);\r
         constructors.put("array_definition", ArrayDefinition.class);\r
@@ -48,6 +51,7 @@ public class UnitCheckingNodeFactory {
         constructors.put("value", Value.class);\r
 \r
 \r
+        constructors.put("power", Power.class);\r
         constructors.put("divide", Divide.class);\r
         constructors.put("multiplication", Multiplication.class);\r
         constructors.put("add_op", AddOp.class);\r
index 8c04b8d2f972f80d9ffef915c7da33ea9aa8db76..60acd1a6d63ef19f81af24ef6355521bd627ed7e 100644 (file)
@@ -132,14 +132,18 @@ void add_op() : {
 \r
 void term() : {\r
 } {\r
-    factor() ( (multiplication() | divide()) factor() )*\r
+    ( LOOKAHEAD(primary() power()) factor() | primary() ) ( (multiplication() | divide()) ( LOOKAHEAD(primary() power()) factor() | primary()) )*\r
 }\r
 \r
 void factor() : {\r
 } {\r
-       primary() ( "^" primary() | ".^" primary() )?\r
+       primary() power() primary()\r
 }\r
 \r
+void power() : {\r
+} {\r
+       "^" | ".^"\r
+}\r  \r
 void multiplication() : {\r
 } {\r
     "*" | ".*"\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java
new file mode 100644 (file)
index 0000000..6e5b1fe
--- /dev/null
@@ -0,0 +1,118 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.Token;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Tuomas Miettinen\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Factor extends UnitCheckingNode {\r
+\r
+    public Factor(int id) {\r
+        super(id);\r
+    }\r
+    \r
+    @Override\r
+    public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+        UnitResult result = new UnitResult();\r
+        \r
+        UnitCheckingNode current = null;\r
+        UnitCheckingNode operator = null;\r
+        UnitCheckingNode base = null;\r
+        \r
+        for(int i = 0; i < jjtGetNumChildren(); i++) {\r
+            current = ((UnitCheckingNode)jjtGetChild(i));\r
+            UnitResult currentUnits = current.getUnits(units);\r
+\r
+            if(currentUnits.getUnitType() == UnitType.ANY) {\r
+                result = new UnitResult();\r
+                result.setUnitType(UnitType.ANY);\r
+                return result;\r
+            } else if(currentUnits.getUnitType() == UnitType.OPERATOR) {\r
+                continue;\r
+            } else if(base == null) {\r
+                base = current;\r
+                continue;\r
+            } else {\r
+                operator = ((UnitCheckingNode)jjtGetChild(i-1));\r
+\r
+                if(operator instanceof Power) {\r
+                    UnitType unitType = currentUnits.getUnitType();\r
+                    if(unitType == UnitType.SCALAR) {\r
+                       int exponent;\r
+                       UnitResult baseUnits = base.getUnits(units);\r
+                       try {\r
+                               exponent = Integer.valueOf(currentUnits.getFullUnit());\r
+                       } catch (NumberFormatException e) {\r
+                               exponent = 1; /* It's a bit of a corner case if someone want's to use\r
+                               an arithmetic expression other than a constant in the exponent. */\r
+                       }\r
+                       \r
+                       if (exponent < 0) {\r
+                               for (int j = 0; j > exponent; --j) {\r
+                                       // Negative exponent turns the base number around.\r
+                                       result.addAllDividers(baseUnits.getDividents());\r
+                                       result.addAllDividents(baseUnits.getDividers());\r
+                                       result.append(operator.printNode());\r
+                                       result.append(baseUnits.getFullUnit());\r
+                               }\r
+                               result.setUnitType(baseUnits.getUnitType());\r
+                       } else if (exponent > 0) {\r
+                               result.appendResult(baseUnits);\r
+                            for (int j = 1; j < exponent; ++j) {\r
+                                       result.addAllDividents(baseUnits.getDividents());\r
+                                       result.addAllDividers(baseUnits.getDividers());\r
+                                       result.append(operator.printNode());\r
+                                       result.append(baseUnits.getFullUnit());\r
+                               }\r
+                               result.setUnitType(baseUnits.getUnitType());\r
+                       } // 0 is a corner case\r
+                    }\r
+                }\r
+            }\r
+        }\r
+//        System.out.println("Term: " + printNode() + " [" + result.getFullUnit() + " : " + result.getUnitType() + "]");\r
+        return result;\r
+    }\r
+    \r
+    @Override\r
+    public String printNode() {\r
+        StringBuilder sb = new StringBuilder();\r
+        Token token = jjtGetFirstToken();\r
+        sb.append(token.image);\r
+\r
+        Token prevToken = null;\r
+        while(token != null && !token.equals(jjtGetLastToken())) {\r
+            prevToken = token;\r
+            token = token.next;\r
+            if(!token.image.equals("[") \r
+                    && !token.image.equals("]")\r
+                    && !prevToken.image.equals("[")\r
+                    && !prevToken.image.equals("]")\r
+                    && !token.image.equals(".")\r
+                    && !prevToken.image.equals("."))\r
+                sb.append(" ");\r
+            sb.append(token.image);\r
+        }\r
+        return sb.toString();\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java
new file mode 100644 (file)
index 0000000..1479946
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class Power extends UnitCheckingNode {\r
+\r
+    public Power(int id) {\r
+        super(id);\r
+    }\r
+    \r
+    @Override\r
+    public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+        UnitResult result = super.getUnits(units);\r
+        result.setUnitType(UnitType.OPERATOR);\r
+        return result;\r
+    }\r
+\r
+}\r
index d8b454e67f6ef8f7bbc84de83aa3f266684b8fbb..77f9c4093f80be2f776237c8d8ebf2383d271a9f 100644 (file)
@@ -62,9 +62,8 @@ public class Term extends UnitCheckingNode {
                     }\r
                 } else if(operator instanceof Divide) {\r
                     result.append(operator.printNode());\r
-                    result.addAllDividers(currentUnits.getDividers());\r
+                    result.addAllDividents(currentUnits.getDividers());\r
                     result.addAllDividers(currentUnits.getDividents());\r
-                    \r
                     UnitType unitType = currentUnits.getUnitType();\r
                     result.setUnitType(unitType);\r
                     if(unitType == UnitType.SCALAR || unitType == UnitType.DMNL)\r