private void Handle()
        {
            var   c = _context.FormulaChars[_tokenIndex];
            Token tokenSeparator;

            if (CharIsTokenSeparator(c, out tokenSeparator))
            {
                if (TokenSeparatorHandler.Handle(c, tokenSeparator, _context, this))
                {
                    return;
                }

                if (_context.CurrentTokenHasValue)
                {
                    if (Regex.IsMatch(_context.CurrentToken, "^\"*$"))
                    {
                        _context.AddToken(_tokenFactory.Create(_context.CurrentToken, TokenType.StringContent));
                    }
                    else
                    {
                        _context.AddToken(CreateToken(_context, Worksheet));
                    }


                    //If the a next token is an opening parantheses and the previous token is interpeted as an address or name, then the currenct token is a function
                    if (tokenSeparator.TokenType == TokenType.OpeningParenthesis && (_context.LastToken.TokenType == TokenType.ExcelAddress || _context.LastToken.TokenType == TokenType.NameValue))
                    {
                        _context.LastToken.TokenType = TokenType.Function;
                    }
                }
                if (tokenSeparator.Value == "-")
                {
                    if (TokenIsNegator(_context))
                    {
                        _context.AddToken(new Token("-", TokenType.Negator));
                        return;
                    }
                }
                _context.AddToken(tokenSeparator);
                _context.NewToken();
                return;
            }
            _context.AppendToCurrentToken(c);
        }
Esempio n. 2
0
        public IEnumerable<Token> Tokenize(string input, string worksheet)
        {
            if (string.IsNullOrEmpty(input))
            {
                return Enumerable.Empty<Token>();
            }
            // MA 1401: Ignore leading plus in formula.
            input = input.TrimStart('+');
            var context = new TokenizerContext(input);
            for (int i = 0; i<context.FormulaChars.Length;i++)
            {
                var c = context.FormulaChars[i];
                Token tokenSeparator;
                if (CharIsTokenSeparator(c, out tokenSeparator))
                {
                    if (context.IsInString)
                    {
                        if (tokenSeparator.TokenType == TokenType.String && i + 1 < context.FormulaChars.Length && context.FormulaChars[i + 1] == '\'')
                        {
                            i++;
                            context.AppendToCurrentToken(c);
                            continue;
                        }
                        else if(tokenSeparator.TokenType != TokenType.String)
                        {
                            context.AppendToCurrentToken(c);
                            continue;
                        }
                    }
                    if (tokenSeparator.TokenType == TokenType.OpeningBracket)
                    {
                        context.AppendToCurrentToken(c);
                        context.BracketCount++;
                        continue;
                    }
                    if (tokenSeparator.TokenType == TokenType.ClosingBracket)
                    {
                        context.AppendToCurrentToken(c);
                        context.BracketCount--;
                        continue;
                    }
                    if (context.BracketCount > 0)
                    {
                        context.AppendToCurrentToken(c);
                        continue;
                    }
                    // two operators in sequence could be "<=" or ">="
                    if (IsPartOfMultipleCharSeparator(context, c))
                    {
                        var sOp = context.LastToken.Value + c.ToString(CultureInfo.InvariantCulture);
                        var op = _tokenProvider.Tokens[sOp];
                        context.ReplaceLastToken(op);
                        context.NewToken();
                        continue;
                    }
                    if (tokenSeparator.TokenType == TokenType.String)
                    {
                        if (context.LastToken != null && context.LastToken.TokenType == TokenType.OpeningEnumerable)
                        {
                            context.AppendToCurrentToken(c);
                            context.ToggleIsInString();
                            continue;
                        }
                        else if (context.LastToken != null &&
                            context.LastToken.TokenType == TokenType.String &&
                            !context.CurrentTokenHasValue) //Added check for enumartion
                        {
                            // We are dealing with an empty string ('').
                            context.AddToken(new Token(string.Empty, TokenType.StringContent));
                        }
                        context.ToggleIsInString();
                    }
                    if (context.CurrentTokenHasValue)
                    {
                        context.AddToken(CreateToken(context, worksheet));
                        //If the a next token is an opening parantheses and the previous token is interpeted as an address or name, then the currenct token is a function
                        if(tokenSeparator.TokenType==TokenType.OpeningParenthesis && (context.LastToken.TokenType==TokenType.ExcelAddress || context.LastToken.TokenType==TokenType.NameValue))
                        {
                            context.LastToken.TokenType=TokenType.Function;
                        }
                    }
                    if (tokenSeparator.Value == "-")
                    {
                        if (TokenIsNegator(context))
                        {
                            context.AddToken(new Token("-", TokenType.Negator));
                            continue;
                        }
                    }
                    context.AddToken(tokenSeparator);
                    context.NewToken();
                    continue;
                }
                context.AppendToCurrentToken(c);
            }
            if (context.CurrentTokenHasValue)
            {
                context.AddToken(CreateToken(context, worksheet));
            }

            CleanupTokens(context);

            return context.Result;
        }
        public IEnumerable <Token> Tokenize(string input, string worksheet)
        {
            if (string.IsNullOrEmpty(input))
            {
                return(Enumerable.Empty <Token>());
            }
            // MA 1401: Ignore leading plus in formula.
            input = input.TrimStart('+');
            var context = new TokenizerContext(input);

            for (int i = 0; i < context.FormulaChars.Length; i++)
            {
                var   c = context.FormulaChars[i];
                Token tokenSeparator;
                if (CharIsTokenSeparator(c, out tokenSeparator))
                {
                    if (context.IsInString)
                    {
                        if (tokenSeparator.TokenType == TokenType.String && i + 1 < context.FormulaChars.Length && context.FormulaChars[i + 1] == '\'')
                        {
                            i++;
                            context.AppendToCurrentToken(c);
                            continue;
                        }
                        else if (tokenSeparator.TokenType != TokenType.String)
                        {
                            context.AppendToCurrentToken(c);
                            continue;
                        }
                    }
                    if (tokenSeparator.TokenType == TokenType.OpeningBracket)
                    {
                        context.AppendToCurrentToken(c);
                        context.BracketCount++;
                        continue;
                    }
                    if (tokenSeparator.TokenType == TokenType.ClosingBracket)
                    {
                        context.AppendToCurrentToken(c);
                        context.BracketCount--;
                        continue;
                    }
                    if (context.BracketCount > 0)
                    {
                        context.AppendToCurrentToken(c);
                        continue;
                    }
                    // two operators in sequence could be "<=" or ">="
                    if (IsPartOfMultipleCharSeparator(context, c))
                    {
                        var sOp = context.LastToken.Value + c.ToString(CultureInfo.InvariantCulture);
                        var op  = _tokenProvider.Tokens[sOp];
                        context.ReplaceLastToken(op);
                        context.NewToken();
                        continue;
                    }
                    if (tokenSeparator.TokenType == TokenType.String)
                    {
                        if (context.LastToken != null && context.LastToken.TokenType == TokenType.OpeningEnumerable)
                        {
                            context.AppendToCurrentToken(c);
                            context.ToggleIsInString();
                            continue;
                        }
                        else if (context.LastToken != null &&
                                 context.LastToken.TokenType == TokenType.String &&
                                 !context.CurrentTokenHasValue) //Added check for enumartion
                        {
                            // We are dealing with an empty string ('').
                            context.AddToken(new Token(string.Empty, TokenType.StringContent));
                        }
                        context.ToggleIsInString();
                    }
                    if (context.CurrentTokenHasValue)
                    {
                        context.AddToken(CreateToken(context, worksheet));
                        //If the a next token is an opening parantheses and the previous token is interpeted as an address or name, then the currenct token is a function
                        if (tokenSeparator.TokenType == TokenType.OpeningParenthesis && (context.LastToken.TokenType == TokenType.ExcelAddress || context.LastToken.TokenType == TokenType.NameValue))
                        {
                            context.LastToken.TokenType = TokenType.Function;
                        }
                    }
                    if (tokenSeparator.Value == "-")
                    {
                        if (TokenIsNegator(context))
                        {
                            context.AddToken(new Token("-", TokenType.Negator));
                            continue;
                        }
                    }
                    context.AddToken(tokenSeparator);
                    context.NewToken();
                    continue;
                }
                context.AppendToCurrentToken(c);
            }
            if (context.CurrentTokenHasValue)
            {
                context.AddToken(CreateToken(context, worksheet));
            }

            CleanupTokens(context);

            return(context.Result);
        }
Esempio n. 4
0
        private void Handle()
        {
            var c = _context.FormulaChars[_tokenIndex];

            if (this.CharIsTokenSeparator(c, out var tokenSeparator))
            {
                if (TokenSeparatorHandler.Handle(c, tokenSeparator, _context, this))
                {
                    return;
                }

                if (_context.CurrentTokenHasValue)
                {
                    if (Regex.IsMatch(_context.CurrentToken, "^\"*$"))
                    {
                        _context.AddToken(_tokenFactory.Create(_context.CurrentToken, TokenType.StringContent));
                    }
                    else
                    {
                        _context.AddToken(CreateToken(_context, this.Worksheet));
                    }

                    //If the a next token is an opening parantheses and the previous token is interpeted as an address or name, then the currenct token is a function
                    if (tokenSeparator.TokenType == TokenType.OpeningParenthesis && (_context.LastToken.TokenType == TokenType.ExcelAddress || _context.LastToken.TokenType == TokenType.NameValue))
                    {
                        _context.LastToken.TokenType = TokenType.Function;
                    }
                }
                if (tokenSeparator.Value == "-")
                {
                    if (TokenIsNegator(_context))
                    {
                        _context.AddToken(new Token("-", TokenType.Negator));
                        return;
                    }
                }
                _context.AddToken(tokenSeparator);
                _context.NewToken();
                return;
            }
            else if (c == '#' && !_context.CurrentTokenHasValue && !_context.IsInSheetName && !_context.IsInString)
            {
                do
                {
                    _context.AppendToCurrentToken(c);
                    _tokenIndex++;
                    if (_tokenIndex > _context.FormulaChars.Length - 1)
                    {
                        break;
                    }
                    c = _context.FormulaChars[_tokenIndex];
                }while (!ExcelErrorValue.Values.TryGetErrorType(_context.CurrentToken, out _));
                _tokenIndex--;
                if (this.CharIsTokenSeparator(c, out _) || _tokenIndex == _context.FormulaChars.Length - 1)
                {
                    ExcelErrorValue.Values.TryGetErrorType(_context.CurrentToken, out eErrorType errorType);
                    switch (errorType)
                    {
                    case eErrorType.Div0:
                        _context.AddToken(new Token(_context.CurrentToken, TokenType.DivideByZeroError));
                        break;

                    case eErrorType.NA:
                        _context.AddToken(new Token(_context.CurrentToken, TokenType.NotApplicableError));
                        break;

                    case eErrorType.Name:
                        _context.AddToken(new Token(_context.CurrentToken, TokenType.NameError));
                        break;

                    case eErrorType.Null:
                        _context.AddToken(new Token(_context.CurrentToken, TokenType.Null));
                        break;

                    case eErrorType.Num:
                        _context.AddToken(new Token(_context.CurrentToken, TokenType.NumericError));
                        break;

                    case eErrorType.Ref:
                        // Let #REF! errors be handled in the TokenFactory.
                        return;

                    case eErrorType.Value:
                        _context.AddToken(new Token(_context.CurrentToken, TokenType.ValueDataTypeError));
                        break;
                    }
                    _context.NewToken();
                }
                return;
            }
            _context.AppendToCurrentToken(c);
        }