Ejemplo n.º 1
0
        public void ParserParse()
        {
            Parser          parser = new Parser();
            ExpressionQueue output = parser.Parse("3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3");

            Assert.AreEqual(13, output.Count);

            Token t = output.Dequeue();

            Assert.IsInstanceOfType(t, typeof(Operand));
            Assert.AreEqual(3L, ((Operand)t).Value);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(Operand));
            Assert.AreEqual(4L, ((Operand)t).Value);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(Operand));
            Assert.AreEqual(2L, ((Operand)t).Value);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(RaspyOperator));
            Assert.AreEqual('*', ((RaspyOperator)t).Symbol);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(Operand));
            Assert.AreEqual(1L, ((Operand)t).Value);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(Operand));
            Assert.AreEqual(5L, ((Operand)t).Value);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(RaspyOperator));
            Assert.AreEqual('-', ((RaspyOperator)t).Symbol);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(Operand));
            Assert.AreEqual(2L, ((Operand)t).Value);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(Operand));
            Assert.AreEqual(3L, ((Operand)t).Value);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(RaspyOperator));
            Assert.AreEqual('^', ((RaspyOperator)t).Symbol);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(RaspyOperator));
            Assert.AreEqual('^', ((RaspyOperator)t).Symbol);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(RaspyOperator));
            Assert.AreEqual('/', ((RaspyOperator)t).Symbol);

            t = output.Dequeue();
            Assert.IsInstanceOfType(t, typeof(RaspyOperator));
            Assert.AreEqual('+', ((RaspyOperator)t).Symbol);
        }
Ejemplo n.º 2
0
        public void EvaluatorInvalidFail()
        {
            Evaluator evaluator = new Evaluator();

            ExpressionQueue expression = new ExpressionQueue("4 + 5 +");
            expression.Enqueue(new Operand(4));
            expression.Enqueue(new Operand(5));
            expression.Enqueue(new RaspyOperator('+', Associativity.Left, 2, 2));
            expression.Enqueue(new RaspyOperator('+', Associativity.Left, 2, 2));

            evaluator.Evaluate(expression);
        }
Ejemplo n.º 3
0
        public void EvaluatorInvalidFail()
        {
            Evaluator evaluator = new Evaluator();

            ExpressionQueue expression = new ExpressionQueue("4 + 5 +");

            expression.Enqueue(new Operand(4));
            expression.Enqueue(new Operand(5));
            expression.Enqueue(new RaspyOperator('+', Associativity.Left, 2, 2));
            expression.Enqueue(new RaspyOperator('+', Associativity.Left, 2, 2));

            evaluator.Evaluate(expression);
        }
Ejemplo n.º 4
0
        public void ParseEmpty()
        {
            Parser          parser = new Parser();
            ExpressionQueue result = parser.Parse(null);

            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.Count);

            result = parser.Parse(string.Empty);
            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.Count);

            result = parser.Parse("     \t");
            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.Count);
        }
Ejemplo n.º 5
0
        public static IExpression <T> BuildBlockExpression <T>(string str, ExpressionQueue <T> root)
        {
            ExpressionQueue <T> result = root;

            bool firstExpressionCreated = false;

            int bracketsCount = 0;

            int lastIndex = 0;

            for (int i = 0; i < str.Length; i++)
            {
                char current = str[i];

                bool isEOF = str.Length == i + 1;

                if (current == '(')
                {
                    bracketsCount++;
                }
                else if (current == ')')
                {
                    bracketsCount--;
                }
                if (bracketsCount == 0 && (isEOF || result.IsExpressionEdge(str, i)))
                {
                    string substring = str.Substring(lastIndex, i + 1 - lastIndex);

                    lastIndex = i + 1;
                    if (!firstExpressionCreated)
                    {
                        result.Handle(substring);

                        firstExpressionCreated = true;
                    }
                    else
                    {
                        substring = substring.TrimStart(' ');

                        result.Handle(substring);
                    }
                }
            }

            return(result);
        }
Ejemplo n.º 6
0
        public void ExtensionsParse()
        {
            ExpressionQueue output = "3+4".Parse();

            Assert.IsNotNull(output);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Parses an infix expression into a an RPN token queue.
        /// </summary>
        /// <param name="expression">The expression to parse.</param>
        /// <returns>An RPN token queue.</returns>
        public ExpressionQueue Parse(string expression)
        {
            ExpressionQueue output = new ExpressionQueue(expression);
            Stack<Token> stack = new Stack<Token>();

            if (!string.IsNullOrEmpty(expression))
            {
                int i = 0;
                ReadResult result;

                while (i < expression.Length)
                {
                    result = this.ReadOperand(expression, i);

                    if (result.Success)
                    {
                        output.Enqueue(result.Token);
                        i = result.Position;
                    }
                    else
                    {
                        result = this.ReadOperator(expression, i);

                        if (result.Success)
                        {
                            RaspyOperator op1 = (RaspyOperator)result.Token;

                            while (stack.Count > 0 && stack.Peek().IsOperator)
                            {
                                RaspyOperator op2 = (RaspyOperator)stack.Peek();

                                if ((op1.Associativity == Associativity.Left && op1.Precedence <= op2.Precedence)
                                    || (op1.Associativity == Associativity.Right && op1.Precedence < op2.Precedence))
                                {
                                    output.Enqueue(stack.Pop());
                                }
                                else
                                {
                                    break;
                                }
                            }

                            stack.Push(result.Token);
                            i = result.Position;
                        }
                        else if (expression[i] == '(')
                        {
                            stack.Push(new Parenthesis(ParenthesisType.Left));
                            i++;
                        }
                        else if (expression[i] == ')')
                        {
                            bool foundLeft = false;

                            while (stack.Count > 0)
                            {
                                Token token = stack.Peek();

                                if (token.IsOperator)
                                {
                                    output.Enqueue(stack.Pop());
                                }
                                else if (token.IsParenthesis)
                                {
                                    if (((Parenthesis)token).ParenthesisType == ParenthesisType.Left)
                                    {
                                        stack.Pop();
                                        foundLeft = true;
                                        break;
                                    }
                                }
                            }

                            i++;

                            if (!foundLeft)
                            {
                                throw new RaspyParseException("The expression contains mismatched parentheses.", expression);
                            }
                        }
                        else if (!char.IsWhiteSpace(expression[i]))
                        {
                            throw new RaspyParseException(string.Format(CultureInfo.InvariantCulture, "The expression contains an invalid character, '{0}'.", expression[i]), expression);
                        }
                        else
                        {
                            i++;
                        }
                    }
                }

                while (stack.Count > 0)
                {
                    Token token = stack.Peek();

                    if (!token.IsParenthesis)
                    {
                        output.Enqueue(stack.Pop());
                    }
                    else
                    {
                        throw new RaspyParseException("The expression contains mismatched parentheses.", expression);
                    }
                }
            }

            return output;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Evaluates a parsed arithmetic expression.
        /// </summary>
        /// <param name="expression">The expression to evaluate.</param>
        /// <returns>The result of the evaluation.</returns>
        public object Evaluate(ExpressionQueue expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression", "expression cannot be null.");
            }

            string infixExpression = expression.InfixExpression;
            string parsedExpression = expression.ToString();
            Stack<Token> stack = new Stack<Token>();

            try
            {
                while (expression.Count > 0)
                {
                    Token token = expression.Dequeue();

                    if (token.IsOperator)
                    {
                        RaspyOperator op = (RaspyOperator)token;
                        IOperationProvider provider = this.providerFactory.GetProvider(op.Symbol);

                        if (provider != null)
                        {
                            List<Token> args = new List<Token>();
                            int i = op.ArgumentCount;

                            while (i-- > 0)
                            {
                                args.Add(stack.Pop());
                            }

                            args.Reverse();
                            stack.Push(provider.Operate(op, args.ToArray()));
                        }
                        else
                        {
                            throw new RaspyEvaluationException(
                                string.Format(CultureInfo.InvariantCulture, "No provider could be found for operator '{0}'.", op.Symbol),
                                infixExpression,
                                parsedExpression);
                        }
                    }
                    else
                    {
                        stack.Push(token);
                    }
                }

                if (stack.Count != 1 || !stack.Peek().IsOperand)
                {
                    throw new RaspyEvaluationException(
                        string.Format(CultureInfo.InvariantCulture, "Invalid expression: '{0}'.", parsedExpression),
                        infixExpression,
                        parsedExpression);
                }

                return ((Operand)stack.Pop()).Value;
            }
            catch (RaspyException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new RaspyEvaluationException(
                    string.Format(CultureInfo.InvariantCulture, "An error occurred while evaluating the expression '{0}'.", parsedExpression),
                    ex,
                    infixExpression,
                    parsedExpression);
            }
        }