import org.simantics.sysdyn.modelImport.model.SketchValve;\r
import org.simantics.sysdyn.modelImport.model.SketchVariable;\r
import org.simantics.sysdyn.modelImport.model.Stock2;\r
+import org.simantics.sysdyn.modelImport.model.Subscript2;\r
import org.simantics.sysdyn.modelImport.model.Valve2;\r
import org.simantics.sysdyn.modelImport.model.Variable2;\r
\r
-/*\r
- * THINGS TO FIX:\r
- * - vensim apparently supports infix operators (:AND: instead of AND()), these must be handled\r
- * - "public" seems to be a keyboard of some sort which causes a problem in certain variable names\r
- * - something is seriously wrong with the sketch import\r
- * - how should models with multiple sketches be handled (this might already work)\r
- * - instead of splitting the file into blocks, the parser could already process the data further which would greatly simplify later methods\r
- */\r
-\r
public class MdlParser2 {\r
\r
private static final String UTF_8 = "{UTF-8}";\r
HashMap<Variable2, Element2> variableToElement = new HashMap<Variable2, Element2>();\r
ArrayList<SketchVariable> shadows = new ArrayList<SketchVariable>();\r
\r
+ for (Subscript2 ss : mdl.getSubscripts()) {\r
+ System.err.println("SUBSCRIPT "+ss.getName()+": "+ss.getValues());\r
+ }\r
+ \r
// add sketch labels and independent elements\r
for (Sketch2 sketch : mdl.getSketches()) {\r
sketch.setEdges();\r
if (line.endsWith("|"))\r
break;\r
} while ((line = reader.readLine()) != null);\r
+ \r
String str = buffer.toString();\r
\r
String cat = MdlUtils.getPossibleCategory(str);\r
mdl.addVariable(var, category);\r
continue;\r
}\r
+ \r
+ Subscript2 subscript = MdlUtils.getPossibleSubscript(str, mdl);\r
+ if (subscript != null) {\r
+ mdl.addSubscript(subscript);\r
+ continue;\r
+ }\r
\r
// if we got this far, the variable could not be parsed\r
System.err.println("unrecognized variable "+str);\r
import org.simantics.sysdyn.modelImport.model.SketchElement;\r
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.Variable2;\r
import org.simantics.sysdyn.modelImport.model.Valve2.TextPosition;\r
\r
private static final String VAR_NAME =\r
"("+VAR_NAME_QUOTED+"|"+VAR_NAME_SIMPLE+")";\r
\r
- private static final String SUBSCRIPT =\r
- "("+VAR_NAME_SIMPLE+")\\[("+VAR_NAME_SIMPLE+"(?:,"+VAR_NAME_SIMPLE+")*)\\]";\r
-\r
- // the first part of the variable string is the variable name \r
- // followed by a delimiter which depends on the type of the declaration\r
private static final String VARIABLE_PATTERN =\r
VAR_NAME+"\\s*=\\s*";\r
- private static final String SUBSCRIPT_PATTERN =\r
- SUBSCRIPT+"\\s*=\\s*";\r
- private static final String VALUE_NEW_PATTERN =\r
- VAR_NAME+"\\s*:\\s*";\r
- private static final String VALUE_EQUALS_PATTERN =\r
- VAR_NAME+"\\s*<->\\s*";\r
- \r
- // the second part is the equation followed by '~'\r
private static final String EQUATION_PATTERN =\r
"([^~]*?(?:"+VAR_NAME_QUOTED+"[^~]*?)*)\\s*~\\s*";\r
- \r
- // the third part is the unit followed by '~'\r
private static final String UNIT_PATTERN =\r
"([^~]*?)\\s*~\\s*";\r
- \r
- // the last part is the description followed by '|'\r
private static final String DESC_PATTERN =\r
"([^\\|]*?)\\s*\\|";\r
-\r
+ \r
public static final String variablePattern = \r
VARIABLE_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
- public static final String subscriptPattern =\r
- SUBSCRIPT_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
- public static final String valueNewPattern = \r
- VALUE_NEW_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
- public static final String valueEqualsPattern = \r
- VALUE_EQUALS_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
\r
private static final int variableName = 1;\r
private static final int variableEquation = 2;\r
private static final int variableUnit = 3;\r
private static final int variableDesc = 4;\r
\r
- private static final String NUMBER = \r
- "-?\\d+(?:.\\d+)?";\r
- \r
public static Variable2 getPossibleVariable(String line, String category) {\r
Matcher matcher = Pattern.compile(variablePattern).matcher(line);\r
\r
return new Variable2(name, expression, unit, range, description);\r
}\r
\r
+ // a subscript variable is a variable that has a different equation\r
+ // depending on the value of the subscript it references\r
+ private static final String VAR_NAME_SUBSCRIPT =\r
+ "("+VAR_NAME_SIMPLE+")\\[("+VAR_NAME_SIMPLE+"(?:,"+VAR_NAME_SIMPLE+")*)\\]";\r
+\r
+ private static final String SUBSCRIPT_VARIABLE_PATTERN =\r
+ VAR_NAME_SUBSCRIPT+"\\s*=\\s*";\r
+\r
+ public static final String subscriptVariablePattern = \r
+ SUBSCRIPT_VARIABLE_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+ \r
+ private static final int subscriptVariableName = 1;\r
+ private static final int subscriptVariableIndices = 2;\r
+ private static final int subscriptVariableEquation = 3;\r
+ 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
+ }\r
+\r
+ private static final String SUBSCRIPT_PATTERN =\r
+ "("+VAR_NAME_SIMPLE+")\\s*(:|<->)\\s*";\r
+ \r
+ public static final String subscriptPattern = \r
+ SUBSCRIPT_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+ \r
+ private static final int subscriptName = 1;\r
+ private static final int subscriptType = 2;\r
+ private static final int subscriptEquation = 3;\r
+ \r
+ public static Subscript2 getPossibleSubscript(String line, MdlModel mdl) {\r
+ Matcher matcher = Pattern.compile(subscriptPattern).matcher(line);\r
+ \r
+ if (!matcher.matches()) {\r
+ return null;\r
+ }\r
+ \r
+ String name = matcher.group(subscriptName);\r
+ boolean equivalence = matcher.group(subscriptType).equals("<->");\r
+ String expression = matcher.group(subscriptEquation);\r
+ \r
+ if (equivalence) {\r
+ return new Subscript2(name, mdl.getSubscript(expression));\r
+ }\r
+ else {\r
+ return new Subscript2(name, expression.split(","));\r
+ }\r
+ }\r
+ \r
private static IExpression parseEquation(String equation) {\r
if (equation.startsWith("INTEG")) {\r
return parseIntegralExpression(equation);\r
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+"|\\?)\\]").matcher(unit);\r
+ Matcher matcher = Pattern.compile("\\[("+NUMBER+"),(("+NUMBER+"),("+NUMBER+")|\\?)\\]").matcher(unit);\r
if (matcher.find()) {\r
- String start = matcher.group(1);\r
- String end = matcher.group(2);\r
- // TODO: and step is?\r
- return new Range(\r
- Double.parseDouble(start), \r
- end.equals("?") ? null : Double.parseDouble(end), \r
- null, \r
- matcher.group());\r
+ Double start, end, step;\r
+ start = Double.parseDouble(matcher.group(1));\r
+ if (matcher.group(2).equals("?")) {\r
+ end = null;\r
+ step = null;\r
+ }\r
+ else {\r
+ end = Double.parseDouble(matcher.group(3));\r
+ step = Double.parseDouble(matcher.group(4));\r
+ }\r
+ return new Range(start, end, step, matcher.group());\r
}\r
else {\r
return null;\r
private static final String POINTS = "(\\d+\\|(?:\\(-?\\d+,-?\\d+\\)\\|)+)";\r
\r
public static final String sketchConnection =\r
- // 1, id, from,to, shape,hid, pol, thick,hasf,dtype,res,color,font,np|plist\r
- "1,"+SAVE+SAVE+SAVE+SAVE+ SKIP+SKIP+SKIP+ SKIP+SKIP+ "0,-1--1--1,.*,"+POINTS;\r
+ // 1, id, from,to, shape,hid, pol, thick,hasf,dtype,res, color,font,np|plist\r
+ "1,"+SAVE+SAVE+SAVE+SAVE+ SKIP+SKIP+SKIP+ SKIP+SKIP+ SKIP+"[^,]*,[^,]*,"+POINTS;\r
\r
// group indices for later use\r
private static final int connectionId = 1;\r
return resource;\r
}\r
\r
- public void setResource(Resource resource) {\r
+ protected void setResource(Resource resource) {\r
this.resource = resource;\r
}\r
\r
--- /dev/null
+package org.simantics.sysdyn.modelImport.model;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class Enumeration2 implements IWriteableObject {\r
+ \r
+ private String name;\r
+ private ArrayList<String> values;\r
+ \r
+ private Resource resource;\r
+ \r
+ public Enumeration2(String name, ArrayList<String> values) {\r
+ this.name = name;\r
+ this.values = values;\r
+ }\r
+ \r
+ public String getName() {\r
+ return name;\r
+ }\r
+ \r
+ public Resource getResource() {\r
+ return resource;\r
+ }\r
+\r
+ @Override\r
+ public void write(WriteGraph graph, Resource parent, WriteContext context)\r
+ throws DatabaseException {\r
+ System.err.println("write enumeration");\r
+ \r
+ resource = null;\r
+ }\r
+\r
+}\r
package org.simantics.sysdyn.modelImport.model;\r
\r
import java.util.ArrayList;\r
+import java.util.Collections;\r
import java.util.HashMap;\r
import java.util.List;\r
\r
private HashMap<String, Variable2> variables;\r
private HashMap<String, ArrayList<Variable2>> groups;\r
\r
+ private HashMap<String, Subscript2> subscripts;\r
+ \r
private ArrayList<Sketch2> sketches;\r
\r
public MdlModel(String name) {\r
this.name = name;\r
this.variables = new HashMap<String, Variable2>();\r
this.groups = new HashMap<String, ArrayList<Variable2>>();\r
+ this.subscripts = new HashMap<String, Subscript2>();\r
this.sketches = new ArrayList<Sketch2>();\r
}\r
\r
return variables.get(name);\r
}\r
\r
+ public List<Variable2> getVariables() {\r
+ return new ArrayList<Variable2>(variables.values());\r
+ }\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
+ public Subscript2 getSubscript(String name) {\r
+ return subscripts.get(name);\r
+ }\r
+ \r
+ public List<Subscript2> getSubscripts() {\r
+ return new ArrayList<Subscript2>(subscripts.values());\r
+ }\r
+ \r
public void addSketch(Sketch2 sketch) {\r
sketches.add(sketch);\r
}\r
package org.simantics.sysdyn.modelImport.model;\r
\r
import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.List;\r
\r
import org.simantics.databoard.Bindings;\r
import org.simantics.db.Resource;\r
private double start, stop, step;\r
\r
// the structure of the model\r
+ private HashMap<String, Enumeration2> enumerations;\r
+ private HashMap<String, ModelVariable> variables;\r
+ \r
private ArrayList<Element2> elements;\r
private ArrayList<Shadow2> shadows;\r
private ArrayList<Connection2> connections;\r
public Model2(String name) {\r
this.name = name;\r
\r
+ enumerations = new HashMap<String, Enumeration2>();\r
+ variables = new HashMap<String, ModelVariable>();\r
+ \r
elements = new ArrayList<Element2>();\r
shadows = new ArrayList<Shadow2>();\r
connections = new ArrayList<Connection2>();\r
public void setStep(double step) {\r
this.step = step;\r
}\r
+ \r
+ public void addEnumeration(Enumeration2 enumeration) {\r
+ if (enumerations.get(enumeration.getName()) != null) {\r
+ System.err.println("enumeration "+enumeration.getName()+" already defined");\r
+ }\r
+ enumerations.put(enumeration.getName(), enumeration);\r
+ }\r
+ \r
+ public Enumeration2 getEnumeration(String name) {\r
+ return enumerations.get(name);\r
+ }\r
+ \r
+ public Collection<Enumeration2> getEnumerations() {\r
+ return enumerations.values();\r
+ }\r
+ \r
+ public void addVariable(ModelVariable variable) {\r
+ if (enumerations.get(variable.getName()) != null) {\r
+ System.err.println("variable "+variable.getName()+" already defined");\r
+ }\r
+ variables.put(variable.getName(), variable);\r
+ \r
+ addElement(variable);\r
+ }\r
+ \r
+ public ModelVariable getVariable(String name) {\r
+ return variables.get(name);\r
+ }\r
+ \r
+ public Collection<ModelVariable> getVariables() {\r
+ return variables.values();\r
+ }\r
\r
public void addElement(Element2 element) {\r
elements.add(element);\r
\r
Resource configuration = graph.getSingleObject(model, sim.HasConfiguration);\r
\r
+ for (Enumeration2 e : getEnumerations()) {\r
+ e.write(graph, configuration, context);\r
+ }\r
+ \r
for (Element2 e : elements) {\r
e.write(graph, configuration, context);\r
}\r
package org.simantics.sysdyn.modelImport.model;\r
\r
+import java.util.List;\r
+\r
import org.simantics.databoard.Bindings;\r
import org.simantics.db.Resource;\r
import org.simantics.db.WriteGraph;\r
protected Range range;\r
protected String unit;\r
protected String description;\r
+ \r
+ protected List<Enumeration2> enumerations;\r
\r
public ModelVariable(double x, double y, double w, double h, String name, IExpression expression, Range range, String unit, String description) {\r
super(x, y, w, h);\r
this.unit = variable.getUnit();\r
this.description = variable.getDescription();\r
}\r
+ \r
+ public String getName() {\r
+ return name;\r
+ }\r
\r
public Resource createVariable(WriteGraph graph, Resource type, Resource parent, WriteContext context) \r
throws DatabaseException {\r
\r
expression.write(graph, variable, context);\r
\r
+ // TODO: write references to enumerations here?\r
+ \r
if (range != null) {\r
range.write(graph, variable, context);\r
}\r
--- /dev/null
+package org.simantics.sysdyn.modelImport.model;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+\r
+public class Subscript2 {\r
+ \r
+ private String name;\r
+ private ArrayList<String> values;\r
+ \r
+ public Subscript2(String name, String...values) {\r
+ this.name = name;\r
+ this.values = new ArrayList<String>(Arrays.asList(values));\r
+ }\r
+ \r
+ public Subscript2(String name, Subscript2 other) {\r
+ this.name = name;\r
+ this.values = other.getValues();\r
+ }\r
+ \r
+ public String getName() {\r
+ return name;\r
+ }\r
+ \r
+ public ArrayList<String> getValues() {\r
+ return values;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.modelImport.model;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class SubscriptExpression implements IExpression {\r
+ \r
+ private ArrayList<SubscriptExpressionElement> elements;\r
+ \r
+ public SubscriptExpression(String[] indices, IExpression expression) {\r
+ elements = new ArrayList<SubscriptExpressionElement>();\r
+ elements.add(new SubscriptExpressionElement(indices, expression));\r
+ }\r
+ \r
+ public List<SubscriptExpressionElement> getElements() {\r
+ return elements;\r
+ }\r
+ \r
+ public void merge(SubscriptExpression other) {\r
+ elements.addAll(other.getElements());\r
+ }\r
+ \r
+ @Override\r
+ public void write(WriteGraph graph, Resource parent, WriteContext context)\r
+ throws DatabaseException {\r
+ System.err.println("write subscript expression");\r
+ }\r
+ \r
+ private class SubscriptExpressionElement {\r
+ \r
+ String[] indices;\r
+ IExpression expression;\r
+ \r
+ public SubscriptExpressionElement(String[] indices, IExpression expression) {\r
+ this.indices = indices;\r
+ this.expression = expression;\r
+ }\r
+ }\r
+\r
+}\r
return description;\r
}\r
\r
+ public void mergeExpression(Variable2 variable) {\r
+ if (expression instanceof SubscriptExpression) {\r
+ ((SubscriptExpression)expression).merge((SubscriptExpression)variable.getExpression());\r
+ }\r
+ }\r
+ \r
}\r