Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/FormulaParsing/LexicalAnalysis/TokenFactory.cs @ 13397

Last change on this file since 13397 was 12074, checked in by sraggl, 9 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 7.1 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 * ******************************************************************************
29 * Mats Alm                       Added                   2013-03-01 (Prior file history on https://github.com/swmal/ExcelFormulaParser)
30 * Jan Källman                      Replaced Adress validate    2013-03-01
31 * *******************************************************************************/
32using System;
33using System.Collections.Generic;
34using System.Globalization;
35using System.Linq;
36using System.Text;
37using System.Text.RegularExpressions;
38using OfficeOpenXml.FormulaParsing;
39using OfficeOpenXml.FormulaParsing.Excel.Functions;
40using OfficeOpenXml.FormulaParsing.ExcelUtilities;
41using OfficeOpenXml.FormulaParsing.Utilities;
42using OfficeOpenXml;
43
44namespace OfficeOpenXml.FormulaParsing.LexicalAnalysis
45{
46    public class TokenFactory : ITokenFactory
47    {
48        public TokenFactory(IFunctionNameProvider functionRepository, INameValueProvider nameValueProvider)
49            : this(new TokenSeparatorProvider(), nameValueProvider, functionRepository)
50        {
51
52        }
53
54        public TokenFactory(ITokenSeparatorProvider tokenSeparatorProvider, INameValueProvider nameValueProvider, IFunctionNameProvider functionNameProvider)
55        {
56            _tokenSeparatorProvider = tokenSeparatorProvider;
57            _functionNameProvider = functionNameProvider;
58            _nameValueProvider = nameValueProvider;
59        }
60
61        private readonly ITokenSeparatorProvider _tokenSeparatorProvider;
62        private readonly IFunctionNameProvider _functionNameProvider;
63        private readonly INameValueProvider _nameValueProvider;
64        public Token Create(IEnumerable<Token> tokens, string token)
65        {
66            return Create(tokens, token, null);
67        }
68        public Token Create(IEnumerable<Token> tokens, string token, string worksheet)
69        {
70            Token tokenSeparator = null;
71            if (_tokenSeparatorProvider.Tokens.TryGetValue(token, out tokenSeparator))
72            {
73                return tokenSeparator;
74            }
75            var tokenList = (IList<Token>)tokens;
76            //Address with worksheet-string before  /JK
77            if (token.StartsWith("!") && tokenList[tokenList.Count-1].TokenType == TokenType.String)
78            {
79                string addr = "";
80                var i = tokenList.Count - 2;
81                if (i > 0)
82                {
83                    if (tokenList[i].TokenType == TokenType.StringContent)
84                    {
85                        addr = "'" + tokenList[i].Value.Replace("'", "''") + "'";
86                    }
87                    else
88                    {
89                        throw(new ArgumentException(string.Format("Invalid formula token sequence near {0}",token)));
90                    }
91                    //Remove the string tokens and content
92                    tokenList.RemoveAt(tokenList.Count - 1);
93                    tokenList.RemoveAt(tokenList.Count - 1);
94                    tokenList.RemoveAt(tokenList.Count - 1);
95
96                    return new Token(addr + token, TokenType.ExcelAddress);
97                }
98                else
99                {
100                    throw(new ArgumentException(string.Format("Invalid formula token sequence near {0}",token)));
101                }
102               
103            }
104
105            if (tokens.Any() && tokens.Last().TokenType == TokenType.String)
106            {
107                return new Token(token, TokenType.StringContent);
108            }
109            if (!string.IsNullOrEmpty(token))
110            {
111                token = token.Trim();
112            }
113            if (Regex.IsMatch(token, RegexConstants.Decimal))
114            {
115                return new Token(token, TokenType.Decimal);
116            }
117            if(Regex.IsMatch(token, RegexConstants.Integer))
118            {
119                return new Token(token, TokenType.Integer);
120            }
121            if (Regex.IsMatch(token, RegexConstants.Boolean, RegexOptions.IgnoreCase))
122            {
123                return new Token(token, TokenType.Boolean);
124            }
125            if (token.ToUpper(CultureInfo.InvariantCulture).Contains("#REF!"))
126            {
127                return new Token(token, TokenType.InvalidReference);
128            }
129            if (token.ToUpper(CultureInfo.InvariantCulture) == "#NUM!")
130            {
131                return new Token(token, TokenType.NumericError);
132            }
133            if (token.ToUpper(CultureInfo.InvariantCulture) == "#VALUE!")
134            {
135                return new Token(token, TokenType.ValueDataTypeError);
136            }
137            if (token.ToUpper(CultureInfo.InvariantCulture) == "#NULL!")
138            {
139                return new Token(token, TokenType.Null);
140            }
141            if (_nameValueProvider != null && _nameValueProvider.IsNamedValue(token, worksheet))
142            {
143                return new Token(token, TokenType.NameValue);
144            }
145            if (_functionNameProvider.IsFunctionName(token))
146            {
147                return new Token(token, TokenType.Function);
148            }
149            if (tokenList.Count > 0 && tokenList[tokenList.Count - 1].TokenType == TokenType.OpeningEnumerable)
150            {
151                return new Token(token, TokenType.Enumerable);
152            }
153            var at = OfficeOpenXml.ExcelAddressBase.IsValid(token);
154            if (at==ExcelAddressBase.AddressType.InternalAddress)
155            {
156                return new Token(token.ToUpper(CultureInfo.InvariantCulture), TokenType.ExcelAddress);
157            }
158            return new Token(token, TokenType.Unrecognized);
159
160        }
161
162        public Token Create(string token, TokenType explicitTokenType)
163        {
164            return new Token(token, explicitTokenType);
165        }
166    }
167}
Note: See TracBrowser for help on using the repository browser.