📄 evaluator.cs
字号:
System.Diagnostics.Stopwatch evalTime = System.Diagnostics.Stopwatch.StartNew();
// make sure the otkens are valid
if (token.AnyErrors == true)
{
// the token already has an error, return the token error as the evaluator error message
ErrorMsg = token.LastErrorMessage;
return false;
}
// create the evaluation stack
Support.ExStack<Parser.TokenItem> eval = new Support.ExStack<Parser.TokenItem>(token.TokenItems.Count);
// start looping through the tokens
int count = token.RPNQueue.Count;
for (int i = 0; i < count; i++)
{
// get the next token item
Parser.TokenItem item = token.RPNQueue[i];
System.Diagnostics.Debug.WriteLine(item.TokenName);
if (item.TokenDataType == EvaluationEngine.Parser.TokenDataType.Token_DataType_Variable)
{
#region Token_DataType_Variable
// determine if we need to assign the variable represented by the token
// or the rule syntax is doing the assignment
if (item.WillBeAssigned == false)
{
// The rule syntax is not doing the assignment, we are doing it.
// lookup the value of the variable and push it onto the evaluation stack
if (token.Variables.VariableExists(item.TokenName) == true)
{
// the variable exists, push it on the stack
eval.Push(new Parser.TokenItem(token.Variables[item.TokenName].VariableValue, Parser.TokenType.Token_Operand, item.InOperandFunction));
}
else
{
// the variable does not exist...push an empty string on the stack
eval.Push(new Parser.TokenItem("", Parser.TokenType.Token_Operand, item.InOperandFunction));
}
}
else
{
// the rule syntax is doing the assignment, add the token item to the evaluation stack
eval.Push(item);
}
#endregion
}
else if (item.TokenType == EvaluationEngine.Parser.TokenType.Token_Operator)
{
#region Token_Operator
// pop 2 items off the stack and perform the operation
// push the result back onto the evaluation stack
Parser.TokenItem rightOperand = null;
Parser.TokenItem leftOperand = null;
try
{
if (eval.Count > 0) rightOperand = eval.Pop();
if (eval.Count > 0) leftOperand = eval.Pop();
}
catch (Exception err)
{
ErrorMsg = "Error in EvaluationEngine.Evaluator.Evaluate() while popping 2 tokens for an operator: " + err.Message;
return false;
}
// double check that we got the tokens before we evaluate
if (rightOperand == null)
{
ErrorMsg = "Failed to evaluate the rule expression: The right operand token is null: There may be an issue with the rule syntax.";
return false;
}
if (leftOperand == null)
{
ErrorMsg = "Failed to evaluate the rule expression: The left operand token is null: There may be an issue with the rule syntax.";
return false;
}
// process the operator
try
{
Parser.TokenItem result = null;
if (EvaluateTokens(leftOperand, rightOperand, item, out result, out ErrorMsg) == false)
return false;
else
{
// double check that we got a result
if (result == null)
{
ErrorMsg = "Failed to evaluate the rule expression: The result of an operator is null: There may be an issue with the rule syntax.";
return false;
}
else
{
eval.Push(result);
}
}
}
catch (Exception err)
{
ErrorMsg = "Failed to evaluate the rule expression: The result of an operator threw an error: " + err.Message;
return false;
}
#endregion
}
else if (item.TokenType == EvaluationEngine.Parser.TokenType.Token_Operand_Function_Stop)
{
#region Token_Operand_Function_Stop
// find the start of the function by popping off items
// evaluate the function and push the result back onto the evaluation stack
// start popping items from the evaluation stack
// until we get the start of the of the operand function
int evalCount = eval.Count;
Parser.TokenItems parameters = new Parser.TokenItems();
try
{
for (int j = 0; j < evalCount; j++)
{
Parser.TokenItem opItem = eval.Pop();
if (opItem.TokenType == EvaluationEngine.Parser.TokenType.Token_Operand_Function_Start)
{
// we found the start of the operand function; let's evaluate it
Parser.TokenItem result = null;
if (EvaluateOperandFunction(opItem, parameters, out result, out ErrorMsg) == false)
return false;
else
{
// make sure we got a result
if (result == null)
{
ErrorMsg = "Failed to evaluate the rule expression: The result of an operand function is null: There may be an issue with the rule syntax.";
return false;
}
else
eval.Push(result);
}
break;
}
else if (opItem.TokenType != EvaluationEngine.Parser.TokenType.Token_Operand_Function_Delimiter)
{
// we have a parameter to the operand function
parameters.AddToFront(opItem);
}
}
}
catch (Exception err)
{
ErrorMsg = "Failed to evaluate the rule expression: The evaluation of an operand function threw an error: " + err.Message;
return false;
}
#endregion
}
else if (item.TokenType == EvaluationEngine.Parser.TokenType.Token_Assignemt_Start)
{
#region Token_Assignment_Start
// assign the value to the variable
// pop 2 items off the stack - save the value into the variable
Parser.TokenItem rightOperand = null;
Parser.TokenItem leftOperand = null;
try
{
if (eval.Count > 0) rightOperand = eval.Pop();
if (eval.Count > 0) leftOperand = eval.Pop();
}
catch (Exception err)
{
ErrorMsg = "Error in EvaluationEngine.Evaluator.Evaluate() while popping 2 tokens for an operator: " + err.Message;
return false;
}
// double check that we got the tokens before we evaluate
if (rightOperand == null)
{
ErrorMsg = "Failed to evaluate the rule expression: The right operand token is null: There may be an issue with the rule syntax.";
return false;
}
if (leftOperand == null)
{
ErrorMsg = "Failed to evaluate the rule expression: The left operand token is null: There may be an issue with the rule syntax.";
return false;
}
// look for the variable and assign the value to it
if (token.Variables.VariableExists(leftOperand.TokenName) == true)
{
// the variable exists, push it on the stack
token.Variables[leftOperand.TokenName].VariableValue = rightOperand.TokenName;
}
else
{
// failed to find the variable....this is an error
ErrorMsg = "Failed to evaluate the rule expression: Failed to find the variable '" + leftOperand.TokenName + "' for the assignment.";
return false;
}
#endregion
}
else if (item.TokenType == EvaluationEngine.Parser.TokenType.Token_Operand_Function_Start)
{
#region New Short Circuit Code
// we are only short circuiting the IIF[] operand function
if (item.TokenName.Trim().ToLower() != "iif[")
{
// add the token to the evaluation stack
eval.Push(item);
}
else
{
// we found the iif statement.
// see if the iff[] operand function allows for short circuiting
if (item.CanShortCircuit == false)
{
// no short circuiting, add it to the evaluation stack
eval.Push(item);
}
else
{
////////////////////////////////////////////////
// We can short circuit this iif[] statement //
////////////////////////////////////////////////
eval.Push(item);
}
}
#endregion
}
else
{
// push the item on the evaluation stack
eval.Push(item);
}
}
if (eval.Count == 1)
{
// just 1 item on the stack; should be our answer
try
{
Parser.TokenItem final = eval.Pop();
sValue = final.TokenName;
// set the results in the token
token.LastEvaluationResult = sValue;
}
catch (Exception err)
{
ErrorMsg = "Failed to evaluate the rule expression after all the tokens have been considered: " + err.Message;
return false;
}
}
else if (eval.Count == 0)
{
// there is no result in the evaluation stack because it my have been assigned
// do nothing here
}
else
{
ErrorMsg = "Invalid Rule Syntax";
return false;
}
// stop the timer
evalTime.Stop();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -