image = "icons/vensimFunction.png";\r
} else {\r
Resource r = graph.getPossibleObject(node.data, l0.PartOf);\r
- if (r != null && graph.isInstanceOf(r, sr.SharedFunctionOntology)) {\r
- image = "icons/functionLink.png";\r
- } else {\r
- image = "icons/function.png";\r
+ if (r != null) {\r
+ boolean shared = false;\r
+ do {\r
+ shared = graph.isInstanceOf(r, sr.SharedFunctionOntology);\r
+ r = graph.getPossibleObject(r, l0.PartOf);\r
+ } while (!shared && (r != null));\r
+ if (shared) {\r
+ image = "icons/functionLink.png";\r
+ } else {\r
+ image = "icons/function.png";\r
+ }\r
}\r
}\r
} else if (node instanceof VariableNode)\r
*/\r
public class ExpressionWidget implements Widget {\r
\r
+ private ExpressionWidgetInput input;\r
private Resource expr;\r
private Variable variable;\r
private Composite parent;\r
public void setInput(ISessionContext context, Object input) { \r
// Update IExpression based on the newly selected expression\r
ExpressionWidgetInput i = AdaptionUtils.adaptToSingle(input, ExpressionWidgetInput.class);\r
+ this.input = i;\r
expr = i.expression;\r
variable = i.variable;\r
ExpressionType et = ExpressionTypes.getExpressionType(expr);\r
IExpression exp = null;\r
switch (et) {\r
case Auxiliary: \r
- exp = new AuxiliaryExpression(); break;\r
+ exp = new AuxiliaryExpression(input); break;\r
case Parameter: \r
- exp = new ParameterExpression(variable); break;\r
+ exp = new ParameterExpression(input); break;\r
case Constant: \r
- exp = new ConstantExpression(); break;\r
+ exp = new ConstantExpression(input); break;\r
case Lookup: \r
exp = new LookupExpression(); break;\r
case WithLookup: \r
- exp = new WithLookupExpression(expr); break;\r
+ exp = new WithLookupExpression(input); break;\r
case Stock: \r
- exp = new StockExpression(); break;\r
+ exp = new StockExpression(input); break;\r
case Delay: \r
- exp = new DelayExpression(expr); break;\r
+ exp = new DelayExpression(input); break;\r
default: \r
exp = new EmptyExpression();\r
}\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.request.PossibleModel;\r
import org.simantics.db.management.ISessionContext;\r
import org.simantics.db.procedure.AsyncListener;\r
import org.simantics.db.request.Read;\r
functions.setText("Functions"); \r
\r
functionTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION);\r
- TableItem item;\r
\r
- //Finding functions\r
- ArrayList<Function> functionList = Function.getAllFunctions();\r
+ // Create a ResourceManager to dispose images when the widget is disposed.\r
+ this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), functionTable);\r
\r
- Collections.sort(functionList);\r
- \r
- // Create a ResourceManager to dispose images when the widget is disposed.\r
- this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), functionTable);\r
- \r
- for(Function function : functionList){\r
- item = new TableItem(functionTable, SWT.NONE);\r
- item.setText(function.getName() + "()");\r
- item.setData(function.getName() + "(" + function.getParameterList() + ")");\r
- item.setImage(Function.getImage(this.resourceManager, function));\r
- }\r
- \r
functions.setControl(functionTable);\r
+ \r
+ // Add the functions only after we know which variable is connected to this widget.\r
}\r
\r
public Composite getWidget() {\r
return composite;\r
}\r
\r
+ private void addFunctions(Resource model) {\r
+ TableItem item;\r
+ \r
+ ArrayList<Function> functionList = Function.getUserDefinedFunctions(model);\r
+ functionList.addAll(Function.getSharedFunctions(model)); \r
+ functionList.addAll(Function.getAllBuiltInFunctions()); \r
+ \r
+ Collections.sort(functionList);\r
+ \r
+ for(Function function : functionList){\r
+ item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText(function.getName() + "()");\r
+ item.setData(function.getName() + "(" + function.getParameterList() + ")");\r
+ item.setImage(Function.getImage(this.resourceManager, function));\r
+ }\r
+ \r
+ }\r
+ \r
@Override\r
public void setInput(ISessionContext context, Object input) {\r
if(input instanceof IStructuredSelection) {\r
final Resource variable = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
if(variable != null) {\r
- \r
+ \r
+ // Fill the function table\r
+ try { \r
+ Resource model = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+ @Override\r
+ public Resource perform(ReadGraph graph) throws DatabaseException {\r
+ return graph.syncRequest(new PossibleModel(variable));\r
+ }\r
+ });\r
+ addFunctions(model);\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ // Fill the variable table\r
SimanticsUI.getSession().asyncRequest(new Read<HashSet<String>>() {\r
\r
@Override\r
\r
public class AuxiliaryExpression extends BasicExpression {\r
\r
- public AuxiliaryExpression() {\r
+ public AuxiliaryExpression(ExpressionWidgetInput input) {\r
+ super(input);\r
try {\r
this.expressionType = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
\r
Label l = new Label(parent, SWT.NONE);\r
l.setText("=");\r
\r
- expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true);\r
+ expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
expression.setExpression(equation);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
}\r
\r
protected ExpressionField expression;\r
protected Resource expressionType;\r
-\r
+ protected ExpressionWidgetInput input;\r
+ \r
+ public BasicExpression(ExpressionWidgetInput input) {\r
+ this.input = input;\r
+ }\r
+ \r
@Override\r
public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
// Create the single field\r
Label l = new Label(parent, SWT.NONE);\r
l.setText("=");\r
\r
- expression = new ExpressionField(parent, SWT.BORDER, null, false);\r
+ expression = new ExpressionField(parent, SWT.BORDER, null, false, input);\r
expression.setExpression(equation);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
\r
import org.eclipse.swt.widgets.Control;\r
import org.eclipse.swt.widgets.Table;\r
import org.eclipse.swt.widgets.TableItem;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.request.Read;\r
import org.simantics.sysdyn.ui.Activator;\r
import org.simantics.sysdyn.ui.utils.ExpressionUtils;\r
+import org.simantics.ui.SimanticsUI;\r
\r
\r
/**\r
private ArrayList<Function> functions;\r
private ArrayList<String> variables = null;\r
private ArrayList<String> timeAndSelfVariables = null;\r
+ private final ExpressionWidgetInput input;\r
\r
private LocalResourceManager resourceManager;\r
\r
\r
private final String allowedConnectedCharactersRegExp = "[\\Q({[:;,<=>+-*/^\\E]";\r
\r
- public CompletionProcessor(Table allowedVariables, boolean allowFunctions){\r
+ public CompletionProcessor(Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) {\r
this.allowedVariables = allowedVariables;\r
+ this.input = input;\r
+ this.functions = new ArrayList<Function>();\r
\r
if (allowFunctions) {\r
- //Finding functions and sorting them.\r
- functions = Function.getAllFunctions();\r
+ if (input != null && CompletionProcessor.this.input.variable != null) {\r
+ // Get the respective model\r
+ Resource model = null;\r
+ try {\r
+ model = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+ @Override\r
+ public Resource perform(ReadGraph graph) throws DatabaseException {\r
+ return Variables.getModel(graph, CompletionProcessor.this.input.variable);\r
+ }\r
+ });\r
+ \r
+ //User defined functions\r
+ functions.addAll(Function.getUserDefinedFunctions(model));\r
+ // Shared functions\r
+ functions.addAll(Function.getSharedFunctions(model));\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ // Collect built in functions and sort all functions.\r
+ functions.addAll(Function.getAllBuiltInFunctions());\r
Collections.sort(functions);\r
}\r
}\r
-\r
+ \r
/**\r
* Collect and sort all variables.\r
*/\r
\r
public class ConstantExpression extends BasicExpression {\r
\r
- public ConstantExpression() {\r
+ public ConstantExpression(ExpressionWidgetInput input) {\r
+ super(input);\r
try {\r
this.expressionType = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
\r
\r
Label l = new Label(parent, SWT.NONE);\r
l.setText("=");\r
-System.out.println("ConstantExpression");\r
- expression = new ExpressionField(parent, SWT.BORDER, null, false);\r
+ //System.out.println("ConstantExpression");\r
+ expression = new ExpressionField(parent, SWT.BORDER, null, false, input);\r
expression.setExpression(equation);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
\r
private ExpressionField equation, delayTime, initialValue;\r
private ExpressionField lastSelectedText = equation;\r
private Spinner order;\r
+ private final ExpressionWidgetInput input;\r
private Resource expression;\r
\r
/**\r
* Creates a new DelayExpression\r
* @param expression\r
*/\r
- public DelayExpression(Resource expression) {\r
- this.expression = expression;\r
+ public DelayExpression(ExpressionWidgetInput input) {\r
+ this.input = input;\r
+ this.expression = input.expression;\r
}\r
\r
/**\r
l.setText("expression");\r
\r
// Equation that is delayed\r
- equation = new ExpressionField(parent, SWT.BORDER, allowedVariables, true);\r
+ equation = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
equation.setExpression(eq);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(equation);\r
equation.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
l.setText("delay time");\r
\r
// How much the equation is delayed\r
- delayTime = new ExpressionField(parent, SWT.BORDER, allowedVariables, true);\r
+ delayTime = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
delayTime.setExpression(dt);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(delayTime);\r
\r
l.setText("initial value");\r
\r
// What is the initial value of the delay (empty == same as equation)\r
- initialValue = new ExpressionField(parent, SWT.BORDER, allowedVariables, true);\r
+ initialValue = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
initialValue.setExpression(iv);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(initialValue);\r
\r
* @param parent\r
* @param style\r
*/\r
- public ExpressionField(Composite parent, int style, Table allowedVariables, boolean allowFunctions) {\r
+ public ExpressionField(Composite parent, int style, Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) {\r
super(parent, style);\r
\r
// Create a ResourceManager to dispose images when the widget is disposed.\r
// Configuration for color management\r
expressionFieldConfiguration = new ExpressionFieldConfiguration(\r
new LocalResourceManager(JFaceResources.getResources(), _sourceViewer.getControl()), \r
- allowedVariables, allowFunctions);\r
+ allowedVariables, allowFunctions, input);\r
_sourceViewer.configure(expressionFieldConfiguration);\r
AnnotationPainter painter = new AnnotationPainter(_sourceViewer, annotationAccess);\r
_sourceViewer.addPainter(painter);\r
CompletionProcessor completionProcessor;\r
ResourceManager resourceManager;\r
\r
+ private final ExpressionWidgetInput input;\r
\r
- public ExpressionFieldConfiguration(ResourceManager resourceManager, Table allowedVariables, boolean allowFunctions) {\r
+ public ExpressionFieldConfiguration(ResourceManager resourceManager, Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) {\r
super();\r
this.resourceManager = resourceManager;\r
this.allowedVariables = allowedVariables;\r
this.allowFunctions = allowFunctions;\r
this.assistSessionActive = false;\r
this.completionProcessor = null;\r
+ this.input = input;\r
}\r
\r
public boolean isAssistSessionActive() {\r
@Override\r
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {\r
ContentAssistant assistant = new ContentAssistant();\r
- completionProcessor = new CompletionProcessor(allowedVariables, allowFunctions);\r
+ completionProcessor = new CompletionProcessor(allowedVariables, allowFunctions, input);\r
assistant.setContentAssistProcessor(completionProcessor, IDocument.DEFAULT_CONTENT_TYPE);\r
assistant.enableAutoActivation(true);\r
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));\r
package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
\r
import java.util.ArrayList;\r
+import java.util.Collection;\r
\r
import org.eclipse.jface.resource.ImageDescriptor;\r
import org.eclipse.jface.resource.LocalResourceManager;\r
* @return String in which the paramters are ", " delimited\r
* @throws DatabaseException\r
*/\r
- private static String getFunctionInputs(ReadGraph graph, SysdynResource sr, Resource r) throws DatabaseException {\r
+ public static String getFunctionInputs(ReadGraph graph, SysdynResource sr, Resource r) throws DatabaseException {\r
Resource inputs = graph.getPossibleObject(r, sr.SysdynModelicaFunction_inputs);\r
String inputStr = null;\r
if (inputs != null) {\r
return inputStr;\r
}\r
\r
- private static String getFunctionDescription(ReadGraph graph, Resource r) throws DatabaseException {\r
+ public static String getFunctionDescription(ReadGraph graph, Resource r) throws DatabaseException {\r
String descriptionStr = null;\r
Layer0 l0 = Layer0.getInstance(graph);\r
Resource description = graph.getPossibleObject(r, l0.HasDescription);\r
}\r
\r
/**\r
- * Get all (atm. only built-in) Modelica functions.\r
- * @return ArrayList containing all functions.\r
+ * Get all built-in Modelica functions.\r
+ * @return ArrayList containing all built-in functions.\r
*/\r
- public static ArrayList<Function> getAllFunctions() {\r
+ public static ArrayList<Function> getAllBuiltInFunctions() {\r
ArrayList<Function> result = null;\r
\r
//Finding functions\r
functions.addAll(getFunctionsOfType(graph, SysdynResource.URIs.Built$in_Functions_Vensim_Functions, Type.VENSIM));\r
functions.addAll(getFunctionsOfType(graph, SysdynResource.URIs.Built$in_Functions_Modelica_Functions, Type.MODELICA));\r
functions.addAll(getFunctionsOfType(graph, SysdynResource.URIs.Built$in_Functions_Modelica_Array_Functions, Type.MODELICA_ARRAY));\r
+ \r
return functions;\r
}\r
});\r
\r
return result;\r
}\r
+ \r
+ /**\r
+ * Get all shared Modelica functions.\r
+ * @param variable of which model is in question\r
+ * @return ArrayList containing all shared functions.\r
+ */\r
+ public static ArrayList<Function> getSharedFunctions(final Resource model) {\r
+ ArrayList<Function> functions = new ArrayList<Function>();\r
+ if (model == null) {\r
+ return functions;\r
+ }\r
+ \r
+ try {\r
+ functions = SimanticsUI.getSession().syncRequest(new Read<ArrayList<Function>>() {\r
+ \r
+ @Override\r
+ public ArrayList<Function> perform(ReadGraph graph) throws DatabaseException {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ \r
+ // Full names of the collected functions\r
+ ArrayList<Function> sharedFunctions = new ArrayList<Function>();\r
+\r
+ Collection<Resource> linkedResources = graph.getObjects(model, l0.IsLinkedTo);\r
+ for (Resource r : linkedResources) {\r
+ // Find the "Shared functions" library \r
+ if (graph.isInstanceOf(r, sr.SharedFunctionOntology)) {\r
+ // Get all function resources under the Shared Functions "folder". \r
+ Collection<Resource> userFunctionResources = getFunctionsInside(graph, r);\r
+ for (Resource function : userFunctionResources) {\r
+ // Construct the Modelica name of the function\r
+ String fullName = NameUtils.getSafeName(graph, function);\r
+ Resource parent = function; // Parent is updated properly in the loop\r
+ do {\r
+ parent = graph.getPossibleObject(parent, l0.PartOf);\r
+ fullName = NameUtils.getSafeName(graph, parent) + "." + fullName;\r
+ } while (!graph.isInstanceOf(parent, l0.Ontology));\r
+ \r
+ // Create a Function object out of the Resource\r
+ Function sharedFunction = new Function(fullName, \r
+ Function.getFunctionInputs(graph, sr, function),\r
+ Type.SHARED, \r
+ Function.getFunctionDescription(graph, function));\r
+ sharedFunctions.add(sharedFunction);\r
+ }\r
+ }\r
+ }\r
+ return sharedFunctions;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return functions;\r
+ }\r
+ \r
+ /**\r
+ * Get all user defined Modelica functions.\r
+ * @param variable of which model is in question\r
+ * @return ArrayList containing all user defined functions.\r
+ */\r
+ public static ArrayList<Function> getUserDefinedFunctions(final Resource model) {\r
+ ArrayList<Function> functions = new ArrayList<Function>();\r
+ if (model == null) {\r
+ return functions;\r
+ }\r
+ \r
+ try {\r
+ functions = SimanticsUI.getSession().syncRequest(new Read<ArrayList<Function>>() {\r
+ \r
+ @Override\r
+ public ArrayList<Function> perform(ReadGraph graph) throws DatabaseException {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
\r
+ // Full names of the collected functions\r
+ ArrayList<Function> userFunctions = new ArrayList<Function>();\r
+ \r
+ // Get all function resources under model recursively\r
+ Collection<Resource> userFunctionResources = getFunctionsInside(graph, model);\r
+ for (Resource function : userFunctionResources) {\r
+ // Construct the Modelica name of the function\r
+ String fullName = NameUtils.getSafeName(graph, function);\r
+ Resource parent = graph.getPossibleObject(function, l0.PartOf);\r
+ while (!graph.isInstanceOf(parent, sr.SysdynModel)) {\r
+ fullName = NameUtils.getSafeName(graph, parent) + "." + fullName;\r
+ parent = graph.getPossibleObject(parent, l0.PartOf);\r
+ }\r
+ \r
+ // Create a Function object out of the Resource\r
+ Function userFunction = new Function(fullName, \r
+ Function.getFunctionInputs(graph, sr, function),\r
+ Type.USER_DEFINED, \r
+ Function.getFunctionDescription(graph, function));\r
+ userFunctions.add(userFunction);\r
+ }\r
+ \r
+ return userFunctions;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return functions;\r
+ }\r
+ \r
+ /**\r
+ * Get functions inside a resource\r
+ * @param graph\r
+ * @param r Recource in which functions are sought\r
+ * @return found function Resources\r
+ * @throws DatabaseException\r
+ */\r
+ public static Collection<Resource> getFunctionsInside(ReadGraph graph, Resource r) throws DatabaseException {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ ArrayList<Resource> functions = new ArrayList<Resource>();\r
+ functions.addAll(graph.syncRequest(new ObjectsWithType(\r
+ r, \r
+ l0.ConsistsOf, \r
+ sr.SysdynModelicaFunction)));\r
+ Collection<Resource> functionLibraries;\r
+ functionLibraries = graph.syncRequest(new ObjectsWithType(\r
+ r, \r
+ l0.ConsistsOf,\r
+ sr.SysdynModelicaFunctionLibrary));\r
+ for (Resource library : functionLibraries) {\r
+ functions.addAll(getFunctionsInside(graph, library));\r
+ }\r
+ return functions;\r
+ }\r
+ \r
/**\r
* Converts the description string to HTML-format\r
* @return HMTL-formatted description.\r
\r
Variable variable;\r
\r
- public ParameterExpression(Variable variable) {\r
- try {\r
+ public ParameterExpression(ExpressionWidgetInput input) {\r
+ super(input);\r
+ try {\r
this.expressionType = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
\r
@Override\r
} catch (DatabaseException e) {\r
e.printStackTrace();\r
} \r
-\r
- this.variable = variable;\r
+ \r
+ this.variable = input.variable;\r
}\r
\r
\r
Label l = new Label(parent, SWT.NONE);\r
l.setText("=");\r
\r
- expression = new ExpressionField(parent, SWT.BORDER, null, false);\r
+ expression = new ExpressionField(parent, SWT.BORDER, null, false, input);\r
expression.setExpression(equation);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
\r
}\r
\r
public ParameterExpression() {\r
+ super(null);\r
try {\r
this.expressionType = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
\r
public class StockExpression implements IExpression {\r
\r
private Text integral;\r
+ private final ExpressionWidgetInput input;\r
private ExpressionField expression;\r
\r
+ public StockExpression(ExpressionWidgetInput input) {\r
+ this.input = input;\r
+ }\r
+ \r
@Override\r
public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
label = new Label(parent, SWT.NONE);\r
label.setText("Initial\nValue");\r
\r
- expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true);\r
+ expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
expression.setExpression(initialEquation);\r
\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
private ChartPanel smallPanel;\r
private Frame smallFrame;\r
\r
+ private final ExpressionWidgetInput input;\r
private Resource expr;\r
\r
- public WithLookupExpression(Resource expression) {\r
- this.expr = expression;\r
+ public WithLookupExpression(ExpressionWidgetInput input) {\r
+ this.input = input;\r
+ this.expr = input.expression;\r
}\r
\r
@Override\r
Label l = new Label(parent, SWT.NONE);\r
l.setText("With\nLookup");\r
\r
- expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true);\r
+ expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true ,input);\r
expression.setExpression(equation);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
\r
l = new Label(parent, SWT.NONE);\r
l.setText("Lookup\ntable");\r
\r
- lookup = new ExpressionField(parent, SWT.BORDER, null, false);\r
+ lookup = new ExpressionField(parent, SWT.BORDER, null, false, input);\r
lookup.setExpression(lookupTable);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(lookup);\r
\r
import java.awt.event.ActionEvent;\r
import java.awt.event.ActionListener;\r
import java.io.StringReader;\r
+import java.util.ArrayList;\r
\r
import javax.swing.Timer;\r
\r
import org.simantics.db.Resource;\r
import org.simantics.db.WriteGraph;\r
import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
import org.simantics.db.management.ISessionContext;\r
import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.modelParser.ModelParser;\r
+import org.simantics.sysdyn.modelParser.ModelParser.Parameter;\r
import org.simantics.sysdyn.modelParser.ParseException;\r
import org.simantics.sysdyn.modelParser.Token;\r
import org.simantics.sysdyn.modelParser.TokenMgrError;\r
private Timer updateChartTimer;\r
private static int VALIDATION_DELAY_TIME = 500;\r
\r
+ private ArrayList<Parameter> inputs;\r
+ private ArrayList<Parameter> outputs;\r
+ \r
public FunctionCodeWidget(Composite parent, WidgetSupport support, int style) {\r
support.register(this);\r
- modelicaCode = new ExpressionField(parent, SWT.BORDER, null, false);\r
+ modelicaCode = new ExpressionField(parent, SWT.BORDER, null, false, null);\r
GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode);\r
\r
\r
String code = modelicaCode.getExpression();\r
StringReader sr = new StringReader(code);\r
ModelParser modelParser = new ModelParser(sr);\r
+ \r
try {\r
modelParser.parse_composition();\r
+ \r
+ inputs = modelParser.getInputs();\r
+ outputs = modelParser.getOutputs();\r
+ \r
+ /*for (Parameter input : inputs) {\r
+ System.out.print("input " + input.type + " " + input.name);\r
+ if (input.optional) System.out.print(" [optional]");\r
+ if (input.description != null) System.out.print(" [Description: " + input.description + "]");\r
+ System.out.println();\r
+ }\r
+ for (Parameter output : outputs) { \r
+ System.out.print("output " + output.type + " " + output.name);\r
+ if (output.description != null) System.out.print(" [Description: " + output.description + "]");\r
+ System.out.println();\r
+ }^*/\r
+\r
} catch (ParseException e1) {\r
Token token = e1.currentToken;\r
modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.beginLine, token.beginColumn, token.endLine, token.endColumn));\r
private void save() {\r
final String code = modelicaCode.getExpression();\r
SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ \r
+ private void removeInputList(WriteGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ \r
+ Resource oldInputList = graph.getPossibleObject(function, sr.SysdynModelicaFunction_inputs);\r
+ if (oldInputList != null) {\r
+ // Find all the inputs \r
+ for (Resource input : ListUtils.toList(graph, oldInputList)) {\r
+ // Check if we have a variable length input\r
+ if (graph.isInstanceOf(input, sr.SysdynModelicaFunction_VariableLengthInput)) {\r
+ // The variable length inputs are found here\r
+ Resource variableLengthInputLabels = graph.getPossibleObject(input, sr.SysdynModelicaFunction_VariableLengthInput_shownLabels);\r
+ if (variableLengthInputLabels != null) {\r
+ // Find labels (strings)\r
+ for (Resource label : ListUtils.toList(graph, variableLengthInputLabels)) {\r
+ //Remove string\r
+ RemoverUtil.remove(graph, label);\r
+ }\r
+ // Remove list\r
+ RemoverUtil.remove(graph, variableLengthInputLabels);\r
+ }\r
+ } \r
+ // Remove the input\r
+ RemoverUtil.remove(graph, input);\r
+ }\r
+ // Remove the list\r
+ RemoverUtil.remove(graph, oldInputList);\r
+ }\r
+ }\r
+ \r
+ private void createInputList(WriteGraph graph) throws DatabaseException {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ \r
+ ArrayList<Resource> inputResources = new ArrayList<Resource>();\r
+ // Create inputs\r
+ for (Parameter input : inputs) {\r
+ Resource r = GraphUtils.create2(graph, sr.SysdynModelicaFunction_Input,\r
+ l0.HasName, input.name, \r
+ sr.Variable_type, input.type,\r
+ sr.SysdynModelicaFunction_optional, input.optional ? l0.True : l0.False);\r
+ if (input.description != null) {\r
+ // Description is optional\r
+ graph.claimLiteral(r, sr.SysdynModelicaFunction_definition, input.description);\r
+ }\r
+ inputResources.add(r);\r
+ }\r
+ graph.claim(\r
+ function, \r
+ sr.SysdynModelicaFunction_inputs, \r
+ ListUtils.create(graph, inputResources));\r
+ }\r
+ \r
+ private void removeOutputList(WriteGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+ Resource oldOutputList = graph.getPossibleObject(function, sr.SysdynModelicaFunction_outputs);\r
+ if (oldOutputList != null) {\r
+ // Find all the outputs \r
+ for (Resource output : ListUtils.toList(graph, oldOutputList)) {\r
+ // Remove the output\r
+ RemoverUtil.remove(graph, output);\r
+ }\r
+ // Remove the list\r
+ RemoverUtil.remove(graph, oldOutputList);\r
+ }\r
+ }\r
\r
+ private void createOutputList(WriteGraph graph) throws DatabaseException {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+ ArrayList<Resource> outputResources = new ArrayList<Resource>();\r
+ // Create outputs\r
+ for (Parameter output : outputs) {\r
+ Resource r = GraphUtils.create2(graph, sr.SysdynModelicaFunction_Output,\r
+ l0.HasName, output.name, \r
+ sr.Variable_type, output.type);\r
+ if (output.description != null) {\r
+ // Description is optional\r
+ graph.claimLiteral(r, sr.SysdynModelicaFunction_definition, output.description);\r
+ }\r
+ outputResources.add(r);\r
+ }\r
+ graph.claim(\r
+ function, \r
+ sr.SysdynModelicaFunction_outputs, \r
+ ListUtils.create(graph, outputResources));\r
+ \r
+ }\r
+ \r
@Override\r
public void perform(WriteGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+ // Remove the existing input list\r
+ removeInputList(graph);\r
+ // Create the new input list\r
+ createInputList(graph);\r
+ \r
+ // Remove the existing output list\r
+ removeOutputList(graph);\r
+ // Create the new output list\r
+ createOutputList(graph);\r
+ \r
+ // Update the function code\r
graph.claimLiteral(\r
function, \r
- SysdynResource.getInstance(graph).SysdynModelicaFunction_modelicaFunctionCode, \r
+ sr.SysdynModelicaFunction_modelicaFunctionCode, \r
code);\r
}\r
});\r
PARSER_BEGIN(ModelParser)\r
package org.simantics.sysdyn.modelParser;\r
\r
-public class ModelParser { \r
+import java.util.ArrayList;\r
+\r
+public class ModelParser {\r
+\r
+ private ArrayList<Parameter> inputs = new ArrayList<Parameter>();\r
+ private ArrayList<Parameter> outputs = new ArrayList<Parameter>();\r
+ \r
+ private enum InterfaceVariableType\r {\r INPUT, OUTPUT, OTHER\r
+ }\r
+\r
+ public class Parameter\r {\r
+ public String name;\r
+ public boolean optional;\r
+ public String description;\r
+ public String type;\r
+ \r
+ public Parameter()\r {\r
+ name = new String("");\r
+ optional = false;\r
+ description = null;\r
+ type = null;\r
+ }\r }\r
+\r
+ public ArrayList<Parameter> getInputs()\r
+ {\r
+ return inputs;\r
+ }\r
+ \r
+ public ArrayList<Parameter> getOutputs()\r
+ {\r
+ return outputs;\r
+ }\r
\r
}\r
\r
\r
TOKEN:\r
{\r
-"algorithm" | "discrete" | "false" | "model" | "redeclare"\r
-| "and" | "each" | "final" | "not" | "replaceable"\r
-| "annotation" | "else" | "flow" | "operator" | "return"\r
-|"assert" | "elseif" | "for" | "or" | "stream"\r
-| "block" | "elsewhen" | "function" | "outer" | "then"\r
-| "break" | "encapsulated" | "if" | "output" | "true"\r
-| "class" | "end" | "import" | "package" | "type"\r
-| "connect" | "enumeration" | "in" | "parameter" | "when"\r
-| "connector" | "equation" | "initial" | "partial" | "while"\r
-| "constant" | "expandable" | "inner" | "protected" | "within"\r
-| "constrainedby" | "extends" | "input" | "public"\r
-| "der" | "external" | "loop" | "record"\r
+"algorithm" | "discrete" | "false" | "model" | "redeclare"\r
+| "and" | "each" | "final" | "not" | "replaceable"\r
+| "annotation" | "else" | "flow" | "operator" | "return"\r
+|"assert" | "elseif" | "for" | "or" | "stream"\r
+| "block" | "elsewhen" | "function" | "outer" | "then"\r
+| "break" | "encapsulated" | "if" | "output" | "true"\r
+| "class" | "end" | "import" | "package" | "type"\r
+| "connect" | "enumeration" | "in" | "parameter" | "when"\r
+| "connector" | "equation" | "initial" | "partial" | "while"\r
+| "constant" | "expandable" | "inner" | "protected" | "within"\r
+| "constrainedby" | "extends" | "input" | "public"\r
+| "der" | "external" | "loop" | "record"\r
| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | ","\r
| "<" | "<=" | ">" | ">=" | "==" | "<>"\r
| "+" | "-" | ".+" | ".-"\r
// [ add_op ] -> ( add_op() )?\r
// { add_op term } -> ( add_op() term() )*\r
\r
-void parse() : {\r} {\r stored_definition() <EOF>\r
+void parse() : {\r
+} {\r
+ stored_definition() <EOF>\r
}\r
\r
/*** Stored Definition - Within ************************************/\r
void stored_definition() : {\r
} {\r
// stored_definition:\r
-// [ within [ name ] ";" ]\r
-// { [ final ] class_definition ";" }\r
- ( "within" ( name() )? ";" )?\r
- ( ( "final" )? class_definition() ";" )*\r}\r\r
+// [ within [ name ] ";" ]\r
+// { [ final ] class_definition ";" }\r
+ ( "within" ( name() )? ";" )?\r
+ ( ( "final" )? class_definition() ";" )*\r
+}\r
+\r
/*** Class Definition **********************************************/\r
\r
void class_definition() : {\r
} {\r
-// class_definition :\r
-// [ encapsulated ]\r
-// [ partial\r
-// ] ( class modelrecordblock expandableconnectortype\r
-// | | | | [ ] | | package | function | operator | operator function | operator record )\r
-// class_specifier\r
- ( "encapsulated" )?\r
- ( "partial" )?\r
- ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
- "package" | "function" | "operator" | "operator function" | "operator record" )\r
- class_specifier()\r}\r
+// class_definition :\r
+// [ encapsulated ]\r
+// [ partial\r
+// ] ( class modelrecordblock expandableconnectortype\r
+// | | | | [ ] | | package | function | operator | operator function | operator record )\r
+// class_specifier\r
+ ( "encapsulated" )?\r
+ ( "partial" )?\r
+ ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
+ "package" | "function" | "operator" | "operator function" | "operator record" )\r
+ class_specifier()\r
+}\r
\r
\r
void class_specifier() : {\r
} {\r
-// class_specifier :\r
-// IDENT string_comment composition end IDENT\r
-// | IDENT "=" base_prefix name [ array_subscripts ]\r
-// [ class_modification ] comment\r
-// | IDENT "=" enumeration "(" ( [enum_list] | ":" ) ")" comment\r
-// | IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment\r
-// | extends IDENT [ class_modification ] string_comment composition\r
-// end IDENT \r
- LOOKAHEAD(2) <IDENT> string_comment() composition() "end" <IDENT>\r
- | LOOKAHEAD(2) <IDENT> "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment()\r
- | LOOKAHEAD(3) <IDENT> "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment()\r
- |LOOKAHEAD(3) <IDENT> "=" "der" "(" name() "," <IDENT> ( "," <IDENT> )* ")" comment()\r
- | "extends" <IDENT> ( class_modification() )? string_comment() composition() "end" <IDENT> \r
+// class_specifier :\r
+// IDENT string_comment composition end IDENT\r
+// | IDENT "=" base_prefix name [ array_subscripts ]\r
+// [ class_modification ] comment\r
+// | IDENT "=" enumeration "(" ( [enum_list] | ":" ) ")" comment\r
+// | IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment\r
+// | extends IDENT [ class_modification ] string_comment composition\r
+// end IDENT \r
+ LOOKAHEAD(2) <IDENT> string_comment() composition() "end" <IDENT>\r
+ | LOOKAHEAD(2) <IDENT> "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment()\r
+ | LOOKAHEAD(3) <IDENT> "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment()\r
+ |LOOKAHEAD(3) <IDENT> "=" "der" "(" name() "," <IDENT> ( "," <IDENT> )* ")" comment()\r
+ | "extends" <IDENT> ( class_modification() )? string_comment() composition() "end" <IDENT> \r
}\r
\r
void base_prefix() : {\r
} {\r
- type_prefix()\r
+ type_prefix()\r
}\r
\r
void enum_list() : {\r
} {\r
-// enumeration_literal { "," enumeration_literal}\r
- enumeration_literal() ( "," enumeration_literal() )* \r
+// enumeration_literal { "," enumeration_literal}\r
+ enumeration_literal() ( "," enumeration_literal() )* \r
}\r
\r
void enumeration_literal() : {\r
} {\r
- <IDENT> comment()\r
+ <IDENT> comment()\r
}\r
\r
void parse_composition() : {\r
} {\r
- composition() <EOF>\r
+ composition() <EOF>\r
}\r
\r
void composition() : {\r
} {\r
-// element_list\r
-// { public element_list |\r
-// protected element_list |\r
-// equation_section |\r
-// algorithm_section\r
-// }\r
-// [ external [ language_specification ]\r
-// [ external_function_call ] [ annotation ] ";" ]\r
-// [ annotation ";" ]\r
- element_list()\r
- ( LOOKAHEAD(2) "public" element_list() | "protected" element_list() | equation_section() | algorithm_section() )*\r
- ( "external" ( language_specification() )? ( external_function_call() )? ( annotation() )? ";" )?\r
- ( annotation() ";" )?\r}\r
+// element_list\r
+// { public element_list |\r
+// protected element_list |\r
+// equation_section |\r
+// algorithm_section\r
+// }\r
+// [ external [ language_specification ]\r
+// [ external_function_call ] [ annotation ] ";" ]\r
+// [ annotation ";" ]\r
+ element_list()\r
+ ( LOOKAHEAD(2) "public" element_list() | "protected" element_list() | equation_section() | algorithm_section() )*\r
+ ( "external" ( language_specification() )? ( external_function_call() )? ( annotation() )? ";" )?\r
+ ( annotation() ";" )?\r
+}\r
\r
void language_specification() : {\r
} {\r
- <STRING>\r
+ <STRING>\r
}\r
\r
void external_function_call() : {\r
} {\r
-// [ component_reference "=" ]\r
-// IDENT "(" [ expression_list ] ")"\r
- ( component_reference() "=" )?\r
- <IDENT> "(" ( expression_list() )? ")"\r}\r
+// [ component_reference "=" ]\r
+// IDENT "(" [ expression_list ] ")"\r
+ ( component_reference() "=" )?\r
+ <IDENT> "(" ( expression_list() )? ")"\r
+}\r
\r
void element_list() : {\r
} {\r
- ( element() ";" )*\r}\r
+ ( element() ";" )*\r
+}\r
\r
void element() : {\r
} {\r
-// import_clause |\r
-// extends_clause |\r
-// [ redeclare ]\r
-// [ final ]\r
-// [ inner ] [ outer ]\r
-// ( ( class_definition | component_clause) |\r
-// replaceable ( class_definition | component_clause)\r
-// [constraining_clause comment])\r
- import_clause() |\r
- extends_clause() |\r
- ( "redeclare" )?\r
- ( "final" )?\r
- ( "inner" )? ( "outer" )?\r
- ( (class_definition() | component_clause()) |\r
- "replaceable" (class_definition() | component_clause())\r
- (constraining_clause() comment())?)\r}\r
+// import_clause |\r
+// extends_clause |\r
+// [ redeclare ]\r
+// [ final ]\r
+// [ inner ] [ outer ]\r
+// ( ( class_definition | component_clause) |\r
+// replaceable ( class_definition | component_clause)\r
+// [constraining_clause comment])\r
+ import_clause() |\r
+ extends_clause() |\r
+ ( "redeclare" )?\r
+ ( "final" )?\r
+ ( "inner" )? ( "outer" )?\r
+ ( (class_definition() | component_clause()) |\r
+ "replaceable" (class_definition() | component_clause())\r
+ (constraining_clause() comment())?)\r
+}\r
\r
void import_clause() : {\r
} {\r
-// import ( IDENT "=" name | name ["." "*"] ) comment\r
- "import" (LOOKAHEAD(2) <IDENT> "=" name() | name() ("." "*")? ) comment()\r
+// import ( IDENT "=" name | name ["." "*"] ) comment\r
+ "import" (LOOKAHEAD(2) <IDENT> "=" name() | name() ("." "*")? ) comment()\r
}\r
\r
/*** Extends *******************************************************/\r
void extends_clause() : {\r
} {\r
-// extends name [ class_modification ] [annotation]\r
- "extends" name() ( class_modification() )? ( annotation() )?\r
+// extends name [ class_modification ] [annotation]\r
+ "extends" name() ( class_modification() )? ( annotation() )?\r
}\r
\r
void constraining_clause() : {\r
} {\r
-// constrainedby name [ class_modification ]\r
- "constrainedby" name() ( class_modification() )?\r
+// constrainedby name [ class_modification ]\r
+ "constrainedby" name() ( class_modification() )?\r
}\r
\r
/*** Component Clause **********************************************/\r
-void component_clause() : { boolean isInput = false;\r
+void component_clause() : {\r
+ InterfaceVariableType ioType = InterfaceVariableType.OTHER;\r
+ String typeSpecifier = "";\r
+ //String arraySubscripts = null;\r
+ ArrayList<Parameter> componentList = new ArrayList<Parameter>();\r
} {\r
\r
-// type_prefix type_specifier [ array_subscripts ] component_list\r
- ( isInput = type_prefix() ) type_specifier() ( array_subscripts() )? component_list(isInput)\r
-}\r
-\r
-boolean type_prefix() : { boolean isInput = false;\r
-} {\r
-// [ flow | stream ]\r
-// [ discrete | parameter | constant ] [ input | output ]\r
- ( "flow" | "stream" )?\r
- ( "discrete" | "parameter" | "constant" )?\r
- ( "output" | "input" { isInput = true; } )?\r
- {\r return isInput;\r
- }\r
-}\r
-\r
-void type_specifier() : {\r
-} {\r
- name()\r
-}\r
-\r
-void component_list(boolean isInput) : {\r
+// type_prefix type_specifier [ array_subscripts ] component_list\r
+ ( ioType = type_prefix() )\r
+ ( typeSpecifier = type_specifier() )\r
+ ( /*arraySubscripts =*/ array_subscripts() )?\r
+ ( componentList = component_list() )\r
+ {\r
+ if (ioType == InterfaceVariableType.INPUT) {\r
+ for (Parameter input : componentList) {\r
+ input.type = typeSpecifier;\r
+ inputs.add(input);\r }\r
+ } else if (ioType == InterfaceVariableType.OUTPUT) {\r
+ for (Parameter output : componentList) {\r
+ output.type = typeSpecifier; \r
+ outputs.add(output);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+InterfaceVariableType type_prefix() : {\r
+ InterfaceVariableType type = InterfaceVariableType.OTHER;\r
+} {\r
+// [ flow | stream ]\r
+// [ discrete | parameter | constant ] [ input | output ]\r
+ ( "flow" | "stream" )?\r
+ ( "discrete" | "parameter" | "constant" )?\r
+ ( "output" { type = InterfaceVariableType.OUTPUT; }\r
+ | "input" { type = InterfaceVariableType.INPUT; }\r
+ )?\r
+ {\r
+ return type;\r
+ }\r
+}\r
+String type_specifier() : {\r
+ String ret = new String("");\r
+} {\r
+ ret = name()\r
+ {\r return ret;\r
+ }\r
+}\r
+\r
+ArrayList<Parameter> component_list() : {\r
+ ArrayList<Parameter> ret = new ArrayList<Parameter>();\r
+ Parameter temp;\r
} {\r
// component_declaration { "," component_declaration }\r
- component_declaration(isInput) ( "," component_declaration(isInput) )*\r
+ temp = component_declaration() { ret.add(temp); }\r ( "," temp = component_declaration() { ret.add(temp); } )*\r
+ {\r return ret;\r
+ }\r
}\r
\r
-void component_declaration(boolean isInput) : {\r
+Parameter component_declaration() : {\r
+ Parameter ret;\r
+ String temp = "";\r
} {\r
// declaration [ conditional_attribute ] comment\r
- declaration(isInput) ( conditional_attribute() )? comment()\r
+ ret = declaration() ( conditional_attribute() )? ret.description = comment()\r
+ {\r
+ return ret;\r
+ }\r
}\r
\r
void conditional_attribute() : {\r
"if" expression()\r
}\r
\r
-void declaration(boolean isInput) : { String input_variable = null;\r
+Parameter declaration() : {\r
+ // Parameter here without comment yet.\r
+ Parameter ret = new Parameter();\r
} {\r
// IDENT [ array_subscripts ] [ modification ]\r
- <IDENT> { if (isInput) input_variable = new String(token.image); }\r
+ <IDENT> { ret.name = new String(token.image); }\r
( array_subscripts() )?\r
- ( modification() { input_variable = null; })?\r
- {\r \r
- if (input_variable != null)\r {\r
- //System.out.println("collect: " + input_variable);\r }\r
- }\r
+ ( ret.optional = modification() )?\r
+ {\r return ret;\r }\r
}\r
\r
/*** Modification **********************************************/\r
-void modification() : {\r
+boolean modification() : {\r
+ boolean optional = false;\r
} {\r
// class_modification [ "=" expression ]\r
// | "=" expression\r
// | ":=" expression\r
- class_modification() ( "=" expression() )?\r
- | "=" expression()\r
- | ":=" expression() \r
+ ( class_modification() ( "=" expression() )?\r
+ | "=" expression() { optional = true; }\r
+ | ":=" expression() { optional = true; } )\r
+ {\r return optional;\r
+ } \r
}\r
\r
void class_modification() : {\r
\r
void component_declaration1() : {\r
} {\r
- declaration(false) comment()\r
+ declaration() comment()\r
}\r
\r
\r
| "end"\r
}\r
\r
-void name() : {\r
+String name() : {\r
+ String ret = new String("");\r
} {\r
// [ "." ] IDENT { "." IDENT }\r
- ( "." )? <IDENT> ( "." <IDENT> )*\r
+ ( "." { ret += "."; } )?\r
+ <IDENT> { ret += token.image; }\r
+ ( "." { ret += "."; }\r
+ <IDENT> { ret += token.image; }\r
+ )*\r
+ {\r return ret;\r
+ }\r
}\r
\r
void component_reference() : {\r
void array_subscripts() : {\r
} {\r
// "[" subscript { "," subscript } "]" \r
- "[" subscript() ( "," subscript() )* "]"\r
+ "[" subscript() ( "," subscript() )* "]"\r
}\r
\r
void subscript() : {\r
} {\r
-// ":" | expression \r ":" | expression()\r
+// ":" | expression \r ":" | expression() \r
}\r
\r
-void comment() : {\r} {\r// string_comment [ annotation ]\r
- string_comment() ( annotation() )?\r
+String comment() : {\r
+ String ret;\r} {\r// string_comment [ annotation ]\r
+ ret = string_comment() ( annotation() )?\r
+ {\r return ret;\r
+ }\r
}\r
\r
-void string_comment() : {\r
+String string_comment() : {\r
+ String ret = null;\r
} {\r
// [ STRING { "+" STRING } ] \r
- ( <STRING> ( "+" <STRING> )* )? \r}\r
+ ( <STRING> { ret = new String(token.image); }\r
+ ( "+" { ret += "+"; }\r
+ <STRING> { ret += token.image; }\r
+ )*\r
+ )?\r
+ {\r return ret;\r
+ } \r}\r
\r
void annotation() : {\r
} {\r