Esempio n. 1
0
 /// <summary>
 /// Обработать унарную математическую операцию (один токен + операция. Например, -10 - сменить знак у 10 на отрицательный)
 /// </summary>
 /// <param name="token">токен</param>
 /// <param name="mathUnaryOperationToken">токен логической операции</param>
 /// <returns>результирующий токен или ошибка. Ошибок быть не может</returns>
 private ICalcToken ProcessUnaryMathOperation(CalcTokenNumber token, CalcTokenMathOperation mathUnaryOperationToken)
 {
     // Выполняем унарную операцию -
     if (mathUnaryOperationToken.MathOperation == CalcMathOperation.UnaryMinus)
     {
         token.Value = token.Value * -1;
     }
     // Выполняем унарную операцию +
     if (mathUnaryOperationToken.MathOperation == CalcMathOperation.UnaryPlus)
     {
         token.Value = Math.Abs(token.Value);
     }
     return(token);
 }
Esempio n. 2
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. 3
0
        /// <summary>
        /// Обработать математическую операцию над двумя токенами
        /// Для корректного выполнения сравнения "больше, меньше, ..." важен порядок токенов, передаваемых в формулу
        /// </summary>
        /// <param name="token1">первый токен</param>
        /// <param name="token2">второй токен</param>
        /// <param name="mathOperationToken">токен матеметической операции</param>
        /// <returns>результирующий токен или ошибка, установленная методом в одном из входных токенов</returns>
        private ICalcToken ProcessMathOperation(ICalcToken token1, ICalcToken token2, CalcTokenMathOperation mathOperationToken)
        {
            double mathResult;
            var    n1 = ((CalcTokenNumber)token1).Value;
            var    n2 = ((CalcTokenNumber)token2).Value;

            var n1s = n1.ToString(CultureInfo.InvariantCulture);

            n1 = double.Parse(n1s, CultureInfo.InvariantCulture);
            var n2s = n2.ToString(CultureInfo.InvariantCulture);

            n2 = double.Parse(n2s, CultureInfo.InvariantCulture);

            switch (mathOperationToken.MathOperation)
            {
            case CalcMathOperation.Plus:
                mathResult = n1 + n2;
                break;

            case CalcMathOperation.Minus:
                mathResult = n1 - n2;
                break;

            case CalcMathOperation.Multiply:
                mathResult = n1 * n2;
                break;

            case CalcMathOperation.Divide:
                if ((int)n2 == 0)
                {
                    token2.Error = FormulaError.DivisionByZero;
                    return(token2);
                }
                mathResult = n1 / n2;
                break;

            case CalcMathOperation.DivideModulo:
                if ((int)n2 == 0)
                {
                    token2.Error = FormulaError.DivisionByZero;
                    return(token2);
                }
                mathResult = n1 % n2;
                break;

            case CalcMathOperation.DivideInteger:
                if ((int)n2 == 0)
                {
                    token2.Error = FormulaError.DivisionByZero;
                    return(token2);
                }
                mathResult = (long)(n1 / n2);
                break;

            default:
                mathOperationToken.Error = FormulaError.UnknownMathOperation;
                return(mathOperationToken);
            }
            // Результат возвращаем в стэк
            return(new CalcTokenNumber(0)
            {
                Value = mathResult
            });
        }