public Token(string RuleSyntax) { tokenItems = new TokenItems(this); ruleSyntax = RuleSyntax.Trim(); lastErrorMessage = ""; GetTokens(); }
public Token(System.IO.FileInfo Filename) { tokenItems = new TokenItems(this); string ErrorMsg = ""; if (Open(Filename, out ErrorMsg) == false) { throw new Exception(ErrorMsg); } }
private bool EvaluateOperandFunction(Parser.TokenItem OperandFunction, Parser.TokenItems Parameters, out Parser.TokenItem Result, out string ErrorMsg) { // intitialize the outgoing variables Result = null; // assume a failure by setting the result to null ErrorMsg = ""; // local variables bool success = true; // validate the parameters if (OperandFunction == null) { ErrorMsg = "Failed to evaluate the operand function: The operand function token is null."; XapLogger.Instance.Error(ErrorMsg); return(false); } if (Parameters == null) { ErrorMsg = "Failed to evaluate the operand function: The parameters collection is null."; XapLogger.Instance.Error(ErrorMsg); return(false); } ScriptCacheManager.Instance.ExtractScriptOperands(); foreach (ScriptOperand operand in ScriptCacheManager.Instance.GetScriptOperands()) { foreach (MethodInfo method in operand.GetEngineOperandMethods()) { if (method.Name + "[" == OperandFunction.TokenName) { //execute the method and exit loop try { object[] p = new object[1]; p[0] = Parameters; Support.OperandResult _retVal = (Support.OperandResult)method.Invoke(operand.EngineOperand, p); success = _retVal.Success; Result = _retVal.Result; } catch (Exception ex) { XapLogger.Instance.Error($"Failed to evaluate the operand function {OperandFunction.TokenName.Trim()}"); ErrorMsg = "Failed to evaluate the operand function " + OperandFunction.TokenName.Trim() + ": " + ex.Message; success = false; } } } } return(success); }
/// <summary> /// This new evaluate function includes support to assignment and short circuit of the IIF[] operand function /// </summary> /// <param name="RPNQueue"></param> /// <param name="sValue"></param> /// <param name="ErrorMsg"></param> /// <returns></returns> public bool Evaluate(Support.ExQueue <Parser.TokenItem> RPNQueue, out string sValue, out string ErrorMsg) { // initialize the outgoing variable ErrorMsg = ""; sValue = ""; // reset the results in the token token.LastEvaluationResult = ""; // create a stop watch to time the evaluation //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; XapLogger.Instance.Error(ErrorMsg); 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 = RPNQueue.Count; int index = 0; // the index of the curent token item in the rpn queue while (index < count) { // get the next token item Parser.TokenItem item = RPNQueue[index]; index++; if (item.TokenDataType == Evaluation.Engine.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 == Evaluation.Engine.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 Evaluation.Engine.Evaluator.Evaluate() while popping 2 tokens for an operator: " + err.Message; XapLogger.Instance.Error(ErrorMsg); 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."; XapLogger.Instance.Error(ErrorMsg); 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."; XapLogger.Instance.Error(ErrorMsg); 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."; XapLogger.Instance.Error(ErrorMsg); 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; XapLogger.Instance.Error(ErrorMsg); return(false); } #endregion } else if (item.TokenType == Evaluation.Engine.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(token); try { for (int j = 0; j < evalCount; j++) { Parser.TokenItem opItem = eval.Pop(); if (opItem.TokenType == Evaluation.Engine.Parser.TokenType.Token_Operand_Function_Start) { // we found the start of the operand function; let's evaluate it Parser.TokenItem result = null; EvaluateOperandFunction(opItem, parameters, out result, out ErrorMsg); //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."; XapLogger.Instance.Error(ErrorMsg); return(false); } else { eval.Push(result); } //} break; } else if (opItem.TokenType != Evaluation.Engine.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; XapLogger.Instance.Error(ErrorMsg); return(false); } #endregion } else if (item.TokenType == Evaluation.Engine.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 Evaluation.Engine.Evaluator.Evaluate() while popping 2 tokens for an operator: " + err.Message; XapLogger.Instance.Error(ErrorMsg); 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."; XapLogger.Instance.Error(ErrorMsg); 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."; XapLogger.Instance.Error(ErrorMsg); 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."; XapLogger.Instance.Error(ErrorMsg); return(false); } #endregion } else if (item.TokenType == Evaluation.Engine.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 // //////////////////////////////////////////////// Parser.TokenItem result = item.ShortCircuit.Evaluate(out ErrorMsg); if (result == null) { // there was an error doing the short circuit return(false); } else { // we successfully did the short circuit eval.Push(result); // increment the index so we skip the ] which should be the next token index++; } } } #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; XapLogger.Instance.Error(ErrorMsg); 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"; XapLogger.Instance.Error(ErrorMsg); return(false); } // stop the timer //evalTime.Stop(); //tokenEvalTime = evalTime.Elapsed.TotalMilliseconds; // token.LastEvaluationTime = tokenEvalTime; // set this evaluation time in the token object. return(true); }
/// <summary> /// This new evaluate function includes support to assignment and short circuit of the IIF[] operand function /// </summary> /// <param name="RPNQueue"></param> /// <param name="sValue"></param> /// <param name="ErrorMsg"></param> /// <returns></returns> public bool Evaluate(Support.ExQueue<Parser.TokenItem> RPNQueue, out string sValue, out string ErrorMsg) { // initialize the outgoing variable ErrorMsg = ""; sValue = ""; // reset the results in the token token.LastEvaluationResult = ""; // create a stop watch to time the evaluation 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 = RPNQueue.Count; int index = 0; // the index of the curent token item in the rpn queue while (index < count) { // get the next token item Parser.TokenItem item = RPNQueue[index]; index++; System.Diagnostics.Debug.WriteLine(item.TokenName); if (item.TokenDataType == 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 == 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 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 == 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(token); try { for (int j = 0; j < evalCount; j++) { Parser.TokenItem opItem = eval.Pop(); if (opItem.TokenType == 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 != 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 == 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 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 == 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 // //////////////////////////////////////////////// Parser.TokenItem result = item.ShortCircuit.Evaluate(out ErrorMsg); if (result == null) { // there was an error doing the short circuit return false; } else { // we successfully did the short circuit eval.Push(result); // increment the index so we skip the ] which should be the next token index++; } } } #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(); tokenEvalTime = evalTime.Elapsed.TotalMilliseconds; token.LastEvaluationTime = tokenEvalTime; // set this evaluation time in the token object. return true; }