Exemplo n.º 1
0
            public static double ProcessArithmetic(List<PhoenixCAS.Token> expression)
            {
                int lpcount = 0;
                int rpcount = 0;
                foreach (Token t in expression)
                {
                    if (t.Type == Token.TokenType.RParen)
                        rpcount++;
                    if (t.Type == Token.TokenType.LParen)
                        lpcount++;
                }
                if (rpcount != lpcount)
                    throw new MismatchedParenthesisException();
                if (expression.Count == 1)
                    if (expression[0].Type != Token.TokenType.Number)
                        if (expression[0].Type == Token.TokenType.Symbol)
                        {
                            if (Token.Symbols.ContainsKey(expression[0].Data))
                                return Token.Symbols[expression[0].Data];
                            else throw new NullSymbolException();
                        }
                        else
                            throw new MalformedExpressionException();
                    else
                        return Convert.ToDouble(expression[0].Data);
                else if (expression.Count == 2 && expression[0].Type != Token.TokenType.Function)
                    if (expression[0].Type != Token.TokenType.Add && expression[0].Type != Token.TokenType.Sub && expression[1].Type != Token.TokenType.Number )
                        throw new MalformedExpressionException();
                    else
                        return ((expression[0].Type == Token.TokenType.Add ? 1 : -1) * Convert.ToDouble(expression[1].Data));
                else
                {
                    if (rpcount > 0)
                    {
                        int innermostLparen= -1;
                        for (int i = 0; i < expression.Count(); i++)
                        {
                            if (expression[i].Type == Token.TokenType.LParen)
                                innermostLparen = i;
                        }
                        int innermostRparen = innermostLparen;
                        for (int i = innermostLparen; i < expression.Count(); i++)
                        {
                            if (expression[i].Type != Token.TokenType.RParen)
                                continue;
                            innermostRparen = i;
                            break;
                        }
                        Token innerExpressionResult = new Token(Token.TokenType.Number, ProcessArithmetic(expression.GetRange(innermostLparen+1, innermostRparen-innermostLparen-1)).ToString());
                        expression.RemoveRange(innermostLparen, innermostRparen - innermostLparen+1);
                        expression.Insert(innermostLparen, innerExpressionResult);
                        return ProcessArithmetic(expression);
                    }

                    for (int i = 0; i < expression.Count; i++)
                    {
                        Token t = expression[i];
                        if (t.Type == Token.TokenType.Symbol)
                            if (Token.Symbols.ContainsKey(t.Data))
                                expression[i] = new Token(Token.TokenType.Number, Token.Symbols[t.Data].ToString());
                            else throw new NullSymbolException();

                    }

                    for (int i = expression.Count - 1; i > -1; i--)
                    {
                        if (expression[i].Type == Token.TokenType.Function)
                        {
                            string[] sa = expression[i].Data.Split("\n".ToCharArray());
                            int args = Convert.ToInt32(sa[0]);
                            string name = sa[1];
                            if (expression.Count() < i + args)
                                throw new NullFunctionException();
                            double result = 0;
                            switch (args)
                            {
                                case 1:
                                    result = Token.SingleFunctions[name](Convert.ToDouble(expression[i + 1].Data));
                                    break;
                                case 2:
                                    result = Token.DoubleFunctions[name](Convert.ToDouble(expression[i + 1].Data), Convert.ToDouble(expression[i + 2].Data));
                                    break;

                                default: throw new NullFunctionException();
                            }
                            expression.Insert(i, new Token(Token.TokenType.Number, result.ToString()));
                            expression.RemoveRange(i+1, args + 1);
                            return ProcessArithmetic(expression);
                        }
                    }

                    int index = 0;
                    int maxPriority = -2;
                    for (int i = 0; i < expression.Count; i++)
                    {
                        /*if ((t1.type == Token.TokenType.ADD || t1.type == Token.TokenType.SUB) && (t2.type == Token.TokenType.ADD || t2.type == Token.TokenType.SUB) ||
                            (t2.type == Token.TokenType.NUMBER && t2.type == Token.TokenType.NUMBER) || t1.type == Token.TokenType.NULL || t2.type == Token.TokenType.NULL)
                            throw new PhoenixCAS.Exceptions.MalformedExpressionException();*/
                        if (expression[i].Priority > maxPriority)
                        {
                            maxPriority = expression[i].Priority;
                            index = i;
                        }
                    }
                    Token t1 = expression[index];
                    Token t2 = expression[index - 1];
                    List<Token> l = new List<Token>(expression);
                    switch (t1.Type)
                    {
                        case Token.TokenType.Add:
                            return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) + Convert.ToDouble(expression[index + 1].Data)).ToString())));
                        case Token.TokenType.Sub:
                            return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) - Convert.ToDouble(expression[index + 1].Data)).ToString())));
                        case Token.TokenType.Multi:
                            return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) * Convert.ToDouble(expression[index + 1].Data)).ToString())));
                        case Token.TokenType.Div:
                            return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) / Convert.ToDouble(expression[index + 1].Data)).ToString())));
                        case Token.TokenType.Caret:
                            return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, Math.Pow(Convert.ToDouble(t2.Data), Convert.ToDouble(expression[index + 1].Data)).ToString())));
                        case Token.TokenType.Modulo:
                            return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) % Convert.ToDouble(expression[index + 1].Data)).ToString())));
                    }

                }
                throw new MalformedExpressionException();
            }
Exemplo n.º 2
0
            private static List<Token> ProcessArithmeticHelper(List<Token> l, int index, Token t)
            {
                List<Token> r = new List<Token>(l);
                r.RemoveRange(index - 1, 3);
                /*if (index - 2 == 1)
                {
                    r.Insert(index - 1, Token.TokenType.ADD);
                    r.Insert(index, t);
                }
                else*/
                r.Insert(index - 1, t);

                return r;
            }