Пример #1
0
        ArithmeticExpression CreateArithmetic(NodeBase node)
        {
            ArithmeticExpression lhs = CreateArithmeticExpression(node.m_Children[0]);
            ArithmeticExpression rhs = CreateArithmeticExpression(node.m_Children[1]);

            return(m_RuleMaker.MakeArithmeticSubExperssion(((ArithmeticNode)node).GetOperator(), lhs, rhs));
        }
Пример #2
0
        ArithmeticExpression CreateArithmeticExpression(NodeBase node)
        {
            ArithmeticExpression expression = null;

            switch (node.m_NodeType)
            {
            case NodeType.ARITHMETIC:
                expression = CreateArithmetic(node);
                break;

            case NodeType.CONSTANT:
            {
                Value value = m_RuleMaker.MakeConstant(((ConstantNode)node).m_ConstantType, ((ConstantNode)node).m_ConstantValue);
                expression = m_RuleMaker.MakeArithmeticExperssion(value);
            }
            break;

            case NodeType.VARIABLE:
            {
                Value value = m_RuleMaker.MakeVariable(((VariableNode)node).m_VariableName, ((VariableNode)node).m_VariableType);
                expression = m_RuleMaker.MakeArithmeticExperssion(value);
            }
            break;
            }

            return(expression);
        }
Пример #3
0
        LogicalExpression CreateLogicalExpression(NodeBase node)
        {
            LogicalExpression expression = null;

            LogicalNode logicalNode = (LogicalNode)node;

            if (logicalNode.m_LogicalType == LogicalOperatorType.NOT)
            {
                LogicalExpression rhs = CreateLogical(node.m_Children[0]);
                expression = m_RuleMaker.MakeLogical(rhs);
            }
            else
            {
                switch (node.m_NodeType)
                {
                case NodeType.RELATIONAL:
                {
                    ArithmeticExpression lhs = CreateArithmeticExpression(node.m_Children[0]);
                    ArithmeticExpression rhs = CreateArithmeticExpression(node.m_Children[1]);
                    expression = m_RuleMaker.MakeRelationalExperssion(((RelationalNode)node).GetOperator(), lhs, rhs);
                }
                break;

                case NodeType.LOGICAL:
                {
                    LogicalExpression lhs = CreateLogical(node.m_Children[0]);
                    LogicalExpression rhs = CreateLogical(node.m_Children[1]);
                    expression = m_RuleMaker.MakeLogical(((LogicalNode)node).GetOperator(), lhs, rhs);
                }
                break;
                }
            }

            return(expression);
        }
Пример #4
0
        public void ExactlyDivideTest()
        {
            FakeVariableLinker fvl = new FakeVariableLinker();
            DoubleVar          d1  = new DoubleVar(FakeVariableLinker.DoubleA);
            LongVar            i1  = new LongVar(FakeVariableLinker.IntA);
            LongConst          a   = new LongConst(300);
            LongConst          c   = new LongConst(603);
            DoubleConst        b   = new DoubleConst(20.7);

            ArithmeticExpression ae = new ArithmeticExpression(a, i1, Operator.ExactlyDivide);

            Assert.IsTrue(ae.GetResult(fvl).ToString() == "5");
            ae = new ArithmeticExpression(c, a, Operator.ExactlyDivide);
            Assert.IsTrue(ae.GetResult(fvl).ToString() == "2");
            ae = new ArithmeticExpression(c, a, Operator.Divide);
            Assert.IsTrue(ae.GetResult(fvl).ToString() == "2.01");
            ae = new ArithmeticExpression(c, b, Operator.ExactlyDivide);
            Assert.IsTrue(ae.GetResult(fvl).ToString() == "29");
            ae = new ArithmeticExpression(c, a, Operator.Remainder);
            Assert.IsTrue(ae.GetResult(fvl).ToString() == "3");
            ae = new ArithmeticExpression(c, b, Operator.Remainder);
            Assert.IsTrue(ae.GetResult(fvl).ToString() == (603 % 20.7).ToString());
            TestContext.WriteLine(ae.GetResult(fvl).ToString()); // Scan
            ae = new ArithmeticExpression(c, new DoubleConst(0), Operator.Divide);
            Assert.ThrowsException <DivideByZeroException>(() => ae.GetResult(fvl));
            ae = new ArithmeticExpression(c, new DoubleConst(15), Operator.Divide);
            Assert.IsTrue(ae.GetResult(fvl).ToString() == "40.2");

            //TestContext.WriteLine(ae.GetResult(fvl).ToString());
        }
Пример #5
0
        public void Visit(ArithmeticExpression operand)
        {
            operand.Left().Accept(this);
            object left = _value;

            operand.Right().Accept(this);
            object right = _value;

            switch (operand.Op().Id())
            {
            case ArithmeticOperator.AddId:
            {
                _value = Add(left, right);
                break;
            }

            case ArithmeticOperator.SubtractId:
            {
                _value = Subtract(left, right);
                break;
            }

            case ArithmeticOperator.MultiplyId:
            {
                _value = Multiply(left, right);
                break;
            }

            case ArithmeticOperator.DivideId:
            {
                _value = Divide(left, right);
                break;
            }
            }
        }
Пример #6
0
        public void Parse_AllFunctions()
        {
            string[] functions =
            {
                "abs",   "sqrt",  "exp",  "ln", "log",
                "sin",   "cos",   "tan",
                "asin",  "acos",  "atan",
                "sinh",  "cosh",  "tanh",
                "round", "floor", "ceil"
            };

            string input = "";

            for (int i = 0; i < functions.Length; i++)
            {
                if (i > 0)
                {
                    input += " + ";
                }

                input += functions[i] + "(x)";
            }

            ArithmeticExpression ae = ArithmeticExpression.Parse(input);

            Assert.IsNotNull(ae);

            for (int i = 0; i < functions.Length; i++)
            {
                Assert.IsTrue(ae.IsCallbackUsed("operator_" + functions[i]));
            }

            Assert.IsFalse(ae.IsCallbackUsed("unknown"));
        }
Пример #7
0
        private void OnDuplicateButtonClick(object sender, EventArgs e)
        {
            ListView.Item selected = listView.FocusedItem;
            if (selected != null && selected.NumericValueSource is ArithmeticExpression)
            {
                ArithmeticExpression ae = ArithmeticExpression.Parse(selected.Text);
                ae.Callbacks = selected.OperatorCallbacks;

                ListView.Item item = new ListView.Item {
                    OperatorCallbacks     = selected.OperatorCallbacks,
                    Color                 = FindNewColor(),
                    CheckState            = selected.CheckState,
                    CheckEnabled          = selected.CheckEnabled,
                    ImageResourceCallback = OnImageResourceCallback,

                    Description        = selected.Description,
                    NumericValueSource = ae,
                    Text        = selected.Text,
                    TextDisplay = selected.TextDisplay
                };

                listView.Items.Add(item);

                listView.FocusedItem = item;

                listView.Invalidate();
                listView.Update();

                listView.EnsureVisible(item);
            }
        }
Пример #8
0
        VariableType ValidateArithmeticExpression(ArithmeticExpression exp, out bool valid)
        {
            VariableType varType = VariableType.INT;

            valid = true;

            if (exp.HasSubExpression())
            {
                bool valid1;
                bool valid2;

                //ArithemticOperator op = exp.GetSubExpression().GetArithmeticOperator();
                VariableType t1 = ValidateArithmeticExpression(exp.GetSubExpression().GetLHSArithmeticExpression(), out valid1);
                VariableType t2 = ValidateArithmeticExpression(exp.GetSubExpression().GetRHSArithmeticExpression(), out valid2);

                valid = IsTypeCompatible(t1, t2, out varType) && valid1 && valid2;
            }
            else //is a value
            {
                if (exp.GetValue().HasVariable()) //is a variable
                {
                    varType = (VariableType)exp.GetValue().GetVariable().GetType2().Value;
                }
                else // is a constant
                {
                    varType = GetConstantType(exp.GetValue().GetConstant());
                }
            }

            return(varType);
        }
 private ITypeRef ArithmeticType(IComparisonOperand operand)
 {
     if (operand is ConstValue)
     {
         return(PrimitiveType(((ConstValue)operand).Value().GetType()));
     }
     if (operand is FieldValue)
     {
         return(((FieldValue)operand).Field.Type);
     }
     if (operand is ArithmeticExpression)
     {
         ArithmeticExpression expr  = (ArithmeticExpression)operand;
         ITypeRef             left  = ArithmeticType(expr.Left());
         ITypeRef             right = ArithmeticType(expr.Right());
         if (left == DoubleType() || right == DoubleType())
         {
             return(DoubleType());
         }
         if (left == FloatType() || right == FloatType())
         {
             return(FloatType());
         }
         if (left == LongType() || right == LongType())
         {
             return(LongType());
         }
         return(IntType());
     }
     return(null);
 }
Пример #10
0
        public override Object Visit(ArithmeticExpression node, Object obj)
        {
            node.FirstOperand.Accept(this, obj);
            node.SecondOperand.Accept(this, obj);

            return(null);
        }
Пример #11
0
        LogicalExpression CreateRelationalExpression(NodeBase node)
        {
            ArithmeticExpression lhs = CreateArithmeticExpression(node.m_Children[0]);
            ArithmeticExpression rhs = CreateArithmeticExpression(node.m_Children[1]);

            return(m_RuleMaker.MakeRelationalExperssion(((RelationalNode)node).GetOperator(), lhs, rhs));
        }
Пример #12
0
        /// <summary>
        /// Checks whether parenthesis are needed within the arithmetic expressions.
        /// </summary>
        /// <param name="element">The parent element.</param>
        /// <param name="expression">The parent arithmetic expression.</param>
        /// <param name="childExpression">The child arithmetic expression.</param>
        /// <returns>Returns true if there is no violation, or false if there is a violation.</returns>
        private bool CheckArithmeticParenthesisForExpressionAndChild(
            CsElement element, ArithmeticExpression expression, ArithmeticExpression childExpression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(childExpression, "childExpression");

            // Parenthesis are only required when the two expressions are not the same operator,
            // and when the two operators come from different families.
            if (expression.OperatorType != childExpression.OperatorType)
            {
                bool sameFamily =
                    ((expression.OperatorType == ArithmeticExpression.Operator.Addition ||
                      expression.OperatorType == ArithmeticExpression.Operator.Subtraction) &&
                     (childExpression.OperatorType == ArithmeticExpression.Operator.Addition ||
                      childExpression.OperatorType == ArithmeticExpression.Operator.Subtraction)) ||
                    ((expression.OperatorType == ArithmeticExpression.Operator.Multiplication ||
                      expression.OperatorType == ArithmeticExpression.Operator.Division) &&
                     (childExpression.OperatorType == ArithmeticExpression.Operator.Multiplication ||
                      childExpression.OperatorType == ArithmeticExpression.Operator.Division)) ||
                    ((expression.OperatorType == ArithmeticExpression.Operator.LeftShift ||
                      expression.OperatorType == ArithmeticExpression.Operator.RightShift) &&
                     (childExpression.OperatorType == ArithmeticExpression.Operator.LeftShift ||
                      childExpression.OperatorType == ArithmeticExpression.Operator.RightShift));

                if (!sameFamily)
                {
                    this.AddViolation(element, expression.LineNumber, Rules.ArithmeticExpressionsMustDeclarePrecedence);
                    return(false);
                }
            }

            return(true);
        }
 public RealArithmeticExpression(ArithmeticOperatorType operatorType,
     ArithmeticExpression left, ArithmeticExpression right)
 {
     this.operatorType = operatorType;
     this.left = left;
     this.right = right;
 }
Пример #14
0
        public void Evaluate_SimpleExpression()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("(2 - 1 + 6) % 5");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual((2 - 1 + 6) % 5, result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #15
0
        public void Evaluate_Parentheses()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("((( ((( ((( 1 + 2 ))) + 3 ))) + 4 ))) + 5");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(1 + 2 + 3 + 4 + 5, result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #16
0
        static void Main(string[] args)
        {
            ArithmeticExpression a = new ArithmeticExpression("(1 + 2) * 4");

            Console.WriteLine(a.PostfixNotation);
            Console.WriteLine(a.Value);
            Console.ReadLine();
        }
 public NumericSpecificationExpression(IJsonParser jsonParser,
     ArithmeticExpression leftArithmeticExpression,
     ArithmeticExpression rightArithmeticExpression)
     : base(jsonParser)
 {
     this.leftArithmeticExpression = leftArithmeticExpression;
     this.rightArithmeticExpression = rightArithmeticExpression;
 }
Пример #18
0
 public void ValuesReturnCorrectResults(
     [Frozen] Mock <Expression> left,
     [Frozen] Mock <Expression> right,
     ArithmeticExpression sut)
 {
     Assert.Equal(left.Object, sut.Left);
     Assert.Equal(right.Object, sut.Right);
 }
Пример #19
0
        static void Main(string[] args)
        {
            string str = "c = a * cdb - g";
            ArithmeticExpression ArithExpression1 = new ArithmeticExpression();

            ArithExpression1.Source = str;
            ArithExpression1.WrapFillLeksemu();
        }
Пример #20
0
        public void Evaluate_Function_Log()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("log(10 * 10 * 10 * 10)");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(4.0, result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #21
0
        public ArithmeticExpression MakeAssignmentRHS(Value value)
        {
            ArithmeticExpression arithmeticExpression = new ArithmeticExpression();

            arithmeticExpression.AddValue(value);

            return(arithmeticExpression);
        }
Пример #22
0
        public void Evaluate_SimpleFunction_AutoMultiply()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("5sqrt(x)");
            double result           = ae.Evaluate(16);

            Assert.AreEqual(5.0 * Math.Sqrt(16), result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #23
0
        public ArithmeticExpression MakeArithmeticExperssion(SubExpressionType expression)
        {
            ArithmeticExpression arithmeticExpression = new ArithmeticExpression();

            arithmeticExpression.AddSubExpression(expression);

            return(arithmeticExpression);
        }
Пример #24
0
        public void Evaluate_Precedence()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("1 / (2 * 4) ^ 2");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(1.0 / Math.Pow(2.0 * 4.0, 2), result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
        static void Main(string[] args)
        {
            Console.Title = "Lab №7";
            ProgramInfo();
            Console.WriteLine();
            int  size;
            bool parsed;

            do
            {
                Console.WriteLine("Enter the size of the array: ");
                parsed = int.TryParse(Console.ReadLine(), out size);
            } while (!parsed || size < 0);
            ArithmeticExpression[] expressions = new ArithmeticExpression[size];
            Console.WriteLine();
            for (int i = 0; i < size; i++)
            {
                bool reenter;
                do
                {
                    reenter = false;
                    double a, b, c;
                    do
                    {
                        Console.WriteLine($"Enter the A{i + 1}: ");
                        parsed = double.TryParse(Console.ReadLine().Replace('.', ','), out a);
                    } while (!parsed);
                    do
                    {
                        Console.WriteLine($"Enter the B{i + 1}: ");
                        parsed = double.TryParse(Console.ReadLine().Replace('.', ','), out b);
                    } while (!parsed);
                    do
                    {
                        Console.WriteLine($"Enter the C{i + 1}: ");
                        parsed = double.TryParse(Console.ReadLine().Replace('.', ','), out c);
                    } while (!parsed);
                    try
                    {                                                           // exceptions checking
                        expressions[i] = new ArithmeticExpression(a, b, c);
                        Console.WriteLine($"Result {i + 1} = {expressions[i].GetResult():F6}");
                    }
                    catch (ArithmeticException exc)
                    {
                        Console.WriteLine(exc.Message);
                        Console.WriteLine("Please, enter the data once more");
                        reenter = true;
                    }
                } while (reenter);                                              // if an exception arose, reenter A, B and C
            }
            Console.WriteLine("\nResults: ");
            for (int i = 0; i < size; i++)
            {
                Console.WriteLine($"Result {i + 1} = {expressions[i].GetResult():F6}");     // safe, because checked on exceptions earlier
            }
            Console.WriteLine("\nPress ENTER to quit");
            Console.Read();
        }
Пример #26
0
        public void Evaluate_Comment()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("1 + 2 + 3 # This is comment!");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(6, result);
            Assert.IsNull(ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #27
0
        public void Evaluate_Constant_AutoMultiply()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("2pi");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(2.0 * Math.PI, result);
            Assert.IsNull(ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #28
0
        public void Evaluate_Constant_3()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("6e-3");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(0.006, result);
            Assert.IsNull(ae.VariableName);
            Assert.IsTrue(ae.IsSimpleConstantOnly);
        }
Пример #29
0
        protected void exitRealArithmeticExpression(String op)
        {
            // popping order matters
            ArithmeticExpression     right = this.arithmeticExpressions.Pop();
            ArithmeticExpression     left  = this.arithmeticExpressions.Pop();
            RealArithmeticExpression expr  = new RealArithmeticExpression(op, left, right);

            this.arithmeticExpressions.Push(expr);
        }
Пример #30
0
        public void Evaluate_Function_RoundDown()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("round(z)");
            double result           = ae.Evaluate(6.49);

            Assert.AreEqual(6.0, result);
            Assert.AreEqual("z", ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #31
0
        public void Evaluate_SimpleFunction()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("cos(custom)");
            double result           = ae.Evaluate(0);

            Assert.AreEqual(1.0, result);
            Assert.AreEqual("custom", ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #32
0
        public void Evaluate_Variable()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("x");
            double result           = ae.Evaluate(-10);

            Assert.AreEqual(-10, result);
            Assert.AreEqual("x", ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #33
0
 public VariableOrExpression(ArithmeticExpression arithmeticExpression)
 {
     ArithmeticExpression = arithmeticExpression;
 }
Пример #34
0
        public IList<string> RunFast(bool calAll = true)
        {
            var result = new List<string>();
            calculate(calAll);

            foreach (var r in _result)
            {
                ArithmeticExpression root = null;
                for (int i = 0; i < r.Item3.Length; ++i)
                {
                    ArithmeticExpression n = new ArithmeticExpression();
                    n.index = r.Item3[i];
                    n.op = r.Item2[n.index];
                    n.numLeft = _numbers[r.Item1[n.index]];
                    n.numRight = _numbers[r.Item1[n.index + 1]];

                    if (root == null)
                    {
                        root = n;
                    }
                    else
                    {
                        if (n.index > root.index)
                        {
                            n.Left = root;
                            root.childPos = CalculateExpression.childLeft;
                        }
                        else
                        {
                            n.Right = root;
                            root.childPos = CalculateExpression.childRight;
                        }

                        root.Parent = n;
                        root = n;
                    }
                }

                if (root == null)
                    continue;

                if (root.index == 1)
                {
                    bool adjLeft = true;
                    if (root.Left == null)
                        adjLeft = false;

                    if (adjLeft)
                    {
                        var node = root.Left.Left == null ? root.Left.Right : root.Left.Left;
                        node.childPos = CalculateExpression.childRight;
                        root.Right = node;
                        root.Left.Left = root.Left.Right = null;
                    }
                    else
                    {
                        var node = root.Right.Left == null ? root.Right.Right : root.Right.Left;
                        node.childPos = CalculateExpression.childLeft;
                        root.Left = node;
                        root.Right.Left = root.Right.Right = null;
                    }
                }

                var exp = root.ToString();
                if (!result.Contains(exp))
                    result.Add(exp);
            }

            return result;
        }
Пример #35
0
            public static ArithmeticExpression Calculate(CalculateExpression left, OpFlag op, CalculateExpression right)
            {
                var e = new ArithmeticExpression();
                e.op = op;
                e.Left = left;
                e.Right = right;

                left.Parent = e;
                left.childPos = childLeft;
                right.Parent = e;
                right.childPos = childRight;

                return e;
            }
Пример #36
0
 public GreaterThan(IJsonParser jsonParser,
     ArithmeticExpression left,
     ArithmeticExpression right)
     : base(jsonParser, left, right)
 {
 }
        public MathExpression Parse(TokenStream tokens)
        {
            #region Sanity Check
            if (tokens == null)
            {
                throw new ArgumentNullException("tokens");
            }
            #endregion

            // Not in postfix?
            if (tokens.Notation != TokenNotation.Postfix)
            {
                throw new MathExpressionException("Invalid expression.", "Tokens are not in postfix notation.");
            }
            // No tokens in stream?
            if (tokens.Count == 0)
            {
                // Treat this as zero.
                return new NumericExpression(0D);
            }

            Stack<MathExpression> stack = new Stack<MathExpression>();
            foreach (Token token in tokens)
            {
                if (token.Type == TokenType.Numeric)
                {
                    // Create numeric expression.
                    stack.Push(new NumericExpression((double)token.Value));
                }
                else if (token.Type == TokenType.Constant)
                {
                    // Create constant expression.
                    var constant = (Tuple<string, double>)token.Value;
                    stack.Push(new ConstantExpression(constant.Item1, constant.Item2));
                }
                else if (token.Type == TokenType.Variable)
                {
                    // Create variable expression.
                    stack.Push(new VariableExpression((string)token.Value));
                }
                else if (token.Type == TokenType.Function)
                {
                    // Get the function.
                    string functionName = (string)token.Value;
                    MathExpressionFunction function = MathExpressionFunctionFactory.Default.GetFunction(functionName);

                    // Make sure we got as many arguments on the stack as we have expected arguments.
                    if (stack.Count != function.ParameterCount)
                    {
                        string message = string.Format("Function '{0}' expect {1} argument(s).", function.Name, function.ParameterCount);
                        throw new MathExpressionException(message);
                    }
                    // Create the expression.
                    var args = stack.Pop(function.ParameterCount).Reverse(); // Arguments are reversed on the stack.
                    stack.Push(new FunctionExpression(function.Name, args.ToArray()));
                }
                else
                {
                    // Make sure that the token is an operator.
                    if (!token.IsOperator())
                    {
                        throw new MathExpressionException("Invalid expression.", "Expected arithmetic operator in token stream.");
                    }
                    // Get the arithmetic operator for the token.
                    var @operator = token.GetArithmeticOperator();
                    if (@operator == ArithmeticOperator.Negation)
                    {
                        // Create negation expression.
                        MathExpression expression = stack.Pop();
                        stack.Push(new NegationExpression(expression));
                    }
                    else
                    {
                        // Create arithmetic expression.
                        MathExpression right = stack.Pop();
                        MathExpression left = stack.Pop();
                        ArithmeticExpression expression = new ArithmeticExpression(@operator, left, right);
                        stack.Push(expression);
                    }
                }
            }

            // There should be exactly one expression on the stack.
            if(stack.Count != 1)
            {
                throw new MathExpressionException("Invalid expression.", "There should be exactly one expression node on the stack.");
            }

            // Pop the expression from the stack.
            return stack.Pop();
        }
Пример #38
0
        /// <summary>
        /// Checks that parenthesis are used correctly within an arithmetic expression.
        /// </summary>
        /// <param name="element">The parent element.</param>
        /// <param name="expression">The expression to check.</param>
        private void CheckArithmeticExpressionParenthesis(Element element, ArithmeticExpression expression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");

            if (expression.LeftHandSide.ExpressionType == ExpressionType.Arithmetic)
            {
                if (!this.CheckArithmeticParenthesisForExpressionAndChild(
                    element, expression, (ArithmeticExpression)expression.LeftHandSide))
                {
                    return;
                }
            }

            if (expression.RightHandSide.ExpressionType == ExpressionType.Arithmetic)
            {
                this.CheckArithmeticParenthesisForExpressionAndChild(
                    element, expression, (ArithmeticExpression)expression.RightHandSide);
            }
        }
        /// <summary>
        /// Reads an arithmetic expression.
        /// </summary>
        /// <param name="leftHandSide">The expression on the left hand side of the operator.</param>
        /// <param name="previousPrecedence">The precedence of the expression just before this one.</param>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <returns>Returns the expression.</returns>
        private ArithmeticExpression GetArithmeticExpression(
            Expression leftHandSide, ExpressionPrecedence previousPrecedence, bool unsafeCode)
        {
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);
            Param.Ignore(unsafeCode);

            ArithmeticExpression expression = null;
            
            // Read the details of the expression.
            OperatorSymbol operatorToken = this.PeekOperatorToken();
            Debug.Assert(
                operatorToken.Category == OperatorCategory.Arithmetic || operatorToken.Category == OperatorCategory.Shift, 
                "Expected an arithmetic or shift operator");

            // Check the precedence of the operators to make sure we can gather this statement now.
            ExpressionPrecedence precedence = this.GetOperatorPrecedence(operatorToken.SymbolType);
            if (this.CheckPrecedence(previousPrecedence, precedence))
            {
                // Add the operator token to the document and advance the symbol manager up to it.
                this.symbols.Advance();
                this.tokens.Add(operatorToken);

                // Get the expression on the right-hand side of the operator.
                Expression rightHandSide = this.GetOperatorRightHandExpression(precedence, unsafeCode);

                // Create the partial token list for the expression.
                CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last);

                // Get the expression operator type.
                ArithmeticExpression.Operator type;
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.Plus:
                        type = ArithmeticExpression.Operator.Addition;
                        break;

                    case OperatorType.Minus:
                        type = ArithmeticExpression.Operator.Subtraction;
                        break;

                    case OperatorType.Multiplication:
                        type = ArithmeticExpression.Operator.Multiplication;
                        break;

                    case OperatorType.Division:
                        type = ArithmeticExpression.Operator.Division;
                        break;

                    case OperatorType.Mod:
                        type = ArithmeticExpression.Operator.Mod;
                        break;

                    case OperatorType.LeftShift:
                        type = ArithmeticExpression.Operator.LeftShift;
                        break;

                    case OperatorType.RightShift:
                        type = ArithmeticExpression.Operator.RightShift;
                        break;

                    default:
                        Debug.Fail("Unexpected operator type");
                        throw new InvalidOperationException();
                }

                // Create and return the expression.
                expression = new ArithmeticExpression(partialTokens, type, leftHandSide, rightHandSide);
            }

            return expression;
        }
Пример #40
0
        /// <summary>
        /// Checks whether parenthesis are needed within the arithmetic expressions.
        /// </summary>
        /// <param name="element">The parent element.</param>
        /// <param name="expression">The parent arithmetic expression.</param>
        /// <param name="childExpression">The child arithmetic expression.</param>
        /// <returns>Returns true if there is no violation, or false if there is a violation.</returns>
        private bool CheckArithmeticParenthesisForExpressionAndChild(
            Element element, ArithmeticExpression expression, ArithmeticExpression childExpression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(childExpression, "childExpression");

            // Parenthesis are only required when the two expressions are not the same operator,
            // and when the two operators come from different families. 
            if (expression.ArithmeticExpressionType != childExpression.ArithmeticExpressionType)
            {
                bool sameFamily =
                    ((expression.ArithmeticExpressionType == ArithmeticExpressionType.Addition ||
                      expression.ArithmeticExpressionType == ArithmeticExpressionType.Subtraction) &&
                     (childExpression.ArithmeticExpressionType == ArithmeticExpressionType.Addition ||
                      childExpression.ArithmeticExpressionType == ArithmeticExpressionType.Subtraction)) ||
                    ((expression.ArithmeticExpressionType == ArithmeticExpressionType.Multiplication ||
                      expression.ArithmeticExpressionType == ArithmeticExpressionType.Division) &&
                     (childExpression.ArithmeticExpressionType == ArithmeticExpressionType.Multiplication ||
                      childExpression.ArithmeticExpressionType == ArithmeticExpressionType.Division)) ||
                    ((expression.ArithmeticExpressionType == ArithmeticExpressionType.LeftShift ||
                      expression.ArithmeticExpressionType == ArithmeticExpressionType.RightShift) &&
                     (childExpression.ArithmeticExpressionType == ArithmeticExpressionType.LeftShift ||
                      childExpression.ArithmeticExpressionType == ArithmeticExpressionType.RightShift));

                if (!sameFamily)
                {
                    this.AddViolation(element, expression.LineNumber, Rules.ArithmeticExpressionsMustDeclarePrecedence);
                    return false;
                }
            }

            return true;
        }