Esempio n. 1
0
        /// <summary>
        /// Общий метод извлечения очередного токена. Вызывает метод TryToExtract в классах токенов
        /// </summary>
        /// <param name="formula">текст формулы</param>
        /// <param name="previousToken">предыдущий токен. Null, если это первый токен</param>
        /// <returns>null - формула разобрана, иначе токен</returns>
        private ICalcToken TryToExtract(string formula, ICalcToken previousToken)
        {
            ICalcToken token;
            var        position = previousToken == null ? 0 : previousToken.GetNextTokenPosition();

            if (formula.Length == position)
            {
                return(null); // Формула распаршена
            }
            if ((token = CalcTokenIfStatement.TryToExtract(formula, position)) != null)
            {
                return(token);
            }
            if ((token = CalcTokenFormulaSeparator.TryToExtract(formula, position)) != null)
            {
                return(token);
            }
            if ((token = CalcTokenNumber.TryToExtract(formula, previousToken, position)) != null)
            {
                return(token);
            }
            if ((token = CalcTokenFormatter.TryToExtract(formula, position)) != null)
            {
                return(token);
            }
            if ((token = CalcTokenBracket.TryToExtract(formula, position)) != null)
            {
                return(token);
            }
            if ((token = CalcTokenLogicOperation.TryToExtract(formula, position)) != null)
            {
                return(token);
            }
            if ((token = CalcTokenMathOperation.TryToExtract(formula, previousToken, position)) != null)
            {
                return(token);
            }
            if (_tokenizers.Any(tokenizer => (token = tokenizer(formula, position)) != null))
            {
                return(token);
            }

            return(new CalcTokenUnknown(position)
            {
                Error = FormulaError.UnexpectedSymbols, TokenText = formula[position].ToString(CultureInfo.InvariantCulture)
            });
        }
Esempio n. 2
0
        /// <summary>
        /// Обработать логическую операцию над двумя логическими токенами (bool) или двумя числами
        /// Для корректного выполнения сравнения "больше, меньше, ..." важен порядок токенов, передаваемых в формулу
        /// </summary>
        /// <param name="token1">первый токен</param>
        /// <param name="token2">второй токен</param>
        /// <param name="logicOperationToken">токен логической операции</param>
        /// <returns>результирующий токен или ошибка, установленная методом в одном из входных токенов</returns>
        private ICalcToken ProcessLogicOperation(ICalcToken token1, ICalcToken token2, CalcTokenLogicOperation logicOperationToken)
        {
            bool boolResult;

            if (token1 is CalcTokenNumber && token2 is CalcTokenNumber)
            {
                var v1Value = ((CalcTokenNumber)token1).Value;
                var v2Value = ((CalcTokenNumber)token2).Value;
                switch (logicOperationToken.LogicOperation)
                {
                case CalcLogicOperation.Equal:
                    boolResult = v1Value == v2Value;
                    break;

                case CalcLogicOperation.Greater:
                    boolResult = v1Value > v2Value;
                    break;

                case CalcLogicOperation.GreaterOrEqual:
                    boolResult = v1Value >= v2Value;
                    break;

                case CalcLogicOperation.Less:
                    boolResult = v1Value < v2Value;
                    break;

                case CalcLogicOperation.LessOrEqual:
                    boolResult = v1Value <= v2Value;
                    break;

                case CalcLogicOperation.Not:
                    boolResult = v1Value != v2Value;
                    break;

                default:
                    logicOperationToken.Error = FormulaError.UnknownLogicOperation;
                    return(logicOperationToken);
                }
            }
            else if (token1 is CalcTokenBoolean && token2 is CalcTokenBoolean)
            {
                var v1Value = ((CalcTokenBoolean)token1).Value;
                var v2Value = ((CalcTokenBoolean)token2).Value;
                switch (logicOperationToken.LogicOperation)
                {
                case CalcLogicOperation.And:
                    boolResult = v1Value && v2Value;
                    break;

                case CalcLogicOperation.Equal:
                    boolResult = v1Value == v2Value;
                    break;

                case CalcLogicOperation.Not:
                    boolResult = v1Value != v2Value;
                    break;

                case CalcLogicOperation.Or:
                    boolResult = v1Value || v2Value;
                    break;

                default:
                    logicOperationToken.Error = FormulaError.UnknownLogicOperation;
                    return(logicOperationToken);
                }
            }
            else
            {
                return(new CalcTokenUnknown(0)
                {
                    Error = FormulaError.CantOperateMathAndLogicValues
                });
            }
            return(new CalcTokenBoolean(0)
            {
                Value = boolResult
            });
        }