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)); }
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); }
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); }
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()); }
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; } } }
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")); }
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); } }
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); }
public override Object Visit(ArithmeticExpression node, Object obj) { node.FirstOperand.Accept(this, obj); node.SecondOperand.Accept(this, obj); return(null); }
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)); }
/// <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; }
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); }
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); }
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; }
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); }
static void Main(string[] args) { string str = "c = a * cdb - g"; ArithmeticExpression ArithExpression1 = new ArithmeticExpression(); ArithExpression1.Source = str; ArithExpression1.WrapFillLeksemu(); }
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); }
public ArithmeticExpression MakeAssignmentRHS(Value value) { ArithmeticExpression arithmeticExpression = new ArithmeticExpression(); arithmeticExpression.AddValue(value); return(arithmeticExpression); }
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); }
public ArithmeticExpression MakeArithmeticExperssion(SubExpressionType expression) { ArithmeticExpression arithmeticExpression = new ArithmeticExpression(); arithmeticExpression.AddSubExpression(expression); return(arithmeticExpression); }
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(); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
public VariableOrExpression(ArithmeticExpression arithmeticExpression) { ArithmeticExpression = arithmeticExpression; }
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; }
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; }
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(); }
/// <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; }
/// <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; }