public class ConditionCalculater
{
public ConditionCalculater()
{
conditionStack = new Stack<bool>();
operatorStack = new Stack<char>();
}
private Stack<bool> conditionStack { get; set; }
private List<char> conditionItem = new List<char>();
private Stack<char> operatorStack { get; set; }
public delegate bool IsConditionMathEventHandler(string condition);
private bool isFinishedAnalysisExpression = false;
public bool AnalysisExpression(IsConditionMathEventHandler MathCondition, string conditionExpression)
{
for (int i = 0; i < conditionExpression.Length; i++)
{
if (i == conditionExpression.Length - 1)
{
isFinishedAnalysisExpression = true;
}
switch (conditionExpression[i])
{
case '{':
conditionItem.Clear();
break;
case '}':
var result = MathCondition(new string(conditionItem.ToArray()));
conditionStack.Push(result);
if (conditionStack.Count >= 2 && operatorStack.Count > 0)
{
Calculate();
}
break;
case '&':
operatorStack.Push('&');
break;
case '|':
operatorStack.Push('|');
break;
case '(':
operatorStack.Push('(');
break;
case ')':
operatorStack.Push(')');
break;
default:
conditionItem.Add(conditionExpression[i]);
break;
}
}
Calculate();
if (conditionStack.Count == 1)
{
return conditionStack.Pop();
}
else
{
throw new Exception("表达式格式错误!");
}
}
private void Calculate()
{
if (operatorStack.Count > 0 && conditionStack.Count > 1)
{
var operatorChar = operatorStack.Peek();
if (CanOperatorCharOperator(operatorChar))
{
var first = conditionStack.Pop();
var second = conditionStack.Pop();
var result = CalculateTwoCondition(first, second, operatorChar);
operatorStack.Pop();
conditionStack.Push(result);
if (conditionStack.Count > 1 && operatorStack.Count > 0)
{
Calculate();
}
}
else
{
if (isFinishedAnalysisExpression)
{
operatorStack.Pop();
Calculate();
}
}
}
}
private bool CanOperatorCharOperator(char operatorChar)
{
bool can = false;
switch (operatorChar)
{
case '(':
can = false;
break;
case ')':
can = false;
break;
case '&':
can = true;
break;
case '|':
can = true;
break;
default:
can = false;
break;
}
return can;
}
private bool CalculateTwoCondition(bool first, bool second, char operatorChar)
{
bool result = false;
switch (operatorChar)
{
case '&':
result = first && second;
break;
case '|':
result = first || second;
break;
default:
break;
}
return result;
}
}