Ejemplo n.º 1
0
        /// <summary>
        ///     Reads a bracket, constant, operator or function token in the input string starting at the specified index.
        /// </summary>
        /// <param name="input">The input string.</param>
        /// <param name="index">The index to start at.</param>
        /// <returns>The <see cref="Token" /> that has been read.</returns>
        public static Token <string> ReadStringToken(string input, ref int index)
        {
            TokenType newType;
            var       endIndex = index;

            while (endIndex < input.Length &&
                   (char.IsLetter(input, endIndex) || CharEx.IsMathematicOperator(input[endIndex]) ||
                    CharEx.IsBracket(input[endIndex])))
            {
                endIndex++;
                var currentString = input.Substring(index, endIndex - index);
                if (_functionActions.ContainsKey(currentString) || _operatorActions.ContainsKey(currentString) ||
                    _constantActions.ContainsKey(currentString) ||
                    currentString.IsBracket()
                    )      // Last two conditions to parse e.g. "* sin(5)" correctly: As soon as the current token has finished, we should stop reading.
                {
                    break; // This indicates that it has been found in the dictionary, so that is already it.
                }
            }

            var stringToken = input.Substring(index, endIndex - index);

            if (_functionActions.ContainsKey(stringToken))
            {
                newType = TokenType.Function;
            }
            else if (_operatorActions.ContainsKey(stringToken))
            {
                newType = TokenType.Operator;
            }
            else if (stringToken.IsBracket())
            {
                newType = TokenType.Bracket;
            }
            else if (_constantActions.ContainsKey(stringToken))
            {
                newType = TokenType.Constant;
            }
            else
            {
                throw new ParserException(
                          $"Invalid token: {stringToken} is not a valid function/operator, bracket or number equivalent.");
            }

            index = endIndex;
            return(new Token <string>(stringToken, newType));
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Reads a bracket, operator or function token in the input string starting at the specified index.
        /// </summary>
        /// <param name="input">The input string.</param>
        /// <param name="index">The index to start at.</param>
        /// <returns>The <see cref="Token" /> that has been read.</returns>
        public static Token <string> ReadStringToken(string input, ref int index)
        {
            TokenType newType;
            int       endIndex = index;

            while (endIndex < input.Length &&
                   (char.IsLetter(input, endIndex) || CharEx.IsMathematicOperator(input[endIndex]) ||
                    CharEx.IsBracket(input[endIndex])))
            {
                endIndex++;
                string currentString = input.Substring(index, endIndex - index);
                if (_functionActions.ContainsKey(currentString) || _operatorActions.ContainsKey(currentString) ||
                    currentString.IsBracket()) // Last two conditions to parse e.g. "* sin(5)" correctly
                {
                    break;
                }
            }

            string stringToken = input.Substring(index, endIndex - index);

            if (_functionActions.ContainsKey(stringToken))
            {
                newType = TokenType.Function;
            }
            else if (_operatorActions.ContainsKey(stringToken))
            {
                newType = TokenType.Operator;
            }
            else if (stringToken.IsBracket())
            {
                newType = TokenType.Bracket;
            }
            else
            {
                throw new ParserException(
                          $"Invalid token: {stringToken} is not a valid function/operator, bracket or number equivalent.");
            }

            index = endIndex;
            return(new Token <string>(stringToken, newType));
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Creates an <see cref="IEnumerable{Token}" /> containing infix tokens from partitioning the specified term.
        /// </summary>
        /// <param name="term">The term to partition into infix tokens.</param>
        /// <returns><see cref="IEnumerable{Token}" /> containing the created infix tokens.</returns>
        public static IEnumerable <Token> CalculateInfixTokens(string term)
        {
            var infixTokens = new List <Token>();

            term = SWhitespace.Replace(term, string.Empty).ToLowerInvariant();
            var i = 0;

            while (i < term.Length)
            {
                var current = term[i];
                if (char.IsLetter(current) || CharEx.IsMathematicOperator(current) || CharEx.IsBracket(current))
                // Functions/Operators/Constants
                {
                    if ((current == '+' || current == '-') &&
                        (i == 0 ||
                         infixTokens.Last().Type == TokenType.Bracket &&
                         ((Token <string>)infixTokens.Last()).Value == "("))
                    // Must be a sign and handled differently.
                    {
                        if (current == '-')
                        {
                            var sb = new StringBuilder(term)
                            {
                                [term.IndexOf(current)] = '!'
                            };
                            term = sb.ToString();
                        }
                        else
                        {
                            term.Remove(term.IndexOf(current), 1);
                        }

                        // Remove the '+' as it is redundant and disturbs our calculations
                    }

                    infixTokens.Add(ReadStringToken(term, ref i));
                }
                else if (char.IsDigit(current)) // Numbers
                {
                    infixTokens.Add(ReadNumberToken(term, ref i));
                }
                else
                {
                    throw new ParserException($"Char {current} cannot be interpreted as a valid token.");
                }
            }

            return(infixTokens);
        }