public void SetValue(string value)
        {
            //(04.07.2006 10:32)
            //Check for text first.
            if (IsText(value))
            {
                this.m_value = GetText(value);
                this.m_type = NODE_TYPE.TEXT;
                return;
            }
            //Check for operators first.
            OperatorMatch opMatch = FindOperators(value, m_operatorManager);
            if (opMatch != null)
            {
                m_type = NODE_TYPE.OPERATOR;
                string leftParam = value.Substring(0, opMatch.StartIndex);
                string rightParam = value.Substring(opMatch.StartIndex + opMatch.Length);
                if (leftParam != "")
                    m_subNodes = new ExpressionTreeNode[]{new ExpressionTreeNode(leftParam, m_column, m_operatorManager),
                        new ExpressionTreeNode(rightParam, m_column, m_operatorManager)};
                else
                    m_subNodes = new ExpressionTreeNode[]{new ExpressionTreeNode(rightParam, m_column, m_operatorManager)};
                m_value = opMatch.ExpressionOperator.FunctionName;
            }
            else if (value.IndexOf("(") != -1)
            {
                int paranStart = value.IndexOf('(');
                string functionName = value.Substring(0, paranStart);
                if (value.Length - paranStart - 2 < 0)
                {
                    throw new ExpressionException("Missing ')'", m_column, value.Length);
                }
                string param = value.Substring(paranStart + 1, value.Length - paranStart - 2);
                if (functionName == "")
                {
                    m_column += 1;
                    SetValue(param);
                    return;
                }
                if (param != "")
                {
                    ArrayList @params = new ArrayList();
                    int col = m_column + paranStart + 1;
                    int depth = 0;
                    string par = "";
                    //(27.07.2006 16:24)
                    //Detects whether we are inside a text or not.
                    bool insideText = false;
                    for (int i = 0; i <= param.Length - 1; i++)
                    {
                        char c = param[i];
                        if (c == '(')
                        {
                            depth += 1;
                        }
                        else if (c == ')')
                        {
                            depth -= 1;
                        }
                        else if (c == '"')
                        {
                            insideText = !insideText;
                        }
                        if (depth == 0 && c == ';' && !insideText)
                        {
                            @params.Add(par);
                            par = "";
                        }
                        else
                        {
                            par += c;
                        }
                    }
                    if (par != "")
                    {
                        @params.Add(par);
                    }

                    m_subNodes = new ExpressionTreeNode[@params.Count];
                    for (int i = 0; i < @params.Count; i++)
                    {
                        m_subNodes[i] = new ExpressionTreeNode((string)@params[i], col, m_operatorManager);
                        col += ((string)@params[i]).Length + 1;
                    }
                    // (23.02.2007 15:15)
                    if (value.IndexOf(')') == -1 || depth > 0)
                        throw new ExpressionException("Missing ')'", m_column, value.Length);
                    else if (depth < 0)
                        throw new ExpressionException("One ')' to much", m_column, value.Length);
                }
                else
                {
                    m_subNodes = new ExpressionTreeNode[] {};
                }
                m_value = functionName;
                m_type = NODE_TYPE.FUNCTION;
            }
            else
            {
                //Number or post data.
                m_value = value.Trim();
                if (IsNumeric(m_value))
                {
                    m_type = NODE_TYPE.NUMBER;
                    m_value = float.Parse((string)m_value);
                }
                else
                {
                    m_type = NODE_TYPE.VARIABLE;
                }
            }
        }
Exemplo n.º 2
0
        //Search for all value nodes in expression.
        //Returns true if it is optimizable.
        //Return false if it is not optimizable.
        private bool FindDependices(string expKey, ExpressionTreeNode node, ArrayList coll, string relative, ExpressionTreeNode parent, bool slack)
        {
            if (node == null)
            {
                return true;
            }
            switch (node.NodeType)
            {
                case ExpressionTreeNode.NODE_TYPE.VARIABLE:
                    //Detect relative dependicy.
                    string key = (string)node.Value;
                    //Check for relative usage of properties.
                    //Etc. dependicy is 'line1.FromPoint' using '.ToPoint'.
                    int propIndex = key.IndexOf(Calculator.PROPERTY_CHAR);
                    if (propIndex != -1)
                    {
                        if (key.Substring(0, propIndex) == "")
                        {
                            //Set new key using full name.
                            key = relative + key;
                            propIndex += relative.Length;
                        }
                        //Check for slack.
                        if (key == expKey)
                        {
                            //Recursive on 1 level.
                            if (!slack)
                            {
                                return false;
                            }
                            else
                            {
                                //Accept slack.
                                return true;
                            }
                        }
                        //Treat sub-properties as properties.
                        int nextPropIndex = key.IndexOf(Calculator.PROPERTY_CHAR, propIndex + 1);
                        if (nextPropIndex != -1)
                        {
                            //Sub-property.
                            //Treat as property.
                            key = key.Substring(0, nextPropIndex);
                        }
                    }
                    else
                    {
                        // The variable does not use a property.
                        if (parent != null && parent.NodeType == ExpressionTreeNode.NODE_TYPE.FUNCTION)
                        {
                            IFunction func = m_functions.Item((string)parent.Value);
                            //Check whether function has information
                            //about which properties of variable that is used.
                            if (func is IVariableReferencePropertyUsage)
                            {
                                IVariable var = this.m_calculator.Variable((string)node.Value);
                                if (var != null)
                                {
                                    IVariableReferencePropertyUsage propFunc = (IVariableReferencePropertyUsage)func;
                                    string[] propertyDependices = propFunc.GetDependices(var.GetType());
                                    if (propertyDependices == null)
                                    {
                                        return false;
                                    }
                                    foreach (string prop in propertyDependices)
                                    {
                                        coll.Add(node.Value + "." + prop);

                                        // (04.05.2007 10:43)
                                        // Add child property dependices.
                                        if (var is IOptimizable)
                                        {
                                            PropertyDependicy[] deps = ((IOptimizable)var).PropertyDependices;
                                            if (deps != null)
                                            {
                                                foreach (PropertyDependicy dep in deps)
                                                {
                                                    if (dep.ParentProperty.Equals(prop))
                                                        coll.Add(node.Value + "." + dep.ChildProperty);
                                                }
                                            }
                                        }
                                    }
                                    return true;
                                }
                            }
                        }

                        // Object reference. Not optimizable.
                        return false;
                    }

                    //Detect property dependices.
                    if (propIndex != -1)
                    {
                        string variableName = key.Substring(0, propIndex);
                        IVariable var = m_calculator.Variable(variableName);
                        if (var == null)
                        {
                            return false;
                        }
                        object obj = var;
                        if (obj is IOptimizable)
                        {
                            IOptimizable opt = (IOptimizable)obj;
                            string propName = key.Substring(propIndex + 1);
                            if (opt.PropertyDependices != null)
                            {
                                foreach (PropertyDependicy propertyDep in opt.PropertyDependices)
                                {
                                    if (propertyDep.ChildProperty == propName)
                                    {
                                        //Add dependicy for property dependicy.
                                        coll.Add(variableName + Calculator.PROPERTY_CHAR + propertyDep.ParentProperty);
                                    }
                                }
                            }
                        }
                    }

                    coll.Add(key);
                    return true;
                case ExpressionTreeNode.NODE_TYPE.FUNCTION:
                case ExpressionTreeNode.NODE_TYPE.OPERATOR:
                    IFunction nodeFunction = m_functions.Item((string)node.Value);
                    if (nodeFunction is IRandomFunction)
                    {
                        //Not optimizable.
                        return false;
                    }

                    //Check if function is slack.
                    bool isSlack = false;
                    if (nodeFunction is ISlackFunction)
                    {
                        isSlack = true;
                    }

                    bool optimizable = true;
                    bool childOptimizable = false;
                    foreach (ExpressionTreeNode child in node.SubNodes)
                    {
                        childOptimizable = FindDependices(expKey, child, coll, relative, node, isSlack);
                        optimizable = optimizable & childOptimizable;
                    }

                    return optimizable;
                default:
                    return true;
                    // default:
                    // //Operator.
                    // bool isOptimizable = true;
                    // isOptimizable = isOptimizable & FindDependices(expKey, node.Left, coll, relative, null, false);
                    // isOptimizable = isOptimizable & FindDependices(expKey, node.Right, coll, relative, null, false);
                    // return isOptimizable;
            }
        }