/// <summary>
        /// Decode the token, is it an operand type double number?
        /// </summary>
        /// <param name="token"></param>
        /// <param name="result"></param>
        /// <param name="exprFinalOperand"></param>
        /// <returns></returns>
        private bool IsOperandDouble(ExprToken token, ParseResult result, ExprFinalOperand exprFinalOperand)
        {
            global::System.IFormatProvider culture = null;

            if (_exprEvalConfig.DecimalAndFunctionSeparators == DecimalAndFunctionSeparators.Standard)
            {
                // the decimal separator is a point, exp: 123.45
                culture = new global::System.Globalization.CultureInfo("en-US");
            }
            else
            {
                // the decimal separator is a comma, exp: 123,45
                culture = new global::System.Globalization.CultureInfo("fr-fr");
            }

            //NumberStyles styles = NumberStyles.AllowExponent | NumberStyles.AllowThousands | NumberStyles.AllowDecimalPoint;
            NumberStyles styles = NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign;

            double numberDouble;

            if (double.TryParse(token.Value, styles, culture, out numberDouble))
            {
                exprFinalOperand.ContentType = OperandType.ValueDouble;
                exprFinalOperand.ValueDouble = numberDouble;
                return(true);
            }

            // its not a double operand value
            return(false);
        }
        private bool CheckObjectNameSyntax(ExprToken token, ParseResult result, ExprFinalOperand exprFinalOperand)
        {
            exprFinalOperand.ContentType = OperandType.ObjectName;

            // the first char mut be: a letter or an underscore
            if (!char.IsLetter(token.Value[0]) && token.Value[0] != '_')
            {
                // erreur! plus de token, token attendu: opérande gauche.
                ExprError error = new ExprError();
                error.Code = ErrorCode.ObjectNameSyntaxWrong;
                result.ListError.Add(error);
                return(false);
            }

            // check others char of the objectName
            // ici();

            exprFinalOperand.ContentType = OperandType.ObjectName;
            return(true);
        }
        /// <summary>
        /// decode les tokens de l'expression.
        /// construit une structure d'objets arborescente binaire basée sur la classe BoolBinExprBase.
        ///
        /// Compact the tokens before decoding it.
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="listTokens"></param>
        /// <returns></returns>
        public ParseResult Parse(string expr, List <ExprToken> listTokens)
        {
            ParseResult result = new ParseResult();

            result.Expression = expr;
            result.ListExprToken.AddRange(listTokens);

            // err, any operator (bool and comp) is defined
            if (_exprEvalConfig == null)
            {
                ExprError error = new ExprError();
                // its an internal error!
                error.Code = ErrorCode.AnyOperatorDefined;
                result.ListError.Add(error);
                return(result);
            }

            // err, the expression is null or empty
            if (listTokens.Count == 0)
            {
                // erreur! plus de token, token attendu: opérande gauche.
                ExprError error = new ExprError();
                error.Code = ErrorCode.ExprIsNullOrEmpty;
                result.ListError.Add(error);
                return(result);
            }

            // adds open and close bracket to the tokens, exp A=B  -> (A=B)
            AddBrackets(listTokens);

            // init stack pour gérer les parenthèse
            Stack <ExpressionBase> stack = new Stack <ExpressionBase>();

            // parcours les tokens un à un
            foreach (ExprToken token in listTokens)
            {
                //----parenthèse ouvrante?  empile le token
                if (token.Value == "(")
                {
                    ExprBracketOpen bracketOpen = new ExprBracketOpen();
                    bracketOpen.Token = token;
                    stack.Push(bracketOpen);
                    continue;
                }

                //----closed bracket found? pop tokens from the stack until find the open bracket, build a sub-expression.
                if (token.Value == ")")
                {
                    SubExprDecoder subExprDecoder = new SubExprDecoder();
                    if (!subExprDecoder.DecodeExpr(stack, token, result))
                    {
                        break;
                    }
                    continue;
                }

                //----opérateur?  empile le token
                // selon langue, recupere la liste des opérateurs et compare.
                if (DecodeTokenOperator(stack, token))
                {
                    continue;
                }

                //----is it function Call parameter separator?
                if (DecodeTokenFunctionCallParameterSeparator(stack, token))
                {
                    continue;
                }


                //----opérande?  empile le token
                // n'est ni une parenthèse ouvrante, fermante, ni un opérateur.
                ExprFinalOperand exprFinalOperand = BuildOperand(token, result);
                stack.Push(exprFinalOperand);
            }

            // decoder le résultat du traitement: la pile ne doit contenir qu'une seule expr
            AnalyzeStackContent(stack, result);
            return(result);
        }
        /// <summary>
        /// Build the final operand: not a separator.
        /// can be a number (positive or negative), an object name (var, fct,...) or a string.
        ///
        /// The string can be well-formed or bad-formed: the end tag is missing.
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private ExprFinalOperand BuildOperand(ExprToken token, ParseResult result)
        {
            ExprFinalOperand exprFinalOperand = new ExprFinalOperand();

            exprFinalOperand.Operand = token.Value;
            exprFinalOperand.Token   = token;

            //----is the value a string? starts with a string tag (quote or double-quote)
            if (_exprEvalConfig.StringTagValue == token.Value[0].ToString())
            {
                // is the last char a string tag?
                //if (_exprEvalConfig.ListStringTag.Contains(token.Value[token.Value.Length-1]) && token.Value.Length>1)
                if (_exprEvalConfig.StringTagValue == token.Value[token.Value.Length - 1].ToString() && token.Value.Length > 1)
                {
                    exprFinalOperand.ContentType = OperandType.ValueString;
                    return(exprFinalOperand);
                }
                exprFinalOperand.ContentType = OperandType.ValueStringBadFormed;
                ExprError error = new ExprError();
                error.Token = token;
                error.Code  = ErrorCode.ValueStringBadFormed;
                result.ListError.Add(error);

                return(exprFinalOperand);
            }

            //----is the value an integer?
            int numberInt;

            if (int.TryParse(token.Value, out numberInt))
            {
                exprFinalOperand.ContentType = OperandType.ValueInt;
                exprFinalOperand.ValueInt    = numberInt;
                return(exprFinalOperand);
            }

            //----is the value a double?
            if (IsOperandDouble(token, result, exprFinalOperand))
            {
                return(exprFinalOperand);
            }

            // is it a bad-formed number? (seems to be number: start with minus or a digit)
            if (token.Value[0] == '-' || char.IsDigit(token.Value[0]))
            {
                exprFinalOperand.ContentType = OperandType.ValueNumberBadFormed;
                ExprError error = new ExprError();
                error.Token = token;
                error.Code  = ErrorCode.ValueNumberBadFormed;
                result.ListError.Add(error);
                return(exprFinalOperand);
            }

            //-----is it a bool value?
            // todo: get values from the configurator: true/false, vrai/faux
            BoolConst boolConst = _exprEvalConfig.ListBoolConst.Find(bc => bc.BoolStringValue.Equals(token.Value, StringComparison.InvariantCultureIgnoreCase));

            if (boolConst != null)
            {
                exprFinalOperand.ContentType = OperandType.ValueBool;
                exprFinalOperand.ValueBool   = boolConst.BoolValue;
                return(exprFinalOperand);
            }

            // it's an object name, (sure?) check the syntax
            CheckObjectNameSyntax(token, result, exprFinalOperand);

            return(exprFinalOperand);
        }
Beispiel #5
0
        /// <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!");
        }
Beispiel #6
0
        private bool ExecExpressionFinalOperand(ExecResult exprExecResult, ExprFinalOperand finalOperand, out ExpressionExecBase exprExecBase)
        {
            // is the operand a variable or a call function?
            if (finalOperand.ContentType == OperandType.ObjectName)
            {
                // is it a variable?
                ExprVariableBase exprVariableBase = _expressionData.ExprExecResult.ListExprVariable.Find(v => v.Name.Equals(finalOperand.Operand, StringComparison.InvariantCultureIgnoreCase));
                if (exprVariableBase != null)
                {
                    // the operand is a string variable?
                    ExprVariableString exprVariableString = exprVariableBase as ExprVariableString;
                    if (exprVariableString != null)
                    {
                        // create a var instance, depending on the type
                        ExprExecVarString exprExecVar = new ExprExecVarString();
                        exprExecVar.ExprVariableString = exprVariableString;
                        exprExecVar.Expr = finalOperand;

                        // set the value
                        exprExecVar.Value = exprVariableString.Value;
                        exprExecBase      = exprExecVar;
                        return(true);
                    }

                    // the operand is an int variable?
                    ExprVariableInt exprVariableInt = exprVariableBase as ExprVariableInt;
                    if (exprVariableInt != null)
                    {
                        // create a var instance, depending on the type
                        ExprExecVarInt exprExecVar = new ExprExecVarInt();
                        exprExecVar.ExprVariableInt = exprVariableInt;
                        exprExecVar.Expr            = finalOperand;

                        // set the value
                        exprExecVar.Value = exprVariableInt.Value;
                        exprExecBase      = exprExecVar;
                        return(true);
                    }


                    // the operand is a double variable?
                    ExprVariableDouble exprVariableDouble = exprVariableBase as ExprVariableDouble;
                    if (exprVariableDouble != null)
                    {
                        // create a var instance, depending on the type
                        ExprExecVarDouble exprExecVar = new ExprExecVarDouble();
                        exprExecVar.ExprVariableDouble = exprVariableDouble;
                        exprExecVar.Expr = finalOperand;

                        // set the value
                        exprExecVar.Value = exprVariableDouble.Value;
                        exprExecBase      = exprExecVar;
                        return(true);
                    }

                    // the operand is a bool variable?
                    ExprVariableBool exprVariableBool = exprVariableBase as ExprVariableBool;
                    if (exprVariableBool != null)
                    {
                        // create a var instance, depending on the type
                        ExprExecVarBool exprExecVar = new ExprExecVarBool();
                        exprExecVar.ExprVariableBool = exprVariableBool;
                        exprExecVar.Expr             = finalOperand;

                        // set the value
                        exprExecVar.Value = exprVariableBool.Value;
                        exprExecBase      = exprExecVar;
                        return(true);
                    }

                    // todo; create an error
                    throw new Exception("The operand variable type is not yet implemented!");
                }

                // so its a function call
                // todo: rechercher dans la liste des fonctions?
                throw new Exception("The function call is not yet implemented!");
            }

            // is the operand a string value (a const string value)?
            if (finalOperand.ContentType == OperandType.ValueString)
            {
                ExprExecValueString exprValueString = new ExprExecValueString();
                exprValueString.Value = finalOperand.Operand;
                exprExecBase          = exprValueString;
                exprValueString.Expr  = finalOperand;

                return(true);
            }

            // is the operand an int value?
            if (finalOperand.ContentType == OperandType.ValueInt)
            {
                ExprExecValueInt exprValueInt = new ExprExecValueInt();
                exprValueInt.Expr  = finalOperand;
                exprValueInt.Value = finalOperand.ValueInt;
                exprExecBase       = exprValueInt;
                return(true);
            }

            // is the operand a double value?
            if (finalOperand.ContentType == OperandType.ValueDouble)
            {
                ExprExecValueDouble exprValueDouble = new ExprExecValueDouble();
                exprValueDouble.Expr  = finalOperand;
                exprValueDouble.Value = finalOperand.ValueDouble;
                exprExecBase          = exprValueDouble;
                return(true);
            }

            // is the operand a bool value?
            if (finalOperand.ContentType == OperandType.ValueBool)
            {
                ExprExecValueBool exprValueBool = new ExprExecValueBool();
                exprValueBool.Expr  = finalOperand;
                exprValueBool.Value = finalOperand.ValueBool;
                exprExecBase        = exprValueBool;
                return(true);
            }

            // todo: create an error
            throw new Exception("The operand const value is not yet implemented!");
        }
Beispiel #7
0
        /// <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);
        }