public FuncNode(string name, Expression[] children, Operator oper)
 {
     CheckBeforeAccept(children);
     this.children = children;
     this.@operator = oper;
     this.name = name;
 }
 public override Expression DeepCopy()
 {
     Expression[] dcChildren = new Expression[children.Length];
     for (int i = 0; i < dcChildren.Length; i++)
     {
         dcChildren[i] = children[i].DeepCopy();
     }
     return new MathExpression.ParensNode(dcChildren);
 }
 public override Expression DeepCopy()
 {
     // TODO Auto-generated method stub
     Expression[] dcChildren = new Expression[children.Length];
     for (int i = 0; i < dcChildren.Length; i++)
     {
         dcChildren[i] = children[i].DeepCopy();
     }
     return new MathExpression.FuncNode(name, dcChildren, @operator);
 }
 //return null;
 /// <summary>Returns true if this node is a descendent of the specified node, false otherwise.
 /// 	</summary>
 /// <remarks>
 /// Returns true if this node is a descendent of the specified node, false otherwise.  By this
 /// methods definition, a node is a descendent of itself.
 /// </remarks>
 public virtual bool IsDescendent(Expression x)
 {
     Expression y = this;
     while (y != null)
     {
         if (y == x)
         {
             return true;
         }
         y = y.parent;
     }
     return false;
 }
        /// <summary>Returns an expression-tree that represents the expression string.</summary>
        /// <remarks>Returns an expression-tree that represents the expression string.  Returns null if the string is empty.
        /// 	</remarks>
        /// <exception cref="ExpressionParseException">If the string is invalid.</exception>
        public static Expression Parse(string s)
        {
            if (s == null)
            {
                throw new ExpressionParseException("Expression string cannot be null.", -1);
            }
            AList<Lexeme> lexemes = Lexify(s);
            //Make tokens
            System.Console.Out.WriteLine("Lexemes:");
            foreach (Lexeme item in lexemes)
            {
                System.Console.Out.Write(item.ToString());
            }
            Operator[] operators = GetOperators();
            string nl = Runtime.GetProperty("line.separator");
            System.Console.Out.WriteLine(nl + "Operators:");
            foreach (Operator oper in operators)
            {
                System.Console.Out.Write(oper.ToString() + " ");
            }
            System.Console.Out.Write(nl);
            //build tree
            Stack<Expression> terms = new Stack<Expression>();
            Stack<Expression> exprOps = new Stack<Expression>();
            Stack<Expression> exprList = new Stack<Expression>();
            Stack<Operator> opStack = new Stack<Operator>();
            Stack<Lexeme> operands = new Stack<Lexeme>();
            // contains expression nodes
            Stack<Lexeme> ops = new Stack<Lexeme>();
            // contains open brackets ( and operators ^,*,/,+,-
            //boolean term = true; // indicates a term should come next, not an operator
            //boolean signed = false; // indicates if the current term has been signed
            //boolean negate = false; // indicates if the sign of the current term is negated
            bool inTermOrPostOp = false;
            //1. While there are still tokens to be read in
            for (int i = 0; i < lexemes.Count; i++)
            {
                //1.1 Get the next token.
                Expression contents;
                Operator currentOperator;
                Lexeme current = lexemes[i];
                switch (current.GetType())
                {
                    case Lexeme.NUMBER:
                    {
                        //1.2.1 A number: push it onto the value stack.
                        inTermOrPostOp = true;
                        operands.AddItem(current);
                        if (debuggging)
                        {
                            System.Console.Out.WriteLine("push term: " + current.GetValue());
                        }
                        terms.AddItem(new NumberNode(current.GetValue()));
                        break;
                    }

                    case Lexeme.WORD:
                    {
                        //1.2.2 A variable: get its value, and push onto the value stack.
                        //maybe variable, maybe function name?
                        operands.AddItem(current);
                        inTermOrPostOp = true;
                        terms.AddItem(new VariableNode(current.GetValue()));
                        if (debuggging)
                        {
                            System.Console.Out.WriteLine("push term: " + current.GetValue());
                        }
                        break;
                    }

                    case Lexeme.LPAREN:
                    {
                        //1.2.3 A left parenthesis: push it onto the operator stack.
                        inTermOrPostOp = false;
                        //is function
                        if (!operands.IsEmpty() && operands.Peek().GetType() == Lexeme.WORD)
                        {
                            Expression funcName = terms.Pop();
                            currentOperator = GetOperatorFromLexeme(operators, operands.Peek(), inTermOrPostOp
                                );
                            opStack.AddItem(currentOperator);
                            if (debuggging)
                            {
                                System.Console.Out.WriteLine("push: " + currentOperator.GetSymbol());
                            }
                        }
                        ops.AddItem(current);
                        currentOperator = GetOperatorFromLexeme(operators, current, inTermOrPostOp);
                        opStack.AddItem(currentOperator);
                        if (debuggging)
                        {
                            System.Console.Out.WriteLine("push: " + currentOperator.GetSymbol());
                        }
                        break;
                    }

                    case Lexeme.COMMA:
                    {
                        operands.AddItem(current);
                        while (!opStack.IsEmpty() && (!opStack.Peek().GetSymbol().Equals("(") && !opStack
                            .Peek().GetSymbol().Equals(",")))
                        {
                            Operator topOperator = opStack.Pop();
                            if (debuggging)
                            {
                                System.Console.Out.WriteLine("pop: " + topOperator.GetSymbol());
                            }
                            Expression[] children;
                            if (topOperator.IsBinary())
                            {
                                Expression operand1 = terms.Pop();
                                Expression operand2 = terms.Pop();
                                children = new Expression[] { operand2, operand1 };
                            }
                            else
                            {
                                //check assoc here
                                Expression operand = terms.Pop();
                                children = new Expression[] { operand };
                            }
                            terms.AddItem(new OpNode(children, topOperator));
                        }
                        inTermOrPostOp = false;
                        if (!opStack.IsEmpty())
                        {
                            opStack.Pop();
                        }
                        else
                        {
                            // remove '(' paren from stack;
                            throw new ExpressionParseException("Expression string cannot missing leading (" +
                                 current, i);
                        }
                        currentOperator = GetOperatorFromLexeme(operators, current, inTermOrPostOp);
                        opStack.AddItem(currentOperator);
                        //terms.add(terms.pop());
                        break;
                    }

                    case Lexeme.RPAREN:
                    {
                        //1.2.4 A right parenthesis:
                        operands.AddItem(current);
                        while (!opStack.IsEmpty() && (!opStack.Peek().GetSymbol().Equals("(") && !opStack
                            .Peek().GetSymbol().Equals(",")))
                        {
                            Operator topOperator = opStack.Pop();
                            if (debuggging)
                            {
                                System.Console.Out.WriteLine("pop: " + topOperator.GetSymbol());
                            }
                            Expression[] children;
                            if (topOperator.IsBinary())
                            {
                                Expression operand1 = terms.Pop();
                                Expression operand2 = terms.Pop();
                                children = new Expression[] { operand2, operand1 };
                            }
                            else
                            {
                                //check assoc here
                                Expression operand = terms.Pop();
                                children = new Expression[] { operand };
                            }
                            terms.AddItem(new OpNode(children, topOperator));
                        }
                        inTermOrPostOp = true;
                        //maybe check if paren?
                        if (!opStack.IsEmpty())
                        {
                            opStack.Pop();
                        }
                        else
                        {
                            // remove '(' paren from stack;
                            throw new ExpressionParseException("Expression string cannot missing leading (",
                                i);
                        }
                        if (!opStack.IsEmpty() && opStack.Peek().IsFunc())
                        {
                            AList<Expression> args = new AList<Expression>();
                            while (!terms.IsEmpty())
                            {
                                if (args.Count < opStack.Peek().GetOperandsSize())
                                {
                                    args.AddItem(terms.Pop());
                                }
                                else
                                {
                                    break;
                                }
                            }
                            //check if args.size()==opStack.peek().getOperandsSize()
                            Collections.Reverse(args);
                            terms.AddItem(new FuncNode(opStack.Peek().GetSymbol(), Sharpen.Collections.ToArray
                                (args, new Expression[args.Count]), opStack.Pop()));
                        }
                        else
                        {
                            contents = terms.Pop();
                            terms.AddItem(new ParensNode(new Expression[] { contents }));
                        }
                        break;
                    }

                    case Lexeme.OPERATOR:
                    {
                        Lexeme thisOp = current;
                        currentOperator = GetOperatorFromLexeme(operators, current, inTermOrPostOp);
                        inTermOrPostOp = false;
                        operands.AddItem(current);
                        //Operator topOp;
                        while (!opStack.IsEmpty() && opStack.Peek().GetPrecednce() >= currentOperator.GetPrecednce
                            ())
                        {
                            //Lexeme poppedOp = ops.pop();
                            Operator topOperator = opStack.Pop();
                            Expression[] children;
                            if (topOperator.IsBinary())
                            {
                                Expression operand1 = terms.Pop();
                                Expression operand2 = terms.Pop();
                                children = new Expression[] { operand2, operand1 };
                            }
                            else
                            {
                                //check assoc here
                                Expression operand = terms.Pop();
                                children = new Expression[] { operand };
                            }
                            terms.AddItem(new OpNode(children, topOperator));
                        }
                        //Apply the operator to the operands, in the correct order.
                        //4 Push the result onto the value stack.
                        //might have to go x->pop(), y->pop(); push(x) for right assoc unary
                        //ops.add(current);
                        opStack.AddItem(currentOperator);
                        break;
                    }

                    default:
                    {
                        throw new ExpressionParseException("Unknown token type", -1);
                    }
                }
            }
            //2. While the operator stack is not empty
            while (!opStack.IsEmpty())
            {
                Operator poppedOp = opStack.Pop();
                Expression[] children;
                if (poppedOp.IsBinary())
                {
                    Expression operand1 = terms.Pop();
                    Expression operand2 = terms.Pop();
                    children = new Expression[] { operand2, operand1 };
                }
                else
                {
                    //check assoc here
                    Expression operand = terms.Pop();
                    children = new Expression[] { operand };
                }
                terms.AddItem(new OpNode(children, poppedOp));
            }
            return terms.Peek();
        }
 public AtomicNode(string name, Expression child, Operator oper)
 {
     //setChild(child);
     this.@operator = oper;
     this.name = name;
 }
 public ParensNode(Expression[] children)
 {
     CheckBeforeAccept(children);
     this.children = children;
 }
 private void ReplaceNodeInTree(Expression tree, Expression rem, Expression add)
 {
     Expression[] treeChildren = tree.GetChildren();
     for (int i = 0; i < treeChildren.Length; i++)
     {
         if (treeChildren[i] == rem)
         {
             treeChildren[i] = add;
         }
         else
         {
             ReplaceNodeInTree(treeChildren[i], rem, add);
         }
     }
 }
 private Expression DeepestReducableNode(Expression node)
 {
     if (node.IsLeaf())
     {
         return node;
     }
     else
     {
         Expression[] myChildren = node.GetChildren();
         Expression firstHighestPrec = null;
         bool allLeafNode = true;
         for (int i = 0; i < myChildren.Length; i++)
         {
             if (!myChildren[i].IsLeaf())
             {
                 allLeafNode = false;
             }
             Expression current = DeepestReducableNode(myChildren[i]);
             if (firstHighestPrec == null || firstHighestPrec.GetPrecedence() < myChildren[i].
                 GetPrecedence())
             {
                 firstHighestPrec = current;
             }
         }
         if (firstHighestPrec == null || allLeafNode)
         {
             return node;
         }
         else
         {
             return firstHighestPrec;
         }
     }
 }
 private static void ToString(Expression x, StringBuilder sb)
 {
     return;
 }
 /// <summary>
 /// Protected method used to verify that the specified expression can be included as a child
 /// expression of this node.
 /// </summary>
 /// <remarks>
 /// Protected method used to verify that the specified expression can be included as a child
 /// expression of this node.
 /// </remarks>
 /// <exception cref="System.ArgumentException">If the specified expression is not accepted.
 /// 	</exception>
 protected internal virtual void CheckBeforeAccept(Expression[] x)
 {
     if (x == null)
     {
         throw new ArgumentException("expression cannot be null");
     }
     foreach (Expression child in x)
     {
         if (child.parent != null)
         {
             throw new ArgumentException("expression must be removed parent");
         }
         if (IsDescendent(child))
         {
             throw new ArgumentException("cyclic reference");
         }
     }
 }
예제 #12
0
 public OpNode(Expression[] children, Operator oper)
 {
     this.@operator = oper;
     this.children = children;
 }