]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Update vensim import, parser now supports most elements commonly found in .mdl files
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 1 Apr 2014 11:09:30 +0000 (11:09 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 1 Apr 2014 11:09:30 +0000 (11:09 +0000)
refs #2924

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/branches/dev-jkauttio@29230 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser2.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtils.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/LookupExpression.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/MdlModel.java

index 7b0b1cd14dc8af24e16ce4f4748a35c0509c0a0e..2cd600b305f4dde6b7253ddef533182d8e5d3d68 100644 (file)
@@ -33,6 +33,7 @@ import org.simantics.sysdyn.modelImport.model.Sketch2;
 import org.simantics.sysdyn.modelImport.model.SketchComment;\r
 import org.simantics.sysdyn.modelImport.model.SketchConnection;\r
 import org.simantics.sysdyn.modelImport.model.SketchElement;\r
+import org.simantics.sysdyn.modelImport.model.SketchObject;\r
 import org.simantics.sysdyn.modelImport.model.SketchValve;\r
 import org.simantics.sysdyn.modelImport.model.SketchVariable;\r
 import org.simantics.sysdyn.modelImport.model.Stock2;\r
@@ -221,6 +222,7 @@ public class MdlParser2 {
                                continue;\r
 \r
                        StringBuilder buffer = new StringBuilder();\r
+                       \r
                        do {\r
                                if (line.endsWith("\\"))\r
                                        buffer.append(line.substring(0, line.length()-1));\r
@@ -245,6 +247,30 @@ public class MdlParser2 {
                                continue;\r
                        }\r
                        \r
+                       Variable2 ss = MdlUtils.getPossibleSubscriptVariable(str, category, mdl);\r
+                       if (ss != null) {\r
+                               Variable2 original = mdl.getVariable(ss.getName());\r
+                               if (original == null) {\r
+                                       mdl.addVariable(ss, category);\r
+                               }\r
+                               else {\r
+                                       original.mergeExpression(ss);\r
+                               }\r
+                               continue;\r
+                       }\r
+                       \r
+                       Variable2 lu = MdlUtils.getPossibleLookUpVariable(str, category);\r
+                       if (lu != null) {\r
+                               System.err.println("found lookup variable "+lu.getName());\r
+                               continue;\r
+                       }\r
+                       \r
+                       Variable2 plain = MdlUtils.getPossibleNoExpressionVariable(str);\r
+                       if (plain != null) {\r
+                               System.err.println("found plain variable "+plain.getName());\r
+                               continue;\r
+                       }\r
+                       \r
                        Subscript2 subscript = MdlUtils.getPossibleSubscript(str, mdl);\r
                        if (subscript != null) {\r
                                mdl.addSubscript(subscript);\r
@@ -266,61 +292,50 @@ public class MdlParser2 {
                        if (line.isEmpty())\r
                                continue;\r
                        \r
+                       SketchObject so;\r
+                       \r
                        if (line.startsWith(SKETCH_START)) {\r
                                sketch = new Sketch2();\r
                                mdl.addSketch(sketch);\r
-                               continue;\r
                        }\r
                        else if (line.startsWith(SKETCH_VERSION)) {\r
                                // version declaration, nothing to do here\r
-                               continue;\r
                        }\r
                        else if (line.startsWith("*")) {\r
                                sketch.setName(line.substring(1));\r
-                               continue;\r
                        }\r
                        else if (line.startsWith("$")) {\r
                                // font declaration, nothing to do here\r
-                               continue;\r
                        }\r
-\r
-                       SketchConnection connection = MdlUtils.getPossibleSketchConnection(line);\r
-                       if (connection != null) {\r
-                               sketch.addConnection(connection);\r
-                               continue;\r
+                       else if ((so = MdlUtils.getPossibleSketchConnection(line)) != null) {\r
+                               sketch.addConnection((SketchConnection)so);\r
                        }\r
-\r
-                       SketchVariable variable = MdlUtils.getPossibleSketchVariable(line, mdl);\r
-                       if (variable != null) {\r
-                               sketch.addVariable(variable);\r
-                               continue;\r
+                       else if ((so = MdlUtils.getPossibleSketchVariable(line, mdl)) != null) {\r
+                               sketch.addVariable((SketchVariable)so);\r
                        }\r
-\r
-                       SketchValve valve = MdlUtils.getPossibleSketchValve(line);\r
-                       if (valve != null) {\r
+                       else if ((so = MdlUtils.getPossibleSketchValve(line)) != null) {\r
+                               SketchValve valve = (SketchValve)so;\r
                                // the next row after a valve should always the variable associated with the valve\r
                                SketchVariable attached = MdlUtils.getPossibleSketchVariable(reader.readLine(), mdl);\r
                                if (attached == null || !attached.isAttached()) {\r
                                        System.err.println("attached variable not found for valve");\r
-                                       continue;\r
                                }\r
                                valve.setAttachedVariable(attached);\r
-                               sketch.addValve(valve);\r
+                               sketch.addValve((SketchValve)valve);\r
                                sketch.addVariable(attached);\r
-                               continue;\r
                        }\r
-\r
-                       SketchComment comment = MdlUtils.getPossibleSketchComment(line);\r
-                       if (comment != null) {\r
+                       else if ((so = MdlUtils.getPossibleSketchComment(line)) != null) {\r
+                               SketchComment comment = (SketchComment)so;\r
                                if (comment.hasTextLine()) {\r
                                        comment.setText(reader.readLine());\r
                                }\r
                                sketch.addComment(comment);\r
-                               continue;\r
                        }\r
-\r
-                       // if we got this far, the element could not be parsed\r
-                       System.err.println("unrecognized element "+line);\r
+                       else {\r
+                               // if we got this far, the element could not be parsed\r
+                               System.err.println("unrecognized element "+line);\r
+                       }\r
+                       \r
                } while ((line = reader.readLine()) != null && !line.startsWith(SKETCH_END));\r
 \r
                return line;\r
index d825fc3ef63b3379d36237799b88d0e8231577c9..d9eb5455573c44985c0ff4c3f33a950c57aa04bf 100644 (file)
@@ -6,6 +6,7 @@ import java.util.regex.Pattern;
 import org.simantics.sysdyn.modelImport.model.DelayExpression;\r
 import org.simantics.sysdyn.modelImport.model.IExpression;\r
 import org.simantics.sysdyn.modelImport.model.IntegralExpression;\r
+import org.simantics.sysdyn.modelImport.model.LookupExpression;\r
 import org.simantics.sysdyn.modelImport.model.MdlModel;\r
 import org.simantics.sysdyn.modelImport.model.NormalExpression;\r
 import org.simantics.sysdyn.modelImport.model.Range;\r
@@ -15,6 +16,7 @@ import org.simantics.sysdyn.modelImport.model.SketchElement;
 import org.simantics.sysdyn.modelImport.model.SketchValve;\r
 import org.simantics.sysdyn.modelImport.model.SketchVariable;\r
 import org.simantics.sysdyn.modelImport.model.Subscript2;\r
+import org.simantics.sysdyn.modelImport.model.SubscriptExpression;\r
 import org.simantics.sysdyn.modelImport.model.Variable2;\r
 import org.simantics.sysdyn.modelImport.model.Valve2.TextPosition;\r
 \r
@@ -27,6 +29,9 @@ public class MdlUtils {
        public enum CommentIcon {\r
                CLOUD, OTHER\r
        }\r
+       \r
+       private static final String NUMBER = \r
+                       "-?\\d+(?:.\\d+)?";\r
 \r
        // most of this data is from the documentation of the .mdl file format \r
        // available in http://www.vensim.com/documentation/24305.htm\r
@@ -95,8 +100,105 @@ public class MdlUtils {
        private static final int subscriptVariableUnit = 4;\r
        private static final int subscriptVariableDesc = 5;\r
        \r
-       public static Variable2 getPossibleSubscriptVariable(String line, String category) {\r
-               return null;\r
+       public static Variable2 getPossibleSubscriptVariable(String line, String category, MdlModel mdl) {\r
+               Matcher matcher = Pattern.compile(subscriptVariablePattern).matcher(line);\r
+               \r
+               if (!matcher.matches()) {\r
+                       return null;\r
+               }\r
+               \r
+               String name = matcher.group(subscriptVariableName);\r
+               // TODO: find out if subscript indices can contain commas and update\r
+               // this method accordingly\r
+               String[] indices = matcher.group(subscriptVariableIndices).split(",");\r
+               IExpression expression = parseEquation(matcher.group(subscriptVariableEquation));\r
+               SubscriptExpression e = new SubscriptExpression(indices, expression);\r
+               \r
+               String unit = matcher.group(subscriptVariableUnit);\r
+               Range range = parseRange(unit);\r
+               if (range != null) {\r
+                       unit = unit.substring(0, unit.indexOf(range.originalString())).trim();\r
+               }\r
+               String description = matcher.group(subscriptVariableDesc);\r
+               \r
+               return new Variable2(name, e, unit, range, description);\r
+       }\r
+       \r
+       private static final String LOOKUP_NAME =\r
+                       "([A-Za-z](?: *\\w+)*)";\r
+       private static final String LOOKUP_RANGE =\r
+                       "\\[\\(("+NUMBER+"),("+NUMBER+")\\)-\\(("+NUMBER+"),("+NUMBER+")\\)\\]";\r
+       private static final String LOOKUP_POINTS =\r
+                       "(\\("+NUMBER+","+NUMBER+"\\)(?:,\\("+NUMBER+","+NUMBER+"\\))*)";\r
+       \r
+       private static final String LOOKUP_PATTERN =\r
+                       LOOKUP_NAME+"\\s*\\(\\s*"+LOOKUP_RANGE+","+LOOKUP_POINTS+"\\s*\\)\\s*~\\s*";\r
+\r
+       public static final String lookupVariablePattern = \r
+                       LOOKUP_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+       \r
+       private static final int lookupVariableName = 1;\r
+       private static final int lookupVariableRangeXMin = 2;\r
+       private static final int lookupVariableRangeYMin = 3;\r
+       private static final int lookupVariableRangeXMax = 4;\r
+       private static final int lookupVariableRangeYMax = 5;\r
+       private static final int lookupVariablePoints = 6;\r
+       private static final int lookupVariableUnit = 7;\r
+       private static final int lookupVariableDesc = 8;\r
+       \r
+       public static Variable2 getPossibleLookUpVariable(String line, String category) {\r
+               Matcher matcher = Pattern.compile(lookupVariablePattern).matcher(line);\r
+               \r
+               if (!matcher.matches()) {\r
+                       return null;\r
+               }\r
+               \r
+               String name = matcher.group(lookupVariableName);\r
+               double xMin = Double.parseDouble(matcher.group(lookupVariableRangeXMin));\r
+               double xMax = Double.parseDouble(matcher.group(lookupVariableRangeYMin));\r
+               double yMin = Double.parseDouble(matcher.group(lookupVariableRangeXMax));\r
+               double yMax = Double.parseDouble(matcher.group(lookupVariableRangeYMax));\r
+               String points = matcher.group(lookupVariablePoints);\r
+               \r
+               LookupExpression e = new LookupExpression(xMin, yMin, xMax, yMax, points);\r
+               \r
+               String unit = matcher.group(lookupVariableUnit);\r
+               Range range = parseRange(unit);\r
+               if (range != null) {\r
+                       unit = unit.substring(0, unit.indexOf(range.originalString())).trim();\r
+               }\r
+               String description = matcher.group(lookupVariableDesc);\r
+               \r
+               return new Variable2(name, e, unit, range, description);\r
+       }\r
+       \r
+       public static final String NO_EXP_PATTERN = \r
+                       VAR_NAME+"\\s*~\\s*";\r
+       \r
+       public static final String noExpressionVariablePattern = \r
+                       NO_EXP_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+       \r
+       private static final int noExpVariableName = 1;\r
+       private static final int noExpVariableUnit = 2;\r
+       private static final int noExpVariableDesc = 3;\r
+       \r
+       public static Variable2 getPossibleNoExpressionVariable(String line) {\r
+               Matcher matcher = Pattern.compile(noExpressionVariablePattern).matcher(line);\r
+               \r
+               if (!matcher.matches()) {\r
+                       return null;\r
+               }\r
+               \r
+               String name = normalize(matcher.group(noExpVariableName));\r
+               \r
+               String unit = matcher.group(noExpVariableUnit);\r
+               Range range = parseRange(unit);\r
+               if (range != null) {\r
+                       unit = unit.substring(0, unit.indexOf(range.originalString())).trim();\r
+               }\r
+               String description = matcher.group(noExpVariableDesc);\r
+               \r
+               return new Variable2(name, null, unit, range, description);\r
        }\r
 \r
        private static final String SUBSCRIPT_PATTERN =\r
@@ -163,9 +265,6 @@ public class MdlUtils {
                return new NormalExpression(normalize(equation));\r
        }\r
        \r
-       private static final String NUMBER = \r
-                       "-?\\d+(?:.\\d+)?";\r
-       \r
        private static Range parseRange(String unit) {\r
                Matcher matcher = Pattern.compile("\\[("+NUMBER+"),(("+NUMBER+"),("+NUMBER+")|\\?)\\]").matcher(unit);\r
                if (matcher.find()) {\r
@@ -186,7 +285,7 @@ public class MdlUtils {
                }\r
        }\r
        \r
-       private static final String categoryPattern = "\\*{56}\\s+\\.(\\S+)\\s+\\*{56}.*";\r
+       private static final String categoryPattern = "\\*{56}\\s*\\.(\\S+)\\s*\\*{56}.*";\r
        \r
        public static String getPossibleCategory(String line) {\r
                Matcher matcher = Pattern.compile(categoryPattern).matcher(line);\r
index 1ee58312c6a7d0657cc931285d1083561070c27f..cc2052f7290250da0c9b08de37ec73a3a259d4bb 100644 (file)
@@ -5,6 +5,20 @@ import org.simantics.db.WriteGraph;
 import org.simantics.db.exception.DatabaseException;\r
 \r
 public class LookupExpression implements IExpression {\r
+       \r
+       private double xMin;\r
+       private double yMin;\r
+       private double xMax;\r
+       private double yMax;\r
+       private String points;\r
+       \r
+       public LookupExpression(double xMin, double yMin, double xMax, double yMax, String points) {\r
+               this.xMin = xMin;\r
+               this.yMin = yMin;\r
+               this.xMax = xMax;\r
+               this.yMax = yMax;\r
+               this.points = points;\r
+       }\r
 \r
        @Override\r
        public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException {\r
index 43f8fa64fd221cbe685d01eaf40ee1aa1794042f..7f211623beff22175aa937ca8c63bb873ccdc919 100644 (file)
@@ -48,7 +48,6 @@ public class MdlModel {
        }\r
        \r
        public void addSubscript(Subscript2 subscript) {\r
-               System.err.println("SUBSCRIPT "+subscript.getName()+": "+subscript.getValues());\r
                subscripts.put(subscript.getName(), subscript);\r
        }\r
        \r