private Expression GetExpressionParametersMultiplied(Expression expr) { if (!expr.Normalized) { throw new Exception(); } if (expr is MultiplyExpression) { if ((expr as MultiplyExpression).Operands.First() is ConstantExpression) { var o = (expr as MultiplyExpression).Operands.Skip(1); if (o.Count() == 1) { return(o.Single()); } else { MultiplyExpression m = new MultiplyExpression(o.ToList()); m.Normalized = true; return(m); } } return(expr); } if (expr is ParameterExpression) { return(expr); } throw new Exception(); }
private Expression expr1(int priority) { Expression retVal; Expression right; if (priority >= 0) { retVal = expr1(priority - 1); } else { return(factor()); } while (inPriority(lookAhead.TokenType, priority)) { switch (lookAhead.TokenType) { case '+': accept(); right = expr1(priority - 1); retVal = new AddExpression(new List <Expression> { retVal, right }); break; case '-': accept(); right = expr1(priority - 1); retVal = new AddExpression(new List <Expression> { retVal, new MultiplyExpression( new List <Expression> { new ConstantExpression(-1), right } ) }); break; case '*': accept(); right = expr1(priority - 1); retVal = new MultiplyExpression(new List <Expression> { retVal, right }); break; default: return(retVal); } } return(retVal); }
public override Expression Normalize() { if (Normalized) { return(this); } if (this.Operands.Count == 0) { return(new ConstantExpression(0)); } if (this.Operands.Count == 1) { return(this.Operands.Single().Normalize()); } List <Expression> finalResult = new List <Expression>(); finalResult.Add(new ConstantExpression(1)); foreach (var operand in Operands) { List <Expression> currentResult = new List <Expression>(); var operandNormalized = operand.Normalize(); foreach (var operand2 in finalResult) { ReadOnlyCollection <Expression> operandSubs = operandNormalized is AddExpression ? (operandNormalized as AddExpression).Operands : new List <Expression> { operandNormalized }.AsReadOnly(); foreach (var operandSub in operandSubs) { if (operand2 is AddExpression || operandSub is AddExpression) { throw new Exception(); } List <Expression> allFactors = new List <Expression>(); foreach (var o in new List <Expression> { operand2, operandSub }) { if (o is MultiplyExpression) { allFactors.AddRange((o as MultiplyExpression).Operands); } else { allFactors.Add(o); } } List <ParameterExpression> allParameters = allFactors.OfType <ParameterExpression>().ToList(); List <ConstantExpression> allConstants = allFactors.OfType <ConstantExpression>().ToList(); double constant = 1; foreach (var c in allConstants) { constant *= c.Constant; } List <Expression> allFactorsNormalized = new List <Expression>(); if (constant != 0) { if (constant != 1 || allParameters.Count == 0) { allFactorsNormalized.Add(new ConstantExpression(constant)); } allFactorsNormalized.AddRange(allParameters.OrderBy(_ => _.ParameterName)); } if (allFactorsNormalized.Count == 1) { currentResult.Add(allFactorsNormalized.Single()); } if (allFactorsNormalized.Count > 1) { var expr = new MultiplyExpression(allFactorsNormalized); expr.Normalized = true; currentResult.Add(expr); } } } finalResult = currentResult; } return(new AddExpression(finalResult).Normalize()); }
public override Expression Normalize() { if (Normalized) { return(this); } var middle = operands.Select(_ => _.Normalize()).Where(_ => { if (_ is ConstantExpression) { if ((_ as ConstantExpression).Constant == 0) { return(false); } } return(true); }); double constant = 0; var normalized = new List <Expression>(); foreach (var operand in middle) { if (operand is ConstantExpression) { constant += operand.Calculate(null); } else if (operand is AddExpression) { foreach (var c in (operand as AddExpression).operands.OfType <ConstantExpression>()) { constant += c.Constant; } normalized.AddRange((operand as AddExpression).operands.Where(_ => !(_ is ConstantExpression))); } else { normalized.Add(operand); } } if (constant != 0) { normalized.Add(new ConstantExpression(constant)); } normalized = normalized.OrderBy(_ => _, CompareExpression.Instance).ToList(); var normalized2 = new List <Expression>(); Expression lastExpression = null; foreach (var expression in normalized) { if (lastExpression != null && !(lastExpression is ConstantExpression) && !(expression is ConstantExpression)) { var operand1 = GetExpressionParametersMultiplied(lastExpression); var operand2 = GetExpressionParametersMultiplied(expression); if (operand1.Equals(operand2)) { var constantd = GetExpressionConstant(lastExpression) + GetExpressionConstant(expression); if (constantd == 0) { lastExpression = null; } else if (constantd == 1) { lastExpression = operand1; } else { var expressionOperands = new List <Expression>(); expressionOperands.Add(new ConstantExpression(constantd)); if (operand1 is ParameterExpression) { expressionOperands.Add(operand1); } else { expressionOperands.AddRange((operand1 as MultiplyExpression).Operands); } lastExpression = new MultiplyExpression(expressionOperands); lastExpression.Normalized = true; } continue; } } if (lastExpression != null) { normalized2.Add(lastExpression); } lastExpression = expression; } if (lastExpression != null) { normalized2.Add(lastExpression); } if (normalized2.Count() == 1) { return(normalized2.Single()); } if (normalized2.Count() == 0) { return(new ConstantExpression(0)); } var exp = new AddExpression(normalized2); exp.Normalized = true; return(exp); }