private char[] alphaNumericCharacters = {\r
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö',\r
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö',\r
- '1','2','3','4','5','6','7','8','9','0','.','_'};\r
+ '1','2','3','4','5','6','7','8','9','0','.'};\r
\r
/**\r
* Create a new RVIModifier and attach a content proposal support to control\r
// If focus is on model browser, default search in all models, allow also current diagram.\r
FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.ALL_MODELS, true);\r
dialog.open();\r
- } else if (d != null && d instanceof IDiagram) {\r
+ } else if (d != null && d instanceof IDiagram && workbenchPart instanceof DiagramEditor) {\r
// If focus is on diagram editor, default search in current diagram, allow also all models.\r
FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.CURRENT_DIAGRAM, true);\r
dialog.open();\r
\r
@Override\r
public String isValid(String label) {\r
- if(!new VariableNameValidator().isValidModelica(label))\r
+ if(!new VariableNameValidator().isValidModelica(label, true))\r
return "Not valid";\r
return null;\r
}\r
private final char[] allowedCharacters = {\r
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö',\r
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö',\r
- '1','2','3','4','5','6','7','8','9','0','.','_','(',')'};\r
+ '1','2','3','4','5','6','7','8','9','0','.','(',')'};\r
\r
private final String allowedConnectedCharactersRegExp = "[\\Q({[:;,<=>+-*/^\\E]";\r
\r
\r
final Token comment = new Token(new TextAttribute(resourceManager.createColor(new RGB(63, 127, 95))));\r
\r
-\r
WordRule reservedWord = new WordRule(new IWordDetector() { \r
@Override\r
public boolean isWordStart(char c) {\r
private char[] alphaNumericCharacters = {\r
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö',\r
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö',\r
- '1','2','3','4','5','6','7','8','9','0','.','_'};\r
+ '1','2','3','4','5','6','7','8','9','0','.'};\r
\r
\r
public VariableNameModifier(Control control, WidgetSupport support, String variableNameRelationUri, String indexUri) {\r
import org.simantics.db.WriteGraph;\r
import org.simantics.db.common.utils.NameUtils;\r
import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ServiceException;\r
import org.simantics.db.request.Read;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
if(nameIsTaken(graph, resource, name)) return false;\r
\r
// Decline names which are against Modelica naming rules\r
- if(!isValidModelica(name)) return false;\r
+ boolean allowSpaces = doesResourceAllowSpacedName(graph, resource);\r
+ if(!isValidModelica(name, allowSpaces)) return false;\r
return true;\r
}\r
\r
/**\r
+ * Determine whether a Sysdyn Variable can have whitespace in its name (based on its type).\r
+ * @param graph\r
+ * @param resource Resource of the variable\r
+ * @return true iff spaces are allowed in the name\r
+ */\r
+ protected boolean doesResourceAllowSpacedName(ReadGraph graph,\r
+ Resource resource) {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ SpreadsheetResource sheet = SpreadsheetResource.getInstance(graph);\r
+ try {\r
+ // Function, FunctionLibrary, and SharedFunctionLibrary are not\r
+ // allowed to have whitespace.\r
+ if (graph.isInstanceOf(resource, sr.Variable)\r
+// || graph.isInstanceOf(resource, sr.Module)\r
+// || graph.isInstanceOf(resource, sr.ModuleType)\r
+ || graph.isInstanceOf(resource, sr.Enumeration)\r
+ || graph.isInstanceOf(resource, sr.EnumerationIndex)\r
+ || graph.isInstanceOf(resource, sheet.Spreadsheet)\r
+ || graph.isInstanceOf(resource, sr.SysdynModel)) {\r
+ return true;\r
+ }\r
+ } catch (ServiceException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
* Checks that the syntax of the given name is valid and there \r
* are no other variables that have the same name in the configuration\r
* \r
* @param name name that is validated\r
* @return true iff the syntax of the name is valid\r
*/\r
- public boolean isValidModelica(String name) {\r
+ public boolean isValidModelica(String name, boolean allowSpaces) {\r
String lowerCase = name.toLowerCase();\r
- Pattern p = Pattern.compile("[a-zA-Z][a-zA-Z0-9]*+");\r
+ String pattern = "[a-zA-Z][a-zA-Z0-9]*" + (allowSpaces ? "( [a-zA-Z][a-zA-Z0-9]*)*" : "");\r
+ Pattern p = Pattern.compile(pattern);\r
Matcher m = p.matcher(lowerCase);\r
- if (!m.matches() || ModelicaSourceViewerConfiguration.keywords.contains(name))\r
+ if (!m.matches()) {\r
return false;\r
- else\r
- return true;\r
+ } else {\r
+ String[] splitNames= name.split("\\s+");\r
+ for (String splitName : splitNames) {\r
+ // Do not allow Modelica keywords to be a part of a whitespaced name\r
+ if (ModelicaSourceViewerConfiguration.keywords.contains(splitName)) {\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+ return true;\r
}\r
\r
/**\r
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod27">component_clause</A></TD>
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod13">type_prefix</A> ) <A HREF="#prod29">type_specifier</A> ( <A HREF="#prod9">array_subscripts</A> )? <A HREF="#prod30">component_list</A></TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod13">type_prefix</A> ) ( <A HREF="#prod29">type_specifier</A> ) ( <A HREF="#prod9">array_subscripts</A> )? ( <A HREF="#prod30">component_list</A> )</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod13">type_prefix</A></TD>
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod35">modification</A></TD>
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod10">class_modification</A> ( "=" <A HREF="#prod34">expression</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"=" <A HREF="#prod34">expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>":=" <A HREF="#prod34">expression</A></TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod10">class_modification</A> ( "=" <A HREF="#prod34">expression</A> )? | "=" <A HREF="#prod34">expression</A> | ":=" <A HREF="#prod34">expression</A> )</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod10">class_modification</A></TD>
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"(" <A HREF="#prod52">output_expression_list</A> ")"</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"(" <A HREF="#prod34">expression</A> ")"</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
import java.util.ArrayList;\r
import java.util.HashMap;\r
\r
-\r
+@SuppressWarnings({"unused", "serial"})\r
public class ExpressionParser {\r
\r
public class ForRange {\r public Token start;\r
| "end"\r
}\r
\r
+Token ident() : {\r
+ Token concatToken = null;\r
+ Token continuationToken = null;\r
+ String fullStr = null;\r
+} {\r
+ <IDENT>\r
+ { concatToken = token; }\r
+ ( continuationToken = ident()\r
+ {\r
+ fullStr = new String("");\r
+ // Replace whitespace sequence with a single space character.\r
+ fullStr += concatToken.image + " " + continuationToken.image;\r
+ \r
+ Token tempToken = new Token(concatToken.kind, fullStr);\r
+ tempToken.beginLine = concatToken.beginLine;\r
+ tempToken.beginColumn = concatToken.beginColumn;\r
+ tempToken.endLine = token.endLine;\r
+ tempToken.endColumn = token.endColumn;\r
+ concatToken = tempToken;\r
+ System.out.println(concatToken.image);\r
+ }\r
+ )?\r
+ {\r return concatToken;\r
+ }\r}\r\r
void name() : {\r
+ Token identToken = null;\r
} {\r
- <IDENT>\r {\r if (functionCall == null)\r
- functionCall = token.image;\r
+ identToken = ident()\r
+ {\r if (functionCall == null)\r
+ functionCall = identToken.image;\r
else\r
- functionCall += "." + token.image;\r
+ functionCall += "." + identToken.image;\r
}\r
( "." name() )?\r
}\r
\r
void component_reference(String prevToken) : {\r
+ Token identToken = null;\r
} {\r
- //IDENT [ array_subscripts ] [ "." component_reference ]\r
- <IDENT> {\r
- String name = token.image; \r
+ //IDENT [ array_subscripts ] [ "." component_reference ]\r
+ identToken = ident()\r
+ {\r
+ String name = identToken.image;\r
// forIndex == true and prevToken != null => this is the second part of an enumeration in for-index\r
if(forIndex == true) {\r if(prevToken != null) {\r
if(enumerationReferences.get(prevToken) == null) {\r enumerationReferences.put(prevToken, new ArrayList<Token>());\r
}\r
List<Token> list = enumerationReferences.get(prevToken);\r
- list.add(token); \r
+ list.add(identToken); \r
\r
// forIndex == true and prevToken == null => this is the enumeration in for-index\r
} else {\r
enumerationReferences.put(name, new ArrayList<Token>());\r
}\r
List<Token> list = enumerationReferences.get(name);\r
- list.add(token);\r
+ list.add(identToken);\r
}\r
} else {\r
if(prevToken != null)\r
references.put(name, new ArrayList<Token>());\r
}\r
List<Token> list = references.get(name);\r
- list.add(token);\r
+ list.add(identToken);\r
\r
if(functionCall != null) {\r
if(!functionCallReferences.containsKey(functionCall))\r
functionCallReferences.put(functionCall, new ArrayList<Token>());\r
List<Token> functionReferencelist = getFunctionCallReferences().get(functionCall);\r
- functionReferencelist.add(token);\r }\r
+ functionReferencelist.add(identToken);\r }\r
}\r
\r
}\r
\r
- ( array_subscripts() )? ( "." component_reference(name) )?\r
+ ( array_subscripts(identToken) )? ( "." component_reference(name) )?\r
}\r
\r
void function_call_args() : {\r
} {\r
//expression [ "," function_arguments | for for_indices ]\r
//| named_arguments\r
- LOOKAHEAD(2) named_argument() ( "," function_arguments() )?\r
+ LOOKAHEAD(named_argument()) named_argument() ( "," function_arguments() )?\r
| expression() ( "," function_arguments() | "for" for_indices() )?\r
\r
}\r
}\r
\r
void for_index() : {\r
+ Token identToken = null;\r
} {\r
//IDENT [ in expression ]\r
- <IDENT>\r {\r
- forIndices.put(token, currentRange);\r
+ identToken = ident()\r
+ {\r
+ forIndices.put(identToken, currentRange);\r
forIndex = true;\r }\r
( "in"\r {\r
ForRange forRange = new ForRange();\r
\r
void named_argument() : {\r
} { \r
- <IDENT> "=" expression()\r
+ ident() "=" expression()\r
}\r
\r
void output_expression_list() : {\r
expression() ( "," expression() )*\r
}\r
\r
-void array_subscripts() : {\r if(ranges.get(token.image) == null) {\r
- ranges.put(token.image, new ArrayList<List<Token>>());\r
+void array_subscripts(Token prevToken) : {\r if(ranges.get(prevToken.image) == null) {\r
+ ranges.put(prevToken.image, new ArrayList<List<Token>>());\r
}\r
- List<List<Token>> rangesList = ranges.get(token.image);\r
+ List<List<Token>> rangesList = ranges.get(prevToken.image);\r
currentRange = new ArrayList<Token>(); \r
} {\r
"[" subscript(currentRange) ( "," subscript(currentRange) )* "]"\r
}\r
\r
void rangeIndex(Token rangeToken, boolean first) : {\r
+ Token identToken = null;\r
if(!first)\r
rangeToken.image = rangeToken.image + ":";\r
} {\r <UNSIGNED_INTEGER>\r {\r
rangeToken.image = rangeToken.image + token.image; \r }\r
- | <IDENT>\r {\r rangeToken.image = rangeToken.image + token.image;\r
+ | identToken = ident()\r
+ {\r rangeToken.image = rangeToken.image + identToken;\r
}\r
}\r \r
\r
\r
import java.util.ArrayList;\r
\r
+@SuppressWarnings({"unused", "serial"})\r
public class ModelParser {\r
\r
private ArrayList<Parameter> inputs = new ArrayList<Parameter>();\r
* ModelicaWriter writes Sysdyn model representations (objmap) into Modelica code.\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
public class ModelicaWriter {\r
\r
HashSet<String> sheetNames = new HashSet<String>();\r
for(Sheet sheet : getSpreadSheets(configurations))\r
- sheetNames.add(sheet.getName());\r
+ sheetNames.add(sheet.getModelicaName());\r
\r
// Write all module configurations to the declarations part (first)\r
for(Configuration conf : configurations) {\r
Module module = (Module)dependency.getHead();\r
Input reference = (Input)dependency.refersTo();\r
if(reference != null && reference.getName() != null && (reference.getVariability() == null || reference.getVariability().isEmpty())) {\r
- b.append(" " + module.getName() + "." + reference.getName() + " = " + variable.getName() + ";\n");\r
+ b.append(" " + module.getName() + "." + reference.getModelicaName() + " = " + variable.getModelicaName() + ";\n");\r
moduleInputs.get(module.getName()).remove(reference);\r
}\r
}\r
for(String moduleLabel : moduleInputs.keySet()) {\r
for(Input input : moduleInputs.get(moduleLabel)) {\r
if(input.getVariability() == null || input.getVariability().isEmpty())\r
- b.append(" " + moduleLabel + "." + input.getName() + " = " + input.getDefaultInputValue(moduleLabel) + ";\n");\r
+ b.append(" " + moduleLabel + "." + input.getModelicaName() + " = " + input.getDefaultInputValue(moduleLabel) + ";\n");\r
}\r
}\r
\r
\r
}\r
\r
- /**\r
+ /**\r
* Define continuous input references\r
* @param b String builder\r
* @param inputReferences Input references\r
for(Input i : inputReferences.keySet()) {\r
if(i.getVariability() == null || i.getVariability().isEmpty()) {\r
// Define only continuous variables here\r
- b.append(" " + i.getName() + " = " + inputReferences.get(i));\r
+ b.append(" " + i.getModelicaName() + " = " + inputReferences.get(i));\r
}\r
}\r
}\r
String expression;\r
// If reference exists, use reference name. Otherwise, use default value.\r
if(reference != null && reference.getName() != null)\r
- expression = module.getName() + "." + reference.getName() + ";\n";\r
+ expression = module.getName() + "." + reference.getModelicaName() + ";\n";\r
\r
else\r
expression = input.getDefaultInputValue() + ";\n";\r
StringBuilder sb = new StringBuilder();\r
sb.append(getEnumerationClassDefinition());\r
sb.append(" ");\r
- sb.append(this.name + "_class");\r
- sb.append(" " + this.name);\r
+ sb.append(getModelicaName() + "_class");\r
+ sb.append(" " + getModelicaName());\r
sb.append(";\n");\r
\r
- sb.append(" parameter Integer " + this.name + "_size = " + this.name + ".size;\n");\r
- sb.append(" parameter Integer " + this.name + "_elements[:] = " + this.name + ".elements;\n");\r
+ sb.append(" parameter Integer " + getModelicaName() + "_size = " + getModelicaName() + ".size;\n");\r
+ sb.append(" parameter Integer " + getModelicaName() + "_elements[:] = " + getModelicaName() + ".elements;\n");\r
return sb.toString();\r
}\r
\r
StringBuilder indexesBuilder = new StringBuilder();\r
for(int i = 1; i <= indexes.size(); i++) {\r
indexesBuilder.append(" constant Integer ");\r
- indexesBuilder.append(indexes.get(i - 1).getName());\r
+ indexesBuilder.append(indexes.get(i - 1).getModelicaName());\r
indexesBuilder.append(" = " + i + ";\n");\r
\r
elementsBuilder.append(i);\r
\r
StringBuilder sb = new StringBuilder();\r
sb.append(" class ");\r
- sb.append(this.name);\r
+ sb.append(getModelicaName());\r
sb.append("_class\n");\r
sb.append(" extends Enumeration_class(size=");\r
sb.append(indexes.size());\r
sb.append(");\n");\r
sb.append(indexesBuilder);\r
sb.append(" end ");\r
- sb.append(this.name);\r
+ sb.append(getModelicaName());\r
sb.append("_class;\n");\r
\r
return sb.toString();\r
public String getName() {\r
return this.name;\r
}\r
+ \r
+ /**\r
+ * Get Modelica compliant name\r
+ * @return The name of this variable with spaces (' ') replaced with \r
+ * underscore characters ('_')\r
+ */\r
+ public String getModelicaName() {\r
+ if (this.name == null)\r
+ return null;\r
+ return this.name.replace(' ', '_');\r
+ }\r
\r
}\r
* Representation of an independent variable\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
public abstract class IndependentVariable extends Variable {\r
sb.append(" ");\r
sb.append(variability.getText().isEmpty() ? "" : variability.getText() + " ");\r
sb.append(getType() + " ");\r
- sb.append(getName());\r
+ sb.append(getModelicaName());\r
sb.append(getRange());\r
\r
// [= expression]\r
if(variability == Variability.PARAMETER || variability == Variability.CONSTANT) {\r
// parameters and constants are guaranteed to have only one expression\r
- String equation = FormatUtils.formatExpressionForModelica(this, getExpressions().get(0).getExpression());\r
+ String expression = getExpressions().get(0).getExpression();\r
+ expression = FormatUtils.replaceWhitespace(expression);\r
+ String equation = FormatUtils.formatExpressionForModelica(this, expression);\r
sb.append(" = " + equation);\r
}\r
\r
return sb.toString();\r
}\r
\r
- /**\r
+ /**\r
* Get the range of this variable, if it is an array variable. \r
* <p>\r
* Format: [EnumerationName.size (, Enumeration2Name.size)*] \r
sb.append("[");\r
Iterator<Enumeration> iterator = enumerations.iterator();\r
while(iterator.hasNext()) {\r
- sb.append(iterator.next().getName() + ".size");\r
+ sb.append(iterator.next().getModelicaName() + ".size");\r
if(iterator.hasNext()) {\r
sb.append(", ");\r
}\r
* Representation of an input variable \r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.Input)\r
Iterator<Enumeration> i = getArrayIndexes().iterator();\r
while(i.hasNext()) {\r
Enumeration e = i.next();\r
- sb.append((inModule != null && !inModule.isEmpty() ? inModule + "." : "") + e.getName() + ".size");\r
+ sb.append((inModule != null && !inModule.isEmpty() ? inModule + "." : "") + e.getModelicaName() + ".size");\r
if(i.hasNext())\r
sb.append(", ");\r
}\r
sb.append("[");\r
Iterator<Enumeration> iterator = enumerations.iterator();\r
while(iterator.hasNext()) {\r
- sb.append(iterator.next().getName() + ".size");\r
+ sb.append(iterator.next().getModelicaName() + ".size");\r
if(iterator.hasNext()) {\r
sb.append(", ");\r
}\r
}\r
\r
boolean continuous = variability == null || variability.isEmpty();\r
- return " " + (continuous ? "" : variability + " ") + getType() + " " + getName() + range + ";\n";\r
+ return " " + (continuous ? "" : variability + " ") + getType() + " " + getModelicaName() + range + ";\n";\r
}\r
\r
@Override\r
Module module = (Module)dependency.getTail();\r
Variable reference = (Variable)dependency.refersTo();\r
// If reference exists, use reference name. Otherwise, use default value.\r
- if(reference != null && reference.getName() != null)\r
- expression = "<b>Reference:</b><br/>" + module.getName() + "." + reference.getName() + ";\n";\r
+ if(reference != null && reference.getModelicaName() != null)\r
+ expression = "<b>Reference:</b><br/>" + module.getName() + "." + reference.getModelicaName() + ";\n";\r
}\r
\r
return expression + super.getDocumentationDefinition(graph);\r
/**\r
* Representation of a module instance\r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.Module)\r
if(outputVariable instanceof Shadow)\r
outputVariable = ((Shadow) outputVariable).getOriginal();\r
\r
- String name = outputVariable.getName();\r
+ String name = outputVariable.getModelicaName();\r
\r
Module module = (Module)dependency.getHead();\r
\r
else\r
declaration = declaration.substring(0, declaration.length() - 2); // Remove ending ";\n" \r
\r
- name = outputVariable.getName() + "_reference";\r
- declaration = declaration.replace(outputVariable.getName(), name);\r
- declaration += " = " + outputVariable.getName() + " /* Reference value to avoid name conflicts in module instantiation */ ;\n";\r
+ name = outputVariable.getModelicaName() + "_reference";\r
+ declaration = declaration.replace(outputVariable.getModelicaName(), name);\r
+ declaration += " = " + outputVariable.getModelicaName() + " /* Reference value to avoid name conflicts in module instantiation */ ;\n";\r
references.append(declaration);\r
break;\r
}\r
}\r
}\r
\r
- declarations.append(", " + reference.getName() + " = " + name);\r
+ declarations.append(", " + reference.getModelicaName() + " = " + name);\r
}\r
}\r
}\r
}\r
first = false;\r
\r
- result.append(getName() + "." + ((Variable)d.refersTo()).getName() + " = " + ((Variable)d.getTail()).getName());\r
+ result.append(getName() + "." + ((Variable)d.refersTo()).getModelicaName() + " = " + ((Variable)d.getTail()).getModelicaName());\r
result.append("<br/>");\r
}\r
result.append("</p>");\r
}\r
first = false;\r
\r
- result.append(((Variable)d.getHead()).getName() + " = " + getName() + "." + ((Variable)d.refersTo()).getName());\r
+ result.append(((Variable)d.getHead()).getModelicaName() + " = " + getName() + "." + ((Variable)d.refersTo()).getModelicaName());\r
result.append("<br/>");\r
}\r
result.append("</p>");\r
/**\r
* Representation of a parameter override\r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.Module_ParameterOverride)\r
* @return override equation\r
*/\r
public String getOverride() {\r
- return variable.getName() + " = " + expression;\r
+ return variable.getModelicaName() + " = " + expression;\r
}\r
\r
}\r
return "";\r
}\r
StringBuilder sb = new StringBuilder();\r
- sb.append(replacedEnumeration.getName());\r
+ sb.append(replacedEnumeration.getModelicaName());\r
sb.append(".size = ");\r
- sb.append(replacingEnumeration.getName());\r
+ sb.append(replacingEnumeration.getModelicaName());\r
sb.append("_size, ");\r
- sb.append(replacedEnumeration.getName());\r
+ sb.append(replacedEnumeration.getModelicaName());\r
sb.append(".elements = ");\r
- sb.append(replacingEnumeration.getName());\r
+ sb.append(replacingEnumeration.getModelicaName());\r
sb.append("_elements");\r
\r
return sb.toString();\r
\r
public String getStringRepresentation() {\r
final StringBuilder clazz = new StringBuilder();\r
- clazz.append("class " + name + "_class\n");\r
+ clazz.append("class " + getModelicaName() + "_class\n");\r
\r
try {\r
Simantics.getSession().syncRequest(new ReadRequest() {\r
e.printStackTrace();\r
}\r
\r
- clazz.append("end " + name + "_class;\n");\r
+ clazz.append("end " + getModelicaName() + "_class;\n");\r
// clazz.append(" " + name + "_class " + name + ";\n");\r
return clazz.toString();\r
}\r
/**\r
* Representation of a Stock variable\r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.Stock)\r
// start parameter is not used, everything needs to be fixed=false\r
if(getArrayIndexes() != null && !getArrayIndexes().isEmpty())\r
each = "each";\r
- return " " + getType() + " " + getName() + getRange() + "(" + each + " fixed=false);\n";\r
+ return " " + getType() + " " + getModelicaName() + getRange() + "(" + each + " fixed=false);\n";\r
} else {\r
// Start parameter is used. Parameter guarantees that there is only one expression.\r
StockExpression e = (StockExpression)getExpressions().get(0);\r
return " " + \r
getType() + \r
" " + \r
- getName() + \r
+ getModelicaName() + \r
getRange() + \r
"(" + \r
(e.getStartValue() != null ? each : "") + \r
/**\r
* Abstract class for representing a variable in system dynamics models \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
public abstract class Variable implements IElement {\r
return this.name;\r
}\r
\r
+ /**\r
+ * Get Modelica compliant name\r
+ * @return The name of this variable with spaces (' ') replaced with \r
+ * underscore characters ('_')\r
+ */\r
+ public String getModelicaName() {\r
+ if (this.name == null)\r
+ return null;\r
+ return this.name.replace(' ', '_');\r
+ }\r
+ \r
/**\r
*\r
* @return Parent configuration of this variable (or null if something is wrong)\r
import org.simantics.objmap.annotations.GraphType;\r
import org.simantics.objmap.annotations.RelatedValue;\r
import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.representation.utils.FormatUtils;\r
\r
/**\r
* Represents a constant expression\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.ConstantExpression)\r
@Override\r
public String getExpression() {\r
return equation;\r
+ } \r
+ \r
+ @Override\r
+ public String getModelicaExpression() {\r
+ return FormatUtils.replaceWhitespace(equation);\r
}\r
}\r
* DL=delay time/3\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.DelayExpression)\r
\r
@Override\r
public String getDeclarationAddition() {\r
-\r
- String delayTime = FormatUtils.formatExpressionForModelica(parent, this.delayTime);\r
- String initialValue = FormatUtils.formatExpressionForModelica(parent, this.initialValue);\r
+ String delayTime = FormatUtils.replaceWhitespace(this.delayTime);\r
+ delayTime = FormatUtils.formatExpressionForModelica(parent, delayTime);\r
+ String initialValue = FormatUtils.replaceWhitespace(this.initialValue);\r
+ initialValue = FormatUtils.formatExpressionForModelica(parent, initialValue);\r
Variability delayTimeVariability = Variability.getVariability((IndependentVariable)parent, delayTime);\r
Variability initialVariability = Variability.CONTINUOUS;\r
if(initialValue != null && initialValue.length() > 0) {\r
String range = parent.getRange();\r
\r
// Delay declaration\r
- declaration.append(" " + parent.getName() + "_delayClass " + parent.getName() + "_delayClass_instance");\r
+ declaration.append(" " + parent.getModelicaName() + "_delayClass " + parent.getModelicaName() + "_delayClass_instance");\r
\r
// Change enumeration sizes from the delay class. Supports overridden enumerations in modules.\r
if(range.length() > 0 || !initialVariability.equals(Variability.CONTINUOUS) || !delayTimeVariability.equals(Variability.CONTINUOUS)) {\r
private String getDelayClass(String range, int n) {\r
StringBuilder sb = new StringBuilder();\r
\r
- sb.append("class " + parent.getName() + "_delayClass\n");\r
+ sb.append("class " + parent.getModelicaName() + "_delayClass\n");\r
\r
// Enumeration sizes as parameters. Sizes correspond the enumeration sizes of variable\r
if(range.length() > 0) {\r
}\r
}\r
\r
+ String delayTime = FormatUtils.replaceWhitespace(this.delayTime);\r
String dt = FormatUtils.formatExpressionForModelica(parent,delayTime);\r
Variability delayTimeVariability = Variability.getVariability(parent, dt);\r
if(!delayTimeVariability.equals(Variability.CONTINUOUS)) {\r
\r
// Get initial value variability\r
Variability initialValueVariability = Variability.CONTINUOUS;\r
- String initEquation = FormatUtils.formatExpressionForModelica(parent, this.initialValue);\r
+ String initEquation = FormatUtils.replaceWhitespace(this.initialValue);\r
+ initEquation = FormatUtils.formatExpressionForModelica(parent, initEquation);\r
if(initialValue != null && initialValue.length() > 0) {\r
initialValueVariability = Variability.getVariability(parent, initEquation);\r
}\r
sb.append("\tdelay" + i + " = LV" + i + " " + (range.isEmpty() ? "/" : "./") + "DL;\n");\r
}\r
\r
- sb.append("end " + parent.getName() + "_delayClass;\n");\r
+ sb.append("end " + parent.getModelicaName() + "_delayClass;\n");\r
return sb.toString();\r
}\r
\r
public String getEquation() {\r
StringBuilder sb = new StringBuilder();\r
\r
- String equation = FormatUtils.formatExpressionForModelica(parent, this.equation);\r
- String delayTime = FormatUtils.formatExpressionForModelica(parent, this.delayTime);\r
- String initialValue = FormatUtils.formatExpressionForModelica(parent, this.initialValue);\r
+ String equation = FormatUtils.replaceWhitespace(this.equation);\r
+ equation = FormatUtils.formatExpressionForModelica(parent, equation);\r
+ String delayTime = FormatUtils.replaceWhitespace(this.delayTime);\r
+ delayTime = FormatUtils.formatExpressionForModelica(parent, delayTime);\r
+ String initialValue = FormatUtils.replaceWhitespace(this.initialValue);\r
+ initialValue = FormatUtils.formatExpressionForModelica(parent, initialValue);\r
\r
// First "valve" in the delay\r
- sb.append(" " + parent.getName() + "_delayClass_instance.delay0 = " + equation + ";\n");\r
+ sb.append(" " + parent.getModelicaName() + "_delayClass_instance.delay0 = " + equation + ";\n");\r
\r
// Delay time (if continuous)\r
Variability delayTimeVariability = Variability.getVariability(parent, delayTime);\r
if(delayTimeVariability.equals(Variability.CONTINUOUS)) {\r
- sb.append(" " + parent.getName() + "_delayClass_instance.delayTime = " + delayTime + ";\n");\r
+ sb.append(" " + parent.getModelicaName() + "_delayClass_instance.delayTime = " + delayTime + ";\n");\r
}\r
\r
// Initial value\r
if(initialValue == null || initialValue.length() == 0) {\r
// No initial value set, use delay0 (the first "valve")\r
- sb.append(" " + parent.getName() + "_delayClass_instance.initialValue = " + parent.getName() + "_delayClass_instance.delay0;\n");\r
+ sb.append(" " + parent.getModelicaName() + "_delayClass_instance.initialValue = " + parent.getModelicaName() + "_delayClass_instance.delay0;\n");\r
} else {\r
// Continuous initial value\r
Variability initialVariability = Variability.getVariability(parent, initialValue);\r
if(initialVariability.equals(Variability.CONTINUOUS)) {\r
- sb.append(" " + parent.getName() + "_delayClass_instance.initialValue = " + initialValue + ";\n");\r
+ sb.append(" " + parent.getModelicaName() + "_delayClass_instance.initialValue = " + initialValue + ";\n");\r
}\r
}\r
\r
// The value of the actual variable\r
String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
- sb.append(" " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + parent.getName() + "_delayClass_instance.delay" + order + ";\n");\r
+ sb.append(" " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + parent.getModelicaName() + "_delayClass_instance.delay" + order + ";\n");\r
return sb.toString();\r
}\r
\r
return "This + is + not + a + parameter + at + any + time";\r
}\r
\r
- \r
+ @Override\r
+ public String getModelicaExpression() {\r
+ return getExpression();\r
+ }\r
+\r
@Override\r
public String validateUnits(ReadGraph graph, SysdynModel model) {\r
if(parent.getUnit() == null)\r
* Abstract class for any expression\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
public abstract class Expression implements IExpression {\r
public String getEquation() {\r
return null;\r
}\r
-\r
+ \r
@Override\r
public String getInitialEquation() {\r
return null;\r
return null;\r
}\r
\r
+ /**\r
+ * Get Modelica compliant expression\r
+ * @return The expression with spaces (' ') replaced with \r
+ * underscore characters ('_')\r
+ */\r
+ public String getModelicaExpression() {\r
+ return null;\r
+ }\r
+ \r
@Override\r
public String getArrayRange() {\r
if(range == null)\r
* Representation of a normal (auxiliary) expression\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.NormalExpression)\r
public String getExpression() {\r
return equation;\r
}\r
-\r
+ \r
+ @Override\r
+ public String getModelicaExpression() {\r
+ return FormatUtils.replaceWhitespace(getExpression());\r
+ }\r
+ \r
@Override\r
public String getEquation() {\r
- String equation = FormatUtils.formatExpressionForModelica(parent, this.equation);\r
+ String equation = FormatUtils.replaceWhitespace(this.equation);\r
+ equation = FormatUtils.formatExpressionForModelica(parent, equation);\r
String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
- return " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
+ return " " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
}\r
\r
}\r
import org.simantics.objmap.annotations.GraphType;\r
import org.simantics.objmap.annotations.RelatedValue;\r
import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.representation.utils.FormatUtils;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
\r
/**\r
* Representation of a parameter expression\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.ParameterExpression)\r
return equation + " /* Actual value read from init file */";\r
}\r
\r
+ @Override\r
+ public String getModelicaExpression() {\r
+ String equation = FormatUtils.replaceWhitespace(this.equation);\r
+ return equation + " /* Actual value read from init file */";\r
+ }\r
+ \r
@Override\r
public String getDeclarationAddition() {\r
return ""; \r
*/\r
@Override\r
public String getEquation() {\r
+ String equation = FormatUtils.replaceWhitespace(this.equation);\r
String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
- return " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
+ return " " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
};\r
\r
public Double getValue() {\r
* Class representing a stock expression in a variable\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.StockExpression)\r
public String getExpression() {\r
return initialEquation;\r
}\r
- \r
\r
+ @Override\r
+ public String getModelicaExpression() {\r
+ return FormatUtils.replaceWhitespace(getExpression());\r
+ }\r
+ \r
@Override\r
public String getEquation() {\r
\r
// Stock equation is always der(Stock)\r
StringBuilder b = new StringBuilder();\r
b.append(" der(")\r
- .append(parent.getName() + range)\r
+ .append(parent.getModelicaName() + range)\r
.append(") =");\r
\r
// Stock equation is formed automatically using incoming and outgoing flows (actually the nearest valves in those flows)\r
} else {\r
b.append(" zeros(");\r
for(int i = 0; i < enumerations.size(); i++) {\r
- b.append(enumerations.get(i).getName() + ".size");\r
+ b.append(enumerations.get(i).getModelicaName() + ".size");\r
if(i != enumerations.size() - 1)\r
b.append(", ");\r
}\r
} else {\r
// incoming valves add and outgoing valves reduce the stock\r
for(Valve valve : outgoing)\r
- b.append("\n - ").append(valve.getName() + range);\r
+ b.append("\n - ").append(valve.getModelicaName() + range);\r
for(Valve valve : incoming)\r
- b.append("\n + ").append(valve.getName() + range);\r
+ b.append("\n + ").append(valve.getModelicaName() + range);\r
}\r
b.append(";\n");\r
return b.toString();\r
\r
@Override\r
public String getInitialEquation() {\r
+ String initialEquation = FormatUtils.replaceWhitespace(this.initialEquation);\r
// if start value is used, no initial equation is returned\r
if(useStartValue())\r
return null;\r
String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
if(range == null)\r
range = "";\r
- return " " + parent.getName() + range + " = " + equation + ";\n";\r
+ return " " + parent.getModelicaName() + range + " = " + equation + ";\n";\r
}\r
\r
\r
* Representation of a withlookup expression\r
* \r
* @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
*\r
*/\r
@GraphType(SysdynResource.URIs.WithLookupExpression)\r
\r
@Override\r
public String getEquation() {\r
- String equation = FormatUtils.formatExpressionForModelica(parent, this.equation);\r
+ String equation = FormatUtils.replaceWhitespace(this.equation);\r
+ equation = FormatUtils.formatExpressionForModelica(parent, equation);\r
String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
\r
return \r
- " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = interpolate(" + equation + ", " + SheetFormatUtils.reformatSheetReferences(parent, lookupTable) + ");\n";\r
+ " " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = interpolate(" + equation + ", " + SheetFormatUtils.reformatSheetReferences(parent, lookupTable) + ");\n";\r
}\r
\r
+ @Override\r
+ public String getModelicaExpression() {\r
+ return "interpolate(" + FormatUtils.replaceWhitespace(equation) + ", " + lookupTable + ")";\r
+ }\r
+ \r
@Override\r
public String getExpression() {\r
return "interpolate(" + equation + ", " + lookupTable + ")";\r
*******************************************************************************/\r
package org.simantics.sysdyn.representation.utils;\r
\r
+import java.io.StringReader;\r
import java.util.ArrayList;\r
\r
+import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
+import org.simantics.sysdyn.expressionParser.ParseException;\r
import org.simantics.sysdyn.representation.Enumeration;\r
import org.simantics.sysdyn.representation.IndependentVariable;\r
import org.simantics.sysdyn.representation.Variability;\r
reference.getArrayIndexes() != null &&\r
!reference.getArrayIndexes().isEmpty();\r
\r
- String refName = reference.getName();\r
+ String refName = reference.getModelicaName();\r
if(reference.getType().equals("Boolean")) {\r
condition= "if initial() or " + refName + " or not " +\r
refName + " then (";\r
if(!first)\r
sb.append(", ");\r
first = false;\r
- sb.append(e.getName() + ".size");\r
+ sb.append(e.getModelicaName() + ".size");\r
}\r
sb.append(")");\r
return sb.toString();\r
}\r
}\r
+ \r
+ /**\r
+ * Replaces each whitespace sequence with a single underscore character ('_').\r
+ * @param app String of which whitespace are replaced\r
+ * @return a new String with whitespace replaced\r
+ */\r
+ public static String replaceWhitespace(String app) {\r
+ String equation = app;\r
+ //String equation = FormatUtils.formatExpressionForModelica(variable, app, false);\r
+ ExpressionParser parser = new ExpressionParser(new StringReader(equation));\r
+ String modifiedEquation = new String(equation);\r
+\r
+ try {\r
+ parser.expr();\r
+ } catch (ParseException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+\r
+ // Collect all references\r
+ ArrayList<String> allReferences = new ArrayList<String>();\r
+ allReferences.addAll(parser.getReferences().keySet());\r
+ allReferences.addAll(parser.getFunctionCallReferences().keySet());\r
+ allReferences.addAll(parser.getEnumerationReferences().keySet());\r
+ \r
+ // Replace whitespace sequences with underscore characters\r
+ for (String reference : allReferences) {\r
+ String regex = reference.replaceAll(" ", "\\\\s+");\r
+ String replacement = reference.replaceAll(" ", "_");\r
+ modifiedEquation = modifiedEquation.replaceAll(regex, replacement);\r
+ }\r
+ \r
+ return modifiedEquation;\r
+ }\r
+\r
}\r
import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
import org.simantics.sysdyn.expressionParser.ExpressionParser.ForRange;\r
import org.simantics.sysdyn.expressionParser.ParseException;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
import org.simantics.sysdyn.representation.Enumeration;\r
import org.simantics.sysdyn.representation.EnumerationIndex;\r
import org.simantics.sysdyn.representation.Variable;\r
try {\r
parser.expr();\r
for(ForRange forRange : parser.getForRanges()) {\r
- if(forRange.start.equals(forRange.end)) {\r
- Variable v = RepresentationUtils.getVariable(variable.getParentConfiguration(), forRange.start.image);\r
- if(v instanceof Enumeration) {\r
- equation = equation.replaceAll("in[\\s]*" + forRange.start.image + "($|[^\\.])", "in " + forRange.start.image + ".elements$1");\r
- }\r
+ // Concat the tokens that form the range, this is\r
+ // necessary for names that have whitespace.\r
+ String rangeString = new String(forRange.start.image);\r
+ Token temp = forRange.start;\r
+ while (!temp.equals(forRange.end)) {\r
+ temp = temp.next;\r
+ rangeString += " " + temp.image;\r
+ }\r
+ Variable v = RepresentationUtils.getVariable(variable.getParentConfiguration(), rangeString);\r
+ if(v instanceof Enumeration) {\r
+ equation = equation.replaceAll("in[\\s]*" + rangeString + "($|[^\\.])", \r
+ "in " + rangeString.replaceAll(" ", "_") + ".elements$1");\r
}\r
}\r
} catch (ParseException e) {\r
\r
public static Variable getVariable(Configuration configuration, String name) {\r
Configuration conf = configuration;\r
- String[] components = name.split("\\.");\r
+ // This function seems to be used with both whitespaced and\r
+ // underscored versions of the variable name.\r
+ String whitespacedName = name.replace('_', ' ');\r
+ String[] components = whitespacedName.split("\\.");\r
\r
for(String component : components) {\r
\r
| "*" | "/" | ".*" | "./"\r
| "^" | ".^"\r
| "=" | ":=" \r
-| <IDENT: ["a"-"z","A"-"Z","_"] (["a"-"z","A"-"Z","_","0"-"9"])* >\r
+| <IDENT: ["a"-"z","A"-"Z","_","\u20ac"] (["a"-"z","A"-"Z","_","\u20ac","0"-"9"])* >\r
| <STRING: "\"" (~["\"", "\\", "\n"] | "\\" ~["\n"])* "\"">\r
{ matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); }\r
| <UNSIGNED_INTEGER: (["0"-"9"])+ >\r
Variable v = (Variable) element;\r
\r
StringBuilder sb = new StringBuilder();\r
- sb.append(v.getName());\r
+ sb.append(v.getModelicaName());\r
\r
\r
if(v.getArrayIndexes() != null && v.getArrayIndexes().size() > 0) {\r
if(!first)\r
sb.append(", ");\r
first = false;\r
- sb.append(e.getName());\r
+ sb.append(e.getModelicaName());\r
}\r
\r
sb.append("]");\r