/// <summary>
        /// Распознавание токенов обращения к значению переменной
        /// </summary>
        /// <param name="formula">Формула</param>
        /// <param name="currentTokenPosition">Текущая позиция в формуле (указывает на начало ещё не разобранного токена)</param>
        /// <returns>Токен</returns>
        public ICalcToken VariableTokenizer(string formula, int currentTokenPosition)
        {
            var token = new CalcTokenNumber(currentTokenPosition);
            string text = string.Empty;
            if (formula[currentTokenPosition] != '[' || formula.Length < currentTokenPosition+2)
                return null;
            text += formula[currentTokenPosition];
            for (var i = currentTokenPosition + 1; i < formula.Length; i++)
            {
                if (formula[i] == '[')
                    return new CalcTokenUnknown(currentTokenPosition) { Error = FormulaError.UnexpectedSymbols, TokenText = text };
                text += formula[i];

                if (formula[i] != ']')
                    continue;
                if (text.Length == 2)
                    return new CalcTokenUnknown(currentTokenPosition) { Error = FormulaError.UnexpectedSymbols, TokenText = text };
                token.TokenText = text;
                var varAndPanelName = text.Substring(1, text.Length - 2).Split('.');
                if (varAndPanelName.Length != 2)
                    return null;
                var varId = Profile.GetVariableByPanelAndName(varAndPanelName[0], varAndPanelName[1]);
                if (varId == Guid.Empty)
                    token.Error = FormulaError.TokenPointsAbsentItem;
                token.Error = FormulaError.Ok;
                return token;
            }
            return new CalcTokenUnknown(currentTokenPosition) { Error = FormulaError.UnexpectedSymbols, TokenText = text };
        }
Пример #2
0
        // InputFormula
        // Как потом раздать результат в другие переменные? Ввести в формулы термин "[R]"?
        private ICalcToken FormulaResultTokenizer(string formula, int currentTokenPosition)
        {
            const string resultTokenText = "[R]";
            var          token           = new CalcTokenNumber(currentTokenPosition)
            {
                TokenText = resultTokenText
            };

            return(formula.Substring(currentTokenPosition, 3) != resultTokenText ? null : token);
        }
Пример #3
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);
 }
Пример #4
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)
            });
        }