public void Bra_A_Eq_Minus_12_Bra() { ExpressionEval evaluator = new ExpressionEval(); // definir langue: fr ou en, sert pour les opérateurs: ET/AND, OU/OR, NON/NOT. evaluator.SetLang(Language.En); string expr = "(A=-12)"; //-1---parse the string, return a syntax tree ParseResult parseResult = evaluator.Parse(expr); Assert.IsFalse(parseResult.HasError, "the expression process should return success"); // check the root node ExprComparison rootBinExpr = parseResult.RootExpr as ExprComparison; Assert.IsNotNull(rootBinExpr, "The root node type should be BoolBinExpr"); // check the left part of the root node ExprFinalOperand operandLeft = rootBinExpr.ExprLeft as ExprFinalOperand; Assert.IsNotNull(operandLeft, "The left root node type should be BoolBinExprOperand"); Assert.AreEqual(operandLeft.Operand, "A", "The left operand should be A"); // check the right part of the root node ExprFinalOperand operandRight = rootBinExpr.ExprRight as ExprFinalOperand; Assert.IsNotNull(operandRight, "The left root node type should be BoolBinExprOperand"); Assert.AreEqual(operandRight.Operand, "-12", "The left operand should be -12"); // check the root node operator Assert.AreEqual(rootBinExpr.Operator, OperatorComparisonCode.Equals, "The root operator should be ="); }
public void Expr_OP_a_Minus_2_CP_Eq_7_ok() { ExpressionEval evaluator = new ExpressionEval(); // definir langue: fr ou en, sert pour les opérateurs: ET/AND, OU/OR, NON/NOT. evaluator.SetLang(Language.En); string expr = "(a-2) = 7"; //-1---parse the string, return a syntax tree ParseResult parseResult = evaluator.Parse(expr); Assert.IsFalse(parseResult.HasError, "the expression process should finish successfully"); // check the root node ExprComparison rootExpr = parseResult.RootExpr as ExprComparison; Assert.IsNotNull(rootExpr, "The root node type should be an ExprComparison"); Assert.AreEqual(OperatorComparisonCode.Equals, rootExpr.Operator, "The operator qqhould: plus"); //----left part (a-2) // check the left part ExprCalculation operandLeft = rootExpr.ExprLeft as ExprCalculation; Assert.IsNotNull(operandLeft, "The left root node type should be an ExprCalculation"); Assert.AreEqual(OperatorCalculationCode.Minus, operandLeft.ListOperator[0].Operator, "The operator should: minus"); // check the right part ExprFinalOperand operandLeftRight = operandLeft.ListExprOperand[0] as ExprFinalOperand; Assert.IsNotNull(operandLeftRight, "The left root node type should be a ExprFinalOperand"); Assert.AreEqual("a", operandLeftRight.Operand, "The left operand should be: a"); // check the right part of the root node ExprFinalOperand operandRightRight = operandLeft.ListExprOperand[1] as ExprFinalOperand; Assert.IsNotNull(operandRightRight, "The left root node type should be a ExprFinalOperand"); Assert.AreEqual(2, operandRightRight.ValueInt, "The left operand should be 2"); //----right part: 7 // check the left part ExprFinalOperand operandRight = rootExpr.ExprRight as ExprFinalOperand; Assert.IsNotNull(operandRight, "The left root node type should be a ExprFinalOperand"); Assert.AreEqual(7, operandRight.ValueInt, "The left operand should be 7"); }
public void fct_OP_a_CP_Ge_b_ok() { string expr = "fct(a) >= b"; List <ExprToken> listTokens = TestCommon.AddTokens("fct", "(", "a", ")", ">="); TestCommon.AddTokens(listTokens, "b"); // decoder, renvoie un arbre de node ExprTokensParser parser = new ExprTokensParser(); // the default list: =, <, >, >=, <=, <> ExpressionEvalConfig config = TestCommon.BuildDefaultConfig(); parser.SetConfiguration(config); // decode the list of tokens ParseResult result = parser.Parse(expr, listTokens); // finished with no error Assert.AreEqual(0, result.ListError.Count, "The tokens should be decoded with success"); // get the root expression ExprComparison exprComparison = result.RootExpr as ExprComparison; Assert.IsNotNull(exprComparison, "The root node type should be Comparison"); //----check the left part of the comparison: the function call ExprFunctionCall exprFunction = exprComparison.ExprLeft as ExprFunctionCall; Assert.IsNotNull(exprFunction, "The root node type should be ExprFunctionCall"); Assert.AreEqual("fct", exprFunction.FunctionName, "The function name should be: fct"); Assert.AreEqual(1, exprFunction.ListExprParameters.Count, "The function call should have one parameter"); // check the parameter: its a final operand ExprFinalOperand paraFunction = exprFunction.ListExprParameters[0] as ExprFinalOperand; Assert.AreEqual("a", paraFunction.Operand, "The parameter name should be: a"); Assert.IsTrue(paraFunction.ContentType == OperandType.ObjectName, "The parameter type should be: ObjectName"); //----check the right part of the root node ExprFinalOperand operandRight = exprComparison.ExprRight as ExprFinalOperand; Assert.IsNotNull(operandRight, "The left root node type should be BoolBinExprOperand"); Assert.AreEqual(operandRight.Operand, "b", "The left operand should be A"); }
public void fct_OP_a_Eq_b_CP_ok() { string expr = "fct(a=b)"; List <ExprToken> listTokens = TestCommon.AddTokens("fct", "(", "a", "=", "b", ")"); // decoder, renvoie un arbre de node ExprTokensParser parser = new ExprTokensParser(); ExpressionEvalConfig config = TestCommon.BuildDefaultConfig(); parser.SetConfiguration(config); // decode the list of tokens ParseResult result = parser.Parse(expr, listTokens); // finished with no error Assert.AreEqual(0, result.ListError.Count, "The tokens should be decoded with success"); // get the root expression ExprFunctionCall rootExpr = result.RootExpr as ExprFunctionCall; Assert.IsNotNull(rootExpr, "The root node type should be ExprFunctionCall"); Assert.AreEqual("fct", rootExpr.FunctionName, "The function name should be: fct"); Assert.AreEqual(1, rootExpr.ListExprParameters.Count, "The function call should have one parameter"); // check the parameter: its a comparison expression ExprComparison exprComparison = rootExpr.ListExprParameters[0] as ExprComparison; Assert.AreEqual(OperatorComparisonCode.Equals, exprComparison.Operator, "The operator name should be: ="); // check the left part: its a final operand: a ExprFinalOperand operandLeft = exprComparison.ExprLeft as ExprFinalOperand; Assert.AreEqual("a", operandLeft.Operand, "should be: a"); Assert.IsTrue(operandLeft.ContentType == OperandType.ObjectName, "The type should be: ObjectName"); // check the right part: its a final operand: a ExprFinalOperand operandRight = exprComparison.ExprRight as ExprFinalOperand; Assert.AreEqual("b", operandRight.Operand, "should be: b"); Assert.IsTrue(operandLeft.ContentType == OperandType.ObjectName, "The type should be: ObjectName"); }
public void A_Eq_B() { string expr = "A=B"; List <ExprToken> listTokens = TestCommon.AddTokens("A", "=", "B"); // decoder, renvoie un arbre de node ExprTokensParser parser = new ExprTokensParser(); // the default list: =, <, >, >=, <=, <> var dictOperators = TestCommon.BuildDefaultConfig(); parser.SetConfiguration(dictOperators); // decode the list of tokens ParseResult result = parser.Parse(expr, listTokens); // finished with no error Assert.AreEqual(0, result.ListError.Count, "The tokens (A=B) should be decoded with success"); //----check the root node ExprComparison rootBinExpr = result.RootExpr as ExprComparison; Assert.IsNotNull(rootBinExpr, "The root node type should be BoolBinExpr"); //----check the left part of the root node ExprFinalOperand operandLeft = rootBinExpr.ExprLeft as ExprFinalOperand; Assert.IsNotNull(operandLeft, "The left root node type should be BoolBinExprOperand"); Assert.AreEqual(operandLeft.Operand, "A", "The left operand should be A"); //----check the right part of the root node ExprFinalOperand operandRight = rootBinExpr.ExprRight as ExprFinalOperand; Assert.IsNotNull(operandRight, "The left root node type should be BoolBinExprOperand"); Assert.AreEqual(operandRight.Operand, "B", "The left operand should be B"); // check the root node operator Assert.AreEqual(rootBinExpr.Operator, OperatorComparisonCode.Equals, "The root operator should be ="); }
public void a_Gt_fct_OP_CP_ok() { string expr = "a > fct()"; List <ExprToken> listTokens = TestCommon.AddTokens("a", ">", "fct", "(", ")"); // decoder, renvoie un arbre de node ExprTokensParser parser = new ExprTokensParser(); // the default list: =, <, >, >=, <=, <> ExpressionEvalConfig config = TestCommon.BuildDefaultConfig(); parser.SetConfiguration(config); // decode the list of tokens ParseResult result = parser.Parse(expr, listTokens); // finished with no error Assert.AreEqual(0, result.ListError.Count, "The tokens should be decoded with success"); // get the root expression ExprComparison exprComparison = result.RootExpr as ExprComparison; Assert.IsNotNull(exprComparison, "The root node type should be Comparison"); //----check the left part of the root node ExprFinalOperand operandLeft = exprComparison.ExprLeft as ExprFinalOperand; Assert.IsNotNull(operandLeft, "The left root node type should be BoolBinExprOperand"); Assert.AreEqual(operandLeft.Operand, "a", "The left operand should be A"); //----check the right part of the comparison: the function call ExprFunctionCall exprFunction = exprComparison.ExprRight as ExprFunctionCall; Assert.IsNotNull(exprFunction, "The root node type should be ExprFunctionCall"); Assert.AreEqual("fct", exprFunction.FunctionName, "The function name should be: fct"); Assert.AreEqual(0, exprFunction.ListExprParameters.Count, "The function call should have any parameter"); }
/// <summary> /// analyze and return the list of variables and functionCalls found in the expression to define before execute it. /// Do also some checks. /// </summary> /// <param name="exprParseResult"></param> /// <param name="expr"></param> /// <returns></returns> private bool AnalyzeSyntaxTree(ParseResult result, ExpressionBase expr) { //----is it a final operand? ExprFinalOperand exprFinalOperand = expr as ExprFinalOperand; if (exprFinalOperand != null) { if (exprFinalOperand.ContentType == OperandType.ObjectName) { // save the objectName (variable) result.AddVariable(exprFinalOperand.Operand); } return(true); } //----is it a function call? ExprFunctionCall exprFunctionCall = expr as ExprFunctionCall; if (exprFunctionCall != null) { // scan parameters of the function call foreach (ExpressionBase exprParam in exprFunctionCall.ListExprParameters) { AnalyzeSyntaxTree(result, exprParam); } result.AddFunctionCall(exprFunctionCall.FunctionName, exprFunctionCall.ListExprParameters.Count); return(true); } //----is it an expression comparison? ExprComparison exprComparison = expr as ExprComparison; if (exprComparison != null) { AnalyzeSyntaxTree(result, exprComparison.ExprLeft); AnalyzeSyntaxTree(result, exprComparison.ExprRight); return(true); } //----is it an expression logical? ExprLogical exprLogical = expr as ExprLogical; if (exprLogical != null) { AnalyzeSyntaxTree(result, exprLogical.ExprLeft); AnalyzeSyntaxTree(result, exprLogical.ExprRight); return(true); } //----is it an expression logical NOT? ExprLogicalNot exprLogicalNot = expr as ExprLogicalNot; if (exprLogicalNot != null) { AnalyzeSyntaxTree(result, exprLogicalNot.ExprBase); return(true); } //----is it an expression calculation? ExprCalculation exprCalculation = expr as ExprCalculation; if (exprCalculation != null) { // analyze all operands of the calculation expression bool res = true; foreach (ExpressionBase exprChild in exprCalculation.ListExprOperand) { res = res && AnalyzeSyntaxTree(result, exprChild); } //AnalyzeSyntaxTree(result, exprCalculation.ExprLeft); //AnalyzeSyntaxTree(result, exprCalculation.ExprRight); return(res); } //----is it a set value expression ? // todo: throw new Exception("todo: AnalyzeSyntaxTree(), expression type not yet implemented!"); }
/// <summary> /// execute the expression, execute the right part, execute the left part, then exec the expr (as 2 value operands) /// /// Returns always a bool value. /// exp: a=12, a>=13 /// /// managed type; int and double. /// for the bool and the string type, only equals and diff are authorized. /// </summary> /// <param name="exprComparison"></param> /// <returns></returns> private bool ExecExpressionComparison(ExecResult exprExecResult, ExprComparison exprComparison, out ExpressionExecBase exprExecBase) { exprExecBase = null; //----first step is to decode/compile both operands ExpressionExecBase exprExecBaseLeft; ExecExpression(exprExecResult, exprComparison.ExprLeft, out exprExecBaseLeft); ExpressionExecBase exprExecBaseRight; ExecExpression(exprExecResult, exprComparison.ExprRight, out exprExecBaseRight); //---Are the operands boolean? ExprExecValueBool exprExecValueLeftBool = exprExecBaseLeft as ExprExecValueBool; if (exprExecValueLeftBool != null) { // decode the right operand, should be a bool value too ExprExecValueBool exprExecValueRightBool = exprExecBaseRight as ExprExecValueBool; if (exprExecValueRightBool == null) { // the type of both operands mismatch! exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperandsTypeMismatchBoolExpected, "Position", exprComparison.ExprRight.Token.Position.ToString()); return(false); } ExprExecValueBool exprValueBoolResult = new ExprExecValueBool(); // is the operator Equals? if (exprComparison.Operator == OperatorComparisonCode.Equals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftBool.Value == exprExecValueRightBool.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator different? if (exprComparison.Operator == OperatorComparisonCode.Different) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftBool.Value != exprExecValueRightBool.Value; exprExecBase = exprValueBoolResult; return(true); } // other operators are not allowed on the boolean type exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperatorNotAllowedForBoolType, "Position", exprComparison.ExprLeft.Token.Position.ToString(), "Operator", exprComparison.Operator.ToString()); return(false); } //---Are the operands integer? ExprExecValueInt exprExecValueLeftInt = exprExecBaseLeft as ExprExecValueInt; if (exprExecValueLeftInt != null) { // decode the right operand, should be an int value too ExprExecValueInt exprExecValueRightInt = exprExecBaseRight as ExprExecValueInt; if (exprExecValueRightInt == null) { // the type of both operands mismatch! exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperandsTypeMismatchIntExpected, "Position", exprComparison.ExprRight.Token.Position.ToString()); return(false); } ExprExecValueBool exprValueBoolResult = new ExprExecValueBool(); // is the operator Equals? if (exprComparison.Operator == OperatorComparisonCode.Equals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftInt.Value == exprExecValueRightInt.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator different? if (exprComparison.Operator == OperatorComparisonCode.Different) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftInt.Value != exprExecValueRightInt.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator greater than? if (exprComparison.Operator == OperatorComparisonCode.Greater) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftInt.Value > exprExecValueRightInt.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator lesser than? if (exprComparison.Operator == OperatorComparisonCode.Less) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftInt.Value < exprExecValueRightInt.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator greater or equals than? if (exprComparison.Operator == OperatorComparisonCode.GreaterEquals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftInt.Value >= exprExecValueRightInt.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator lesser or equals than? if (exprComparison.Operator == OperatorComparisonCode.LessEquals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftInt.Value <= exprExecValueRightInt.Value; exprExecBase = exprValueBoolResult; return(true); } // other operators are not allowed on the boolean type (impossible to be there!) exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperatorNotYetImplementedForIntType, "Position", exprComparison.ExprLeft.Token.Position.ToString(), "Operator", exprComparison.Operator.ToString()); return(false); } //---Are the operands double? ExprExecValueDouble exprExecValueLeftDouble = exprExecBaseLeft as ExprExecValueDouble; if (exprExecValueLeftDouble != null) { // decode the right operand, should be an int value too ExprExecValueDouble exprExecValueRightDouble = exprExecBaseRight as ExprExecValueDouble; if (exprExecValueRightDouble == null) { // the type of both operands mismatch! exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperandsTypeMismatchDoubleExpected, "Position", exprComparison.ExprRight.Token.Position.ToString()); return(false); } // the result is always a bool (its a comparison) ExprExecValueBool exprValueBoolResult = new ExprExecValueBool(); // is the operator Equals? if (exprComparison.Operator == OperatorComparisonCode.Equals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftDouble.Value == exprExecValueRightDouble.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator different? if (exprComparison.Operator == OperatorComparisonCode.Different) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftDouble.Value != exprExecValueRightDouble.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator greater than? if (exprComparison.Operator == OperatorComparisonCode.Greater) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftDouble.Value > exprExecValueRightDouble.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator lesser than? if (exprComparison.Operator == OperatorComparisonCode.Less) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftDouble.Value < exprExecValueRightDouble.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator greater or equals than? if (exprComparison.Operator == OperatorComparisonCode.GreaterEquals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftDouble.Value >= exprExecValueRightDouble.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator lesser or equals than? if (exprComparison.Operator == OperatorComparisonCode.LessEquals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftDouble.Value <= exprExecValueRightDouble.Value; exprExecBase = exprValueBoolResult; return(true); } // other operators are not allowed on the boolean type (impossible to be there!) exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperatorNotYetImplementedForDoubleType, "Position", exprComparison.ExprLeft.Token.Position.ToString(), "Operator", exprComparison.Operator.ToString()); return(false); } //---Are the operands string? ExprExecValueString exprExecValueLeftString = exprExecBaseLeft as ExprExecValueString; if (exprExecValueLeftString != null) { // decode the right operand, should be a bool value too ExprExecValueString exprExecValueRightString = exprExecBaseRight as ExprExecValueString; if (exprExecValueRightString == null) { // the type of both operands mismatch! exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperandsTypeMismatchStringExpected, "Position", exprComparison.ExprRight.Token.Position.ToString()); return(false); } ExprExecValueBool exprValueBoolResult = new ExprExecValueBool(); // is the operator Equals? if (exprComparison.Operator == OperatorComparisonCode.Equals) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftString.Value == exprExecValueRightString.Value; exprExecBase = exprValueBoolResult; return(true); } // is the operator different? if (exprComparison.Operator == OperatorComparisonCode.Different) { // ok, execute the comparison exprValueBoolResult.Value = exprExecValueLeftString.Value != exprExecValueRightString.Value; exprExecBase = exprValueBoolResult; return(true); } // other operators are not allowed on the boolean type exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperatorNotAllowedForStringType, "Position", exprComparison.ExprLeft.Token.Position.ToString(), "Operator", exprComparison.Operator.ToString()); return(false); } // if reached, the operand type is not yet implemented (or unknowed) exprExecResult.AddErrorExec(ErrorCode.ExprComparisonOperandTypeNotYetImplemented, "Position", exprComparison.ExprLeft.Token.Position.ToString(), "Token", exprExecBaseLeft.Expr.Token.ToString()); return(false); }
/// <summary> /// start the execution, analyze and return the list of variables to create. /// todo: recréer un syntax tree, avec des valeurs! /// /// -->Doit renvoyer comme résultat un objet de type ExprValueXXX, non?? (si pas d'erreur). /// </summary> /// <returns></returns> private bool ExecExpression(ExecResult exprExecResult, ExpressionBase expr, out ExpressionExecBase exprExecBase) { exprExecBase = null; //----is it a final operand (value, var or call function)? ExprFinalOperand finalOperand = expr as ExprFinalOperand; if (finalOperand != null) { return(ExecExpressionFinalOperand(exprExecResult, finalOperand, out exprExecBase)); } //----is it a comparison expression? ExprComparison exprComparison = expr as ExprComparison; if (exprComparison != null) { // execute the expression, execute the right part, execute the left part, then exec the expr (as 2 value operands) return(ExecExpressionComparison(exprExecResult, exprComparison, out exprExecBase)); } //----is it a logical expression (bin/2 operands)? ExprLogical exprLogical = expr as ExprLogical; if (exprLogical != null) { return(ExecExpressionLogical(exprExecResult, exprLogical, out exprExecBase)); } //----is it a NOT logical expression? ExprLogicalNot exprLogicalNot = expr as ExprLogicalNot; if (exprLogicalNot != null) { return(ExecExpressionLogicalNot(exprExecResult, exprLogicalNot, out exprExecBase)); } //----is it a calculation expression? ExprCalculation exprCalculation = expr as ExprCalculation; if (exprCalculation != null) { // execute the expression, execute the right part, execute the left part, then exec the expr (as 2 value operands) return(ExecExpressionCalculation(exprExecResult, exprCalculation, out exprExecBase)); } //----is it function call? ExprFunctionCall exprFunctionCall = expr as ExprFunctionCall; if (exprFunctionCall != null) { return(ExecExpressionFunctionCall(exprExecResult, exprFunctionCall, out exprExecBase)); } //----is it a setValue expression? // todo: future // todo: error, expression not yet implemented!! exprExecResult.AddErrorExec(ErrorCode.ExpressionTypeNotYetImplemented, "Expr", expr.GetType().ToString()); return(false); }