public BinaryTree(string expression)
        {
            #region Initialization

            Root = new BinaryNode
                   (
                value:  null,
                oper:   null,
                parent: null,
                left:   null,
                right:  null
                   );
            char       symbol  = '\0';
            long?      number  = null;
            BinaryNode current = Root;

            BinaryNode     subOperationRoot = null;
            CharEnumerator charEnumerator   = expression.GetEnumerator();

            #endregion

            while (charEnumerator.MoveNext())
            {
                symbol = charEnumerator.Current;

                #region Whitespace

                if (symbol == ' ')
                {
                    // Skip white space
                    continue;
                }

                #endregion

                #region Numeral

                // If numeral, continue to read all consecutive numerals
                if (char.IsNumber(symbol))
                {
                    number = number.Append(symbol);
                    continue;
                }

                #endregion

                #region Not numeral

                // Symbol is not a numeral; add number to tokens
                if (number.HasValue)
                {
                    if (current.Value != null)
                    {
                        throw new MathExpressionException("Consecutive operands.");
                    }
                    current.Value = new Fraction((long)number);
                    number        = null;
                }

                #endregion

                #region Sub-expression '('

                if (symbol == '(')
                {
                    // Read the sub-expression
                    StringBuilder stringBuilder = new StringBuilder();
                    Stack <char>  stack         = new Stack <char>();
                    while (charEnumerator.MoveNext())
                    {
                        char subSymbol = charEnumerator.Current;

                        if (subSymbol == '(')
                        {
                            stack.Push(')');
                        }
                        else if (subSymbol == ')')
                        {
                            if (stack.Any())
                            {
                                stack.Pop();
                            }
                            else
                            {
                                break;
                            }
                        }

                        stringBuilder.Append(subSymbol);
                    }
                    if (stack.Any())
                    {
                        throw new MathExpressionException("Unmatched paranthesis.");
                    }

                    BinaryTree subTree = new BinaryTree(stringBuilder.ToString());
                    current.Value    = subTree.Root.Value;
                    current.Operator = subTree.Root.Operator;
                    current.Left     = subTree.Root.Left;
                    current.Right    = subTree.Root.Right;

                    continue;
                }

                #endregion

                #region Operator '+' '-'

                if (symbol == '+' || symbol == '-')
                {
                    BinaryNode newBinaryNode = new BinaryNode
                                               (
                        value: null,
                        oper: new Operator(symbol),
                        parent: null,
                        left: Root,
                        right: null
                                               );

                    newBinaryNode.Right = new BinaryNode
                                          (
                        value: null,
                        oper: null,
                        parent: newBinaryNode,
                        left: null,
                        right: null
                                          );

                    Root.Parent = newBinaryNode;
                    Root        = newBinaryNode;
                    current     = newBinaryNode.Right;

                    subOperationRoot = null;

                    continue;
                }

                #endregion

                #region Operator '*' '/'

                if (symbol == '*' || symbol == '/')
                {
                    BinaryNode newBinaryNode;
                    BinaryNode newBinaryNodeleft = subOperationRoot ?? current;

                    newBinaryNode = new BinaryNode
                                    (
                        value:  null,
                        oper:   new Operator(symbol),
                        parent: newBinaryNodeleft.Parent,
                        left:   newBinaryNodeleft,
                        right:  null
                                    );

                    if (newBinaryNodeleft == Root)
                    {
                        Root = newBinaryNode;
                    }
                    else
                    {
                        newBinaryNodeleft.Parent.Right = newBinaryNode;
                    }


                    newBinaryNode.Right = new BinaryNode
                                          (
                        value: null,
                        oper: null,
                        parent: newBinaryNode,
                        left: null,
                        right: null
                                          );
                    current.Parent = newBinaryNode;
                    current        = newBinaryNode.Right;

                    subOperationRoot = newBinaryNode;

                    continue;
                }

                #endregion

                throw new MathExpressionException("Unrecognized symbol.");
            }

            if (number is null && symbol != '(')
            {
                throw new MathExpressionException("Missing opperand.");
            }

            if (number != null)
            {
                current.Value = new Fraction((long)number);
            }
        }
Exemplo n.º 2
0
 public BinaryNode(Fraction?value, Operator oper, BinaryNode parent, BinaryNode left, BinaryNode right)
 {
     Value    = value;
     Operator = oper;
     Parent   = parent;
     Left     = left;
     Right    = right;
 }