Example #1
0
 private static void ToString(Expression x, StringBuilder sb)
 {
     if (x is OpNode)
     {
         OpNode o = (OpNode)x;
         sb.Append("(");
         ToString(o.leftChild, sb);
         sb.Append(o.GetSymbol());
         ToString(o.rightChild, sb);
         sb.Append(")");
     }
     else
     {
         if (x is TermNode)
         {
             TermNode t = (TermNode)x;
             if (t.GetNegate())
             {
                 sb.Append("(");
                 sb.Append("-");
             }
             sb.Append(t.GetName());
             if (t is FuncNode)
             {
                 FuncNode f = (FuncNode)t;
                 sb.Append("(");
                 if (f.NumChildren() > 0)
                 {
                     ToString(f.Child(0), sb);
                 }
                 for (int i = 1; i < f.NumChildren(); i++)
                 {
                     sb.Append(", ");
                     ToString(f.Child(i), sb);
                 }
                 sb.Append(")");
             }
             if (t.GetNegate())
             {
                 sb.Append(")");
             }
         }
         else
         {
             if (x is ValNode)
             {
                 sb.Append(((ValNode)x).val);
             }
         }
     }
 }
Example #2
0
 private static void GetTermNames(Expression x, Bag b, bool varNames)
 {
     if (x is OpNode)
     {
         OpNode o = (OpNode)x;
         GetTermNames(o.leftChild, b, varNames);
         GetTermNames(o.rightChild, b, varNames);
     }
     else
     {
         if (x is VarNode)
         {
             if (varNames)
             {
                 VarNode v = (VarNode)x;
                 if (!b.Contains(v.name))
                 {
                     b.Add(v.name);
                 }
             }
         }
         else
         {
             if (x is FuncNode)
             {
                 FuncNode f = (FuncNode)x;
                 if (!varNames)
                 {
                     if (!b.Contains(f.name))
                     {
                         b.Add(f.name);
                     }
                 }
                 for (int i = 0; i < f.NumChildren(); i++)
                 {
                     GetTermNames(f.Child(i), b, varNames);
                 }
             }
         }
     }
 }
Example #3
0
        private static Expression Build(string s, int indexErrorOffset)
        {
            // do not remove (required condition for functions with no parameters, e.g. Pi())
            if (s.Trim().Length == 0)
            {
                return(null);
            }

            Stack s1 = Stack.Allocate();
            // contains expression nodes
            Stack s2 = Stack.Allocate();

            try
            {
                // contains open brackets ( and operators ^,*,/,+,-
                bool term = true;
                // indicates a term should come next, not an operator
                bool signed = false;
                // indicates if the current term has been signed
                bool negate = false;
                // indicates if the sign of the current term is negated
                for (int i = 0; i < s.Length; i++)
                {
                    char c = s[i];
                    if (c == ' ' || c == '\t' || c == '\n')
                    {
                        continue;
                    }

                    if (term)
                    {
                        if (c == '(')
                        {
                            if (negate)
                            {
                                throw new ExpressionParseException("Open bracket found after negate.", i);
                            }

                            s2.Push("(");
                        }
                        else
                        {
                            if (!signed && (c == '+' || c == '-'))
                            {
                                signed = true;
                                if (c == '-')
                                {
                                    negate = true;
                                }
                            }
                            else
                            {
                                // by default negate is false
                                if (c >= '0' && c <= '9' || c == '.')
                                {
                                    int j = i + 1;
                                    while (j < s.Length)
                                    {
                                        c = s[j];
                                        if (c >= '0' && c <= '9' || c == '.')
                                        {
                                            j++;
                                        }
                                        else
                                        {
                                            // code to account for "computerized scientific notation"
                                            if (c == 'e' || c == 'E')
                                            {
                                                j++;
                                                if (j < s.Length)
                                                {
                                                    c = s[j];
                                                    if (c != '+' && c != '-' && (c < '0' || c > '9'))
                                                    {
                                                        throw new ExpressionParseException(
                                                                  "Expected digit, plus sign or minus sign but found: " +
                                                                  c.ToString(), j + indexErrorOffset);
                                                    }

                                                    j++;
                                                }

                                                while (j < s.Length)
                                                {
                                                    c = s[j];
                                                    if (c < '0' || c > '9')
                                                    {
                                                        break;
                                                    }

                                                    j++;
                                                }

                                                break;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }
                                    }

                                    double d  = 0;
                                    string _d = Sharpen.Runtime.Substring(s, i, j);
                                    try
                                    {
                                        d = double.Parse(_d);
                                    }
                                    catch
                                    {
                                        throw new ExpressionParseException("Improperly formatted value: " + _d,
                                                                           i + indexErrorOffset);
                                    }

                                    if (negate)
                                    {
                                        d = -d;
                                    }

                                    s1.Push(new ValNode(d));
                                    i      = j - 1;
                                    negate = false;
                                    term   = false;
                                    signed = false;
                                }
                                else
                                {
                                    if (c != ',' && c != ')' && c != '^' && c != '*' && c != '/' && c != '+' &&
                                        c != '-')
                                    {
                                        int j = i + 1;
                                        while (j < s.Length)
                                        {
                                            c = s[j];
                                            if (c != ',' && c != ' ' && c != '\t' && c != '\n' && c != '(' &&
                                                c != ')' && c != '^' && c != '*' && c != '/' && c != '+' && c != '-')
                                            {
                                                j++;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }

                                        if (j < s.Length)
                                        {
                                            int k = j;
                                            while (c == ' ' || c == '\t' || c == '\n')
                                            {
                                                k++;
                                                if (k == s.Length)
                                                {
                                                    break;
                                                }

                                                c = s[k];
                                            }

                                            if (c == '(')
                                            {
                                                FuncNode fn   = new FuncNode(Sharpen.Runtime.Substring(s, i, j), negate);
                                                int      b    = 1;
                                                int      kOld = k + 1;
                                                while (b != 0)
                                                {
                                                    k++;
                                                    if (k >= s.Length)
                                                    {
                                                        throw new ExpressionParseException(
                                                                  "Missing function close bracket.", i + indexErrorOffset);
                                                    }

                                                    c = s[k];
                                                    if (c == ')')
                                                    {
                                                        b--;
                                                    }
                                                    else
                                                    {
                                                        if (c == '(')
                                                        {
                                                            b++;
                                                        }
                                                        else
                                                        {
                                                            if (c == ',' && b == 1)
                                                            {
                                                                Expression o = Build(
                                                                    Sharpen.Runtime.Substring(s, kOld, k), kOld);
                                                                if (o == null)
                                                                {
                                                                    throw new ExpressionParseException(
                                                                              "Incomplete function.",
                                                                              kOld + indexErrorOffset);
                                                                }

                                                                fn.Add(o);
                                                                kOld = k + 1;
                                                            }
                                                        }
                                                    }
                                                }

                                                Expression o_1 = Build(Sharpen.Runtime.Substring(s, kOld, k), kOld);
                                                if (o_1 == null)
                                                {
                                                    if (fn.NumChildren() > 0)
                                                    {
                                                        throw new ExpressionParseException("Incomplete function.",
                                                                                           kOld + indexErrorOffset);
                                                    }
                                                }
                                                else
                                                {
                                                    fn.Add(o_1);
                                                }

                                                s1.Push(fn);
                                                i = k;
                                            }
                                            else
                                            {
                                                s1.Push(new VarNode(Sharpen.Runtime.Substring(s, i, j), negate));
                                                i = k - 1;
                                            }
                                        }
                                        else
                                        {
                                            s1.Push(new VarNode(Sharpen.Runtime.Substring(s, i, j), negate));
                                            i = j - 1;
                                        }

                                        negate = false;
                                        term   = false;
                                        signed = false;
                                    }
                                    else
                                    {
                                        throw new ExpressionParseException("Unexpected character: " + c.ToString(),
                                                                           i + indexErrorOffset);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (c == ')')
                        {
                            Stack s3 = Stack.Allocate();
                            Stack s4 = Stack.Allocate();
                            try
                            {
                                while (true)
                                {
                                    if (s2.IsEmpty())
                                    {
                                        throw new ExpressionParseException("Missing open bracket.",
                                                                           i + indexErrorOffset);
                                    }

                                    object o = s2.Pop();
                                    if (o.Equals("("))
                                    {
                                        break;
                                    }
                                    s3.AddToTail(s1.Pop());
                                    s4.AddToTail(o);
                                }
                                s3.AddToTail(s1.Pop());
                                s1.Push(Build(s3, s4));
                            }
                            finally
                            {
                                s3.ReleaseReference();
                                s4.ReleaseReference();
                            }
                        }
                        else
                        {
                            if (c == '^' || c == '*' || c == '/' || c == '+' || c == '-')
                            {
                                term = true;
                                s2.Push(c.ToString());
                            }
                            else
                            {
                                throw new ExpressionParseException(
                                          "Expected operator or close bracket but found: " + c.ToString(),
                                          i + indexErrorOffset);
                            }
                        }
                    }
                }

                if (s1.Size() != s2.Size() + 1)
                {
                    throw new ExpressionParseException("Incomplete expression.", indexErrorOffset + s.Length);
                }

                return(Build(s1, s2));
            }
            finally
            {
                s1.ReleaseReference();
                s2.ReleaseReference();
            }
        }