Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Can Group these 2 tokens ?
        /// (because both represents a special token).
        /// Manage these cases: negative numbers like:  3toks: -, -, 12 ---> 2toks: -, -12
        /// a, -, -, 12  -> group it a, -, -12
        /// a, -, 3      -> don't group -3 !!
        /// a, =, -, 3   -> group it   a, =, -3
        /// a and - 3    - group it,
        /// </summary>
        /// <returns></returns>
        private bool CanGroupTokens(ExprToken prevToken, ExprToken token, ExprToken nextToken)
        {
            // DEBUG:
            //ExprToken prevToken = null;

            if (nextToken == null)
            {
                // no more next token, so can't group
                return(false);
            }

            // manage negative number
            if (token.Value == "-")
            {
                // the next one is again a minus sign?
                if (nextToken.Value == "-")
                {
                    // its a special case (exp: --12)
                    return(false);
                }

                // need to check the previous token: can group only if its a calculation token: +,-, *,/, modulo
                // exp: a-3  don't group -3!!
                // ok can group, its a negative number (have to check that the next token is a number)
                if (prevToken == null)
                {
                    // can group, exp -3 ...
                    return(true);
                }

                // if the previous token is an operator: logical, comparison or calculation -> group it , its a negative number.
                // todo: manque cas spécial du modulo!!  exp: 12 modulo -3 -> il faut grouper!!
                if (_exprEvalConfig.IsOperator(prevToken.Value))
                {
                    // ok, can group, exp: + - 3  --> + -3
                    return(true);
                }

                // can't group, exp: a - 3
                return(false);
            }

            // the current token is the start of a special token having more than one char, exp: >=
            string specialToken;

            if (IsStartSpecialOperator(token.Value, out specialToken))
            {
                // the next token should be the end of the special large operator
                if (IsEndSpecialOperator(specialToken, nextToken.Value))
                {
                    // ok, can group these two tokens
                    return(true);
                }
            }

            // can't group these two tokens
            return(false);
        }
Ejemplo n.º 3
0
        private void FinalizeToken(List <ExprToken> listExprToken, ExprToken token)
        {
            // termine le token précédent s'il y a
            if (token == null)
            {
                return;
            }

            listExprToken.Add(token);
        }
Ejemplo n.º 4
0
        public ExprError AddError(ErrorCode errorCode, ExprToken token)
        {
            var error = new ExprError();

            error.Code  = errorCode;
            error.Token = token;

            ListError.Add(error);
            return(error);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Decode the token, is it an operator??
        /// Depending of the language, get the right operator.
        /// can be:
        ///     Logical, comparison, calculation or a setValue.
        /// </summary>
        /// <param name="token"></param>
        private bool DecodeTokenOperator(Stack <ExpressionBase> stack, ExprToken token)
        {
            //----is it a comparison operator?
            if (_exprEvalConfig.DictComparisonOperators.ContainsKey(token.Value.ToLower()))
            {
                OperatorComparisonCode operComp = _exprEvalConfig.DictComparisonOperators[token.Value.ToLower()];

                // empile le token opérateur
                ExprOperatorComparison exprOperatorComparison = new ExprOperatorComparison();
                exprOperatorComparison.Operator = operComp;
                exprOperatorComparison.Token    = token;
                stack.Push(exprOperatorComparison);
                return(true);
            }

            // is it a logical operator?
            if (_exprEvalConfig.DictLogicalOperators.ContainsKey(token.Value.ToLower()))
            {
                OperatorLogicalCode operLogical = _exprEvalConfig.DictLogicalOperators[token.Value.ToLower()];

                // is it the NOT operator?
                if (operLogical == OperatorLogicalCode.Not)
                {
                    // empile le token opérateur
                    ExprOperatorLogicalNot exprOperatorLogicalNot = new ExprOperatorLogicalNot();
                    exprOperatorLogicalNot.Token = token;
                    stack.Push(exprOperatorLogicalNot);
                    return(true);
                }

                // empile le token opérateur
                ExprOperatorLogical exprOperatorLogical = new ExprOperatorLogical();
                exprOperatorLogical.Operator = operLogical;
                exprOperatorLogical.Token    = token;
                stack.Push(exprOperatorLogical);
                return(true);
            }

            // is it a calculation operator?
            if (_exprEvalConfig.DictCalculationOperators.ContainsKey(token.Value.ToLower()))
            {
                OperatorCalculationCode operCalc = _exprEvalConfig.DictCalculationOperators[token.Value.ToLower()];

                // empile le token opérateur
                ExprOperatorCalculation exprOperatorCalc = new ExprOperatorCalculation();
                exprOperatorCalc.Operator = operCalc;
                exprOperatorCalc.Token    = token;
                stack.Push(exprOperatorCalc);
                return(true);
            }

            // the token is not an operator
            return(false);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Build a new token, add it to the list (if exists).
        /// </summary>
        /// <param name="listExprToken"></param>
        /// <param name="currPos"></param>
        /// <param name="strToken"></param>
        /// <returns></returns>
        private ExprToken BuildToken(List <ExprToken> listExprToken, int currPos, string strToken)
        {
            var token = new ExprToken();

            token.Position = currPos;
            token.Value    = strToken;

            if (listExprToken != null)
            {
                listExprToken.Add(token);
            }

            return(token);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// adds open and close bracket to the tokens, exp A=B  -> (A=B)
        ///
        /// Only if there is no brackets, open and close.
        ///
        /// Because the process is made for expressions having always opne and close bracket.
        /// </summary>
        /// <param name="listTokens"></param>
        private void AddBrackets(List <ExprToken> listTokens)
        {
            // get the first token
            ExprToken firstToken = listTokens[0];
            ExprToken lastToken  = listTokens[listTokens.Count - 1];

            //if (firstToken.Value == "(" && lastToken.Value == ")")
            // the expression has an opened and a closed bracket, so nothing to do
            //    return;


            // there is no open and close bracket,  so add it
            ExprToken tokenOpenBracket = new ExprToken();

            tokenOpenBracket.Position = 0;
            tokenOpenBracket.Value    = "(";
            listTokens.Insert(0, tokenOpenBracket);

            ExprToken tokenCloseBracket = new ExprToken();

            tokenCloseBracket.Position = 0;
            tokenCloseBracket.Value    = ")";
            listTokens.Add(tokenCloseBracket);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Split the expression string, generate tokens.
        /// </summary>
        /// <returns></returns>
        public List <ExprToken> SplitExpr(string expr)
        {
            List <ExprToken> listExprToken = new List <ExprToken>();

            if (_listSpecial2CharOperators == null)
            {
                return(listExprToken);
            }

            if (string.IsNullOrWhiteSpace(expr))
            {
                return(listExprToken);
            }

            // scan the string expression, char by char
            int       currPos = 0;
            char      currChar;
            ExprToken token = null;

            while (true)
            {
                // plus de char à traiter?
                if (currPos >= expr.Length)
                // finalise token encours, s'il y a
                {
                    // termine le token précédent s'il y a
                    FinalizeToken(listExprToken, token);
                    token = null;
                    break;
                }

                // recup car en cours
                currChar = expr[currPos];

                //----Est-ce un car séparteur pur (espace, tab,...)? (ne pas garder)
                if (_listSeparatorPure.Contains(currChar))
                {
                    // termine le token précédent s'il y a
                    FinalizeToken(listExprToken, token);
                    token = null;

                    // passe au char suivant
                    currPos++;
                    continue;
                }

                //----Est-ce un car séparateur spécial? (à garder)
                if (_exprEvalConfig.ListSeparatorSpecial.Contains(currChar))
                {
                    // termine le token précédent s'il y a
                    FinalizeToken(listExprToken, token);

                    // est un nouveau token
                    BuildToken(listExprToken, currPos, currChar.ToString());
                    token = null;

                    // passe au char suivant
                    currPos++;
                    continue;
                }

                //----Is it a string start tag?
                if (_exprEvalConfig.StringTagValue == currChar.ToString())
                {
                    // termine le token précédent s'il y a
                    FinalizeToken(listExprToken, token);

                    // save start position of the string
                    int  posStartString = currPos;
                    char tagStartString = currChar;

                    // find the string end tag (must find)
                    int posEndString;
                    if (!FindStringEndTag(expr, posStartString, tagStartString, out posEndString))
                    {
                        // create a new token
                        token = BuildToken(listExprToken, currPos, expr.Substring(currPos, posEndString + 1 - currPos));
                        token = null;

                        // stop, no end tag found, so get all the end of the expr string
                        return(listExprToken);
                    }

                    // create a new token
                    token = BuildToken(listExprToken, currPos, expr.Substring(currPos, posEndString + 1 - currPos));
                    token = null;

                    currPos = posEndString;

                    // passe au char suivant
                    currPos++;
                    continue;
                }

                //----Is it a comment start tag?
                // todo:

                //----le car courant est un car std de token
                // pas de token précédent?
                if (token == null)
                {
                    // create a new token
                    token = BuildToken(null, currPos, currChar.ToString());

                    // passe au char suivant
                    currPos++;
                    continue;
                }

                // car de token, ajoute le char au token
                token.Value += currChar.ToString();
                // passe au char suivant
                currPos++;
            }

            // return the list of token found in the string
            return(listExprToken);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// group tokens if necessary, like operators comparators (having 2 char length)
        /// Depends on specials char.
        /// group also negative number, exp: -, 12  becomes -12
        ///
        /// exp:  '>', '='  becomes '>='
        ///
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="listTokens"></param>
        /// <returns></returns>
        public List <ExprToken> GroupTokens(string expr, List <ExprToken> listTokens)
        {
            List <ExprToken> listTokensOut = new List <ExprToken>();

            // expr is null or mepty, contains no token, so the returned list is empty
            if (listTokens.Count == 0)
            {
                return(listTokensOut);
            }

            if (_listSpecial2CharOperators == null)
            {
                return(listTokensOut);
            }

            // scan all tokens
            int       i = 0;
            ExprToken prevToken;
            ExprToken token;
            ExprToken nextToken;

            while (true)
            {
                // no more token to process
                if (i >= listTokens.Count)
                {
                    break;
                }

                if (i > 0)
                {
                    prevToken = listTokens[i - 1];
                }
                else
                {
                    prevToken = null;
                }

                // get the current token
                token = listTokens[i];

                // get the next one if exists
                nextToken = GetToken(listTokens, i + 1);

                // both current token and the next can be grouped/compacted
                // need the previous to manage the minus case
                if (CanGroupTokens(prevToken, token, nextToken))
                {
                    // build a new token based on two: current and next
                    ExprToken groupToken = new ExprToken();
                    groupToken.Position = token.Position;
                    groupToken.Value    = token.Value + nextToken.Value;

                    // save it
                    listTokensOut.Add(groupToken);

                    // move to next token (first step)
                    i++;
                }
                else
                {
                    listTokensOut.Add(token);
                }
                i++;
            }

            return(listTokensOut);
        }
Ejemplo n.º 11
0
        /// <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);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Is the token a function call paramater separator?
        /// a comma or a dot-comma, depending on the configuration.
        /// </summary>
        /// <param name="stack"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        private bool DecodeTokenFunctionCallParameterSeparator(Stack <ExpressionBase> stack, ExprToken token)
        {
            // is it a function call parameter separator?
            if (_exprEvalConfig.DecimalAndFunctionSeparators == DecimalAndFunctionSeparators.Standard)
            {
                // is it the comma?  exp: fct(a,b)
                if (token.Value == ",")
                {
                    // yes!
                    ExprFunctionCallParameterSeparator exprSeparator = new ExprFunctionCallParameterSeparator();
                    exprSeparator.Token = token;
                    stack.Push(exprSeparator);
                    return(true);
                }

                // no
                return(false);
            }

            // is it a function call parameter separator?
            if (_exprEvalConfig.DecimalAndFunctionSeparators == DecimalAndFunctionSeparators.ExcelLike)
            {
                // is it the dot-comma?  exp: fct(a;b)
                if (token.Value == ";")
                {
                    // yes!
                    ExprFunctionCallParameterSeparator exprSeparator = new ExprFunctionCallParameterSeparator();
                    exprSeparator.Token = token;
                    stack.Push(exprSeparator);
                    return(true);
                }

                // no
                return(false);
            }

            // not the function call parameter separator
            return(false);
        }